aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-06-15 20:28:56 -0700
committerGitHub <noreply@github.com>2017-06-15 20:28:56 -0700
commit33766b2714443399808c950e5bb74b1f124f2bc4 (patch)
treee55725db70e6f70b0d8d139097ca42646f021c14 /components
parente3a52536b650f4aeb951b474936a0b67821f112e (diff)
parentffc45e9aaa59d5540c5f0480fbe13f48658ec593 (diff)
downloadservo-33766b2714443399808c950e5bb74b1f124f2bc4.tar.gz
servo-33766b2714443399808c950e5bb74b1f124f2bc4.zip
Auto merge of #17348 - emilio:bup, r=bholley
style: Inline RestyleData. Bug: 1368236 MozReview-Commit-ID: 49s3SO0PMHf <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17348) <!-- Reviewable:end -->
Diffstat (limited to 'components')
-rw-r--r--components/layout/wrapper.rs11
-rw-r--r--components/layout_thread/lib.rs11
-rw-r--r--components/style/data.rs141
-rw-r--r--components/style/dom.rs3
-rw-r--r--components/style/invalidation/element/invalidator.rs12
-rw-r--r--components/style/invalidation/stylesheets.rs14
-rw-r--r--components/style/matching.rs20
-rw-r--r--components/style/sharing/mod.rs55
-rw-r--r--components/style/traversal.rs94
9 files changed, 169 insertions, 192 deletions
diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs
index 4ae7c403e37..87fe65bb3b9 100644
--- a/components/layout/wrapper.rs
+++ b/components/layout/wrapper.rs
@@ -171,19 +171,14 @@ impl<T: ThreadSafeLayoutNode> ThreadSafeLayoutNodeHelpers for T {
let damage = {
let data = node.get_raw_data().unwrap();
- if let Some(r) = data.style_data.element_data.borrow().get_restyle() {
- // We're reflowing a node that just got a restyle, and so the
- // damage has been computed and stored in the RestyleData.
- r.damage
- } else if !data.layout_data.borrow().flags.contains(::data::HAS_BEEN_TRAVERSED) {
+
+ if !data.layout_data.borrow().flags.contains(::data::HAS_BEEN_TRAVERSED) {
// We're reflowing a node that was styled for the first time and
// has never been visited by layout. Return rebuild_and_reflow,
// because that's what the code expects.
RestyleDamage::rebuild_and_reflow()
} else {
- // We're reflowing a node whose style data didn't change, but whose
- // layout may change due to changes in ancestors or descendants.
- RestyleDamage::empty()
+ data.style_data.element_data.borrow().restyle.damage
}
};
diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs
index 7c7b5fd89ed..d53fa05a37f 100644
--- a/components/layout_thread/lib.rs
+++ b/components/layout_thread/lib.rs
@@ -1116,7 +1116,7 @@ impl LayoutThread {
let el = node.as_element().unwrap();
if let Some(mut d) = element.mutate_data() {
if d.has_styles() {
- d.ensure_restyle().hint.insert(RestyleHint::restyle_subtree());
+ d.restyle.hint.insert(RestyleHint::restyle_subtree());
}
}
if let Some(p) = el.parent_element() {
@@ -1152,7 +1152,7 @@ impl LayoutThread {
if needs_dirtying {
if let Some(mut d) = element.mutate_data() {
if d.has_styles() {
- d.ensure_restyle().hint.insert(RestyleHint::restyle_subtree());
+ d.restyle.hint.insert(RestyleHint::restyle_subtree());
}
}
}
@@ -1197,12 +1197,11 @@ impl LayoutThread {
}
let mut style_data = style_data.borrow_mut();
- let mut restyle_data = style_data.ensure_restyle();
// Stash the data on the element for processing by the style system.
- restyle_data.hint.insert(restyle.hint.into());
- restyle_data.damage = restyle.damage;
- debug!("Noting restyle for {:?}: {:?}", el, restyle_data);
+ style_data.restyle.hint.insert(restyle.hint.into());
+ style_data.restyle.damage = restyle.damage;
+ debug!("Noting restyle for {:?}: {:?}", el, style_data.restyle);
}
// Create a layout context for use throughout the following passes.
diff --git a/components/style/data.rs b/components/style/data.rs
index 46d9fe8afe0..0363d397d74 100644
--- a/components/style/data.rs
+++ b/components/style/data.rs
@@ -348,17 +348,26 @@ impl ElementStyles {
}
}
+bitflags! {
+ flags RestyleFlags: u8 {
+ /// Whether the styles changed for this restyle.
+ const WAS_RESTYLED = 1 << 0,
+ /// Whether we reframed/reconstructed any ancestor or self.
+ const ANCESTOR_WAS_RECONSTRUCTED = 1 << 1,
+ }
+}
+
/// 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.
-#[derive(Debug, Default)]
+#[derive(Debug)]
pub struct RestyleData {
/// The restyle hint, which indicates whether selectors need to be rematched
/// for this element, its children, and its descendants.
pub hint: RestyleHint,
- /// Whether we reframed/reconstructed any ancestor or self.
- pub reconstructed_ancestor: bool,
+ /// A few flags to have in mind.
+ flags: RestyleFlags,
/// The restyle damage, indicating what kind of layout changes are required
/// afte restyling.
@@ -366,9 +375,53 @@ pub struct RestyleData {
}
impl RestyleData {
- /// Returns true if this RestyleData might invalidate the current style.
- pub fn has_invalidations(&self) -> bool {
- self.hint.has_self_invalidations()
+ fn new() -> Self {
+ Self {
+ hint: RestyleHint::empty(),
+ flags: RestyleFlags::empty(),
+ damage: RestyleDamage::empty(),
+ }
+ }
+
+ /// Clear all the restyle state associated with this element.
+ fn clear(&mut self) {
+ *self = Self::new();
+ }
+
+ /// Returns whether this element or any ancestor is going to be
+ /// reconstructed.
+ pub fn reconstructed_self_or_ancestor(&self) -> bool {
+ self.reconstructed_ancestor() ||
+ self.damage.contains(RestyleDamage::reconstruct())
+ }
+
+ /// Returns whether any ancestor of this element was restyled.
+ fn reconstructed_ancestor(&self) -> bool {
+ self.flags.contains(ANCESTOR_WAS_RECONSTRUCTED)
+ }
+
+ /// Sets the flag that tells us whether we've reconstructed an ancestor.
+ pub fn set_reconstructed_ancestor(&mut self) {
+ // If it weren't for animation-only traversals, we could assert
+ // `!self.reconstructed_ancestor()` here.
+ self.flags.insert(ANCESTOR_WAS_RECONSTRUCTED);
+ }
+
+ /// Mark this element as restyled, which is useful to know whether we need
+ /// to do a post-traversal.
+ pub fn set_restyled(&mut self) {
+ self.flags.insert(WAS_RESTYLED);
+ }
+
+ /// Mark this element as restyled, which is useful to know whether we need
+ /// to do a post-traversal.
+ pub fn is_restyle(&self) -> bool {
+ self.flags.contains(WAS_RESTYLED)
+ }
+
+ /// Returns whether this element has been part of a restyle.
+ pub fn contains_restyle_data(&self) -> bool {
+ self.is_restyle() || !self.hint.is_empty() || !self.damage.is_empty()
}
}
@@ -382,9 +435,8 @@ pub struct ElementData {
/// The computed styles for the element and its pseudo-elements.
styles: Option<ElementStyles>,
- /// Restyle tracking. We separate this into a separate allocation so that
- /// we can drop it when no restyles are pending on the elemnt.
- restyle: Option<Box<RestyleData>>,
+ /// Restyle state.
+ pub restyle: RestyleData,
}
/// The kind of restyle that a single element should do.
@@ -402,6 +454,14 @@ pub enum RestyleKind {
}
impl ElementData {
+ /// Borrows both styles and restyle mutably at the same time.
+ pub fn styles_and_restyle_mut(
+ &mut self
+ ) -> (&mut ElementStyles, &mut RestyleData) {
+ (self.styles.as_mut().unwrap(),
+ &mut self.restyle)
+ }
+
/// Invalidates style for this element, its descendants, and later siblings,
/// based on the snapshot of the element that we took when attributes or
/// state changed.
@@ -437,7 +497,7 @@ impl ElementData {
pub fn new(existing: Option<ElementStyles>) -> Self {
ElementData {
styles: existing,
- restyle: None,
+ restyle: RestyleData::new(),
}
}
@@ -448,7 +508,7 @@ impl ElementData {
/// Returns whether we have any outstanding style invalidation.
pub fn has_invalidations(&self) -> bool {
- self.restyle.as_ref().map_or(false, |r| r.has_invalidations())
+ self.restyle.hint.has_self_invalidations()
}
/// Returns the kind of restyling that we're going to need to do on this
@@ -465,10 +525,7 @@ impl ElementData {
return RestyleKind::MatchAndCascade;
}
- debug_assert!(self.restyle.is_some());
- let restyle_data = self.restyle.as_ref().unwrap();
-
- let hint = restyle_data.hint;
+ let hint = self.restyle.hint;
if shared_context.traversal_flags.for_animation_only() {
// return either CascadeWithReplacements or CascadeOnly in case of
// animation-only restyle.
@@ -488,7 +545,8 @@ impl ElementData {
return RestyleKind::CascadeWithReplacements(hint & RestyleHint::replacements());
}
- debug_assert!(hint.has_recascade_self(), "We definitely need to do something!");
+ debug_assert!(hint.has_recascade_self(),
+ "We definitely need to do something!");
return RestyleKind::CascadeOnly;
}
@@ -513,13 +571,6 @@ impl ElementData {
self.styles.as_mut().expect("Calling styles_mut() on unstyled ElementData")
}
- /// Borrows both styles and restyle mutably at the same time.
- pub fn styles_and_restyle_mut(&mut self) -> (&mut ElementStyles,
- Option<&mut RestyleData>) {
- (self.styles.as_mut().unwrap(),
- self.restyle.as_mut().map(|r| &mut **r))
- }
-
/// Sets the computed element styles.
pub fn set_styles(&mut self, styles: ElementStyles) {
self.styles = Some(styles);
@@ -558,47 +609,9 @@ impl ElementData {
important_rules != other_important_rules
}
- /// Returns true if the Element has a RestyleData.
- pub fn has_restyle(&self) -> bool {
- self.restyle.is_some()
- }
-
- /// Drops any RestyleData.
- pub fn clear_restyle(&mut self) {
- self.restyle = None;
- }
-
- /// Creates a RestyleData if one doesn't exist.
- ///
- /// Asserts that the Element has been styled.
- pub fn ensure_restyle(&mut self) -> &mut RestyleData {
- debug_assert!(self.styles.is_some(), "restyling unstyled element");
- if self.restyle.is_none() {
- self.restyle = Some(Box::new(RestyleData::default()));
- }
- self.restyle.as_mut().unwrap()
- }
-
- /// Gets a reference to the restyle data, if any.
- pub fn get_restyle(&self) -> Option<&RestyleData> {
- self.restyle.as_ref().map(|r| &**r)
- }
-
- /// Gets a reference to the restyle data. Panic if the element does not
- /// have restyle data.
- pub fn restyle(&self) -> &RestyleData {
- self.get_restyle().expect("Calling restyle without RestyleData")
- }
-
- /// Gets a mutable reference to the restyle data, if any.
- pub fn get_restyle_mut(&mut self) -> Option<&mut RestyleData> {
- self.restyle.as_mut().map(|r| &mut **r)
- }
-
- /// Gets a mutable reference to the restyle data. Panic if the element does
- /// not have restyle data.
- pub fn restyle_mut(&mut self) -> &mut RestyleData {
- self.get_restyle_mut().expect("Calling restyle_mut without RestyleData")
+ /// Drops any restyle state from the element.
+ pub fn clear_restyle_state(&mut self) {
+ self.restyle.clear();
}
/// Returns SMIL overriden value if exists.
diff --git a/components/style/dom.rs b/components/style/dom.rs
index 795eb51c247..769cedfda28 100644
--- a/components/style/dom.rs
+++ b/components/style/dom.rs
@@ -567,8 +567,7 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone +
Some(d) => d,
None => return false,
};
- return data.get_restyle()
- .map_or(false, |r| r.hint.has_animation_hint());
+ return data.restyle.hint.has_animation_hint()
}
/// Gets declarations from XBL bindings from the element. Only gecko element could have this.
diff --git a/components/style/invalidation/element/invalidator.rs b/components/style/invalidation/element/invalidator.rs
index df92a4f3a8d..ed759076e23 100644
--- a/components/style/invalidation/element/invalidator.rs
+++ b/components/style/invalidation/element/invalidator.rs
@@ -114,7 +114,7 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E>
// We can't just return here because there may also be attribute
// changes as well that imply additional hints.
let mut data = self.data.as_mut().unwrap();
- data.ensure_restyle().hint.insert(RestyleHint::restyle_subtree().into());
+ data.restyle.hint.insert(RestyleHint::restyle_subtree());
}
let mut classes_removed = SmallVec::<[Atom; 8]>::new();
@@ -211,7 +211,7 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E>
if invalidated_self {
if let Some(ref mut data) = self.data {
- data.ensure_restyle().hint.insert(RESTYLE_SELF.into());
+ data.restyle.hint.insert(RESTYLE_SELF);
}
}
@@ -287,10 +287,8 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E>
match self.data {
None => return false,
Some(ref data) => {
- if let Some(restyle) = data.get_restyle() {
- if restyle.hint.contains_subtree() {
- return false;
- }
+ if data.restyle.hint.contains_subtree() {
+ return false;
}
}
}
@@ -494,7 +492,7 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E>
if invalidated_self {
if let Some(ref mut data) = self.data {
- data.ensure_restyle().hint.insert(RESTYLE_SELF.into());
+ data.restyle.hint.insert(RESTYLE_SELF);
}
}
diff --git a/components/style/invalidation/stylesheets.rs b/components/style/invalidation/stylesheets.rs
index c72a733467c..b28ae6fed87 100644
--- a/components/style/invalidation/stylesheets.rs
+++ b/components/style/invalidation/stylesheets.rs
@@ -134,7 +134,7 @@ impl StylesheetInvalidationSet {
if self.fully_invalid {
debug!("process_invalidations: fully_invalid({:?})",
element);
- data.ensure_restyle().hint.insert(RestyleHint::restyle_subtree());
+ data.restyle.hint.insert(RestyleHint::restyle_subtree());
return true;
}
}
@@ -165,19 +165,17 @@ impl StylesheetInvalidationSet {
return false;
}
- if let Some(ref r) = data.get_restyle() {
- if r.hint.contains_subtree() {
- debug!("process_invalidations_in_subtree: {:?} was already invalid",
- element);
- return false;
- }
+ if data.restyle.hint.contains_subtree() {
+ debug!("process_invalidations_in_subtree: {:?} was already invalid",
+ element);
+ return false;
}
for scope in &self.invalid_scopes {
if scope.matches(element) {
debug!("process_invalidations_in_subtree: {:?} matched {:?}",
element, scope);
- data.ensure_restyle().hint.insert(RestyleHint::restyle_subtree());
+ data.restyle.hint.insert(RestyleHint::restyle_subtree());
return true;
}
}
diff --git a/components/style/matching.rs b/components/style/matching.rs
index 320546147bf..a1cde2f85d5 100644
--- a/components/style/matching.rs
+++ b/components/style/matching.rs
@@ -707,8 +707,7 @@ trait PrivateMatchMethods: TElement {
// for followup work to make the optimization here more optimal by considering
// each bit individually.
let skip_applying_damage =
- restyle.damage.contains(RestyleDamage::reconstruct()) ||
- restyle.reconstructed_ancestor;
+ restyle.reconstructed_self_or_ancestor();
let difference = self.compute_style_difference(&old_values,
&new_values,
@@ -1187,12 +1186,10 @@ pub trait MatchMethods : TElement {
}
});
- if matches_different_pseudos {
- if let Some(r) = data.get_restyle_mut() {
- // Any changes to the matched pseudo-elements trigger
- // reconstruction.
- r.damage |= RestyleDamage::reconstruct();
- }
+ if matches_different_pseudos && data.restyle.is_restyle() {
+ // Any changes to the matched pseudo-elements trigger
+ // reconstruction.
+ data.restyle.damage |= RestyleDamage::reconstruct();
}
}
@@ -1257,16 +1254,11 @@ pub trait MatchMethods : TElement {
/// Computes and applies restyle damage.
fn accumulate_damage(&self,
shared_context: &SharedStyleContext,
- restyle: Option<&mut RestyleData>,
+ restyle: &mut RestyleData,
old_values: Option<&ComputedValues>,
new_values: &Arc<ComputedValues>,
pseudo: Option<&PseudoElement>)
-> ChildCascadeRequirement {
- let restyle = match restyle {
- Some(r) => r,
- None => return ChildCascadeRequirement::MustCascadeChildren,
- };
-
let old_values = match old_values {
Some(v) => v,
None => return ChildCascadeRequirement::MustCascadeChildren,
diff --git a/components/style/sharing/mod.rs b/components/style/sharing/mod.rs
index 5971eb34367..a1cedbd4b73 100644
--- a/components/style/sharing/mod.rs
+++ b/components/style/sharing/mod.rs
@@ -377,38 +377,38 @@ impl<E: TElement> StyleSharingTarget<E> {
// We used to have pseudos (because we had styles).
// Check for damage from the set of pseudos changing or
// pseudos being restyled.
- let (styles, restyle_data) = data.styles_and_restyle_mut();
- if let Some(restyle_data) = restyle_data {
- let old_pseudos = &styles.pseudos;
- let new_pseudos = &shared_style.pseudos;
- if !old_pseudos.has_same_pseudos_as(new_pseudos) {
- restyle_data.damage |= RestyleDamage::reconstruct();
- } else {
- // It's a bit unfortunate that we have to keep
- // mapping PseudoElements back to indices
- // here....
- for pseudo in old_pseudos.keys() {
- let old_values =
- old_pseudos.get(&pseudo).unwrap().values.as_ref().map(|v| &**v);
- let new_values =
- new_pseudos.get(&pseudo).unwrap().values();
- self.element.accumulate_damage(
- &shared_context,
- Some(restyle_data),
- old_values,
- new_values,
- Some(&pseudo)
- );
- }
+ let (styles, mut restyle_data) = data.styles_and_restyle_mut();
+ let old_pseudos = &styles.pseudos;
+ let new_pseudos = &shared_style.pseudos;
+
+ if !old_pseudos.has_same_pseudos_as(new_pseudos) {
+ restyle_data.damage |= RestyleDamage::reconstruct();
+ } else {
+ // It's a bit unfortunate that we have to keep
+ // mapping PseudoElements back to indices
+ // here....
+ for pseudo in old_pseudos.keys() {
+ let old_values =
+ old_pseudos.get(&pseudo).unwrap().values.as_ref().map(|v| &**v);
+ let new_values =
+ new_pseudos.get(&pseudo).unwrap().values();
+ self.element.accumulate_damage(
+ &shared_context,
+ restyle_data,
+ old_values,
+ new_values,
+ Some(&pseudo)
+ );
}
}
}
- let old_values = data.get_styles_mut()
- .and_then(|s| s.primary.values.take());
+ let old_values =
+ data.get_styles_mut().and_then(|s| s.primary.values.take());
+
self.element.accumulate_damage(
&shared_context,
- data.get_restyle_mut(),
+ &mut data.restyle,
old_values.as_ref().map(|v| &**v),
shared_style.primary.values(),
None
@@ -597,9 +597,6 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
match sharing_result {
Ok(shared_style) => {
// Yay, cache hit. Share the style.
-
- debug_assert_eq!(data.has_styles(), data.has_restyle());
-
let child_cascade_requirement =
target.accumulate_damage_when_sharing(shared_context,
&shared_style,
diff --git a/components/style/traversal.rs b/components/style/traversal.rs
index 9f085cfe374..004c2485afd 100644
--- a/components/style/traversal.rs
+++ b/components/style/traversal.rs
@@ -10,7 +10,6 @@ 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};
-use selector_parser::RestyleDamage;
use sharing::{StyleSharingBehavior, StyleSharingTarget};
#[cfg(feature = "servo")] use servo_config::opts;
use smallvec::SmallVec;
@@ -296,10 +295,8 @@ pub trait DomTraversal<E: TElement> : Sync {
if el.is_native_anonymous() {
if let Some(parent) = el.traversal_parent() {
let parent_data = parent.borrow_data().unwrap();
- let going_to_reframe = parent_data.get_restyle().map_or(false, |r| {
- r.reconstructed_ancestor ||
- r.damage.contains(RestyleDamage::reconstruct())
- });
+ let going_to_reframe =
+ parent_data.restyle.reconstructed_self_or_ancestor();
let mut is_before_or_after_pseudo = false;
if let Some(pseudo) = el.implemented_pseudo_element() {
@@ -337,9 +334,8 @@ pub trait DomTraversal<E: TElement> : Sync {
Some(d) => d,
None => return false,
};
- return data.get_restyle()
- .map_or(false, |r| r.hint.has_animation_hint() ||
- r.hint.has_recascade_self());
+ return data.restyle.hint.has_animation_hint() ||
+ data.restyle.hint.has_recascade_self();
}
// If the dirty descendants bit is set, we need to traverse no
@@ -360,18 +356,15 @@ pub trait DomTraversal<E: TElement> : Sync {
return true;
}
- // Check the restyle data.
- if let Some(r) = data.get_restyle() {
- // If we have a restyle hint or need to recascade, we need to
- // visit the element.
- //
- // Note that this is different than checking has_current_styles(),
- // since that can return true even if we have a restyle hint
- // indicating that the element's descendants (but not necessarily
- // the element) need restyling.
- if !r.hint.is_empty() {
- return true;
- }
+ // If we have a restyle hint or need to recascade, we need to
+ // visit the element.
+ //
+ // Note that this is different than checking has_current_styles(),
+ // since that can return true even if we have a restyle hint
+ // indicating that the element's descendants (but not necessarily
+ // the element) need restyling.
+ if !data.restyle.hint.is_empty() {
+ return true;
}
// Servo uses the post-order traversal for flow construction, so
@@ -381,7 +374,7 @@ pub trait DomTraversal<E: TElement> : Sync {
// We also need to traverse nodes with explicit damage and no other
// restyle data, so that this damage can be cleared.
if (cfg!(feature = "servo") || traversal_flags.for_reconstruct()) &&
- data.get_restyle().map_or(false, |r| !r.damage.is_empty()) {
+ !data.restyle.damage.is_empty() {
return true;
}
@@ -690,20 +683,17 @@ pub fn recalc_style_at<E, D>(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 => RestyleHint::empty(),
- Some(r) => {
- debug_assert!(context.shared.traversal_flags.for_animation_only() ||
- !r.hint.has_animation_hint(),
- "animation restyle hint should be handled during \
- animation-only restyles");
- r.hint.propagate(&context.shared.traversal_flags)
- },
+ let mut propagated_hint = {
+ debug_assert!(context.shared.traversal_flags.for_animation_only() ||
+ !data.restyle.hint.has_animation_hint(),
+ "animation restyle hint should be handled during \
+ animation-only restyles");
+ data.restyle.hint.propagate(&context.shared.traversal_flags)
};
// FIXME(bholley): Need to handle explicitly-inherited reset properties
// somewhere.
- propagated_hint.insert(hint.into());
+ propagated_hint.insert(hint);
trace!("propagated_hint={:?} \
is_display_none={:?}, implementing_pseudo={:?}",
@@ -730,10 +720,9 @@ pub fn recalc_style_at<E, D>(traversal: &D,
DontLog) &&
(has_dirty_descendants_for_this_restyle ||
!propagated_hint.is_empty()) {
- let reconstructed_ancestor = data.get_restyle().map_or(false, |r| {
- r.reconstructed_ancestor ||
- r.damage.contains(RestyleDamage::reconstruct())
- });
+ let reconstructed_ancestor =
+ data.restyle.reconstructed_self_or_ancestor();
+
preprocess_children::<E, D>(
context,
element,
@@ -746,7 +735,7 @@ pub fn recalc_style_at<E, D>(traversal: &D,
// data here, since we won't need to perform a post-traversal to pick up
// any change hints.
if context.shared.traversal_flags.for_reconstruct() {
- data.clear_restyle();
+ data.clear_restyle_state();
}
if context.shared.traversal_flags.for_animation_only() {
@@ -792,6 +781,10 @@ fn compute_style<E, D>(_traversal: &D,
debug!("compute_style: {:?} (kind={:?})", element, kind);
+ if data.has_styles() {
+ data.restyle.set_restyled();
+ }
+
match kind {
MatchAndCascade => {
debug_assert!(!context.shared.traversal_flags.for_animation_only(),
@@ -870,31 +863,24 @@ where
continue;
}
- // Handle element snapshots and invalidation of descendants and siblings
- // as needed.
- //
- // NB: This will be a no-op if there's no restyle data and no snapshot.
- child_data.invalidate_style_if_needed(child, &context.shared);
-
trace!(" > {:?} -> {:?} + {:?}, pseudo: {:?}",
child,
- child_data.get_restyle().map(|r| &r.hint),
+ child_data.restyle.hint,
propagated_hint,
child.implemented_pseudo_element());
- // If the child doesn't have pre-existing RestyleData and we don't have
- // any reason to create one, avoid the useless allocation and move on to
- // the next child.
- if !reconstructed_ancestor && propagated_hint.is_empty() && !child_data.has_restyle() {
- continue;
- }
-
- let mut restyle_data = child_data.ensure_restyle();
-
// Propagate the parent restyle hint, that may make us restyle the whole
// subtree.
- restyle_data.reconstructed_ancestor = reconstructed_ancestor;
- restyle_data.hint.insert(propagated_hint);
+ if reconstructed_ancestor {
+ child_data.restyle.set_reconstructed_ancestor();
+ }
+ child_data.restyle.hint.insert(propagated_hint);
+
+ // Handle element snapshots and invalidation of descendants and siblings
+ // as needed.
+ //
+ // NB: This will be a no-op if there's no snapshot.
+ child_data.invalidate_style_if_needed(child, &context.shared);
}
}