diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index 9709680300d3..d21c994cb977 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -242,8 +242,11 @@ impl TreeNodeRef> for AbstractNode { } } - fn is_root(&self) -> bool { - self.parent_node().is_none() + fn is_document(&self) -> bool { + match self.type_id() { + DocumentNodeTypeId(*) => true, + _ => false + } } } @@ -327,11 +330,6 @@ impl<'self, View> AbstractNode { self.node().next_sibling } - /// Is this node a root? - pub fn is_root(self) -> bool { - self.parent_node().is_none() - } - // // Downcasting borrows // @@ -434,13 +432,6 @@ impl<'self, View> AbstractNode { self.transmute_mut(f) } - pub fn is_document(self) -> bool { - match self.type_id() { - DocumentNodeTypeId(*) => true, - _ => false - } - } - // FIXME: This should be doing dynamic borrow checking for safety. pub fn with_imm_element(self, f: &fn(&Element) -> R) -> R { if !self.is_element() { diff --git a/src/components/style/selector_matching.rs b/src/components/style/selector_matching.rs index a4fc7975de19..723119fdeae1 100644 --- a/src/components/style/selector_matching.rs +++ b/src/components/style/selector_matching.rs @@ -478,6 +478,8 @@ fn matches_simple_selector, T: TreeNodeRefAsElement, E: Ele } FirstChild => matches_first_child(element), + Root => matches_root(element), + Negation(ref negated) => { !negated.iter().all(|s| matches_simple_selector(s, element)) }, @@ -491,6 +493,15 @@ fn url_is_visited(_url: &str) -> bool { false } +#[inline] +fn matches_root, T: TreeNodeRefAsElement, E: ElementLike>( + element: &T) -> bool { + match element.node().parent_node() { + Some(parent) => parent.is_document(), + None => false + } +} + #[inline] fn matches_first_child, T: TreeNodeRefAsElement, E: ElementLike>( element: &T) -> bool { @@ -502,8 +513,14 @@ fn matches_first_child, T: TreeNodeRefAsElement, E: Element if node.is_element() { return false } + }, + None => match node.node().parent_node() { + // Selectors level 3 says :first-child does not match the + // root of the document; Warning, level 4 says, for the time + // being, the contrary... + Some(parent) => return !parent.is_document(), + None => return false } - None => return !element.is_root(), } } } diff --git a/src/components/style/selectors.rs b/src/components/style/selectors.rs index ce732068a608..aa7bdb03bca5 100644 --- a/src/components/style/selectors.rs +++ b/src/components/style/selectors.rs @@ -64,7 +64,7 @@ pub enum SimpleSelector { Visited, FirstChild, // Empty, -// Root, + Root, // Lang(~str), // NthChild(i32, i32), // ... @@ -190,8 +190,9 @@ fn compute_specificity(mut selector: &CompoundSelector, &ClassSelector(*) | &AttrExists(*) | &AttrEqual(*) | &AttrIncludes(*) | &AttrDashMatch(*) | &AttrPrefixMatch(*) | &AttrSubstringMatch(*) | &AttrSuffixMatch(*) - | &AnyLink | &Link | &Visited | &FirstChild -// | &Empty | &Root | &Lang(*) | &NthChild(*) + | &AnyLink | &Link | &Visited + | &FirstChild | &Root +// | &Empty | &Lang(*) | &NthChild(*) => specificity.class_like_selectors += 1, &NamespaceSelector(*) => (), &Negation(ref negated) @@ -437,7 +438,7 @@ fn parse_simple_pseudo_class(name: &str) -> Option { "link" => Some(Link), "visited" => Some(Visited), "first-child" => Some(FirstChild), -// "root" => Some(Root), + "root" => Some(Root), // "empty" => Some(Empty), _ => None } diff --git a/src/components/util/tree.rs b/src/components/util/tree.rs index c84de3495793..7f41dd2958e4 100644 --- a/src/components/util/tree.rs +++ b/src/components/util/tree.rs @@ -263,7 +263,7 @@ pub trait TreeNodeRef: Clone { fn is_element(&self) -> bool; - fn is_root(&self) -> bool; + fn is_document(&self) -> bool; } pub trait TreeNodeRefAsElement: TreeNodeRef { diff --git a/src/test/html/test-css-pseudo-root.html b/src/test/html/test-css-pseudo-root.html new file mode 100644 index 000000000000..f82349d5ea44 --- /dev/null +++ b/src/test/html/test-css-pseudo-root.html @@ -0,0 +1,17 @@ + + + + + + :root test + + + + The background of the page should be green and you should see not red at all. +

And the background of this sentence should be green too.

+ + diff --git a/src/test/ref/basic.list b/src/test/ref/basic.list index 3a4742786b38..778c344d0e34 100644 --- a/src/test/ref/basic.list +++ b/src/test/ref/basic.list @@ -1,3 +1,5 @@ == basic_width_px.html basic_width_em.html == hello_a.html hello_b.html == margin_a.html margin_b.html +== root_pseudo_a.html root_pseudo_b.html +== first_child_pseudo_a.html first_child_pseudo_b.html diff --git a/src/test/ref/first_child_pseudo_a.html b/src/test/ref/first_child_pseudo_a.html new file mode 100644 index 000000000000..467999d711f2 --- /dev/null +++ b/src/test/ref/first_child_pseudo_a.html @@ -0,0 +1,25 @@ + + + + :first-child test + + + +

+

+

+

+ + diff --git a/src/test/ref/first_child_pseudo_b.html b/src/test/ref/first_child_pseudo_b.html new file mode 100644 index 000000000000..5ddf44ad4df4 --- /dev/null +++ b/src/test/ref/first_child_pseudo_b.html @@ -0,0 +1,22 @@ + + + + :first-child test + + + +

+

+

+

+ + diff --git a/src/test/ref/root_pseudo_a.html b/src/test/ref/root_pseudo_a.html new file mode 100644 index 000000000000..e54e4ab013a7 --- /dev/null +++ b/src/test/ref/root_pseudo_a.html @@ -0,0 +1,15 @@ + + + + :root test + + + + The background of the page should be green and you should see not red at all. +

And the background of this sentence should be green too.

+ + diff --git a/src/test/ref/root_pseudo_b.html b/src/test/ref/root_pseudo_b.html new file mode 100644 index 000000000000..4b6d7a04ffcd --- /dev/null +++ b/src/test/ref/root_pseudo_b.html @@ -0,0 +1,13 @@ + + + + :root test + + + + The background of the page should be green and you should see not red at all. +

And the background of this sentence should be green too.

+ +