mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
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
This commit is contained in:
parent
ba5568a0a6
commit
f3e373bc62
19 changed files with 359 additions and 138 deletions
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue