Introduce an NthIndexCache type and pipe it from ThreadLocalStyleContext to MatchingContext.

Some future refactoring here to pass fewer things as parameters would be nice.
This commit is contained in:
Bobby Holley 2017-09-20 12:43:29 -07:00
parent 05c03d5104
commit 48466bf876
11 changed files with 83 additions and 24 deletions

View file

@ -2188,7 +2188,8 @@ impl ElementMethods for Element {
Err(_) => Err(Error::Syntax), Err(_) => Err(Error::Syntax),
Ok(selectors) => { Ok(selectors) => {
let quirks_mode = document_from_node(self).quirks_mode(); let quirks_mode = document_from_node(self).quirks_mode();
let mut ctx = MatchingContext::new(MatchingMode::Normal, None, // FIXME(bholley): Consider an nth-index cache here.
let mut ctx = MatchingContext::new(MatchingMode::Normal, None, None,
quirks_mode); quirks_mode);
Ok(matches_selector_list(&selectors, &Root::from_ref(self), &mut ctx)) Ok(matches_selector_list(&selectors, &Root::from_ref(self), &mut ctx))
} }
@ -2209,7 +2210,8 @@ impl ElementMethods for Element {
for element in root.inclusive_ancestors() { for element in root.inclusive_ancestors() {
if let Some(element) = Root::downcast::<Element>(element) { if let Some(element) = Root::downcast::<Element>(element) {
let quirks_mode = document_from_node(self).quirks_mode(); let quirks_mode = document_from_node(self).quirks_mode();
let mut ctx = MatchingContext::new(MatchingMode::Normal, None, // FIXME(bholley): Consider an nth-index cache here.
let mut ctx = MatchingContext::new(MatchingMode::Normal, None, None,
quirks_mode); quirks_mode);
if matches_selector_list(&selectors, &element, &mut ctx) { if matches_selector_list(&selectors, &element, &mut ctx) {
return Ok(Some(element)); return Ok(Some(element));

View file

@ -363,7 +363,9 @@ impl<'a> Iterator for QuerySelectorIterator {
self.iterator.by_ref().filter_map(|node| { self.iterator.by_ref().filter_map(|node| {
// TODO(cgaebel): Is it worth it to build a bloom filter here // TODO(cgaebel): Is it worth it to build a bloom filter here
// (instead of passing `None`)? Probably. // (instead of passing `None`)? Probably.
let mut ctx = MatchingContext::new(MatchingMode::Normal, None, //
// FIXME(bholley): Consider an nth-index cache here.
let mut ctx = MatchingContext::new(MatchingMode::Normal, None, None,
node.owner_doc().quirks_mode()); node.owner_doc().quirks_mode());
if let Some(element) = Root::downcast(node) { if let Some(element) = Root::downcast(node) {
if matches_selector_list(selectors, &element, &mut ctx) { if matches_selector_list(selectors, &element, &mut ctx) {
@ -754,7 +756,8 @@ impl Node {
Err(_) => Err(Error::Syntax), Err(_) => Err(Error::Syntax),
// Step 3. // Step 3.
Ok(selectors) => { Ok(selectors) => {
let mut ctx = MatchingContext::new(MatchingMode::Normal, None, // FIXME(bholley): Consider an nth-index cache here.
let mut ctx = MatchingContext::new(MatchingMode::Normal, None, None,
self.owner_doc().quirks_mode()); self.owner_doc().quirks_mode());
Ok(self.traverse_preorder().filter_map(Root::downcast).find(|element| { Ok(self.traverse_preorder().filter_map(Root::downcast).find(|element| {
matches_selector_list(&selectors, element, &mut ctx) matches_selector_list(&selectors, element, &mut ctx)

View file

@ -69,15 +69,22 @@ impl QuirksMode {
} }
} }
/// A cache to speed up matching of nth-index-like selectors.
///
/// NB: This is just a dummy type right now, it will be fleshed out in later patches.
#[derive(Default)]
pub struct NthIndexCache(usize);
/// Data associated with the matching process for a element. This context is /// Data associated with the matching process for a element. This context is
/// used across many selectors for an element, so it's not appropriate for /// used across many selectors for an element, so it's not appropriate for
/// transient data that applies to only a single selector. /// transient data that applies to only a single selector.
#[derive(Clone)]
pub struct MatchingContext<'a> { pub struct MatchingContext<'a> {
/// Input with the matching mode we should use when matching selectors. /// Input with the matching mode we should use when matching selectors.
pub matching_mode: MatchingMode, pub matching_mode: MatchingMode,
/// Input with the bloom filter used to fast-reject selectors. /// Input with the bloom filter used to fast-reject selectors.
pub bloom_filter: Option<&'a BloomFilter>, pub bloom_filter: Option<&'a BloomFilter>,
/// An optional cache to speed up nth-index-like selectors.
nth_index_cache: Option<&'a mut NthIndexCache>,
/// Input that controls how matching for links is handled. /// Input that controls how matching for links is handled.
pub visited_handling: VisitedHandlingMode, pub visited_handling: VisitedHandlingMode,
/// Output that records whether we encountered a "relevant link" while /// Output that records whether we encountered a "relevant link" while
@ -94,12 +101,14 @@ impl<'a> MatchingContext<'a> {
/// Constructs a new `MatchingContext`. /// Constructs a new `MatchingContext`.
pub fn new(matching_mode: MatchingMode, pub fn new(matching_mode: MatchingMode,
bloom_filter: Option<&'a BloomFilter>, bloom_filter: Option<&'a BloomFilter>,
nth_index_cache: Option<&'a mut NthIndexCache>,
quirks_mode: QuirksMode) quirks_mode: QuirksMode)
-> Self -> Self
{ {
Self { Self {
matching_mode: matching_mode, matching_mode: matching_mode,
bloom_filter: bloom_filter, bloom_filter: bloom_filter,
nth_index_cache: nth_index_cache,
visited_handling: VisitedHandlingMode::AllLinksUnvisited, visited_handling: VisitedHandlingMode::AllLinksUnvisited,
relevant_link_found: false, relevant_link_found: false,
quirks_mode: quirks_mode, quirks_mode: quirks_mode,
@ -110,6 +119,7 @@ impl<'a> MatchingContext<'a> {
/// Constructs a new `MatchingContext` for use in visited matching. /// Constructs a new `MatchingContext` for use in visited matching.
pub fn new_for_visited(matching_mode: MatchingMode, pub fn new_for_visited(matching_mode: MatchingMode,
bloom_filter: Option<&'a BloomFilter>, bloom_filter: Option<&'a BloomFilter>,
nth_index_cache: Option<&'a mut NthIndexCache>,
visited_handling: VisitedHandlingMode, visited_handling: VisitedHandlingMode,
quirks_mode: QuirksMode) quirks_mode: QuirksMode)
-> Self -> Self
@ -119,6 +129,7 @@ impl<'a> MatchingContext<'a> {
bloom_filter: bloom_filter, bloom_filter: bloom_filter,
visited_handling: visited_handling, visited_handling: visited_handling,
relevant_link_found: false, relevant_link_found: false,
nth_index_cache: nth_index_cache,
quirks_mode: quirks_mode, quirks_mode: quirks_mode,
classes_and_ids_case_sensitivity: quirks_mode.classes_and_ids_case_sensitivity(), classes_and_ids_case_sensitivity: quirks_mode.classes_and_ids_case_sensitivity(),
} }

View file

@ -724,26 +724,26 @@ fn matches_simple_selector<E, F>(
element.is_empty() element.is_empty()
} }
Component::NthChild(a, b) => { Component::NthChild(a, b) => {
matches_generic_nth_child(element, a, b, false, false, flags_setter) matches_generic_nth_child(element, context, a, b, false, false, flags_setter)
} }
Component::NthLastChild(a, b) => { Component::NthLastChild(a, b) => {
matches_generic_nth_child(element, a, b, false, true, flags_setter) matches_generic_nth_child(element, context, a, b, false, true, flags_setter)
} }
Component::NthOfType(a, b) => { Component::NthOfType(a, b) => {
matches_generic_nth_child(element, a, b, true, false, flags_setter) matches_generic_nth_child(element, context, a, b, true, false, flags_setter)
} }
Component::NthLastOfType(a, b) => { Component::NthLastOfType(a, b) => {
matches_generic_nth_child(element, a, b, true, true, flags_setter) matches_generic_nth_child(element, context, a, b, true, true, flags_setter)
} }
Component::FirstOfType => { Component::FirstOfType => {
matches_generic_nth_child(element, 0, 1, true, false, flags_setter) matches_generic_nth_child(element, context, 0, 1, true, false, flags_setter)
} }
Component::LastOfType => { Component::LastOfType => {
matches_generic_nth_child(element, 0, 1, true, true, flags_setter) matches_generic_nth_child(element, context, 0, 1, true, true, flags_setter)
} }
Component::OnlyOfType => { Component::OnlyOfType => {
matches_generic_nth_child(element, 0, 1, true, false, flags_setter) && matches_generic_nth_child(element, context, 0, 1, true, false, flags_setter) &&
matches_generic_nth_child(element, 0, 1, true, true, flags_setter) matches_generic_nth_child(element, context, 0, 1, true, true, flags_setter)
} }
Component::Negation(ref negated) => { Component::Negation(ref negated) => {
context.nesting_level += 1; context.nesting_level += 1;
@ -767,6 +767,7 @@ fn select_name<'a, T>(is_html: bool, local_name: &'a T, local_name_lower: &'a T)
#[inline] #[inline]
fn matches_generic_nth_child<E, F>(element: &E, fn matches_generic_nth_child<E, F>(element: &E,
context: &mut LocalMatchingContext<E::Impl>,
a: i32, a: i32,
b: i32, b: i32,
is_of_type: bool, is_of_type: bool,

View file

@ -23,6 +23,7 @@ use properties::ComputedValues;
use rule_cache::RuleCache; use rule_cache::RuleCache;
use rule_tree::StrongRuleNode; use rule_tree::StrongRuleNode;
use selector_parser::{EAGER_PSEUDO_COUNT, SnapshotMap}; use selector_parser::{EAGER_PSEUDO_COUNT, SnapshotMap};
use selectors::context::NthIndexCache;
use selectors::matching::ElementSelectorFlags; use selectors::matching::ElementSelectorFlags;
use servo_arc::Arc; use servo_arc::Arc;
#[cfg(feature = "servo")] use servo_atoms::Atom; #[cfg(feature = "servo")] use servo_atoms::Atom;
@ -719,6 +720,8 @@ pub struct ThreadLocalStyleContext<E: TElement> {
/// A checker used to ensure that parallel.rs does not recurse indefinitely /// A checker used to ensure that parallel.rs does not recurse indefinitely
/// even on arbitrarily deep trees. See Gecko bug 1376883. /// even on arbitrarily deep trees. See Gecko bug 1376883.
pub stack_limit_checker: StackLimitChecker, pub stack_limit_checker: StackLimitChecker,
/// A cache for nth-index-like selectors.
pub nth_index_cache: NthIndexCache,
} }
impl<E: TElement> ThreadLocalStyleContext<E> { impl<E: TElement> ThreadLocalStyleContext<E> {
@ -737,6 +740,7 @@ impl<E: TElement> ThreadLocalStyleContext<E> {
font_metrics_provider: E::FontMetricsProvider::create_from(shared), font_metrics_provider: E::FontMetricsProvider::create_from(shared),
stack_limit_checker: StackLimitChecker::new( stack_limit_checker: StackLimitChecker::new(
(STYLE_THREAD_STACK_SIZE_KB - STACK_SAFETY_MARGIN_KB) * 1024), (STYLE_THREAD_STACK_SIZE_KB - STACK_SAFETY_MARGIN_KB) * 1024),
nth_index_cache: NthIndexCache::default(),
} }
} }
@ -754,6 +758,7 @@ impl<E: TElement> ThreadLocalStyleContext<E> {
font_metrics_provider: E::FontMetricsProvider::create_from(shared), font_metrics_provider: E::FontMetricsProvider::create_from(shared),
stack_limit_checker: StackLimitChecker::new( stack_limit_checker: StackLimitChecker::new(
(STYLE_THREAD_STACK_SIZE_KB - STACK_SAFETY_MARGIN_KB) * 1024), (STYLE_THREAD_STACK_SIZE_KB - STACK_SAFETY_MARGIN_KB) * 1024),
nth_index_cache: NthIndexCache::default(),
} }
} }

View file

@ -633,10 +633,12 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E>
debug!("TreeStyleInvalidator::process_invalidation({:?}, {:?}, {:?})", debug!("TreeStyleInvalidator::process_invalidation({:?}, {:?}, {:?})",
self.element, invalidation, invalidation_kind); self.element, invalidation, invalidation_kind);
// FIXME(bholley): Consider passing an nth-index cache here.
let mut context = let mut context =
MatchingContext::new_for_visited( MatchingContext::new_for_visited(
MatchingMode::Normal, MatchingMode::Normal,
None, None,
None,
VisitedHandlingMode::AllLinksVisitedAndUnvisited, VisitedHandlingMode::AllLinksVisitedAndUnvisited,
self.shared_context.quirks_mode(), self.shared_context.quirks_mode(),
); );
@ -946,12 +948,14 @@ impl<'a, 'b: 'a, E> InvalidationCollector<'a, 'b, E>
// whether any parent had a snapshot, and whether those snapshots were // whether any parent had a snapshot, and whether those snapshots were
// taken due to an element class/id change, but it's not clear it'd be // taken due to an element class/id change, but it's not clear it'd be
// worth it. // worth it.
//
// FIXME(bholley): Consider passing an nth-index cache here.
let mut now_context = let mut now_context =
MatchingContext::new_for_visited(MatchingMode::Normal, None, MatchingContext::new_for_visited(MatchingMode::Normal, None, None,
VisitedHandlingMode::AllLinksUnvisited, VisitedHandlingMode::AllLinksUnvisited,
self.shared_context.quirks_mode()); self.shared_context.quirks_mode());
let mut then_context = let mut then_context =
MatchingContext::new_for_visited(MatchingMode::Normal, None, MatchingContext::new_for_visited(MatchingMode::Normal, None, None,
VisitedHandlingMode::AllLinksUnvisited, VisitedHandlingMode::AllLinksUnvisited,
self.shared_context.quirks_mode()); self.shared_context.quirks_mode());

View file

@ -10,6 +10,7 @@ use Atom;
use bloom::StyleBloom; use bloom::StyleBloom;
use context::{SelectorFlagsMap, SharedStyleContext}; use context::{SelectorFlagsMap, SharedStyleContext};
use dom::TElement; use dom::TElement;
use selectors::context::NthIndexCache;
use sharing::{StyleSharingCandidate, StyleSharingTarget}; use sharing::{StyleSharingCandidate, StyleSharingTarget};
/// Determines whether a target and a candidate have compatible parents for sharing. /// Determines whether a target and a candidate have compatible parents for sharing.
@ -99,16 +100,25 @@ pub fn revalidate<E>(target: &mut StyleSharingTarget<E>,
candidate: &mut StyleSharingCandidate<E>, candidate: &mut StyleSharingCandidate<E>,
shared_context: &SharedStyleContext, shared_context: &SharedStyleContext,
bloom: &StyleBloom<E>, bloom: &StyleBloom<E>,
nth_index_cache: &mut NthIndexCache,
selector_flags_map: &mut SelectorFlagsMap<E>) selector_flags_map: &mut SelectorFlagsMap<E>)
-> bool -> bool
where E: TElement, where E: TElement,
{ {
let stylist = &shared_context.stylist; let stylist = &shared_context.stylist;
let for_element = let for_element = target.revalidation_match_results(
target.revalidation_match_results(stylist, bloom, selector_flags_map); stylist,
bloom,
nth_index_cache,
selector_flags_map,
);
let for_candidate = candidate.revalidation_match_results(stylist, bloom); let for_candidate = candidate.revalidation_match_results(
stylist,
bloom,
nth_index_cache,
);
// This assert "ensures", to some extent, that the two candidates have // This assert "ensures", to some extent, that the two candidates have
// matched the same rulehash buckets, and as such, that the bits we're // matched the same rulehash buckets, and as such, that the bits we're

View file

@ -75,6 +75,7 @@ use matching::MatchMethods;
use owning_ref::OwningHandle; use owning_ref::OwningHandle;
use properties::ComputedValues; use properties::ComputedValues;
use rule_tree::StrongRuleNode; use rule_tree::StrongRuleNode;
use selectors::context::NthIndexCache;
use selectors::matching::{ElementSelectorFlags, VisitedHandlingMode}; use selectors::matching::{ElementSelectorFlags, VisitedHandlingMode};
use servo_arc::{Arc, NonZeroPtrMut}; use servo_arc::{Arc, NonZeroPtrMut};
use smallbitvec::SmallBitVec; use smallbitvec::SmallBitVec;
@ -203,6 +204,7 @@ impl ValidationData {
element: E, element: E,
stylist: &Stylist, stylist: &Stylist,
bloom: &StyleBloom<E>, bloom: &StyleBloom<E>,
nth_index_cache: &mut NthIndexCache,
bloom_known_valid: bool, bloom_known_valid: bool,
flags_setter: &mut F flags_setter: &mut F
) -> &SmallBitVec ) -> &SmallBitVec
@ -230,6 +232,7 @@ impl ValidationData {
self.revalidation_match_results = self.revalidation_match_results =
Some(stylist.match_revalidation_selectors(&element, Some(stylist.match_revalidation_selectors(&element,
bloom_to_use, bloom_to_use,
nth_index_cache,
flags_setter)); flags_setter));
} }
@ -289,11 +292,13 @@ impl<E: TElement> StyleSharingCandidate<E> {
&mut self, &mut self,
stylist: &Stylist, stylist: &Stylist,
bloom: &StyleBloom<E>, bloom: &StyleBloom<E>,
nth_index_cache: &mut NthIndexCache,
) -> &SmallBitVec { ) -> &SmallBitVec {
self.validation_data.revalidation_match_results( self.validation_data.revalidation_match_results(
self.element, self.element,
stylist, stylist,
bloom, bloom,
nth_index_cache,
/* bloom_known_valid = */ false, /* bloom_known_valid = */ false,
&mut |_, _| {}) &mut |_, _| {})
} }
@ -346,6 +351,7 @@ impl<E: TElement> StyleSharingTarget<E> {
&mut self, &mut self,
stylist: &Stylist, stylist: &Stylist,
bloom: &StyleBloom<E>, bloom: &StyleBloom<E>,
nth_index_cache: &mut NthIndexCache,
selector_flags_map: &mut SelectorFlagsMap<E> selector_flags_map: &mut SelectorFlagsMap<E>
) -> &SmallBitVec { ) -> &SmallBitVec {
// It's important to set the selector flags. Otherwise, if we succeed in // It's important to set the selector flags. Otherwise, if we succeed in
@ -372,6 +378,7 @@ impl<E: TElement> StyleSharingTarget<E> {
self.element, self.element,
stylist, stylist,
bloom, bloom,
nth_index_cache,
/* bloom_known_valid = */ true, /* bloom_known_valid = */ true,
&mut set_selector_flags) &mut set_selector_flags)
} }
@ -385,6 +392,7 @@ impl<E: TElement> StyleSharingTarget<E> {
let shared_context = &context.shared; let shared_context = &context.shared;
let selector_flags_map = &mut context.thread_local.selector_flags; let selector_flags_map = &mut context.thread_local.selector_flags;
let bloom_filter = &context.thread_local.bloom_filter; let bloom_filter = &context.thread_local.bloom_filter;
let nth_index_cache = &mut context.thread_local.nth_index_cache;
if cache.dom_depth != bloom_filter.matching_depth() { if cache.dom_depth != bloom_filter.matching_depth() {
debug!("Can't share style, because DOM depth changed from {:?} to {:?}, element: {:?}", debug!("Can't share style, because DOM depth changed from {:?} to {:?}, element: {:?}",
@ -398,6 +406,7 @@ impl<E: TElement> StyleSharingTarget<E> {
shared_context, shared_context,
selector_flags_map, selector_flags_map,
bloom_filter, bloom_filter,
nth_index_cache,
self self
) )
} }
@ -596,6 +605,7 @@ impl<E: TElement> StyleSharingCache<E> {
shared_context: &SharedStyleContext, shared_context: &SharedStyleContext,
selector_flags_map: &mut SelectorFlagsMap<E>, selector_flags_map: &mut SelectorFlagsMap<E>,
bloom_filter: &StyleBloom<E>, bloom_filter: &StyleBloom<E>,
nth_index_cache: &mut NthIndexCache,
target: &mut StyleSharingTarget<E>, target: &mut StyleSharingTarget<E>,
) -> Option<ResolvedElementStyles> { ) -> Option<ResolvedElementStyles> {
if shared_context.options.disable_style_sharing_cache { if shared_context.options.disable_style_sharing_cache {
@ -621,6 +631,7 @@ impl<E: TElement> StyleSharingCache<E> {
candidate, candidate,
&shared_context, &shared_context,
bloom_filter, bloom_filter,
nth_index_cache,
selector_flags_map selector_flags_map
) )
}) })
@ -631,6 +642,7 @@ impl<E: TElement> StyleSharingCache<E> {
candidate: &mut StyleSharingCandidate<E>, candidate: &mut StyleSharingCandidate<E>,
shared: &SharedStyleContext, shared: &SharedStyleContext,
bloom: &StyleBloom<E>, bloom: &StyleBloom<E>,
nth_index_cache: &mut NthIndexCache,
selector_flags_map: &mut SelectorFlagsMap<E> selector_flags_map: &mut SelectorFlagsMap<E>
) -> Option<ResolvedElementStyles> { ) -> Option<ResolvedElementStyles> {
// Check that we have the same parent, or at least that the parents // Check that we have the same parent, or at least that the parents
@ -705,7 +717,7 @@ impl<E: TElement> StyleSharingCache<E> {
} }
if !checks::revalidate(target, candidate, shared, bloom, if !checks::revalidate(target, candidate, shared, bloom,
selector_flags_map) { nth_index_cache, selector_flags_map) {
trace!("Miss: Revalidation"); trace!("Miss: Revalidation");
return None; return None;
} }

View file

@ -413,10 +413,12 @@ where
let map = &mut self.context.thread_local.selector_flags; let map = &mut self.context.thread_local.selector_flags;
let bloom_filter = self.context.thread_local.bloom_filter.filter(); let bloom_filter = self.context.thread_local.bloom_filter.filter();
let nth_index_cache = &mut self.context.thread_local.nth_index_cache;
let mut matching_context = let mut matching_context =
MatchingContext::new_for_visited( MatchingContext::new_for_visited(
MatchingMode::Normal, MatchingMode::Normal,
Some(bloom_filter), Some(bloom_filter),
Some(nth_index_cache),
visited_handling, visited_handling,
self.context.shared.quirks_mode(), self.context.shared.quirks_mode(),
); );
@ -486,11 +488,13 @@ where
} }
let bloom_filter = self.context.thread_local.bloom_filter.filter(); let bloom_filter = self.context.thread_local.bloom_filter.filter();
let nth_index_cache = &mut self.context.thread_local.nth_index_cache;
let mut matching_context = let mut matching_context =
MatchingContext::new_for_visited( MatchingContext::new_for_visited(
MatchingMode::ForStatelessPseudoElement, MatchingMode::ForStatelessPseudoElement,
Some(bloom_filter), Some(bloom_filter),
Some(nth_index_cache),
visited_handling, visited_handling,
self.context.shared.quirks_mode(), self.context.shared.quirks_mode(),
); );

View file

@ -30,7 +30,7 @@ use selector_map::{PrecomputedHashMap, SelectorMap, SelectorMapEntry};
use selector_parser::{SelectorImpl, PerPseudoElementMap, PseudoElement}; use selector_parser::{SelectorImpl, PerPseudoElementMap, PseudoElement};
use selectors::attr::NamespaceConstraint; use selectors::attr::NamespaceConstraint;
use selectors::bloom::{BloomFilter, NonCountingBloomFilter}; use selectors::bloom::{BloomFilter, NonCountingBloomFilter};
use selectors::matching::{ElementSelectorFlags, matches_selector, MatchingContext, MatchingMode}; use selectors::matching::{ElementSelectorFlags, matches_selector, MatchingContext, MatchingMode, NthIndexCache};
use selectors::matching::VisitedHandlingMode; use selectors::matching::VisitedHandlingMode;
use selectors::parser::{AncestorHashes, Combinator, Component, Selector}; use selectors::parser::{AncestorHashes, Combinator, Component, Selector};
use selectors::parser::{SelectorIter, SelectorMethods}; use selectors::parser::{SelectorIter, SelectorMethods};
@ -1027,6 +1027,7 @@ impl Stylist {
let mut declarations = ApplicableDeclarationList::new(); let mut declarations = ApplicableDeclarationList::new();
let mut matching_context = let mut matching_context =
MatchingContext::new(MatchingMode::ForStatelessPseudoElement, MatchingContext::new(MatchingMode::ForStatelessPseudoElement,
None,
None, None,
self.quirks_mode); self.quirks_mode);
@ -1061,6 +1062,7 @@ impl Stylist {
MatchingContext::new_for_visited( MatchingContext::new_for_visited(
MatchingMode::ForStatelessPseudoElement, MatchingMode::ForStatelessPseudoElement,
None, None,
None,
VisitedHandlingMode::RelevantLinkVisited, VisitedHandlingMode::RelevantLinkVisited,
self.quirks_mode, self.quirks_mode,
); );
@ -1203,7 +1205,7 @@ impl Stylist {
V: Push<ApplicableDeclarationBlock> + VecLike<ApplicableDeclarationBlock>, V: Push<ApplicableDeclarationBlock> + VecLike<ApplicableDeclarationBlock>,
{ {
let mut matching_context = let mut matching_context =
MatchingContext::new(MatchingMode::Normal, None, self.quirks_mode); MatchingContext::new(MatchingMode::Normal, None, None, self.quirks_mode);
let mut dummy_flag_setter = |_: &E, _: ElementSelectorFlags| {}; let mut dummy_flag_setter = |_: &E, _: ElementSelectorFlags| {};
let rule_hash_target = element.rule_hash_target(); let rule_hash_target = element.rule_hash_target();
@ -1427,6 +1429,7 @@ impl Stylist {
&self, &self,
element: &E, element: &E,
bloom: Option<&BloomFilter>, bloom: Option<&BloomFilter>,
nth_index_cache: &mut NthIndexCache,
flags_setter: &mut F flags_setter: &mut F
) -> SmallBitVec ) -> SmallBitVec
where where
@ -1435,8 +1438,12 @@ impl Stylist {
{ {
// NB: `MatchingMode` doesn't really matter, given we don't share style // NB: `MatchingMode` doesn't really matter, given we don't share style
// between pseudos. // between pseudos.
let mut matching_context = let mut matching_context = MatchingContext::new(
MatchingContext::new(MatchingMode::Normal, bloom, self.quirks_mode); MatchingMode::Normal,
bloom,
Some(nth_index_cache),
self.quirks_mode
);
// Note that, by the time we're revalidating, we're guaranteed that the // Note that, by the time we're revalidating, we're guaranteed that the
// candidate and the entry have the same id, classes, and local name. // candidate and the entry have the same id, classes, and local name.

View file

@ -1503,7 +1503,7 @@ pub extern "C" fn Servo_StyleRule_SelectorMatchesElement(rule: RawServoStyleRule
}; };
let element = GeckoElement(element); let element = GeckoElement(element);
let mut ctx = MatchingContext::new(matching_mode, None, element.owner_document_quirks_mode()); let mut ctx = MatchingContext::new(matching_mode, None, None, element.owner_document_quirks_mode());
matches_selector(selector, 0, None, &element, &mut ctx, &mut |_, _| {}) matches_selector(selector, 0, None, &element, &mut ctx, &mut |_, _| {})
}) })
} }