diff --git a/components/layout_thread/dom_wrapper.rs b/components/layout_thread/dom_wrapper.rs index 14a2e5f3867..1b58f9f81b5 100644 --- a/components/layout_thread/dom_wrapper.rs +++ b/components/layout_thread/dom_wrapper.rs @@ -713,7 +713,6 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> { &self, pseudo_class: &NonTSPseudoClass, _: &mut MatchingContext, - _: VisitedHandlingMode, _: &mut F, ) -> bool where @@ -1221,7 +1220,6 @@ impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> { &self, _: &NonTSPseudoClass, _: &mut MatchingContext, - _: VisitedHandlingMode, _: &mut F, ) -> bool where diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 30ac45802a8..4c7d4be40d8 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -89,7 +89,6 @@ use script_layout_interface::message::ReflowGoal; use script_thread::ScriptThread; use selectors::Element as SelectorsElement; use selectors::attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivity}; -use selectors::context::VisitedHandlingMode; use selectors::matching::{ElementSelectorFlags, MatchingContext}; use selectors::sink::Push; use servo_arc::Arc; @@ -2636,7 +2635,6 @@ impl<'a> SelectorsElement for DomRoot { &self, pseudo_class: &NonTSPseudoClass, _: &mut MatchingContext, - _: VisitedHandlingMode, _: &mut F, ) -> bool where diff --git a/components/selectors/context.rs b/components/selectors/context.rs index be18c29e1f9..4df494eca98 100644 --- a/components/selectors/context.rs +++ b/components/selectors/context.rs @@ -105,8 +105,6 @@ where pub bloom_filter: Option<&'a BloomFilter>, /// An optional cache to speed up nth-index-like selectors. pub nth_index_cache: Option<&'a mut NthIndexCache>, - /// Input that controls how matching for links is handled. - pub visited_handling: VisitedHandlingMode, /// The element which is going to match :scope pseudo-class. It can be /// either one :scope element, or the scoping element. /// @@ -120,10 +118,13 @@ where /// See https://drafts.csswg.org/selectors-4/#scope-pseudo pub scope_element: Option, + /// Controls how matching for links is handled. + visited_handling: VisitedHandlingMode, + /// The current nesting level of selectors that we're matching. /// - /// FIXME(emilio): Consider putting the mutable stuff in a Cell. - /// immutable again. + /// FIXME(emilio): Consider putting the mutable stuff in a Cell, then make + /// MatchingContext immutable again. nesting_level: usize, /// An optional hook function for checking whether a pseudo-element @@ -210,4 +211,26 @@ where self.nesting_level -= 1; result } + + #[inline] + pub fn visited_handling(&self) -> VisitedHandlingMode { + self.visited_handling + } + + /// Runs F with a different VisitedHandlingMode. + #[inline] + pub fn with_visited_handling_mode( + &mut self, + handling_mode: VisitedHandlingMode, + f: F, + ) -> R + where + F: FnOnce(&mut Self) -> R, + { + let original_handling_mode = self.visited_handling; + self.visited_handling = handling_mode; + let result = f(self); + self.visited_handling = original_handling_mode; + result + } } diff --git a/components/selectors/matching.rs b/components/selectors/matching.rs index 2b8e7123ac0..97679e989a9 100644 --- a/components/selectors/matching.rs +++ b/components/selectors/matching.rs @@ -61,7 +61,6 @@ impl ElementSelectorFlags { struct LocalMatchingContext<'a, 'b: 'a, Impl: SelectorImpl> { shared: &'a mut MatchingContext<'b, Impl>, matches_hover_and_active_quirk: MatchesHoverAndActiveQuirk, - visited_handling: VisitedHandlingMode, } #[inline(always)] @@ -245,10 +244,8 @@ where selector.combinator_at_parse_order(from_offset - 1); // This asserts. } - let visited_handling = context.visited_handling; let mut local_context = LocalMatchingContext { shared: context, - visited_handling, matches_hover_and_active_quirk: MatchesHoverAndActiveQuirk::No, }; @@ -321,12 +318,10 @@ where } } - let visited_handling = context.visited_handling; let result = matches_complex_selector_internal( iter, element, context, - visited_handling, flags_setter, Rightmost::Yes, ); @@ -433,7 +428,6 @@ fn matches_complex_selector_internal( mut selector_iter: SelectorIter, element: &E, context: &mut MatchingContext, - visited_handling: VisitedHandlingMode, flags_setter: &mut F, rightmost: Rightmost, ) -> SelectorMatchingResult @@ -447,7 +441,6 @@ where &mut selector_iter, element, context, - visited_handling, flags_setter, rightmost ); @@ -483,12 +476,11 @@ where // Stop matching :visited as soon as we find a link, or a combinator for // something that isn't an ancestor. - let mut visited_handling = - if element.is_link() || combinator.is_sibling() { - VisitedHandlingMode::AllLinksUnvisited - } else { - visited_handling - }; + let mut visited_handling = if element.is_link() || combinator.is_sibling() { + VisitedHandlingMode::AllLinksUnvisited + } else { + context.visited_handling() + }; loop { let element = match next_element { @@ -496,14 +488,16 @@ where Some(next_element) => next_element, }; - let result = matches_complex_selector_internal( - selector_iter.clone(), - &element, - context, - visited_handling, - flags_setter, - Rightmost::No, - ); + let result = + context.with_visited_handling_mode(visited_handling, |context| { + matches_complex_selector_internal( + selector_iter.clone(), + &element, + context, + flags_setter, + Rightmost::No, + ) + }); match (result, combinator) { // Return the status immediately. @@ -537,12 +531,9 @@ where _ => {}, } - visited_handling = - if element.is_link() || combinator.is_sibling() { - VisitedHandlingMode::AllLinksUnvisited - } else { - visited_handling - }; + if element.is_link() || combinator.is_sibling() { + visited_handling = VisitedHandlingMode::AllLinksUnvisited; + } next_element = next_element_for_combinator(&element, combinator); } @@ -570,7 +561,6 @@ fn matches_compound_selector( selector_iter: &mut SelectorIter, element: &E, context: &mut MatchingContext, - visited_handling: VisitedHandlingMode, flags_setter: &mut F, rightmost: Rightmost, ) -> bool @@ -612,7 +602,6 @@ where let mut local_context = LocalMatchingContext { shared: context, - visited_handling, matches_hover_and_active_quirk, }; iter::once(selector).chain(selector_iter).all(|simple| { @@ -738,7 +727,6 @@ where element.match_non_ts_pseudo_class( pc, &mut context.shared, - context.visited_handling, flags_setter ) } @@ -788,10 +776,8 @@ where matches_generic_nth_child(element, context, 0, 1, true, true, flags_setter) } Component::Negation(ref negated) => { - let visited_handling = context.visited_handling; context.shared.nest(|context| { let mut local_context = LocalMatchingContext { - visited_handling, matches_hover_and_active_quirk: MatchesHoverAndActiveQuirk::No, shared: context, }; diff --git a/components/selectors/tree.rs b/components/selectors/tree.rs index 0ae6d7307a5..ea36aac6f89 100644 --- a/components/selectors/tree.rs +++ b/components/selectors/tree.rs @@ -6,7 +6,6 @@ //! between layout and style. use attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivity}; -use context::VisitedHandlingMode; use matching::{ElementSelectorFlags, MatchingContext}; use parser::SelectorImpl; use servo_arc::NonZeroPtrMut; @@ -69,7 +68,6 @@ pub trait Element: Sized + Clone + Debug { &self, pc: &::NonTSPseudoClass, context: &mut MatchingContext, - visited_handling: VisitedHandlingMode, flags_setter: &mut F, ) -> bool where diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 12ff3517192..cdfd8258536 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -1997,7 +1997,6 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { &self, pseudo_class: &NonTSPseudoClass, context: &mut MatchingContext, - visited_handling: VisitedHandlingMode, flags_setter: &mut F, ) -> bool where @@ -2057,10 +2056,10 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { }, NonTSPseudoClass::AnyLink => self.is_link(), NonTSPseudoClass::Link => { - self.is_link() && visited_handling.matches_unvisited() + self.is_link() && context.visited_handling().matches_unvisited() } NonTSPseudoClass::Visited => { - self.is_link() && visited_handling.matches_visited() + self.is_link() && context.visited_handling().matches_visited() } NonTSPseudoClass::MozFirstNode => { flags_setter(self, ElementSelectorFlags::HAS_EDGE_CHILD_SELECTOR); diff --git a/components/style/invalidation/element/element_wrapper.rs b/components/style/invalidation/element/element_wrapper.rs index e2ceedf912d..afd5bbcb2cb 100644 --- a/components/style/invalidation/element/element_wrapper.rs +++ b/components/style/invalidation/element/element_wrapper.rs @@ -11,7 +11,6 @@ use element_state::ElementState; use selector_parser::{NonTSPseudoClass, PseudoElement, SelectorImpl, Snapshot, SnapshotMap, AttrValue}; use selectors::{Element, OpaqueElement}; use selectors::attr::{AttrSelectorOperation, CaseSensitivity, NamespaceConstraint}; -use selectors::context::VisitedHandlingMode; use selectors::matching::{ElementSelectorFlags, MatchingContext}; use std::cell::Cell; use std::fmt; @@ -150,7 +149,6 @@ impl<'a, E> Element for ElementWrapper<'a, E> &self, pseudo_class: &NonTSPseudoClass, context: &mut MatchingContext, - visited_handling: VisitedHandlingMode, _setter: &mut F, ) -> bool where @@ -198,10 +196,10 @@ impl<'a, E> Element for ElementWrapper<'a, E> // Instead, we use the `visited_handling` to determine if they // match. NonTSPseudoClass::Link => { - return self.is_link() && visited_handling.matches_unvisited() + return self.is_link() && context.visited_handling().matches_unvisited() } NonTSPseudoClass::Visited => { - return self.is_link() && visited_handling.matches_visited() + return self.is_link() && context.visited_handling().matches_visited() } #[cfg(feature = "gecko")] @@ -236,7 +234,6 @@ impl<'a, E> Element for ElementWrapper<'a, E> return self.element.match_non_ts_pseudo_class( pseudo_class, context, - visited_handling, &mut |_, _| {}, ) } @@ -246,7 +243,6 @@ impl<'a, E> Element for ElementWrapper<'a, E> self.element.match_non_ts_pseudo_class( pseudo_class, context, - visited_handling, &mut |_, _| {}, ) } diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 8234a0c7b3b..ec8b738bccd 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -1246,7 +1246,7 @@ impl Stylist { // Step 2: Presentational hints. let length_before_preshints = applicable_declarations.len(); element.synthesize_presentational_hints_for_legacy_attributes( - context.visited_handling, + context.visited_handling(), applicable_declarations ); if applicable_declarations.len() != length_before_preshints {