aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/style/invalidation/element/invalidator.rs4
-rw-r--r--components/style/traversal.rs29
-rw-r--r--ports/geckolib/glue.rs8
3 files changed, 28 insertions, 13 deletions
diff --git a/components/style/invalidation/element/invalidator.rs b/components/style/invalidation/element/invalidator.rs
index ed759076e23..2ed012d37d1 100644
--- a/components/style/invalidation/element/invalidator.rs
+++ b/components/style/invalidation/element/invalidator.rs
@@ -239,7 +239,7 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E>
let mut any_invalidated = false;
while let Some(sibling) = current {
- let mut sibling_data = sibling.get_data().map(|d| d.borrow_mut());
+ let mut sibling_data = sibling.mutate_data();
let sibling_data = sibling_data.as_mut().map(|d| &mut **d);
let mut sibling_invalidator = TreeStyleInvalidator::new(
@@ -302,7 +302,7 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E>
None => continue,
};
- let mut child_data = child.get_data().map(|d| d.borrow_mut());
+ let mut child_data = child.mutate_data();
let child_data = child_data.as_mut().map(|d| &mut **d);
let mut child_invalidator = TreeStyleInvalidator::new(
diff --git a/components/style/traversal.rs b/components/style/traversal.rs
index 004c2485afd..a265f49ba2c 100644
--- a/components/style/traversal.rs
+++ b/components/style/traversal.rs
@@ -326,14 +326,21 @@ pub trait DomTraversal<E: TElement> : Sync {
// the element if the element has animation only dirty
// descendants bit, animation-only restyle hint or recascade.
if traversal_flags.for_animation_only() {
- if el.has_animation_only_dirty_descendants() {
- return true;
- }
-
+ // Skip elements that have no style data since animation-only
+ // restyle is not necessary for the elements.
let data = match el.borrow_data() {
Some(d) => d,
None => return false,
};
+
+ if !data.has_styles() {
+ return false;
+ }
+
+ if el.has_animation_only_dirty_descendants() {
+ return true;
+ }
+
return data.restyle.hint.has_animation_hint() ||
data.restyle.hint.has_recascade_self();
}
@@ -455,7 +462,11 @@ pub trait DomTraversal<E: TElement> : Sync {
let el = kid.as_element();
if el.as_ref().and_then(|el| el.borrow_data())
.map_or(false, |d| d.has_styles()) {
- unsafe { parent.set_dirty_descendants(); }
+ if self.shared_context().traversal_flags.for_animation_only() {
+ unsafe { parent.set_animation_only_dirty_descendants(); }
+ } else {
+ unsafe { parent.set_dirty_descendants(); }
+ }
}
}
f(thread_local, kid);
@@ -855,14 +866,14 @@ where
None => continue,
};
- let mut child_data =
- unsafe { D::ensure_element_data(&child).borrow_mut() };
-
// If the child is unstyled, we don't need to set up any restyling.
- if !child_data.has_styles() {
+ if child.borrow_data().map_or(true, |d| !d.has_styles()) {
continue;
}
+ let mut child_data =
+ unsafe { D::ensure_element_data(&child).borrow_mut() };
+
trace!(" > {:?} -> {:?} + {:?}, pseudo: {:?}",
child,
child_data.restyle.hint,
diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs
index be85629987f..2ae1ea05f92 100644
--- a/ports/geckolib/glue.rs
+++ b/ports/geckolib/glue.rs
@@ -300,7 +300,9 @@ pub extern "C" fn Servo_TraverseSubtree(root: RawGeckoElementBorrowed,
return false;
}
- element.has_dirty_descendants() || element.borrow_data().unwrap().restyle.contains_restyle_data()
+ element.has_dirty_descendants() ||
+ element.has_animation_only_dirty_descendants() ||
+ element.borrow_data().unwrap().restyle.contains_restyle_data()
}
/// Checks whether the rule tree has crossed its threshold for unused nodes, and
@@ -2801,7 +2803,9 @@ pub extern "C" fn Servo_AssertTreeIsClean(root: RawGeckoElementBorrowed) {
let root = GeckoElement(root);
fn assert_subtree_is_clean<'le>(el: GeckoElement<'le>) {
- debug_assert!(!el.has_dirty_descendants() && !el.has_animation_only_dirty_descendants());
+ debug_assert!(!el.has_dirty_descendants() && !el.has_animation_only_dirty_descendants(),
+ "{:?} has still dirty bit {:?} or animation-only dirty bit {:?}",
+ el, el.has_dirty_descendants(), el.has_animation_only_dirty_descendants());
for child in el.as_node().traversal_children() {
if let Some(child) = child.as_element() {
assert_subtree_is_clean(child);