mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
style: Track document state dependencies in the invalidation maps.
This commit is contained in:
parent
14661e470f
commit
2c1d72ad1a
1 changed files with 39 additions and 4 deletions
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
use {Atom, LocalName, Namespace};
|
use {Atom, LocalName, Namespace};
|
||||||
use context::QuirksMode;
|
use context::QuirksMode;
|
||||||
use element_state::ElementState;
|
use element_state::{DocumentState, ElementState};
|
||||||
use fallible::FallibleVec;
|
use fallible::FallibleVec;
|
||||||
use hashglobe::FailedAllocationError;
|
use hashglobe::FailedAllocationError;
|
||||||
use selector_map::{MaybeCaseInsensitiveHashMap, SelectorMap, SelectorMapEntry};
|
use selector_map::{MaybeCaseInsensitiveHashMap, SelectorMap, SelectorMapEntry};
|
||||||
|
@ -133,6 +133,19 @@ impl SelectorMapEntry for StateDependency {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The same, but for document state selectors.
|
||||||
|
#[derive(Clone, Debug, MallocSizeOf)]
|
||||||
|
pub struct DocumentStateDependency {
|
||||||
|
/// The selector that is affected. We don't need to track an offset, since
|
||||||
|
/// when it changes it changes for the whole document anyway.
|
||||||
|
#[cfg_attr(feature = "gecko",
|
||||||
|
ignore_malloc_size_of = "CssRules have primary refs, we measure there")]
|
||||||
|
#[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")]
|
||||||
|
pub selector: Selector<SelectorImpl>,
|
||||||
|
/// The state this dependency is affected by.
|
||||||
|
pub state: DocumentState,
|
||||||
|
}
|
||||||
|
|
||||||
/// A map where we store invalidations.
|
/// A map where we store invalidations.
|
||||||
///
|
///
|
||||||
/// This is slightly different to a SelectorMap, in the sense of that the same
|
/// This is slightly different to a SelectorMap, in the sense of that the same
|
||||||
|
@ -151,6 +164,8 @@ pub struct InvalidationMap {
|
||||||
pub id_to_selector: MaybeCaseInsensitiveHashMap<Atom, SmallVec<[Dependency; 1]>>,
|
pub id_to_selector: MaybeCaseInsensitiveHashMap<Atom, SmallVec<[Dependency; 1]>>,
|
||||||
/// A map of all the state dependencies.
|
/// A map of all the state dependencies.
|
||||||
pub state_affecting_selectors: SelectorMap<StateDependency>,
|
pub state_affecting_selectors: SelectorMap<StateDependency>,
|
||||||
|
/// A list of document state dependencies in the rules we represent.
|
||||||
|
pub document_state_selectors: Vec<DocumentStateDependency>,
|
||||||
/// A map of other attribute affecting selectors.
|
/// A map of other attribute affecting selectors.
|
||||||
pub other_attribute_affecting_selectors: SelectorMap<Dependency>,
|
pub other_attribute_affecting_selectors: SelectorMap<Dependency>,
|
||||||
/// Whether there are attribute rules of the form `[class~="foo"]` that may
|
/// Whether there are attribute rules of the form `[class~="foo"]` that may
|
||||||
|
@ -172,6 +187,7 @@ impl InvalidationMap {
|
||||||
class_to_selector: MaybeCaseInsensitiveHashMap::new(),
|
class_to_selector: MaybeCaseInsensitiveHashMap::new(),
|
||||||
id_to_selector: MaybeCaseInsensitiveHashMap::new(),
|
id_to_selector: MaybeCaseInsensitiveHashMap::new(),
|
||||||
state_affecting_selectors: SelectorMap::new(),
|
state_affecting_selectors: SelectorMap::new(),
|
||||||
|
document_state_selectors: Vec::new(),
|
||||||
other_attribute_affecting_selectors: SelectorMap::new(),
|
other_attribute_affecting_selectors: SelectorMap::new(),
|
||||||
has_class_attribute_selectors: false,
|
has_class_attribute_selectors: false,
|
||||||
has_id_attribute_selectors: false,
|
has_id_attribute_selectors: false,
|
||||||
|
@ -181,6 +197,7 @@ impl InvalidationMap {
|
||||||
/// Returns the number of dependencies stored in the invalidation map.
|
/// Returns the number of dependencies stored in the invalidation map.
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.state_affecting_selectors.len() +
|
self.state_affecting_selectors.len() +
|
||||||
|
self.document_state_selectors.len() +
|
||||||
self.other_attribute_affecting_selectors.len() +
|
self.other_attribute_affecting_selectors.len() +
|
||||||
self.id_to_selector.iter().fold(0, |accum, (_, ref v)| {
|
self.id_to_selector.iter().fold(0, |accum, (_, ref v)| {
|
||||||
accum + v.len()
|
accum + v.len()
|
||||||
|
@ -195,7 +212,7 @@ impl InvalidationMap {
|
||||||
pub fn note_selector(
|
pub fn note_selector(
|
||||||
&mut self,
|
&mut self,
|
||||||
selector: &Selector<SelectorImpl>,
|
selector: &Selector<SelectorImpl>,
|
||||||
quirks_mode: QuirksMode
|
quirks_mode: QuirksMode,
|
||||||
) -> Result<(), FailedAllocationError> {
|
) -> Result<(), FailedAllocationError> {
|
||||||
self.collect_invalidations_for(selector, quirks_mode)
|
self.collect_invalidations_for(selector, quirks_mode)
|
||||||
}
|
}
|
||||||
|
@ -205,6 +222,7 @@ impl InvalidationMap {
|
||||||
self.class_to_selector.clear();
|
self.class_to_selector.clear();
|
||||||
self.id_to_selector.clear();
|
self.id_to_selector.clear();
|
||||||
self.state_affecting_selectors.clear();
|
self.state_affecting_selectors.clear();
|
||||||
|
self.document_state_selectors.clear();
|
||||||
self.other_attribute_affecting_selectors.clear();
|
self.other_attribute_affecting_selectors.clear();
|
||||||
self.has_id_attribute_selectors = false;
|
self.has_id_attribute_selectors = false;
|
||||||
self.has_class_attribute_selectors = false;
|
self.has_class_attribute_selectors = false;
|
||||||
|
@ -222,6 +240,8 @@ impl InvalidationMap {
|
||||||
let mut combinator;
|
let mut combinator;
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
|
|
||||||
|
let mut document_state = DocumentState::empty();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let sequence_start = index;
|
let sequence_start = index;
|
||||||
|
|
||||||
|
@ -229,6 +249,7 @@ impl InvalidationMap {
|
||||||
classes: SmallVec::new(),
|
classes: SmallVec::new(),
|
||||||
ids: SmallVec::new(),
|
ids: SmallVec::new(),
|
||||||
state: ElementState::empty(),
|
state: ElementState::empty(),
|
||||||
|
document_state: &mut document_state,
|
||||||
other_attributes: false,
|
other_attributes: false,
|
||||||
has_id_attribute_selectors: false,
|
has_id_attribute_selectors: false,
|
||||||
has_class_attribute_selectors: false,
|
has_class_attribute_selectors: false,
|
||||||
|
@ -297,15 +318,28 @@ impl InvalidationMap {
|
||||||
index += 1; // Account for the combinator.
|
index += 1; // Account for the combinator.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !document_state.is_empty() {
|
||||||
|
self.document_state_selectors.try_push(DocumentStateDependency {
|
||||||
|
state: document_state,
|
||||||
|
selector: selector.clone(),
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A struct that collects invalidations for a given compound selector.
|
/// A struct that collects invalidations for a given compound selector.
|
||||||
struct CompoundSelectorDependencyCollector {
|
struct CompoundSelectorDependencyCollector<'a> {
|
||||||
/// The state this compound selector is affected by.
|
/// The state this compound selector is affected by.
|
||||||
state: ElementState,
|
state: ElementState,
|
||||||
|
|
||||||
|
/// The document this _complex_ selector is affected by.
|
||||||
|
///
|
||||||
|
/// We don't need to track state per compound selector, since it's global
|
||||||
|
/// state and it changes for everything.
|
||||||
|
document_state: &'a mut DocumentState,
|
||||||
|
|
||||||
/// The classes this compound selector is affected by.
|
/// The classes this compound selector is affected by.
|
||||||
///
|
///
|
||||||
/// NB: This will be often a single class, but could be multiple in
|
/// NB: This will be often a single class, but could be multiple in
|
||||||
|
@ -330,7 +364,7 @@ struct CompoundSelectorDependencyCollector {
|
||||||
has_class_attribute_selectors: bool,
|
has_class_attribute_selectors: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SelectorVisitor for CompoundSelectorDependencyCollector {
|
impl<'a> SelectorVisitor for CompoundSelectorDependencyCollector<'a> {
|
||||||
type Impl = SelectorImpl;
|
type Impl = SelectorImpl;
|
||||||
|
|
||||||
fn visit_simple_selector(&mut self, s: &Component<SelectorImpl>) -> bool {
|
fn visit_simple_selector(&mut self, s: &Component<SelectorImpl>) -> bool {
|
||||||
|
@ -353,6 +387,7 @@ impl SelectorVisitor for CompoundSelectorDependencyCollector {
|
||||||
}
|
}
|
||||||
_ => pc.state_flag(),
|
_ => pc.state_flag(),
|
||||||
};
|
};
|
||||||
|
*self.document_state |= pc.document_state_flag();
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue