1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
commit 4112ea0d8cb1
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date: Mon Oct 30 11:02:16 2017 -0400
Bug 1412011 - selectors: Be consistent about how we get a parent element for selector matching. r=xidorn, a=ritu
Source-Repo: https://github.com/servo/servo
Source-Revision: de7595f16fa41c32ca5654aef53c60ad19bb108a
--HG--
extra : rebase_source : fc932c8d05ec1861ee16d7a89bfe1da1228d1c08
---
servo/components/selectors/matching.rs | 49 +++++++++++++++++++++++-----------
1 file changed, 33 insertions(+), 16 deletions(-)
diff --git servo/components/selectors/matching.rs servo/components/selectors/matching.rs
index c6c2db3c4719..30586b27f457 100644
--- servo/components/selectors/matching.rs
+++ servo/components/selectors/matching.rs
@@ -515,6 +515,32 @@ pub fn matches_complex_selector<E, F>(mut iter: SelectorIter<E::Impl>,
}
}
+#[inline(always)]
+fn next_element_for_combinator<E>(
+ element: &E,
+ combinator: Combinator,
+) -> Option<E>
+where
+ E: Element,
+{
+ match combinator {
+ Combinator::NextSibling |
+ Combinator::LaterSibling => {
+ element.prev_sibling_element()
+ }
+ Combinator::Child |
+ Combinator::Descendant => {
+ if element.blocks_ancestor_combinators() {
+ return None;
+ }
+ element.parent_element()
+ }
+ Combinator::PseudoElement => {
+ element.pseudo_element_originating_element()
+ }
+ }
+}
+
fn matches_complex_selector_internal<E, F>(mut selector_iter: SelectorIter<E::Impl>,
element: &E,
context: &mut LocalMatchingContext<E::Impl>,
@@ -546,28 +572,23 @@ fn matches_complex_selector_internal<E, F>(mut selector_iter: SelectorIter<E::Im
match combinator {
None => SelectorMatchingResult::Matched,
Some(c) => {
- let (mut next_element, candidate_not_found) = match c {
+ let candidate_not_found= match c {
Combinator::NextSibling | Combinator::LaterSibling => {
// Only ancestor combinators are allowed while looking for
// relevant links, so switch to not looking.
*relevant_link = RelevantLinkStatus::NotLooking;
- (element.prev_sibling_element(),
- SelectorMatchingResult::NotMatchedAndRestartFromClosestDescendant)
+ SelectorMatchingResult::NotMatchedAndRestartFromClosestDescendant
}
Combinator::Child | Combinator::Descendant => {
- if element.blocks_ancestor_combinators() {
- (None, SelectorMatchingResult::NotMatchedGlobally)
- } else {
- (element.parent_element(),
- SelectorMatchingResult::NotMatchedGlobally)
- }
+ SelectorMatchingResult::NotMatchedGlobally
}
Combinator::PseudoElement => {
- (element.pseudo_element_originating_element(),
- SelectorMatchingResult::NotMatchedGlobally)
+ SelectorMatchingResult::NotMatchedGlobally
}
};
+ let mut next_element = next_element_for_combinator(element, c);
+
loop {
let element = match next_element {
None => return candidate_not_found,
@@ -607,11 +628,7 @@ fn matches_complex_selector_internal<E, F>(mut selector_iter: SelectorIter<E::Im
// can continue to matching on the next candidate element.
_ => {},
}
- next_element = if siblings {
- element.prev_sibling_element()
- } else {
- element.parent_element()
- };
+ next_element = next_element_for_combinator(&element, c);
}
}
}
|