diff --git a/components/selectors/matching.rs b/components/selectors/matching.rs index f55833f7fb6..3414f9d6efa 100644 --- a/components/selectors/matching.rs +++ b/components/selectors/matching.rs @@ -322,13 +322,8 @@ where }, } - for component in &mut iter { - // The only other parser-allowed Components in this sequence are - // state pseudo-classes, or one of the other things that can contain - // them. - if !component.matches_for_stateless_pseudo_element() { - return false; - } + if !iter.matches_for_stateless_pseudo_element() { + return false; } // Advance to the non-pseudo-element part of the selector. diff --git a/components/selectors/parser.rs b/components/selectors/parser.rs index e2ad8e30caf..e66fa75c587 100644 --- a/components/selectors/parser.rs +++ b/components/selectors/parser.rs @@ -802,6 +802,33 @@ impl<'a, Impl: 'a + SelectorImpl> SelectorIter<'a, Impl> { self.next_sequence().is_none() } + #[inline] + pub(crate) fn matches_for_stateless_pseudo_element(&mut self) -> bool { + let first = match self.next() { + Some(c) => c, + // Note that this is the common path that we keep inline: the + // pseudo-element not having anything to its right. + None => return true, + }; + self.matches_for_stateless_pseudo_element_internal(first) + } + + #[inline(never)] + fn matches_for_stateless_pseudo_element_internal(&mut self, first: &Component) -> bool { + if !first.matches_for_stateless_pseudo_element() { + return false; + } + for component in self { + // The only other parser-allowed Components in this sequence are + // state pseudo-classes, or one of the other things that can contain + // them. + if !component.matches_for_stateless_pseudo_element() { + return false; + } + } + true + } + /// Returns remaining count of the simple selectors and combinators in the Selector. #[inline] pub fn selector_length(&self) -> usize { @@ -1076,7 +1103,7 @@ impl Component { /// `maybe_allowed_after_pseudo_element` should end up here, and /// `NonTSPseudoClass` never matches (as it is a stateless pseudo after /// all). - pub(crate) fn matches_for_stateless_pseudo_element(&self) -> bool { + fn matches_for_stateless_pseudo_element(&self) -> bool { debug_assert!( self.maybe_allowed_after_pseudo_element(), "Someone messed up pseudo-element parsing: {:?}",