mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
style: Record ElementState bits that selectors depend on.
This commit is contained in:
parent
5cf915118e
commit
b405a1cb67
2 changed files with 36 additions and 6 deletions
|
@ -11,6 +11,7 @@ use bit_vec::BitVec;
|
||||||
use context::QuirksMode;
|
use context::QuirksMode;
|
||||||
use data::ComputedStyle;
|
use data::ComputedStyle;
|
||||||
use dom::{AnimationRules, TElement};
|
use dom::{AnimationRules, TElement};
|
||||||
|
use element_state::ElementState;
|
||||||
use error_reporting::RustLogReporter;
|
use error_reporting::RustLogReporter;
|
||||||
use font_metrics::FontMetricsProvider;
|
use font_metrics::FontMetricsProvider;
|
||||||
use keyframes::KeyframesAnimation;
|
use keyframes::KeyframesAnimation;
|
||||||
|
@ -135,6 +136,11 @@ pub struct Stylist {
|
||||||
/// returning `true` for `"style"` just due to a hash collision.)
|
/// returning `true` for `"style"` just due to a hash collision.)
|
||||||
style_attribute_dependency: bool,
|
style_attribute_dependency: bool,
|
||||||
|
|
||||||
|
/// The element state bits that are relied on by selectors. Like
|
||||||
|
/// `attribute_dependencies`, this is used to avoid taking element snapshots
|
||||||
|
/// when an irrelevant element state bit changes.
|
||||||
|
state_dependencies: ElementState,
|
||||||
|
|
||||||
/// Selectors that require explicit cache revalidation (i.e. which depend
|
/// Selectors that require explicit cache revalidation (i.e. which depend
|
||||||
/// on state that is not otherwise visible to the cache, like attributes or
|
/// on state that is not otherwise visible to the cache, like attributes or
|
||||||
/// tree-structural state like child index and pseudos).
|
/// tree-structural state like child index and pseudos).
|
||||||
|
@ -203,6 +209,7 @@ impl Stylist {
|
||||||
dependencies: DependencySet::new(),
|
dependencies: DependencySet::new(),
|
||||||
attribute_dependencies: BloomFilter::new(),
|
attribute_dependencies: BloomFilter::new(),
|
||||||
style_attribute_dependency: false,
|
style_attribute_dependency: false,
|
||||||
|
state_dependencies: ElementState::empty(),
|
||||||
selectors_for_cache_revalidation: SelectorMap::new(),
|
selectors_for_cache_revalidation: SelectorMap::new(),
|
||||||
num_selectors: 0,
|
num_selectors: 0,
|
||||||
num_declarations: 0,
|
num_declarations: 0,
|
||||||
|
@ -275,6 +282,7 @@ impl Stylist {
|
||||||
self.dependencies.clear();
|
self.dependencies.clear();
|
||||||
self.attribute_dependencies.clear();
|
self.attribute_dependencies.clear();
|
||||||
self.style_attribute_dependency = false;
|
self.style_attribute_dependency = false;
|
||||||
|
self.state_dependencies = ElementState::empty();
|
||||||
self.selectors_for_cache_revalidation = SelectorMap::new();
|
self.selectors_for_cache_revalidation = SelectorMap::new();
|
||||||
self.num_selectors = 0;
|
self.num_selectors = 0;
|
||||||
self.num_declarations = 0;
|
self.num_declarations = 0;
|
||||||
|
@ -396,7 +404,7 @@ impl Stylist {
|
||||||
self.add_rule_to_map(selector, locked, stylesheet);
|
self.add_rule_to_map(selector, locked, stylesheet);
|
||||||
self.dependencies.note_selector(selector);
|
self.dependencies.note_selector(selector);
|
||||||
self.note_for_revalidation(selector);
|
self.note_for_revalidation(selector);
|
||||||
self.note_attribute_dependencies(selector);
|
self.note_attribute_and_state_dependencies(selector);
|
||||||
}
|
}
|
||||||
self.rules_source_order += 1;
|
self.rules_source_order += 1;
|
||||||
}
|
}
|
||||||
|
@ -473,9 +481,15 @@ impl Stylist {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether the given ElementState bit is relied upon by a selector
|
||||||
|
/// of some rule in the stylist.
|
||||||
|
pub fn has_state_dependency(&self, state: ElementState) -> bool {
|
||||||
|
self.state_dependencies.intersects(state)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn note_attribute_dependencies(&mut self, selector: &Selector<SelectorImpl>) {
|
fn note_attribute_and_state_dependencies(&mut self, selector: &Selector<SelectorImpl>) {
|
||||||
selector.visit(&mut AttributeDependencyVisitor(self));
|
selector.visit(&mut AttributeAndStateDependencyVisitor(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the style for a given "precomputed" pseudo-element, taking the
|
/// Computes the style for a given "precomputed" pseudo-element, taking the
|
||||||
|
@ -1006,10 +1020,11 @@ impl Drop for Stylist {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Visitor to collect names that appear in attribute selectors.
|
/// Visitor to collect names that appear in attribute selectors and any
|
||||||
struct AttributeDependencyVisitor<'a>(&'a mut Stylist);
|
/// dependencies on ElementState bits.
|
||||||
|
struct AttributeAndStateDependencyVisitor<'a>(&'a mut Stylist);
|
||||||
|
|
||||||
impl<'a> SelectorVisitor for AttributeDependencyVisitor<'a> {
|
impl<'a> SelectorVisitor for AttributeAndStateDependencyVisitor<'a> {
|
||||||
type Impl = SelectorImpl;
|
type Impl = SelectorImpl;
|
||||||
|
|
||||||
fn visit_attribute_selector(&mut self, selector: &AttrSelector<Self::Impl>) -> bool {
|
fn visit_attribute_selector(&mut self, selector: &AttrSelector<Self::Impl>) -> bool {
|
||||||
|
@ -1026,6 +1041,13 @@ impl<'a> SelectorVisitor for AttributeDependencyVisitor<'a> {
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_simple_selector(&mut self, s: &Component<SelectorImpl>) -> bool {
|
||||||
|
if let Component::NonTSPseudoClass(ref p) = *s {
|
||||||
|
self.0.state_dependencies.insert(p.state_flag());
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Visitor determine whether a selector requires cache revalidation.
|
/// Visitor determine whether a selector requires cache revalidation.
|
||||||
|
|
|
@ -17,6 +17,7 @@ use style::context::{ThreadLocalStyleContext, ThreadLocalStyleContextCreationInf
|
||||||
use style::data::{ElementData, ElementStyles, RestyleData};
|
use style::data::{ElementData, ElementStyles, RestyleData};
|
||||||
use style::dom::{AnimationOnlyDirtyDescendants, DirtyDescendants};
|
use style::dom::{AnimationOnlyDirtyDescendants, DirtyDescendants};
|
||||||
use style::dom::{ShowSubtreeData, TElement, TNode};
|
use style::dom::{ShowSubtreeData, TElement, TNode};
|
||||||
|
use style::element_state::ElementState;
|
||||||
use style::error_reporting::RustLogReporter;
|
use style::error_reporting::RustLogReporter;
|
||||||
use style::font_metrics::get_metrics_provider_for_product;
|
use style::font_metrics::get_metrics_provider_for_product;
|
||||||
use style::gecko::data::{PerDocumentStyleData, PerDocumentStyleDataImpl};
|
use style::gecko::data::{PerDocumentStyleData, PerDocumentStyleDataImpl};
|
||||||
|
@ -2338,3 +2339,10 @@ pub extern "C" fn Servo_StyleSet_MightHaveAttributeDependency(raw_data: RawServo
|
||||||
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
||||||
unsafe { Atom::with(local_name, &mut |atom| data.stylist.might_have_attribute_dependency(atom)) }
|
unsafe { Atom::with(local_name, &mut |atom| data.stylist.might_have_attribute_dependency(atom)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn Servo_StyleSet_HasStateDependency(raw_data: RawServoStyleSetBorrowed,
|
||||||
|
state: u64) -> bool {
|
||||||
|
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
||||||
|
data.stylist.has_state_dependency(ElementState::from_bits_truncate(state))
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue