selectors: Be consistent about how we get next elements for selector-matching.

This fixes bug 1412011.

MozReview-Commit-ID: JgLoBNjA3m8
This commit is contained in:
Emilio Cobos Álvarez 2017-10-26 17:51:30 +02:00
parent 22dc480272
commit 529f33eb6f
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C

View file

@ -486,6 +486,32 @@ enum Rightmost {
No, No,
} }
#[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>( fn matches_complex_selector_internal<E, F>(
mut selector_iter: SelectorIter<E::Impl>, mut selector_iter: SelectorIter<E::Impl>,
element: &E, element: &E,
@ -538,28 +564,23 @@ where
Some(c) => c, Some(c) => c,
}; };
let (mut next_element, candidate_not_found) = match combinator { let candidate_not_found = match combinator {
Combinator::NextSibling | Combinator::LaterSibling => { Combinator::NextSibling |
Combinator::LaterSibling => {
// Only ancestor combinators are allowed while looking for // Only ancestor combinators are allowed while looking for
// relevant links, so switch to not looking. // relevant links, so switch to not looking.
*relevant_link = RelevantLinkStatus::NotLooking; *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)
}
} }
Combinator::Child |
Combinator::Descendant |
Combinator::PseudoElement => { Combinator::PseudoElement => {
(element.pseudo_element_originating_element(), SelectorMatchingResult::NotMatchedGlobally
SelectorMatchingResult::NotMatchedGlobally)
} }
}; };
let mut next_element = next_element_for_combinator(element, combinator);
loop { loop {
let element = match next_element { let element = match next_element {
None => return candidate_not_found, None => return candidate_not_found,
@ -606,11 +627,7 @@ where
_ => {}, _ => {},
} }
next_element = if siblings { next_element = next_element_for_combinator(&element, combinator);
element.prev_sibling_element()
} else {
element.parent_element()
};
} }
} }