From 57d02dc0e9cf7837fea43e13c203853651e734d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Tue, 13 Jun 2017 17:11:56 +0300 Subject: [PATCH] Handle PseudoElement case in :active and :hover quirk --- components/selectors/matching.rs | 29 +++++++++++++++++++---------- components/style/gecko/wrapper.rs | 6 +++--- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/components/selectors/matching.rs b/components/selectors/matching.rs index 3ab8f83c004..62cd7ee5448 100644 --- a/components/selectors/matching.rs +++ b/components/selectors/matching.rs @@ -66,11 +66,12 @@ pub struct LocalMatchingContext<'a, 'b: 'a, Impl: SelectorImpl> { /// been advanced partway through the current compound selector, and the callee may need /// the whole thing. offset: usize, - /// Holds a bool flag to see if LocalMatchingContext is within a functional - /// pseudo class argument. This is used for pseudo classes like - /// `:-moz-any` or `:not`. If this flag is true, :active and :hover - /// quirk shouldn't match. - pub within_functional_pseudo_class_argument: bool, + /// Holds a bool flag to see whether :active and :hover quirk should try to + /// match or not. This flag can only be true in these two cases: + /// - LocalMatchingContext is currently within a functional pseudo class + /// like `:-moz-any` or `:not`. + /// - PseudoElements are encountered when matching mode is ForStatelessPseudoElement. + pub hover_active_quirk_disabled: bool, } impl<'a, 'b, Impl> LocalMatchingContext<'a, 'b, Impl> @@ -83,7 +84,8 @@ impl<'a, 'b, Impl> LocalMatchingContext<'a, 'b, Impl> shared: shared, selector: selector, offset: 0, - within_functional_pseudo_class_argument: false, + // We flip this off once third sequence is reached. + hover_active_quirk_disabled: selector.has_pseudo_element(), } } @@ -91,6 +93,13 @@ impl<'a, 'b, Impl> LocalMatchingContext<'a, 'b, Impl> /// To be able to correctly re-synthesize main SelectorIter. pub fn note_next_sequence(&mut self, selector_iter: &SelectorIter) { if let QuirksMode::Quirks = self.shared.quirks_mode() { + if self.selector.has_pseudo_element() && self.offset != 0 { + // This is the _second_ call to note_next_sequence, + // which means we've moved past the compound + // selector adjacent to the pseudo-element. + self.hover_active_quirk_disabled = false; + } + self.offset = self.selector.len() - selector_iter.selector_length(); } } @@ -99,7 +108,7 @@ impl<'a, 'b, Impl> LocalMatchingContext<'a, 'b, Impl> /// https://quirks.spec.whatwg.org/#the-active-and-hover-quirk pub fn active_hover_quirk_matches(&mut self) -> bool { if self.shared.quirks_mode() != QuirksMode::Quirks || - self.within_functional_pseudo_class_argument { + self.hover_active_quirk_disabled { return false; } @@ -717,13 +726,13 @@ fn matches_simple_selector( matches_generic_nth_child(element, 0, 1, true, true, flags_setter) } Component::Negation(ref negated) => { - let old_value = context.within_functional_pseudo_class_argument; - context.within_functional_pseudo_class_argument = true; + let old_value = context.hover_active_quirk_disabled; + context.hover_active_quirk_disabled = true; let result = !negated.iter().all(|ss| { matches_simple_selector(ss, element, context, relevant_link, flags_setter) }); - context.within_functional_pseudo_class_argument = old_value; + context.hover_active_quirk_disabled = old_value; result } } diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index b419e258e45..461b96e0f90 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -1566,12 +1566,12 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { } NonTSPseudoClass::MozPlaceholder => false, NonTSPseudoClass::MozAny(ref sels) => { - let old_value = context.within_functional_pseudo_class_argument; - context.within_functional_pseudo_class_argument = true; + let old_value = context.hover_active_quirk_disabled; + context.hover_active_quirk_disabled = true; let result = sels.iter().any(|s| { matches_complex_selector(s.iter(), self, context, flags_setter) }); - context.within_functional_pseudo_class_argument = old_value; + context.hover_active_quirk_disabled = old_value; result } NonTSPseudoClass::Lang(ref lang_arg) => {