diff --git a/components/style/data.rs b/components/style/data.rs index defb0a49759..b9aed397f23 100644 --- a/components/style/data.rs +++ b/components/style/data.rs @@ -259,11 +259,14 @@ impl ElementData { return InvalidationResult::empty(); } - let mut processor = - StateAndAttrInvalidationProcessor::new(shared_context); + let mut processor = StateAndAttrInvalidationProcessor::new( + shared_context, + element, + self, + ); + let invalidator = TreeStyleInvalidator::new( element, - Some(self), shared_context.quirks_mode(), stack_limit_checker, nth_index_cache, diff --git a/components/style/invalidation/element/collector.rs b/components/style/invalidation/element/collector.rs index 2bdc5f4a0cc..ff74ad9f3a2 100644 --- a/components/style/invalidation/element/collector.rs +++ b/components/style/invalidation/element/collector.rs @@ -51,18 +51,24 @@ where /// An invalidation processor for style changes due to state and attribute /// changes. -pub struct StateAndAttrInvalidationProcessor<'a, 'b: 'a> { +pub struct StateAndAttrInvalidationProcessor<'a, 'b: 'a, E> { 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. - pub fn new(shared_context: &'a SharedStyleContext<'b>) -> Self { - Self { shared_context } + pub fn new( + shared_context: &'a SharedStyleContext<'b>, + element: E, + data: &'a mut ElementData, + ) -> Self { + Self { shared_context, element, data } } } -impl<'a, 'b: 'a, E> InvalidationProcessor for StateAndAttrInvalidationProcessor<'a, 'b> +impl<'a, 'b: 'a, E> InvalidationProcessor for StateAndAttrInvalidationProcessor<'a, 'b, E> where E: TElement, { @@ -74,14 +80,12 @@ where fn collect_invalidations( &mut self, element: E, - mut data: Option<&mut ElementData>, nth_index_cache: Option<&mut NthIndexCache>, quirks_mode: QuirksMode, descendant_invalidations: &mut InvalidationVector, sibling_invalidations: &mut InvalidationVector, ) -> bool { 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?"); let wrapper = @@ -102,8 +106,7 @@ where trace!(" > visitedness change, force subtree restyle"); // We can't just return here because there may also be attribute // changes as well that imply additional hints. - let data = data.as_mut().unwrap(); - data.hint.insert(RestyleHint::restyle_subtree()); + self.data.hint.insert(RestyleHint::restyle_subtree()); } let mut classes_removed = SmallVec::<[Atom; 8]>::new(); @@ -183,52 +186,43 @@ where }; if invalidated_self { - if let Some(ref mut data) = data { - data.hint.insert(RESTYLE_SELF); - } + self.data.hint.insert(RESTYLE_SELF); } invalidated_self } - fn should_process_descendants( - &mut self, - _element: E, - data: Option<&mut ElementData>, - ) -> bool { - let data = match data { + fn should_process_descendants(&mut self, element: E) -> bool { + if element == self.element { + return !self.data.styles.is_display_none() && + !self.data.hint.contains(RESTYLE_DESCENDANTS) + } + + let data = match element.borrow_data() { None => return false, - Some(ref data) => data, + Some(data) => data, }; !data.styles.is_display_none() && !data.hint.contains(RESTYLE_DESCENDANTS) } - fn recursion_limit_exceeded( - &mut self, - _element: E, - data: Option<&mut ElementData>, - ) { - if let Some(data) = data { + fn recursion_limit_exceeded(&mut self, element: E) { + if element == self.element { + self.data.hint.insert(RESTYLE_DESCENDANTS); + return; + } + + if let Some(mut data) = element.mutate_data() { data.hint.insert(RESTYLE_DESCENDANTS); } } - fn invalidated_descendants( - &mut self, - element: E, - data: Option<&mut ElementData>, - child: E, - ) { + fn invalidated_descendants(&mut self, element: E, child: E) { if child.get_data().is_none() { 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, // but may be arbitrarily deep. // @@ -245,12 +239,9 @@ where } } - fn invalidated_self( - &mut self, - _element: E, - data: Option<&mut ElementData>, - ) { - if let Some(data) = data { + fn invalidated_self(&mut self, element: E) { + debug_assert_ne!(element, self.element); + if let Some(mut data) = element.mutate_data() { data.hint.insert(RESTYLE_SELF); } } diff --git a/components/style/invalidation/element/invalidator.rs b/components/style/invalidation/element/invalidator.rs index 7ad87363066..388fb36aae8 100644 --- a/components/style/invalidation/element/invalidator.rs +++ b/components/style/invalidation/element/invalidator.rs @@ -6,7 +6,6 @@ //! element styles need to be invalidated. use context::StackLimitChecker; -use data::ElementData; use dom::{TElement, TNode}; use selector_parser::SelectorImpl; use selectors::NthIndexCache; @@ -18,9 +17,6 @@ use smallvec::SmallVec; use std::fmt; /// 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 where E: TElement, @@ -36,7 +32,6 @@ where fn collect_invalidations( &mut self, element: E, - data: Option<&mut ElementData>, nth_index_cache: Option<&mut NthIndexCache>, quirks_mode: QuirksMode, descendant_invalidations: &mut InvalidationVector, @@ -45,34 +40,17 @@ where /// Returns whether the invalidation process should process the descendants /// of the given element. - fn should_process_descendants( - &mut self, - element: E, - data: Option<&mut ElementData>, - ) -> bool; + fn should_process_descendants(&mut self, element: E) -> bool; /// Executes an arbitrary action when the recursion limit is exceded (if /// any). - fn recursion_limit_exceeded( - &mut self, - element: E, - data: Option<&mut ElementData>, - ); + fn recursion_limit_exceeded(&mut self, element: E); /// Executes an action when `Self` is invalidated. - fn invalidated_self( - &mut self, - element: E, - data: Option<&mut ElementData>, - ); + fn invalidated_self(&mut self, element: E); /// Executes an action when any descendant of `Self` is invalidated. - fn invalidated_descendants( - &mut self, - element: E, - data: Option<&mut ElementData>, - child: E, - ); + fn invalidated_descendants(&mut self, element: E, child: E); } /// The struct that takes care of encapsulating all the logic on where and how @@ -83,16 +61,6 @@ where P: InvalidationProcessor { 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, stack_limit_checker: Option<&'a StackLimitChecker>, nth_index_cache: Option<&'a mut NthIndexCache>, @@ -232,7 +200,6 @@ where /// Trivially constructs a new `TreeStyleInvalidator`. pub fn new( element: E, - data: Option<&'a mut ElementData>, quirks_mode: QuirksMode, stack_limit_checker: Option<&'a StackLimitChecker>, nth_index_cache: Option<&'a mut NthIndexCache>, @@ -240,7 +207,6 @@ where ) -> Self { Self { element, - data, quirks_mode, stack_limit_checker, nth_index_cache, @@ -257,7 +223,6 @@ where let invalidated_self = self.processor.collect_invalidations( self.element, - self.data.as_mut().map(|d| &mut **d), self.nth_index_cache.as_mut().map(|c| &mut **c), self.quirks_mode, &mut descendant_invalidations, @@ -291,11 +256,8 @@ where let mut any_invalidated = false; while let Some(sibling) = current { - let mut sibling_data = sibling.mutate_data(); - let mut sibling_invalidator = TreeStyleInvalidator::new( sibling, - sibling_data.as_mut().map(|d| &mut **d), self.quirks_mode, self.stack_limit_checker, self.nth_index_cache.as_mut().map(|c| &mut **c), @@ -359,11 +321,8 @@ where let mut invalidated_child = false; let invalidated_descendants = { - let mut child_data = child.mutate_data(); - let mut child_invalidator = TreeStyleInvalidator::new( child, - child_data.as_mut().map(|d| &mut **d), self.quirks_mode, self.stack_limit_checker, 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, // we need to propagate it as appropriate. if invalidated_child || invalidated_descendants { - self.processor.invalidated_descendants( - self.element, - self.data.as_mut().map(|d| &mut **d), - child, - ); + self.processor.invalidated_descendants(self.element, child); } invalidated_child || invalidated_descendants @@ -467,10 +422,7 @@ where debug!(" > {:?}", invalidations); let should_process = - self.processor.should_process_descendants( - self.element, - self.data.as_mut().map(|d| &mut **d), - ); + self.processor.should_process_descendants(self.element); if !should_process { return false; @@ -478,10 +430,7 @@ where if let Some(checker) = self.stack_limit_checker { if checker.limit_exceeded() { - self.processor.recursion_limit_exceeded( - self.element, - self.data.as_mut().map(|d| &mut **d) - ); + self.processor.recursion_limit_exceeded(self.element); return true; } } @@ -771,10 +720,7 @@ where } if invalidated_self { - self.processor.invalidated_self( - self.element, - self.data.as_mut().map(|d| &mut **d), - ); + self.processor.invalidated_self(self.element); } SingleInvalidationResult { invalidated_self, matched, }