mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
style: Stop threading the ElementData around the invalidator.
This commit is contained in:
parent
40d9cd99b5
commit
7c2265360f
3 changed files with 46 additions and 106 deletions
|
@ -259,11 +259,14 @@ impl ElementData {
|
||||||
return InvalidationResult::empty();
|
return InvalidationResult::empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut processor =
|
let mut processor = StateAndAttrInvalidationProcessor::new(
|
||||||
StateAndAttrInvalidationProcessor::new(shared_context);
|
shared_context,
|
||||||
|
element,
|
||||||
|
self,
|
||||||
|
);
|
||||||
|
|
||||||
let invalidator = TreeStyleInvalidator::new(
|
let invalidator = TreeStyleInvalidator::new(
|
||||||
element,
|
element,
|
||||||
Some(self),
|
|
||||||
shared_context.quirks_mode(),
|
shared_context.quirks_mode(),
|
||||||
stack_limit_checker,
|
stack_limit_checker,
|
||||||
nth_index_cache,
|
nth_index_cache,
|
||||||
|
|
|
@ -51,18 +51,24 @@ where
|
||||||
|
|
||||||
/// An invalidation processor for style changes due to state and attribute
|
/// An invalidation processor for style changes due to state and attribute
|
||||||
/// changes.
|
/// changes.
|
||||||
pub struct StateAndAttrInvalidationProcessor<'a, 'b: 'a> {
|
pub struct StateAndAttrInvalidationProcessor<'a, 'b: 'a, E> {
|
||||||
shared_context: &'a SharedStyleContext<'b>,
|
shared_context: &'a SharedStyleContext<'b>,
|
||||||
|
element: E,
|
||||||
|
data: &'a mut ElementData,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b: 'a> StateAndAttrInvalidationProcessor<'a, 'b> {
|
impl<'a, 'b: 'a, E> StateAndAttrInvalidationProcessor<'a, 'b, E> {
|
||||||
/// Creates a new StateAndAttrInvalidationProcessor.
|
/// Creates a new StateAndAttrInvalidationProcessor.
|
||||||
pub fn new(shared_context: &'a SharedStyleContext<'b>) -> Self {
|
pub fn new(
|
||||||
Self { shared_context }
|
shared_context: &'a SharedStyleContext<'b>,
|
||||||
|
element: E,
|
||||||
|
data: &'a mut ElementData,
|
||||||
|
) -> Self {
|
||||||
|
Self { shared_context, element, data }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b: 'a, E> InvalidationProcessor<E> for StateAndAttrInvalidationProcessor<'a, 'b>
|
impl<'a, 'b: 'a, E> InvalidationProcessor<E> for StateAndAttrInvalidationProcessor<'a, 'b, E>
|
||||||
where
|
where
|
||||||
E: TElement,
|
E: TElement,
|
||||||
{
|
{
|
||||||
|
@ -74,14 +80,12 @@ where
|
||||||
fn collect_invalidations(
|
fn collect_invalidations(
|
||||||
&mut self,
|
&mut self,
|
||||||
element: E,
|
element: E,
|
||||||
mut data: Option<&mut ElementData>,
|
|
||||||
nth_index_cache: Option<&mut NthIndexCache>,
|
nth_index_cache: Option<&mut NthIndexCache>,
|
||||||
quirks_mode: QuirksMode,
|
quirks_mode: QuirksMode,
|
||||||
descendant_invalidations: &mut InvalidationVector,
|
descendant_invalidations: &mut InvalidationVector,
|
||||||
sibling_invalidations: &mut InvalidationVector,
|
sibling_invalidations: &mut InvalidationVector,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
debug_assert!(element.has_snapshot(), "Why bothering?");
|
debug_assert!(element.has_snapshot(), "Why bothering?");
|
||||||
debug_assert!(data.is_some(), "How exactly?");
|
|
||||||
debug_assert_eq!(quirks_mode, self.shared_context.quirks_mode(), "How exactly?");
|
debug_assert_eq!(quirks_mode, self.shared_context.quirks_mode(), "How exactly?");
|
||||||
|
|
||||||
let wrapper =
|
let wrapper =
|
||||||
|
@ -102,8 +106,7 @@ where
|
||||||
trace!(" > visitedness change, force subtree restyle");
|
trace!(" > visitedness change, force subtree restyle");
|
||||||
// We can't just return here because there may also be attribute
|
// We can't just return here because there may also be attribute
|
||||||
// changes as well that imply additional hints.
|
// changes as well that imply additional hints.
|
||||||
let data = data.as_mut().unwrap();
|
self.data.hint.insert(RestyleHint::restyle_subtree());
|
||||||
data.hint.insert(RestyleHint::restyle_subtree());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut classes_removed = SmallVec::<[Atom; 8]>::new();
|
let mut classes_removed = SmallVec::<[Atom; 8]>::new();
|
||||||
|
@ -183,52 +186,43 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
if invalidated_self {
|
if invalidated_self {
|
||||||
if let Some(ref mut data) = data {
|
self.data.hint.insert(RESTYLE_SELF);
|
||||||
data.hint.insert(RESTYLE_SELF);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidated_self
|
invalidated_self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_process_descendants(
|
fn should_process_descendants(&mut self, element: E) -> bool {
|
||||||
&mut self,
|
if element == self.element {
|
||||||
_element: E,
|
return !self.data.styles.is_display_none() &&
|
||||||
data: Option<&mut ElementData>,
|
!self.data.hint.contains(RESTYLE_DESCENDANTS)
|
||||||
) -> bool {
|
}
|
||||||
let data = match data {
|
|
||||||
|
let data = match element.borrow_data() {
|
||||||
None => return false,
|
None => return false,
|
||||||
Some(ref data) => data,
|
Some(data) => data,
|
||||||
};
|
};
|
||||||
|
|
||||||
!data.styles.is_display_none() &&
|
!data.styles.is_display_none() &&
|
||||||
!data.hint.contains(RESTYLE_DESCENDANTS)
|
!data.hint.contains(RESTYLE_DESCENDANTS)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recursion_limit_exceeded(
|
fn recursion_limit_exceeded(&mut self, element: E) {
|
||||||
&mut self,
|
if element == self.element {
|
||||||
_element: E,
|
self.data.hint.insert(RESTYLE_DESCENDANTS);
|
||||||
data: Option<&mut ElementData>,
|
return;
|
||||||
) {
|
}
|
||||||
if let Some(data) = data {
|
|
||||||
|
if let Some(mut data) = element.mutate_data() {
|
||||||
data.hint.insert(RESTYLE_DESCENDANTS);
|
data.hint.insert(RESTYLE_DESCENDANTS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invalidated_descendants(
|
fn invalidated_descendants(&mut self, element: E, child: E) {
|
||||||
&mut self,
|
|
||||||
element: E,
|
|
||||||
data: Option<&mut ElementData>,
|
|
||||||
child: E,
|
|
||||||
) {
|
|
||||||
if child.get_data().is_none() {
|
if child.get_data().is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if data.as_ref().map_or(true, |d| d.styles.is_display_none()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The child may not be a flattened tree child of the current element,
|
// The child may not be a flattened tree child of the current element,
|
||||||
// but may be arbitrarily deep.
|
// but may be arbitrarily deep.
|
||||||
//
|
//
|
||||||
|
@ -245,12 +239,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invalidated_self(
|
fn invalidated_self(&mut self, element: E) {
|
||||||
&mut self,
|
debug_assert_ne!(element, self.element);
|
||||||
_element: E,
|
if let Some(mut data) = element.mutate_data() {
|
||||||
data: Option<&mut ElementData>,
|
|
||||||
) {
|
|
||||||
if let Some(data) = data {
|
|
||||||
data.hint.insert(RESTYLE_SELF);
|
data.hint.insert(RESTYLE_SELF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
//! element styles need to be invalidated.
|
//! element styles need to be invalidated.
|
||||||
|
|
||||||
use context::StackLimitChecker;
|
use context::StackLimitChecker;
|
||||||
use data::ElementData;
|
|
||||||
use dom::{TElement, TNode};
|
use dom::{TElement, TNode};
|
||||||
use selector_parser::SelectorImpl;
|
use selector_parser::SelectorImpl;
|
||||||
use selectors::NthIndexCache;
|
use selectors::NthIndexCache;
|
||||||
|
@ -18,9 +17,6 @@ use smallvec::SmallVec;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
/// A trait to abstract the collection of invalidations for a given pass.
|
/// A trait to abstract the collection of invalidations for a given pass.
|
||||||
///
|
|
||||||
/// The `data` argument is a mutable reference to the element's style data, if
|
|
||||||
/// any.
|
|
||||||
pub trait InvalidationProcessor<E>
|
pub trait InvalidationProcessor<E>
|
||||||
where
|
where
|
||||||
E: TElement,
|
E: TElement,
|
||||||
|
@ -36,7 +32,6 @@ where
|
||||||
fn collect_invalidations(
|
fn collect_invalidations(
|
||||||
&mut self,
|
&mut self,
|
||||||
element: E,
|
element: E,
|
||||||
data: Option<&mut ElementData>,
|
|
||||||
nth_index_cache: Option<&mut NthIndexCache>,
|
nth_index_cache: Option<&mut NthIndexCache>,
|
||||||
quirks_mode: QuirksMode,
|
quirks_mode: QuirksMode,
|
||||||
descendant_invalidations: &mut InvalidationVector,
|
descendant_invalidations: &mut InvalidationVector,
|
||||||
|
@ -45,34 +40,17 @@ where
|
||||||
|
|
||||||
/// Returns whether the invalidation process should process the descendants
|
/// Returns whether the invalidation process should process the descendants
|
||||||
/// of the given element.
|
/// of the given element.
|
||||||
fn should_process_descendants(
|
fn should_process_descendants(&mut self, element: E) -> bool;
|
||||||
&mut self,
|
|
||||||
element: E,
|
|
||||||
data: Option<&mut ElementData>,
|
|
||||||
) -> bool;
|
|
||||||
|
|
||||||
/// Executes an arbitrary action when the recursion limit is exceded (if
|
/// Executes an arbitrary action when the recursion limit is exceded (if
|
||||||
/// any).
|
/// any).
|
||||||
fn recursion_limit_exceeded(
|
fn recursion_limit_exceeded(&mut self, element: E);
|
||||||
&mut self,
|
|
||||||
element: E,
|
|
||||||
data: Option<&mut ElementData>,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Executes an action when `Self` is invalidated.
|
/// Executes an action when `Self` is invalidated.
|
||||||
fn invalidated_self(
|
fn invalidated_self(&mut self, element: E);
|
||||||
&mut self,
|
|
||||||
element: E,
|
|
||||||
data: Option<&mut ElementData>,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Executes an action when any descendant of `Self` is invalidated.
|
/// Executes an action when any descendant of `Self` is invalidated.
|
||||||
fn invalidated_descendants(
|
fn invalidated_descendants(&mut self, element: E, child: E);
|
||||||
&mut self,
|
|
||||||
element: E,
|
|
||||||
data: Option<&mut ElementData>,
|
|
||||||
child: E,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The struct that takes care of encapsulating all the logic on where and how
|
/// The struct that takes care of encapsulating all the logic on where and how
|
||||||
|
@ -83,16 +61,6 @@ where
|
||||||
P: InvalidationProcessor<E>
|
P: InvalidationProcessor<E>
|
||||||
{
|
{
|
||||||
element: E,
|
element: E,
|
||||||
// TODO(emilio): It's tempting enough to just avoid running invalidation for
|
|
||||||
// elements without data.
|
|
||||||
//
|
|
||||||
// But that's be wrong for sibling invalidations when a new element has been
|
|
||||||
// inserted in the tree and still has no data (though I _think_ the slow
|
|
||||||
// selector bits save us, it'd be nice not to depend on them).
|
|
||||||
//
|
|
||||||
// Seems like we could at least avoid running invalidation for the
|
|
||||||
// descendants if an element has no data, though.
|
|
||||||
data: Option<&'a mut ElementData>,
|
|
||||||
quirks_mode: QuirksMode,
|
quirks_mode: QuirksMode,
|
||||||
stack_limit_checker: Option<&'a StackLimitChecker>,
|
stack_limit_checker: Option<&'a StackLimitChecker>,
|
||||||
nth_index_cache: Option<&'a mut NthIndexCache>,
|
nth_index_cache: Option<&'a mut NthIndexCache>,
|
||||||
|
@ -232,7 +200,6 @@ where
|
||||||
/// Trivially constructs a new `TreeStyleInvalidator`.
|
/// Trivially constructs a new `TreeStyleInvalidator`.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
element: E,
|
element: E,
|
||||||
data: Option<&'a mut ElementData>,
|
|
||||||
quirks_mode: QuirksMode,
|
quirks_mode: QuirksMode,
|
||||||
stack_limit_checker: Option<&'a StackLimitChecker>,
|
stack_limit_checker: Option<&'a StackLimitChecker>,
|
||||||
nth_index_cache: Option<&'a mut NthIndexCache>,
|
nth_index_cache: Option<&'a mut NthIndexCache>,
|
||||||
|
@ -240,7 +207,6 @@ where
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
element,
|
element,
|
||||||
data,
|
|
||||||
quirks_mode,
|
quirks_mode,
|
||||||
stack_limit_checker,
|
stack_limit_checker,
|
||||||
nth_index_cache,
|
nth_index_cache,
|
||||||
|
@ -257,7 +223,6 @@ where
|
||||||
|
|
||||||
let invalidated_self = self.processor.collect_invalidations(
|
let invalidated_self = self.processor.collect_invalidations(
|
||||||
self.element,
|
self.element,
|
||||||
self.data.as_mut().map(|d| &mut **d),
|
|
||||||
self.nth_index_cache.as_mut().map(|c| &mut **c),
|
self.nth_index_cache.as_mut().map(|c| &mut **c),
|
||||||
self.quirks_mode,
|
self.quirks_mode,
|
||||||
&mut descendant_invalidations,
|
&mut descendant_invalidations,
|
||||||
|
@ -291,11 +256,8 @@ where
|
||||||
let mut any_invalidated = false;
|
let mut any_invalidated = false;
|
||||||
|
|
||||||
while let Some(sibling) = current {
|
while let Some(sibling) = current {
|
||||||
let mut sibling_data = sibling.mutate_data();
|
|
||||||
|
|
||||||
let mut sibling_invalidator = TreeStyleInvalidator::new(
|
let mut sibling_invalidator = TreeStyleInvalidator::new(
|
||||||
sibling,
|
sibling,
|
||||||
sibling_data.as_mut().map(|d| &mut **d),
|
|
||||||
self.quirks_mode,
|
self.quirks_mode,
|
||||||
self.stack_limit_checker,
|
self.stack_limit_checker,
|
||||||
self.nth_index_cache.as_mut().map(|c| &mut **c),
|
self.nth_index_cache.as_mut().map(|c| &mut **c),
|
||||||
|
@ -359,11 +321,8 @@ where
|
||||||
|
|
||||||
let mut invalidated_child = false;
|
let mut invalidated_child = false;
|
||||||
let invalidated_descendants = {
|
let invalidated_descendants = {
|
||||||
let mut child_data = child.mutate_data();
|
|
||||||
|
|
||||||
let mut child_invalidator = TreeStyleInvalidator::new(
|
let mut child_invalidator = TreeStyleInvalidator::new(
|
||||||
child,
|
child,
|
||||||
child_data.as_mut().map(|d| &mut **d),
|
|
||||||
self.quirks_mode,
|
self.quirks_mode,
|
||||||
self.stack_limit_checker,
|
self.stack_limit_checker,
|
||||||
self.nth_index_cache.as_mut().map(|c| &mut **c),
|
self.nth_index_cache.as_mut().map(|c| &mut **c),
|
||||||
|
@ -392,11 +351,7 @@ where
|
||||||
// Since we keep the traversal flags in terms of the flattened tree,
|
// Since we keep the traversal flags in terms of the flattened tree,
|
||||||
// we need to propagate it as appropriate.
|
// we need to propagate it as appropriate.
|
||||||
if invalidated_child || invalidated_descendants {
|
if invalidated_child || invalidated_descendants {
|
||||||
self.processor.invalidated_descendants(
|
self.processor.invalidated_descendants(self.element, child);
|
||||||
self.element,
|
|
||||||
self.data.as_mut().map(|d| &mut **d),
|
|
||||||
child,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidated_child || invalidated_descendants
|
invalidated_child || invalidated_descendants
|
||||||
|
@ -467,10 +422,7 @@ where
|
||||||
debug!(" > {:?}", invalidations);
|
debug!(" > {:?}", invalidations);
|
||||||
|
|
||||||
let should_process =
|
let should_process =
|
||||||
self.processor.should_process_descendants(
|
self.processor.should_process_descendants(self.element);
|
||||||
self.element,
|
|
||||||
self.data.as_mut().map(|d| &mut **d),
|
|
||||||
);
|
|
||||||
|
|
||||||
if !should_process {
|
if !should_process {
|
||||||
return false;
|
return false;
|
||||||
|
@ -478,10 +430,7 @@ where
|
||||||
|
|
||||||
if let Some(checker) = self.stack_limit_checker {
|
if let Some(checker) = self.stack_limit_checker {
|
||||||
if checker.limit_exceeded() {
|
if checker.limit_exceeded() {
|
||||||
self.processor.recursion_limit_exceeded(
|
self.processor.recursion_limit_exceeded(self.element);
|
||||||
self.element,
|
|
||||||
self.data.as_mut().map(|d| &mut **d)
|
|
||||||
);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -771,10 +720,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
if invalidated_self {
|
if invalidated_self {
|
||||||
self.processor.invalidated_self(
|
self.processor.invalidated_self(self.element);
|
||||||
self.element,
|
|
||||||
self.data.as_mut().map(|d| &mut **d),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SingleInvalidationResult { invalidated_self, matched, }
|
SingleInvalidationResult { invalidated_self, matched, }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue