CSS: Use libutil’s traits in Selector matching to not depend on libscript.

This commit is contained in:
Simon Sapin 2013-10-16 20:20:29 +01:00
parent 6d808fbdd0
commit b0f694d5b0
5 changed files with 27 additions and 28 deletions

View file

@ -235,7 +235,7 @@ DONE_script = $(B)src/components/script/libscript.dummy
DEPS_script = $(CRATE_script) $(SRC_script) $(DONE_SUBMODULES) $(DONE_util) $(DONE_net) $(DONE_gfx) $(DONE_msg)
RFLAGS_style = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/util -L $(B)src/components/script -L $(B)src/components/gfx -L $(B)src/components/net -L $(B)src/components/msg
RFLAGS_style = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/util
MAKO_ZIP = $(S)src/components/style/Mako-0.8.1.zip
MAKO_style = $(S)src/components/style/properties.rs
MAKO_SRC_style = $(MAKO_style).mako
@ -243,8 +243,7 @@ SRC_style = $(call rwildcard,$(S)src/components/style/,*.rs) $(MAKO_style)
CRATE_style = $(S)src/components/style/style.rc
DONE_style = $(B)src/components/style/libstyle.dummy
# TODO: reverse the dependency with script
DEPS_style = $(CRATE_style) $(SRC_style) $(DONE_SUBMODULES) $(DONE_util) $(DONE_script)
DEPS_style = $(CRATE_style) $(SRC_style) $(DONE_SUBMODULES) $(DONE_util)
RFLAGS_servo = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/gfx -L $(B)src/components/util -L $(B)src/components/net -L $(B)src/components/script -L $(B)src/components/style -L $(B)src/components/msg

View file

@ -155,7 +155,7 @@ impl<View> TreeNodeRef<Node<View>> for AbstractNode<View> {
self.transmute_mut(callback)
}
fn is_element(self) -> bool {
fn is_element(&self) -> bool {
match self.type_id() {
ElementNodeTypeId(*) => true,
_ => false
@ -165,7 +165,7 @@ impl<View> TreeNodeRef<Node<View>> for AbstractNode<View> {
impl<View> TreeNodeRefAsElement<Node<View>, Element> for AbstractNode<View> {
#[inline]
fn with_imm_element_like<R>(self, f: &fn(&Element) -> R) -> R {
fn with_imm_element_like<R>(&self, f: &fn(&Element) -> R) -> R {
self.with_imm_element(f)
}
}

View file

@ -9,9 +9,7 @@ use selectors::*;
use stylesheets::parse_stylesheet;
use media_queries::{Device, Screen};
use properties::{PropertyDeclaration, PropertyDeclarationBlock};
use script::dom::node::{AbstractNode, ScriptView};
use script::dom::element::Element;
use servo_util::tree::{TreeNodeRef, ElementLike};
use servo_util::tree::{TreeNodeRefAsElement, TreeNode, ElementLike};
pub enum StylesheetOrigin {
@ -78,10 +76,9 @@ impl Stylist {
}
}
pub fn get_applicable_declarations(&self, element: AbstractNode<ScriptView>,
style_attribute: Option<&PropertyDeclarationBlock>,
pseudo_element: Option<PseudoElement>)
-> ~[@[PropertyDeclaration]] {
pub fn get_applicable_declarations<N: TreeNode<T>, T: TreeNodeRefAsElement<N, E>, E: ElementLike>(
&self, element: &T, style_attribute: Option<&PropertyDeclarationBlock>,
pseudo_element: Option<PseudoElement>) -> ~[@[PropertyDeclaration]] {
assert!(element.is_element())
assert!(style_attribute.is_none() || pseudo_element.is_none(),
"Style attributes do not apply to pseudo-elements")
@ -90,7 +87,7 @@ impl Stylist {
macro_rules! append(
($rules: expr) => {
for rule in $rules.iter() {
if matches_selector(rule.selector, element, pseudo_element) {
if matches_selector::<N, T, E>(rule.selector, element, pseudo_element) {
applicable_declarations.push(rule.declarations)
}
}
@ -144,16 +141,16 @@ impl Ord for Rule {
#[inline]
fn matches_selector(selector: &Selector, element: AbstractNode<ScriptView>,
pseudo_element: Option<PseudoElement>) -> bool {
fn matches_selector<N: TreeNode<T>, T: TreeNodeRefAsElement<N, E>, E: ElementLike>(
selector: &Selector, element: &T, pseudo_element: Option<PseudoElement>) -> bool {
selector.pseudo_element == pseudo_element &&
matches_compound_selector(&selector.compound_selectors, element)
matches_compound_selector::<N, T, E>(&selector.compound_selectors, element)
}
fn matches_compound_selector(selector: &CompoundSelector,
element: AbstractNode<ScriptView>) -> bool {
if do element.with_imm_element |element| {
fn matches_compound_selector<N: TreeNode<T>, T: TreeNodeRefAsElement<N, E>, E: ElementLike>(
selector: &CompoundSelector, element: &T) -> bool {
if do element.with_imm_element_like |element: &E| {
!do selector.simple_selectors.iter().all |simple_selector| {
matches_simple_selector(simple_selector, element)
}
@ -169,14 +166,17 @@ fn matches_compound_selector(selector: &CompoundSelector,
NextSibling => (true, true),
LaterSibling => (true, false),
};
let mut node = element;
let mut node = element.clone();
loop {
match if siblings { node.prev_sibling() } else { node.parent_node() } {
let next_node = do node.with_base |node| {
if siblings { node.prev_sibling() } else { node.parent_node() }
};
match next_node {
None => return false,
Some(next_node) => node = next_node,
}
if node.is_element() {
if matches_compound_selector(&**next_selector, node) {
if matches_compound_selector(&**next_selector, &node) {
return true
} else if just_one {
return false
@ -188,13 +188,14 @@ fn matches_compound_selector(selector: &CompoundSelector,
}
#[inline]
fn matches_simple_selector(selector: &SimpleSelector, element: &Element) -> bool {
fn matches_simple_selector<E: ElementLike>(selector: &SimpleSelector, element: &E) -> bool {
static WHITESPACE: &'static [char] = &'static [' ', '\t', '\n', '\r', '\x0C'];
match *selector {
// TODO: case-sensitivity depends on the document type
// TODO: intern element names
LocalNameSelector(ref name) => element.tag_name.eq_ignore_ascii_case(name.as_slice()),
LocalNameSelector(ref name)
=> element.get_local_name().eq_ignore_ascii_case(name.as_slice()),
NamespaceSelector(_) => false, // TODO, when the DOM supports namespaces on elements.
// TODO: case-sensitivity depends on the document type and quirks mode
// TODO: cache and intern IDs on elements.
@ -234,7 +235,7 @@ fn matches_simple_selector(selector: &SimpleSelector, element: &Element) -> bool
#[inline]
fn match_attribute(attr: &AttrSelector, element: &Element, f: &fn(&str)-> bool) -> bool {
fn match_attribute<E: ElementLike>(attr: &AttrSelector, element: &E, f: &fn(&str)-> bool) -> bool {
match attr.namespace {
Some(_) => false, // TODO, when the DOM supports namespaces on attributes
None => match element.get_attr(attr.name) {

View file

@ -15,7 +15,6 @@
extern mod extra;
extern mod cssparser;
extern mod servo_util (name = "util");
extern mod script;
// The "real" public API

View file

@ -249,11 +249,11 @@ pub trait TreeNodeRef<Node>: Clone {
TreeIterator::new(nodes)
}
fn is_element(self) -> bool;
fn is_element(&self) -> bool;
}
pub trait TreeNodeRefAsElement<Node, E: ElementLike>: TreeNodeRef<Node> {
fn with_imm_element_like<R>(self, f: &fn(&E) -> R) -> R;
fn with_imm_element_like<R>(&self, f: &fn(&E) -> R) -> R;
}
fn gather<Node, Ref: TreeNodeRef<Node>>(cur: &Ref, refs: &mut ~[Ref],