mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
auto merge of #1297 : SimonSapin/servo/last-child, r=SimonSapin
Same as #1296, with a fixed commit message.
This commit is contained in:
commit
df7ec2613b
7 changed files with 132 additions and 2 deletions
|
@ -478,6 +478,10 @@ fn matches_simple_selector<N: TreeNode<T>, T: TreeNodeRefAsElement<N, E>, E: Ele
|
|||
}
|
||||
FirstChild => matches_first_child(element),
|
||||
|
||||
LastChild => matches_last_child(element),
|
||||
|
||||
OnlyChild => matches_first_child(element) && matches_last_child(element),
|
||||
|
||||
Root => matches_root(element),
|
||||
|
||||
Negation(ref negated) => {
|
||||
|
@ -525,6 +529,29 @@ fn matches_first_child<N: TreeNode<T>, T: TreeNodeRefAsElement<N, E>, E: Element
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn matches_last_child<N: TreeNode<T>, T: TreeNodeRefAsElement<N, E>, E: ElementLike>(
|
||||
element: &T) -> bool {
|
||||
let mut node = element.clone();
|
||||
loop {
|
||||
match node.node().next_sibling() {
|
||||
Some(next_sibling) => {
|
||||
node = next_sibling;
|
||||
if node.is_element() {
|
||||
return false
|
||||
}
|
||||
},
|
||||
None => match node.node().parent_node() {
|
||||
// Selectors level 3 says :last-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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn match_attribute<N: TreeNode<T>, T: TreeNodeRefAsElement<N, E>, E: ElementLike>(
|
||||
attr: &AttrSelector, element: &T, f: &fn(&str)-> bool) -> bool {
|
||||
|
|
|
@ -62,7 +62,7 @@ pub enum SimpleSelector {
|
|||
AnyLink,
|
||||
Link,
|
||||
Visited,
|
||||
FirstChild,
|
||||
FirstChild, LastChild, OnlyChild,
|
||||
// Empty,
|
||||
Root,
|
||||
// Lang(~str),
|
||||
|
@ -191,7 +191,7 @@ fn compute_specificity(mut selector: &CompoundSelector,
|
|||
| &AttrExists(*) | &AttrEqual(*) | &AttrIncludes(*) | &AttrDashMatch(*)
|
||||
| &AttrPrefixMatch(*) | &AttrSubstringMatch(*) | &AttrSuffixMatch(*)
|
||||
| &AnyLink | &Link | &Visited
|
||||
| &FirstChild | &Root
|
||||
| &FirstChild | &LastChild | &OnlyChild | &Root
|
||||
// | &Empty | &Lang(*) | &NthChild(*)
|
||||
=> specificity.class_like_selectors += 1,
|
||||
&NamespaceSelector(*) => (),
|
||||
|
@ -438,6 +438,8 @@ fn parse_simple_pseudo_class(name: &str) -> Option<SimpleSelector> {
|
|||
"link" => Some(Link),
|
||||
"visited" => Some(Visited),
|
||||
"first-child" => Some(FirstChild),
|
||||
"last-child" => Some(LastChild),
|
||||
"only-child" => Some(OnlyChild),
|
||||
"root" => Some(Root),
|
||||
// "empty" => Some(Empty),
|
||||
_ => None
|
||||
|
|
|
@ -3,3 +3,5 @@
|
|||
== margin_a.html margin_b.html
|
||||
== root_pseudo_a.html root_pseudo_b.html
|
||||
== first_child_pseudo_a.html first_child_pseudo_b.html
|
||||
== last_child_pseudo_a.html last_child_pseudo_b.html
|
||||
== only_child_pseudo_a.html only_child_pseudo_b.html
|
||||
|
|
25
src/test/ref/last_child_pseudo_a.html
Normal file
25
src/test/ref/last_child_pseudo_a.html
Normal file
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>:last-child test</title>
|
||||
<style type="text/css">
|
||||
html:last-child { background: red; }
|
||||
html { background: yellow;}
|
||||
|
||||
p { width: 20px; height: 20px; background: orange; float: left; margin-left: 10px; }
|
||||
div { clear: both; }
|
||||
#p1, #p2, #p3 { background: red; }
|
||||
#d1 > *:last-child { background: green }
|
||||
#d2 > *:last-child { background: green }
|
||||
#d3 > *:last-child { background: green }
|
||||
#p4 { background: green; }
|
||||
#d4 > *:last-child { background: red }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="d1"><p> </p><p id="p1"> </p></div>
|
||||
<div id="d2"><p> </p><p id="p2"> </p> </div>
|
||||
<div id="d3"><p> </p><p id="p3"> </p><!-- comment --></div>
|
||||
<div id="d4"><p> </p><p id="p4"> </p><span> </span></div>
|
||||
</body>
|
||||
</html>
|
22
src/test/ref/last_child_pseudo_b.html
Normal file
22
src/test/ref/last_child_pseudo_b.html
Normal file
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>:last-child test</title>
|
||||
<style type="text/css">
|
||||
html { background: yellow;}
|
||||
|
||||
p { width: 20px; height: 20px; background: orange; float: left; margin-left: 10px; }
|
||||
div { clear: both; }
|
||||
#p1 { background: green; }
|
||||
#p2 { background: green; }
|
||||
#p3 { background: green; }
|
||||
#p4 { background: green; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="d1"><p> </p><p id="p1"> </p></div>
|
||||
<div id="d2"><p> </p><p id="p2"> </p> </div>
|
||||
<div id="d3"><p> </p><p id="p3"> </p><!-- comment --></div>
|
||||
<div id="d4"><p> </p><p id="p4"> </p><span> </span></div>
|
||||
</body>
|
||||
</html>
|
29
src/test/ref/only_child_pseudo_a.html
Normal file
29
src/test/ref/only_child_pseudo_a.html
Normal file
|
@ -0,0 +1,29 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>:only-child test</title>
|
||||
<style type="text/css">
|
||||
html:only-child { background: red; }
|
||||
html { background: yellow;}
|
||||
|
||||
p { width: 20px; height: 20px; background: orange; float: left; margin-left: 10px; }
|
||||
div { clear: both; }
|
||||
#d1 > p, #d2 > p, #d3 > p, #d4 > p { background: red; }
|
||||
#d1 > *:only-child { background: green }
|
||||
#d2 > *:only-child { background: green }
|
||||
#d3 > *:only-child { background: green }
|
||||
#d4 > *:only-child { background: green }
|
||||
#p5, #p6 { background: green; }
|
||||
#d5 > *:only-child { background: red }
|
||||
#d6 > *:only-child { background: red }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="d1"><p> </p></div>
|
||||
<div id="d2"> <p> </p></div>
|
||||
<div id="d3"><p> </p><!-- comment --></div>
|
||||
<div id="d4"><!-- comment --><p> </p></div>
|
||||
<div id="d5"><p id="p5"> </p><span> </span></div>
|
||||
<div id="d6"><span> </span><p id="p6"> </p></div>
|
||||
</body>
|
||||
</html>
|
23
src/test/ref/only_child_pseudo_b.html
Normal file
23
src/test/ref/only_child_pseudo_b.html
Normal file
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>:only-child test</title>
|
||||
<style type="text/css">
|
||||
html:only-child { background: red; }
|
||||
html { background: yellow;}
|
||||
|
||||
p { width: 20px; height: 20px; background: orange; float: left; margin-left: 10px; }
|
||||
div { clear: both; }
|
||||
#d1 > p, #d2 > p, #d3 > p, #d4 > p { background: green; }
|
||||
#p5, #p6 { background: green; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="d1"><p> </p></div>
|
||||
<div id="d2"> <p> </p></div>
|
||||
<div id="d3"><p> </p><!-- comment --></div>
|
||||
<div id="d4"><!-- comment --><p> </p></div>
|
||||
<div id="d5"><p id="p5"> </p><span> </span></div>
|
||||
<div id="d6"><span> </span><p id="p6"> </p></div>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue