diff options
-rw-r--r-- | components/style/invalidation/element/invalidator.rs | 4 | ||||
-rw-r--r-- | components/style/traversal.rs | 29 | ||||
-rw-r--r-- | ports/geckolib/glue.rs | 8 |
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); |