aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout_thread
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2020-06-15 11:51:23 +0200
committerMartin Robinson <mrobinson@igalia.com>2020-06-16 16:33:55 +0200
commitf3e373bc623fd355cb08122d31a76f6548e6827a (patch)
tree94d416bc55b50b1e343ab02fad79a513d4cd418d /components/layout_thread
parentba5568a0a60cbd4bbedd3b766b7182824d75b131 (diff)
downloadservo-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.rs24
-rw-r--r--components/layout_thread/lib.rs16
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)