diff --git a/components/style/data.rs b/components/style/data.rs index d96cfafa9fe..2ab5e6e0e34 100644 --- a/components/style/data.rs +++ b/components/style/data.rs @@ -16,7 +16,6 @@ use selectors::matching::VisitedHandlingMode; use shared_lock::{Locked, StylesheetGuards}; use std::fmt; use stylearc::Arc; -use traversal::TraversalFlags; /// The structure that represents the result of style computation. This is /// effectively a tuple of rules and computed values, that is, the rule node, @@ -349,97 +348,6 @@ impl ElementStyles { } } -/// Restyle hint for storing on ElementData. -/// -/// We wrap it in a newtype to force the encapsulation of the complexity of -/// handling the correct invalidations in this file. -/// -/// TODO(emilio): This will probably be a non-issue in a bit. -#[derive(Clone, Copy, Debug)] -pub struct StoredRestyleHint(pub RestyleHint); - -impl StoredRestyleHint { - /// Propagates this restyle hint to a child element. - pub fn propagate(&mut self, traversal_flags: &TraversalFlags) -> Self { - use std::mem; - - // In the middle of an animation only restyle, we don't need to - // propagate any restyle hints, and we need to remove ourselves. - if traversal_flags.for_animation_only() { - self.0.remove_animation_hints(); - return Self::empty(); - } - - debug_assert!(!self.0.has_animation_hint(), - "There should not be any animation restyle hints \ - during normal traversal"); - - // Else we should clear ourselves, and return the propagated hint. - let new_hint = mem::replace(&mut self.0, RestyleHint::empty()) - .propagate_for_non_animation_restyle(); - StoredRestyleHint(new_hint) - } - - /// Creates an empty `StoredRestyleHint`. - pub fn empty() -> Self { - StoredRestyleHint(RestyleHint::empty()) - } - - /// Creates a restyle hint that forces the whole subtree to be restyled, - /// including the element. - pub fn subtree() -> Self { - StoredRestyleHint(RestyleHint::restyle_subtree()) - } - - /// Creates a restyle hint that indicates the element must be recascaded. - pub fn recascade_self() -> Self { - StoredRestyleHint(RestyleHint::recascade_self()) - } - - /// Returns true if the hint indicates that our style may be invalidated. - pub fn has_self_invalidations(&self) -> bool { - self.0.affects_self() - } - - /// Whether the restyle hint is empty (nothing requires to be restyled). - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } - - /// Insert another restyle hint, effectively resulting in the union of both. - pub fn insert(&mut self, other: Self) { - self.0.insert(other.0) - } - - /// Contains whether the whole subtree is invalid. - pub fn contains_subtree(&self) -> bool { - self.0.contains(RestyleHint::restyle_subtree()) - } - - /// Returns true if the hint has animation-only restyle. - pub fn has_animation_hint(&self) -> bool { - self.0.has_animation_hint() - } - - /// Returns true if the hint indicates the current element must be - /// recascaded. - pub fn has_recascade_self(&self) -> bool { - self.0.has_recascade_self() - } -} - -impl Default for StoredRestyleHint { - fn default() -> Self { - Self::empty() - } -} - -impl From for StoredRestyleHint { - fn from(hint: RestyleHint) -> Self { - StoredRestyleHint(hint) - } -} - /// Transient data used by the restyle algorithm. This structure is instantiated /// either before or during restyle traversal, and is cleared at the end of node /// processing. @@ -447,7 +355,7 @@ impl From for StoredRestyleHint { pub struct RestyleData { /// The restyle hint, which indicates whether selectors need to be rematched /// for this element, its children, and its descendants. - pub hint: StoredRestyleHint, + pub hint: RestyleHint, /// The restyle damage, indicating what kind of layout changes are required /// afte restyling. @@ -588,8 +496,8 @@ impl ElementData { debug_assert!(self.restyle.is_some()); let restyle_data = self.restyle.as_ref().unwrap(); - let hint = restyle_data.hint.0; + let hint = restyle_data.hint; if shared_context.traversal_flags.for_animation_only() { // return either CascadeWithReplacements or CascadeOnly in case of // animation-only restyle. diff --git a/components/style/invalidation/element/restyle_hints.rs b/components/style/invalidation/element/restyle_hints.rs index 786c267f203..4b968da031f 100644 --- a/components/style/invalidation/element/restyle_hints.rs +++ b/components/style/invalidation/element/restyle_hints.rs @@ -6,6 +6,7 @@ #[cfg(feature = "gecko")] use gecko_bindings::structs::nsRestyleHint; +use traversal::TraversalFlags; bitflags! { /// The kind of restyle we need to do for a given element. @@ -57,9 +58,40 @@ impl RestyleHint { RECASCADE_SELF | RECASCADE_DESCENDANTS } + /// Returns whether this hint invalidates the element and all its + /// descendants. + pub fn contains_subtree(&self) -> bool { + self.contains(RESTYLE_SELF | RESTYLE_DESCENDANTS) + } + + /// Returns whether we need to restyle this element. + pub fn has_self_invalidations(&self) -> bool { + self.intersects(RESTYLE_SELF | RECASCADE_SELF | Self::replacements()) + } + + /// Propagates this restyle hint to a child element. + pub fn propagate(&mut self, traversal_flags: &TraversalFlags) -> Self { + use std::mem; + + // In the middle of an animation only restyle, we don't need to + // propagate any restyle hints, and we need to remove ourselves. + if traversal_flags.for_animation_only() { + self.remove_animation_hints(); + return Self::empty(); + } + + debug_assert!(!self.has_animation_hint(), + "There should not be any animation restyle hints \ + during normal traversal"); + + // Else we should clear ourselves, and return the propagated hint. + mem::replace(self, Self::empty()) + .propagate_for_non_animation_restyle() + } + /// Returns a new `CascadeHint` appropriate for children of the current /// element. - pub fn propagate_for_non_animation_restyle(&self) -> Self { + fn propagate_for_non_animation_restyle(&self) -> Self { if self.contains(RESTYLE_DESCENDANTS) { return Self::restyle_subtree() } @@ -86,13 +118,6 @@ impl RestyleHint { RESTYLE_SMIL | RESTYLE_CSS_ANIMATIONS | RESTYLE_CSS_TRANSITIONS } - /// Returns whether the hint specifies that some work must be performed on - /// the current element. - #[inline] - pub fn affects_self(&self) -> bool { - self.intersects(RESTYLE_SELF | RECASCADE_SELF | Self::replacements()) - } - /// Returns whether the hint specifies that the currently element must be /// recascaded. pub fn has_recascade_self(&self) -> bool { @@ -145,6 +170,12 @@ impl RestyleHint { } } +impl Default for RestyleHint { + fn default() -> Self { + Self::empty() + } +} + #[cfg(feature = "gecko")] impl From for RestyleHint { fn from(raw: nsRestyleHint) -> Self { diff --git a/components/style/invalidation/stylesheets.rs b/components/style/invalidation/stylesheets.rs index 4ac69f8fa02..c72a733467c 100644 --- a/components/style/invalidation/stylesheets.rs +++ b/components/style/invalidation/stylesheets.rs @@ -8,9 +8,9 @@ #![deny(unsafe_code)] use Atom; -use data::StoredRestyleHint; use dom::{TElement, TNode}; use fnv::FnvHashSet; +use invalidation::element::restyle_hints::RestyleHint; use selector_parser::SelectorImpl; use selectors::attr::CaseSensitivity; use selectors::parser::{Component, Selector}; @@ -134,7 +134,7 @@ impl StylesheetInvalidationSet { if self.fully_invalid { debug!("process_invalidations: fully_invalid({:?})", element); - data.ensure_restyle().hint.insert(StoredRestyleHint::subtree()); + data.ensure_restyle().hint.insert(RestyleHint::restyle_subtree()); return true; } } @@ -177,7 +177,7 @@ impl StylesheetInvalidationSet { if scope.matches(element) { debug!("process_invalidations_in_subtree: {:?} matched {:?}", element, scope); - data.ensure_restyle().hint.insert(StoredRestyleHint::subtree()); + data.ensure_restyle().hint.insert(RestyleHint::restyle_subtree()); return true; } } diff --git a/components/style/traversal.rs b/components/style/traversal.rs index 53e0dc38281..c3e8e9ce251 100644 --- a/components/style/traversal.rs +++ b/components/style/traversal.rs @@ -6,7 +6,7 @@ use atomic_refcell::AtomicRefCell; use context::{SharedStyleContext, StyleContext, ThreadLocalStyleContext}; -use data::{ElementData, ElementStyles, StoredRestyleHint}; +use data::{ElementData, ElementStyles}; use dom::{DirtyDescendants, NodeInfo, OpaqueNode, TElement, TNode}; use invalidation::element::restyle_hints::{RECASCADE_SELF, RECASCADE_DESCENDANTS, RestyleHint}; use matching::{ChildCascadeRequirement, MatchMethods}; @@ -691,7 +691,7 @@ pub fn recalc_style_at(traversal: &D, // Now that matching and cascading is done, clear the bits corresponding to // those operations and compute the propagated restyle hint. let mut propagated_hint = match data.get_restyle_mut() { - None => StoredRestyleHint::empty(), + None => RestyleHint::empty(), Some(r) => { debug_assert!(context.shared.traversal_flags.for_animation_only() || !r.hint.has_animation_hint(), @@ -842,7 +842,7 @@ fn compute_style(_traversal: &D, fn preprocess_children(context: &mut StyleContext, element: E, - propagated_hint: StoredRestyleHint, + propagated_hint: RestyleHint, damage_handled: RestyleDamage) where E: TElement, D: DomTraversal,