diff options
author | Martin Robinson <mrobinson@igalia.com> | 2020-06-15 11:51:23 +0200 |
---|---|---|
committer | Martin Robinson <mrobinson@igalia.com> | 2020-06-16 16:33:55 +0200 |
commit | f3e373bc623fd355cb08122d31a76f6548e6827a (patch) | |
tree | 94d416bc55b50b1e343ab02fad79a513d4cd418d /components/layout_thread | |
parent | ba5568a0a60cbd4bbedd3b766b7182824d75b131 (diff) | |
download | servo-f3e373bc623fd355cb08122d31a76f6548e6827a.tar.gz servo-f3e373bc623fd355cb08122d31a76f6548e6827a.zip |
Add animation and transition support for pseudo-elements
This change extends the DocumentAnimationSet to hold animations for
pseudo-elements. Since pseudo-elements in Servo are not in the DOM like
in Gecko, they need to be handled a bit carefully in stylo. When a
pseudo-element has an animation, recascade the style. Finally, this
change passes the pseudo-element string properly to animation events.
Fixes: #10316
Diffstat (limited to 'components/layout_thread')
-rw-r--r-- | components/layout_thread/dom_wrapper.rs | 24 | ||||
-rw-r--r-- | components/layout_thread/lib.rs | 16 |
2 files changed, 31 insertions, 9 deletions
diff --git a/components/layout_thread/dom_wrapper.rs b/components/layout_thread/dom_wrapper.rs index 3d3f50317a9..f0d25ff8c49 100644 --- a/components/layout_thread/dom_wrapper.rs +++ b/components/layout_thread/dom_wrapper.rs @@ -476,7 +476,7 @@ impl<'le> TElement for ServoLayoutElement<'le> { let node = self.as_node(); let document = node.owner_doc(); context.animations.get_animation_declarations( - &AnimationSetKey(node.opaque()), + &AnimationSetKey::new_for_non_pseudo(node.opaque()), context.current_time_for_animations, document.style_shared_lock(), ) @@ -489,7 +489,7 @@ impl<'le> TElement for ServoLayoutElement<'le> { let node = self.as_node(); let document = node.owner_doc(); context.animations.get_transition_declarations( - &AnimationSetKey(node.opaque()), + &AnimationSetKey::new_for_non_pseudo(node.opaque()), context.current_time_for_animations, document.style_shared_lock(), ) @@ -613,16 +613,26 @@ impl<'le> TElement for ServoLayoutElement<'le> { } fn has_animations(&self, context: &SharedStyleContext) -> bool { - return self.has_css_animations(context) || self.has_css_transitions(context); + // This is not used for pseudo elements currently so we can pass None. + return self.has_css_animations(context, /* pseudo_element = */ None) || + self.has_css_transitions(context, /* pseudo_element = */ None); } - fn has_css_animations(&self, context: &SharedStyleContext) -> bool { - let key = AnimationSetKey(self.as_node().opaque()); + fn has_css_animations( + &self, + context: &SharedStyleContext, + pseudo_element: Option<PseudoElement>, + ) -> bool { + let key = AnimationSetKey::new(self.as_node().opaque(), pseudo_element); context.animations.has_active_animations(&key) } - fn has_css_transitions(&self, context: &SharedStyleContext) -> bool { - let key = AnimationSetKey(self.as_node().opaque()); + fn has_css_transitions( + &self, + context: &SharedStyleContext, + pseudo_element: Option<PseudoElement>, + ) -> bool { + let key = AnimationSetKey::new(self.as_node().opaque(), pseudo_element); context.animations.has_active_transitions(&key) } diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 5930e85b08c..07cb7c5a4c8 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -109,7 +109,7 @@ use style::invalidation::element::restyle_hints::RestyleHint; use style::logical_geometry::LogicalPoint; use style::media_queries::{Device, MediaList, MediaType}; use style::properties::PropertyId; -use style::selector_parser::SnapshotMap; +use style::selector_parser::{PseudoElement, SnapshotMap}; use style::servo::restyle_damage::ServoRestyleDamage; use style::shared_lock::{SharedRwLock, SharedRwLockReadGuard, StylesheetGuards}; use style::stylesheets::{ @@ -1651,7 +1651,19 @@ impl LayoutThread { fn traverse_flow(flow: &mut dyn Flow, invalid_nodes: &mut FxHashSet<AnimationSetKey>) { flow.mutate_fragments(&mut |fragment| { - invalid_nodes.remove(&AnimationSetKey(fragment.node)); + // Ideally we'd only not cancel ::before and ::after animations if they + // were actually in the tree. At this point layout has lost information + // about whether or not they exist, but have had their fragments accumulated + // together. + invalid_nodes.remove(&AnimationSetKey::new_for_non_pseudo(fragment.node)); + invalid_nodes.remove(&AnimationSetKey::new_for_pseudo( + fragment.node, + PseudoElement::Before, + )); + invalid_nodes.remove(&AnimationSetKey::new_for_pseudo( + fragment.node, + PseudoElement::After, + )); }); for kid in flow.mut_base().children.iter_mut() { traverse_flow(kid, invalid_nodes) |