diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/animations.rs | 22 | ||||
-rw-r--r-- | components/script/dom/document.rs | 12 | ||||
-rw-r--r-- | components/script/script_thread.rs | 7 |
3 files changed, 34 insertions, 7 deletions
diff --git a/components/script/animations.rs b/components/script/animations.rs index 73131763430..49dfe77e1b4 100644 --- a/components/script/animations.rs +++ b/components/script/animations.rs @@ -2,8 +2,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -#![deny(missing_docs)] - //! The set of animations for a document. use crate::dom::animationevent::AnimationEvent; @@ -47,6 +45,11 @@ pub(crate) struct Animations { /// A list of pending animation-related events. pending_events: DomRefCell<Vec<TransitionOrAnimationEvent>>, + + /// The timeline value at the last time all animations were marked dirty. + /// This is used to prevent marking animations dirty when the timeline + /// has not changed. + timeline_value_at_last_dirty: Cell<f64>, } impl Animations { @@ -56,6 +59,7 @@ impl Animations { has_running_animations: Cell::new(false), rooted_nodes: Default::default(), pending_events: Default::default(), + timeline_value_at_last_dirty: Cell::new(0.0), } } @@ -65,12 +69,23 @@ impl Animations { self.pending_events.borrow_mut().clear(); } - pub(crate) fn mark_animating_nodes_as_dirty(&self) { + // Mark all animations dirty, if they haven't been marked dirty since the + // specified `current_timeline_value`. Returns true if animations were marked + // dirty or false otherwise. + pub(crate) fn mark_animating_nodes_as_dirty(&self, current_timeline_value: f64) -> bool { + if current_timeline_value <= self.timeline_value_at_last_dirty.get() { + return false; + } + self.timeline_value_at_last_dirty + .set(current_timeline_value); + let sets = self.sets.sets.read(); let rooted_nodes = self.rooted_nodes.borrow(); for node in sets.keys().filter_map(|key| rooted_nodes.get(&key.node)) { node.dirty(NodeDamage::NodeStyleDamaged); } + + true } pub(crate) fn update_for_new_timeline_value(&self, window: &Window, now: f64) { @@ -97,7 +112,6 @@ impl Animations { } self.unroot_unused_nodes(&sets); - //self.update_running_animations_presence(window); } /// Cancel animations for the given node, if any exist. diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index d8a01e68b4d..f636e11fc51 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -3852,6 +3852,18 @@ impl Document { .update_for_new_timeline_value(&self.window, current_timeline_value); } + pub(crate) fn maybe_mark_animating_nodes_as_dirty(&self) { + let current_timeline_value = self.current_animation_timeline_value(); + let marked_dirty = self + .animations + .borrow() + .mark_animating_nodes_as_dirty(current_timeline_value); + + if marked_dirty { + self.window().add_pending_reflow(); + } + } + pub(crate) fn current_animation_timeline_value(&self) -> f64 { self.animation_timeline.borrow().current_value() } diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index b417f453cdf..f52fc0d777a 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -1702,10 +1702,12 @@ impl ScriptThread { true } - // Perform step 11.10 from https://html.spec.whatwg.org/multipage/#event-loops. + // Perform step 7.10 from https://html.spec.whatwg.org/multipage/#event-loop-processing-model. + // Described at: https://drafts.csswg.org/web-animations-1/#update-animations-and-send-events fn update_animations_and_send_events(&self) { for (_, document) in self.documents.borrow().iter() { document.update_animation_timeline(); + document.maybe_mark_animating_nodes_as_dirty(); } for (_, document) in self.documents.borrow().iter() { @@ -3012,8 +3014,7 @@ impl ScriptThread { document.run_the_animation_frame_callbacks(); } if tick_type.contains(AnimationTickType::CSS_ANIMATIONS_AND_TRANSITIONS) { - document.animations().mark_animating_nodes_as_dirty(); - document.window().add_pending_reflow(); + document.maybe_mark_animating_nodes_as_dirty(); } } |