зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 2 changesets (bug 1845095) for causing build bustages related to DummyAtom: PrecomputedHash. CLOSED TREE
Backed out changeset c3549dbe2420 (bug 1845095) Backed out changeset 2b7db53664a6 (bug 1845095)
This commit is contained in:
Родитель
adfbcc4b42
Коммит
8ec6e4224d
|
@ -7,7 +7,6 @@ use crate::bloom::BloomFilter;
|
|||
use crate::nth_index_cache::{NthIndexCache, NthIndexCacheInner};
|
||||
use crate::parser::{Selector, SelectorImpl};
|
||||
use crate::relative_selector::cache::RelativeSelectorCache;
|
||||
use crate::relative_selector::filter::RelativeSelectorFilterMap;
|
||||
use crate::tree::{Element, OpaqueElement};
|
||||
|
||||
/// What kind of selector matching mode we should use.
|
||||
|
@ -78,9 +77,10 @@ pub enum NeedsSelectorFlags {
|
|||
Yes,
|
||||
}
|
||||
|
||||
/// Whether we're matching in the contect of invalidation.
|
||||
/// Whether we need to ignore nth child selectors for this match request (only expected during
|
||||
/// invalidation).
|
||||
#[derive(PartialEq)]
|
||||
pub enum MatchingForInvalidation {
|
||||
pub enum IgnoreNthChildForInvalidation {
|
||||
No,
|
||||
Yes,
|
||||
}
|
||||
|
@ -142,15 +142,13 @@ impl RelativeSelectorMatchingState {
|
|||
}
|
||||
}
|
||||
|
||||
/// Set of caches (And cache-likes) that speed up expensive selector matches.
|
||||
/// Set of caches that speed up expensive selector matches.
|
||||
#[derive(Default)]
|
||||
pub struct SelectorCaches {
|
||||
/// A cache to speed up nth-index-like selectors.
|
||||
pub nth_index: NthIndexCache,
|
||||
/// A cache to speed up relative selector matches. See module documentation.
|
||||
pub relative_selector: RelativeSelectorCache,
|
||||
/// A map of bloom filters to fast-reject relative selector matches.
|
||||
pub relative_selector_filter_map: RelativeSelectorFilterMap,
|
||||
}
|
||||
|
||||
/// Data associated with the matching process for a element. This context is
|
||||
|
@ -203,8 +201,9 @@ where
|
|||
quirks_mode: QuirksMode,
|
||||
needs_selector_flags: NeedsSelectorFlags,
|
||||
|
||||
/// Whether we're matching in the contect of invalidation.
|
||||
matching_for_invalidation: MatchingForInvalidation,
|
||||
/// Whether this match request should ignore nth child selectors (only expected during
|
||||
/// invalidation).
|
||||
ignores_nth_child_selectors_for_invalidation: IgnoreNthChildForInvalidation,
|
||||
|
||||
/// Caches to speed up expensive selector matches.
|
||||
pub selector_caches: &'a mut SelectorCaches,
|
||||
|
@ -224,7 +223,7 @@ where
|
|||
selector_caches: &'a mut SelectorCaches,
|
||||
quirks_mode: QuirksMode,
|
||||
needs_selector_flags: NeedsSelectorFlags,
|
||||
matching_for_invalidation: MatchingForInvalidation,
|
||||
ignores_nth_child_selectors_for_invalidation: IgnoreNthChildForInvalidation,
|
||||
) -> Self {
|
||||
Self::new_for_visited(
|
||||
matching_mode,
|
||||
|
@ -233,7 +232,7 @@ where
|
|||
VisitedHandlingMode::AllLinksUnvisited,
|
||||
quirks_mode,
|
||||
needs_selector_flags,
|
||||
matching_for_invalidation,
|
||||
ignores_nth_child_selectors_for_invalidation,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -245,7 +244,7 @@ where
|
|||
visited_handling: VisitedHandlingMode,
|
||||
quirks_mode: QuirksMode,
|
||||
needs_selector_flags: NeedsSelectorFlags,
|
||||
matching_for_invalidation: MatchingForInvalidation,
|
||||
ignores_nth_child_selectors_for_invalidation: IgnoreNthChildForInvalidation,
|
||||
) -> Self {
|
||||
Self {
|
||||
matching_mode,
|
||||
|
@ -254,7 +253,7 @@ where
|
|||
quirks_mode,
|
||||
classes_and_ids_case_sensitivity: quirks_mode.classes_and_ids_case_sensitivity(),
|
||||
needs_selector_flags,
|
||||
matching_for_invalidation,
|
||||
ignores_nth_child_selectors_for_invalidation,
|
||||
scope_element: None,
|
||||
current_host: None,
|
||||
nesting_level: 0,
|
||||
|
@ -311,10 +310,10 @@ where
|
|||
self.needs_selector_flags == NeedsSelectorFlags::Yes
|
||||
}
|
||||
|
||||
/// Whether or not we're matching to invalidate.
|
||||
/// Whether we need to ignore nth child selectors (only expected during invalidation).
|
||||
#[inline]
|
||||
pub fn matching_for_invalidation(&self) -> bool {
|
||||
self.matching_for_invalidation == MatchingForInvalidation::Yes
|
||||
pub fn ignores_nth_child_selectors_for_invalidation(&self) -> bool {
|
||||
self.ignores_nth_child_selectors_for_invalidation == IgnoreNthChildForInvalidation::Yes
|
||||
}
|
||||
|
||||
/// The case-sensitivity for class and ID selectors
|
||||
|
|
|
@ -429,46 +429,6 @@ fn matches_relative_selector<E: Element>(
|
|||
return false;
|
||||
}
|
||||
|
||||
fn relative_selector_match_early<E: Element>(
|
||||
selector: &RelativeSelector<E::Impl>,
|
||||
element: &E,
|
||||
context: &mut MatchingContext<E::Impl>,
|
||||
) -> Option<bool> {
|
||||
if context.matching_for_invalidation() {
|
||||
// In the context of invalidation, we can't use caching/filtering due to
|
||||
// now/then matches. DOM structure also may have changed, so just pretend
|
||||
// that we always match.
|
||||
return Some(!context.in_negation());
|
||||
}
|
||||
// See if we can return a cached result.
|
||||
if let Some(cached) = context
|
||||
.selector_caches
|
||||
.relative_selector
|
||||
.lookup(element.opaque(), selector)
|
||||
{
|
||||
return Some(cached.matched());
|
||||
}
|
||||
// See if we can fast-reject.
|
||||
if context
|
||||
.selector_caches
|
||||
.relative_selector_filter_map
|
||||
.fast_reject(
|
||||
element,
|
||||
selector,
|
||||
context.quirks_mode(),
|
||||
)
|
||||
{
|
||||
// Alright, add as unmatched to cache.
|
||||
context.selector_caches.relative_selector.add(
|
||||
element.opaque(),
|
||||
selector,
|
||||
RelativeSelectorCachedMatch::NotMatched,
|
||||
);
|
||||
return Some(false);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Matches a relative selector in a list of relative selectors.
|
||||
fn matches_relative_selectors<E: Element>(
|
||||
selectors: &[RelativeSelector<E::Impl>],
|
||||
|
@ -486,11 +446,16 @@ fn matches_relative_selectors<E: Element>(
|
|||
}
|
||||
|
||||
for relative_selector in selectors.iter() {
|
||||
if let Some(result) = relative_selector_match_early(relative_selector, element, context) {
|
||||
if result {
|
||||
// See if we can return a cached result.
|
||||
if let Some(cached) = context
|
||||
.selector_caches
|
||||
.relative_selector
|
||||
.lookup(element.opaque(), &relative_selector)
|
||||
{
|
||||
if cached.matched() {
|
||||
return true;
|
||||
}
|
||||
// Early return indicates no match, continue to next selector.
|
||||
// Did not match, continue on.
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1067,8 +1032,7 @@ where
|
|||
let has_selectors = !selectors.is_empty();
|
||||
let selectors_match =
|
||||
!has_selectors || matches_complex_selector_list(selectors, element, context, rightmost);
|
||||
if context.matching_for_invalidation() {
|
||||
// Skip expensive indexing math in invalidation.
|
||||
if context.ignores_nth_child_selectors_for_invalidation() {
|
||||
return selectors_match && !context.in_negation();
|
||||
}
|
||||
|
||||
|
|
|
@ -203,9 +203,9 @@ macro_rules! with_all_bounds {
|
|||
pub trait SelectorImpl: Clone + Debug + Sized + 'static {
|
||||
type ExtraMatchingData<'a>: Sized + Default;
|
||||
type AttrValue: $($InSelector)*;
|
||||
type Identifier: $($InSelector)* + PrecomputedHash;
|
||||
type LocalName: $($InSelector)* + Borrow<Self::BorrowedLocalName> + PrecomputedHash;
|
||||
type NamespaceUrl: $($CommonBounds)* + Default + Borrow<Self::BorrowedNamespaceUrl> + PrecomputedHash;
|
||||
type Identifier: $($InSelector)*;
|
||||
type LocalName: $($InSelector)* + Borrow<Self::BorrowedLocalName>;
|
||||
type NamespaceUrl: $($CommonBounds)* + Default + Borrow<Self::BorrowedNamespaceUrl>;
|
||||
type NamespacePrefix: $($InSelector)* + Default;
|
||||
type BorrowedNamespaceUrl: ?Sized + Eq;
|
||||
type BorrowedLocalName: ?Sized + Eq;
|
||||
|
@ -512,17 +512,18 @@ pub struct AncestorHashes {
|
|||
pub packed_hashes: [u32; 3],
|
||||
}
|
||||
|
||||
pub(crate) fn collect_selector_hashes<'a, Impl: SelectorImpl, Iter>(
|
||||
iter: Iter,
|
||||
fn collect_ancestor_hashes<Impl: SelectorImpl>(
|
||||
iter: SelectorIter<Impl>,
|
||||
quirks_mode: QuirksMode,
|
||||
hashes: &mut [u32; 4],
|
||||
len: &mut usize,
|
||||
create_inner_iterator: fn(&'a Selector<Impl>) -> Iter,
|
||||
) -> bool
|
||||
where
|
||||
Iter: Iterator<Item = &'a Component<Impl>>,
|
||||
Impl::Identifier: PrecomputedHash,
|
||||
Impl::LocalName: PrecomputedHash,
|
||||
Impl::NamespaceUrl: PrecomputedHash,
|
||||
{
|
||||
for component in iter {
|
||||
for component in AncestorIter::new(iter) {
|
||||
let hash = match *component {
|
||||
Component::LocalName(LocalName {
|
||||
ref name,
|
||||
|
@ -578,13 +579,7 @@ where
|
|||
// in the filter if there's more than one selector, as that'd
|
||||
// exclude elements that may match one of the other selectors.
|
||||
if list.len() == 1 &&
|
||||
!collect_selector_hashes(
|
||||
create_inner_iterator(&list[0]),
|
||||
quirks_mode,
|
||||
hashes,
|
||||
len,
|
||||
create_inner_iterator,
|
||||
)
|
||||
!collect_ancestor_hashes(list[0].iter(), quirks_mode, hashes, len)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -602,17 +597,12 @@ where
|
|||
true
|
||||
}
|
||||
|
||||
fn collect_ancestor_hashes<Impl: SelectorImpl>(
|
||||
iter: SelectorIter<Impl>,
|
||||
quirks_mode: QuirksMode,
|
||||
hashes: &mut [u32; 4],
|
||||
len: &mut usize,
|
||||
) {
|
||||
collect_selector_hashes(AncestorIter::new(iter), quirks_mode, hashes, len, |s| AncestorIter(s.iter()));
|
||||
}
|
||||
|
||||
impl AncestorHashes {
|
||||
pub fn new<Impl: SelectorImpl>(selector: &Selector<Impl>, quirks_mode: QuirksMode) -> Self
|
||||
where
|
||||
Impl::Identifier: PrecomputedHash,
|
||||
Impl::LocalName: PrecomputedHash,
|
||||
Impl::NamespaceUrl: PrecomputedHash,
|
||||
{
|
||||
// Compute ancestor hashes for the bloom filter.
|
||||
let mut hashes = [0u32; 4];
|
||||
|
@ -840,17 +830,6 @@ impl<Impl: SelectorImpl> Selector<Impl> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator over this selector in matching order (right-to-left),
|
||||
/// skipping the leftmost |offset| Components.
|
||||
#[inline]
|
||||
pub fn iter_until(&self, offset: usize) -> SelectorIter<Impl> {
|
||||
let iter = self.0.slice()[..self.len() - offset].iter();
|
||||
SelectorIter {
|
||||
iter,
|
||||
next_combinator: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the combinator at index `index` (zero-indexed from the right),
|
||||
/// or panics if the component is not a combinator.
|
||||
#[inline]
|
||||
|
|
|
@ -1,158 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/// Bloom filter for relative selectors.
|
||||
use fxhash::FxHashMap;
|
||||
|
||||
use crate::bloom::BloomFilter;
|
||||
use crate::context::QuirksMode;
|
||||
use crate::parser::{
|
||||
collect_selector_hashes, RelativeSelector, RelativeSelectorMatchHint,
|
||||
};
|
||||
use crate::tree::{Element, OpaqueElement};
|
||||
use crate::SelectorImpl;
|
||||
|
||||
enum Entry {
|
||||
/// Filter lookup happened once. Construction of the filter is expensive,
|
||||
/// so this is set when the element for subtree traversal is encountered.
|
||||
Lookup,
|
||||
/// Filter lookup happened more than once, and the filter for this element's
|
||||
/// subtree traversal is constructed. Could use special handlings for pseudo-classes
|
||||
/// such as `:hover` and `:focus`, see Bug 1845503.
|
||||
HasFilter(Box<BloomFilter>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Hash, Eq, PartialEq)]
|
||||
enum TraversalKind {
|
||||
Children,
|
||||
Descendants,
|
||||
}
|
||||
|
||||
fn add_to_filter<E: Element>(element: &E, filter: &mut BloomFilter, kind: TraversalKind) -> bool {
|
||||
let mut child = element.first_element_child();
|
||||
while let Some(e) = child {
|
||||
if !e.add_element_unique_hashes(filter) {
|
||||
return false;
|
||||
}
|
||||
if kind == TraversalKind::Descendants {
|
||||
if !add_to_filter(&e, filter, kind) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
child = e.next_sibling_element();
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Hash, Eq, PartialEq)]
|
||||
struct Key(OpaqueElement, TraversalKind);
|
||||
|
||||
/// Map of bloom filters for fast-rejecting relative selectors.
|
||||
#[derive(Default)]
|
||||
pub struct RelativeSelectorFilterMap {
|
||||
map: FxHashMap<Key, Entry>,
|
||||
}
|
||||
|
||||
fn fast_reject<Impl: SelectorImpl>(
|
||||
selector: &RelativeSelector<Impl>,
|
||||
quirks_mode: QuirksMode,
|
||||
filter: &BloomFilter,
|
||||
) -> bool {
|
||||
let mut hashes = [0u32; 4];
|
||||
let mut len = 0;
|
||||
// For inner selectors, we only collect from the single rightmost compound.
|
||||
// This is because inner selectors can cause breakouts: e.g. `.anchor:has(:is(.a .b) .c)`
|
||||
// can match when `.a` is the ancestor of `.anchor`. Including `.a` would possibly fast
|
||||
// reject the subtree for not having `.a`, even if the selector would match.
|
||||
// Technically, if the selector's traversal is non-sibling subtree, we can traverse
|
||||
// inner selectors up to the point where a descendant/child combinator is encountered
|
||||
// (e.g. In `.anchor:has(:is(.a ~ .b) .c)`, `.a` is guaranteed to be the a descendant
|
||||
// of `.anchor`). While that can be separately handled, well, this is simpler.
|
||||
collect_selector_hashes(
|
||||
selector.selector.iter(),
|
||||
quirks_mode,
|
||||
&mut hashes,
|
||||
&mut len,
|
||||
|s| s.iter(),
|
||||
);
|
||||
for i in 0..len {
|
||||
if !filter.might_contain_hash(hashes[i]) {
|
||||
// Definitely rejected.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
impl RelativeSelectorFilterMap {
|
||||
fn get_filter<E: Element>(&mut self, element: &E, kind: TraversalKind) -> Option<&BloomFilter> {
|
||||
// Insert flag to indicate that we looked up the filter once, and
|
||||
// create the filter if and only if that flag is there.
|
||||
let key = Key(element.opaque(), kind);
|
||||
let entry = self
|
||||
.map
|
||||
.entry(key)
|
||||
.and_modify(|entry| {
|
||||
if !matches!(entry, Entry::Lookup) {
|
||||
return;
|
||||
}
|
||||
let mut filter = BloomFilter::new();
|
||||
// Go through all children/descendants of this element and add their hashes.
|
||||
if add_to_filter(element, &mut filter, kind) {
|
||||
*entry = Entry::HasFilter(Box::new(filter));
|
||||
}
|
||||
})
|
||||
.or_insert(Entry::Lookup);
|
||||
match entry {
|
||||
Entry::Lookup => None,
|
||||
Entry::HasFilter(ref filter) => Some(filter.as_ref()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Potentially reject the given selector for this element.
|
||||
/// This may seem redundant in presence of the cache, but the cache keys into the
|
||||
/// selector-element pair specifically, while this filter keys to the element
|
||||
/// and the traversal kind, so it is useful for handling multiple selectors
|
||||
/// that effectively end up looking at the same(-ish, for siblings) subtree.
|
||||
pub fn fast_reject<Impl: SelectorImpl, E: Element>(
|
||||
&mut self,
|
||||
element: &E,
|
||||
selector: &RelativeSelector<Impl>,
|
||||
quirks_mode: QuirksMode,
|
||||
) -> bool {
|
||||
if matches!(selector.match_hint, RelativeSelectorMatchHint::InNextSibling) {
|
||||
// Don't bother.
|
||||
return false;
|
||||
}
|
||||
let is_sibling = matches!(
|
||||
selector.match_hint,
|
||||
RelativeSelectorMatchHint::InSibling |
|
||||
RelativeSelectorMatchHint::InNextSiblingSubtree |
|
||||
RelativeSelectorMatchHint::InSiblingSubtree
|
||||
);
|
||||
let is_subtree = matches!(
|
||||
selector.match_hint,
|
||||
RelativeSelectorMatchHint::InSubtree |
|
||||
RelativeSelectorMatchHint::InNextSiblingSubtree |
|
||||
RelativeSelectorMatchHint::InSiblingSubtree
|
||||
);
|
||||
let kind = if is_subtree {
|
||||
TraversalKind::Descendants
|
||||
} else {
|
||||
TraversalKind::Children
|
||||
};
|
||||
if is_sibling {
|
||||
// Contain the entirety of the parent's children/subtree in the filter, and use that.
|
||||
// This is less likely to reject, especially for sibling subtree matches; however, it's less
|
||||
// expensive memory-wise, compared to storing filters for each sibling.
|
||||
element.parent_element().map_or(false, |parent| {
|
||||
self.get_filter(&parent, kind)
|
||||
.map_or(false, |filter| fast_reject(selector, quirks_mode, filter))
|
||||
})
|
||||
} else {
|
||||
self.get_filter(element, kind)
|
||||
.map_or(false, |filter| fast_reject(selector, quirks_mode, filter))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,4 +3,3 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
pub mod cache;
|
||||
pub mod filter;
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
//! between layout and style.
|
||||
|
||||
use crate::attr::{AttrSelectorOperation, CaseSensitivity, NamespaceConstraint};
|
||||
use crate::bloom::BloomFilter;
|
||||
use crate::matching::{ElementSelectorFlags, MatchingContext};
|
||||
use crate::parser::SelectorImpl;
|
||||
use std::fmt::Debug;
|
||||
|
@ -161,8 +160,4 @@ pub trait Element: Sized + Clone + Debug {
|
|||
fn ignores_nth_child_selectors(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Add hashes unique to this element to the given filter, returning true
|
||||
/// if any got added.
|
||||
fn add_element_unique_hashes(&self, filter: &mut BloomFilter) -> bool;
|
||||
}
|
||||
|
|
|
@ -111,8 +111,7 @@ pub fn is_attr_name_excluded_from_filter(atom: &crate::Atom) -> bool {
|
|||
*atom == atom!("class") || *atom == atom!("id") || *atom == atom!("style")
|
||||
}
|
||||
|
||||
/// Gather all relevant hash for fast-reject filters from an element.
|
||||
pub fn each_relevant_element_hash<E, F>(element: E, mut f: F)
|
||||
fn each_relevant_element_hash<E, F>(element: E, mut f: F)
|
||||
where
|
||||
E: TElement,
|
||||
F: FnMut(u32),
|
||||
|
|
|
@ -651,7 +651,7 @@ pub struct ThreadLocalStyleContext<E: TElement> {
|
|||
/// A checker used to ensure that parallel.rs does not recurse indefinitely
|
||||
/// even on arbitrarily deep trees. See Gecko bug 1376883.
|
||||
pub stack_limit_checker: StackLimitChecker,
|
||||
/// Collection of caches (And cache-likes) for speeding up expensive selector matches.
|
||||
/// Collection of caches for speeding up expensive selector matches.
|
||||
pub selector_caches: SelectorCaches,
|
||||
}
|
||||
|
||||
|
|
|
@ -312,12 +312,8 @@ impl ElementData {
|
|||
return InvalidationResult::empty();
|
||||
}
|
||||
|
||||
let mut processor = StateAndAttrInvalidationProcessor::new(
|
||||
shared_context,
|
||||
element,
|
||||
self,
|
||||
selector_caches,
|
||||
);
|
||||
let mut processor =
|
||||
StateAndAttrInvalidationProcessor::new(shared_context, element, self, selector_caches);
|
||||
|
||||
let invalidator = TreeStyleInvalidator::new(element, stack_limit_checker, &mut processor);
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ use crate::selector_parser::SelectorImpl;
|
|||
use crate::values::AtomIdent;
|
||||
use selectors::attr::CaseSensitivity;
|
||||
use selectors::matching::{
|
||||
self, MatchingForInvalidation, MatchingContext, MatchingMode, NeedsSelectorFlags,
|
||||
self, IgnoreNthChildForInvalidation, MatchingContext, MatchingMode, NeedsSelectorFlags,
|
||||
SelectorCaches,
|
||||
};
|
||||
use selectors::attr::{AttrSelectorOperation, NamespaceConstraint};
|
||||
|
@ -39,7 +39,7 @@ where
|
|||
&mut selector_caches,
|
||||
quirks_mode,
|
||||
NeedsSelectorFlags::No,
|
||||
MatchingForInvalidation::No,
|
||||
IgnoreNthChildForInvalidation::No,
|
||||
);
|
||||
context.scope_element = Some(element.opaque());
|
||||
context.current_host = element.containing_shadow_host().map(|e| e.opaque());
|
||||
|
@ -63,7 +63,7 @@ where
|
|||
&mut selector_caches,
|
||||
quirks_mode,
|
||||
NeedsSelectorFlags::No,
|
||||
MatchingForInvalidation::No,
|
||||
IgnoreNthChildForInvalidation::No,
|
||||
);
|
||||
context.scope_element = Some(element.opaque());
|
||||
context.current_host = element.containing_shadow_host().map(|e| e.opaque());
|
||||
|
@ -746,7 +746,7 @@ pub fn query_selector<E, Q>(
|
|||
&mut selector_caches,
|
||||
quirks_mode,
|
||||
NeedsSelectorFlags::No,
|
||||
MatchingForInvalidation::No,
|
||||
IgnoreNthChildForInvalidation::No,
|
||||
);
|
||||
let root_element = root.as_element();
|
||||
matching_context.scope_element = root_element.map(|e| e.opaque());
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
//! the separation between the style system implementation and everything else.
|
||||
|
||||
use crate::applicable_declarations::ApplicableDeclarationBlock;
|
||||
use crate::bloom::each_relevant_element_hash;
|
||||
use crate::context::{PostAnimationTasks, QuirksMode, SharedStyleContext, UpdateAnimationsTasks};
|
||||
use crate::data::ElementData;
|
||||
use crate::dom::{LayoutIterator, NodeInfo, OpaqueNode, TDocument, TElement, TNode, TShadowRoot};
|
||||
|
@ -70,7 +69,6 @@ use dom::{DocumentState, ElementState};
|
|||
use euclid::default::Size2D;
|
||||
use fxhash::FxHashMap;
|
||||
use selectors::attr::{AttrSelectorOperation, CaseSensitivity, NamespaceConstraint};
|
||||
use selectors::bloom::{BloomFilter, BLOOM_HASH_MASK};
|
||||
use selectors::matching::VisitedHandlingMode;
|
||||
use selectors::matching::{ElementSelectorFlags, MatchingContext};
|
||||
use selectors::sink::Push;
|
||||
|
@ -2092,9 +2090,4 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
|||
fn ignores_nth_child_selectors(&self) -> bool {
|
||||
self.is_root_of_native_anonymous_subtree()
|
||||
}
|
||||
|
||||
fn add_element_unique_hashes(&self, filter: &mut BloomFilter) -> bool {
|
||||
each_relevant_element_hash(*self, |hash| filter.insert_hash(hash & BLOOM_HASH_MASK));
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::invalidation::element::state_and_attributes;
|
|||
use crate::stylist::CascadeData;
|
||||
use dom::DocumentState;
|
||||
use selectors::matching::{
|
||||
MatchingForInvalidation, MatchingContext, MatchingMode, NeedsSelectorFlags, QuirksMode,
|
||||
IgnoreNthChildForInvalidation, MatchingContext, MatchingMode, NeedsSelectorFlags, QuirksMode,
|
||||
SelectorCaches, VisitedHandlingMode,
|
||||
};
|
||||
|
||||
|
@ -57,7 +57,7 @@ impl<'a, E: TElement, I> DocumentStateInvalidationProcessor<'a, E, I> {
|
|||
VisitedHandlingMode::AllLinksVisitedAndUnvisited,
|
||||
quirks_mode,
|
||||
NeedsSelectorFlags::No,
|
||||
MatchingForInvalidation::No,
|
||||
IgnoreNthChildForInvalidation::No,
|
||||
);
|
||||
|
||||
matching_context.extra_data.invalidation_data.document_state = document_states_changed;
|
||||
|
|
|
@ -12,7 +12,6 @@ use crate::values::AtomIdent;
|
|||
use crate::{CaseSensitivityExt, LocalName, Namespace, WeakAtom};
|
||||
use dom::ElementState;
|
||||
use selectors::attr::{AttrSelectorOperation, CaseSensitivity, NamespaceConstraint};
|
||||
use selectors::bloom::BloomFilter;
|
||||
use selectors::matching::{ElementSelectorFlags, MatchingContext};
|
||||
use selectors::{Element, OpaqueElement};
|
||||
use std::cell::Cell;
|
||||
|
@ -389,9 +388,4 @@ where
|
|||
.assigned_slot()
|
||||
.map(|e| ElementWrapper::new(e, self.snapshot_map))
|
||||
}
|
||||
|
||||
fn add_element_unique_hashes(&self, _filter: &mut BloomFilter) -> bool {
|
||||
// Should not be relevant in the context of checking past elements in invalidation.
|
||||
false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ use crate::{Atom, WeakAtom};
|
|||
use dom::ElementState;
|
||||
use selectors::attr::CaseSensitivity;
|
||||
use selectors::matching::{
|
||||
matches_selector, MatchingForInvalidation, MatchingContext, MatchingMode,
|
||||
matches_selector, IgnoreNthChildForInvalidation, MatchingContext, MatchingMode,
|
||||
NeedsSelectorFlags, SelectorCaches, VisitedHandlingMode,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
|
@ -69,7 +69,7 @@ impl<'a, 'b: 'a, E: TElement + 'b> StateAndAttrInvalidationProcessor<'a, 'b, E>
|
|||
VisitedHandlingMode::AllLinksVisitedAndUnvisited,
|
||||
shared_context.quirks_mode(),
|
||||
NeedsSelectorFlags::No,
|
||||
MatchingForInvalidation::Yes,
|
||||
IgnoreNthChildForInvalidation::Yes,
|
||||
);
|
||||
|
||||
Self {
|
||||
|
|
|
@ -137,8 +137,7 @@ where
|
|||
|
||||
let for_element = target.revalidation_match_results(stylist, bloom, selector_caches);
|
||||
|
||||
let for_candidate =
|
||||
candidate.revalidation_match_results(stylist, bloom, selector_caches);
|
||||
let for_candidate = candidate.revalidation_match_results(stylist, bloom, selector_caches);
|
||||
|
||||
// This assert "ensures", to some extent, that the two candidates have
|
||||
// matched the same rulehash buckets, and as such, that the bits we're
|
||||
|
|
|
@ -17,7 +17,7 @@ use crate::selector_parser::{PseudoElement, SelectorImpl};
|
|||
use crate::stylist::RuleInclusion;
|
||||
use log::Level::Trace;
|
||||
use selectors::matching::{
|
||||
MatchingForInvalidation, MatchingContext, MatchingMode, NeedsSelectorFlags,
|
||||
IgnoreNthChildForInvalidation, MatchingContext, MatchingMode, NeedsSelectorFlags,
|
||||
RelativeSelectorMatchingState, VisitedHandlingMode,
|
||||
};
|
||||
use servo_arc::Arc;
|
||||
|
@ -473,7 +473,7 @@ where
|
|||
visited_handling,
|
||||
self.context.shared.quirks_mode(),
|
||||
NeedsSelectorFlags::Yes,
|
||||
MatchingForInvalidation::No,
|
||||
IgnoreNthChildForInvalidation::No,
|
||||
);
|
||||
|
||||
let stylist = &self.context.shared.stylist;
|
||||
|
@ -568,7 +568,7 @@ where
|
|||
visited_handling,
|
||||
self.context.shared.quirks_mode(),
|
||||
NeedsSelectorFlags::Yes,
|
||||
MatchingForInvalidation::No,
|
||||
IgnoreNthChildForInvalidation::No,
|
||||
);
|
||||
matching_context.extra_data.originating_element_style = Some(originating_element_style);
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ use selectors::bloom::BloomFilter;
|
|||
use selectors::matching::{
|
||||
matches_selector, MatchingContext, MatchingMode, NeedsSelectorFlags, SelectorCaches,
|
||||
};
|
||||
use selectors::matching::{MatchingForInvalidation, VisitedHandlingMode};
|
||||
use selectors::matching::{IgnoreNthChildForInvalidation, VisitedHandlingMode};
|
||||
use selectors::parser::{
|
||||
AncestorHashes, Combinator, Component, Selector, SelectorIter, SelectorList,
|
||||
};
|
||||
|
@ -1140,7 +1140,7 @@ impl Stylist {
|
|||
&mut selector_caches,
|
||||
self.quirks_mode,
|
||||
needs_selector_flags,
|
||||
MatchingForInvalidation::No,
|
||||
IgnoreNthChildForInvalidation::No,
|
||||
);
|
||||
|
||||
matching_context.pseudo_element_matching_fn = matching_fn;
|
||||
|
@ -1175,7 +1175,7 @@ impl Stylist {
|
|||
VisitedHandlingMode::RelevantLinkVisited,
|
||||
self.quirks_mode,
|
||||
needs_selector_flags,
|
||||
MatchingForInvalidation::No,
|
||||
IgnoreNthChildForInvalidation::No,
|
||||
);
|
||||
matching_context.pseudo_element_matching_fn = matching_fn;
|
||||
matching_context.extra_data.originating_element_style = Some(originating_element_style);
|
||||
|
@ -1394,7 +1394,7 @@ impl Stylist {
|
|||
selector_caches,
|
||||
self.quirks_mode,
|
||||
needs_selector_flags,
|
||||
MatchingForInvalidation::No,
|
||||
IgnoreNthChildForInvalidation::No,
|
||||
);
|
||||
|
||||
// Note that, by the time we're revalidating, we're guaranteed that the
|
||||
|
|
|
@ -10,7 +10,7 @@ use cssparser::{Parser, ParserInput, SourceLocation, UnicodeRange};
|
|||
use dom::{DocumentState, ElementState};
|
||||
use malloc_size_of::MallocSizeOfOps;
|
||||
use nsstring::{nsCString, nsString};
|
||||
use selectors::matching::{MatchingForInvalidation, SelectorCaches};
|
||||
use selectors::matching::{IgnoreNthChildForInvalidation, SelectorCaches};
|
||||
use servo_arc::{Arc, ArcBorrow};
|
||||
use smallvec::SmallVec;
|
||||
use style::values::generics::color::ColorMixFlags;
|
||||
|
@ -2506,7 +2506,7 @@ pub extern "C" fn Servo_StyleRule_SelectorMatchesElement(
|
|||
visited_mode,
|
||||
quirks_mode,
|
||||
NeedsSelectorFlags::No,
|
||||
MatchingForInvalidation::No,
|
||||
IgnoreNthChildForInvalidation::No,
|
||||
);
|
||||
ctx.with_shadow_host(host, |ctx| {
|
||||
matches_selector(selector, 0, None, &element, ctx)
|
||||
|
|
Загрузка…
Ссылка в новой задаче