Implement animationiteration event

This event is triggered when an animation iterates. This change also
moves iteration out of style calculation to an "update animations" which
is the next part of having animation event handling match the HTML spec.
This commit is contained in:
Martin Robinson 2020-05-18 20:32:27 +02:00
parent f02aba1ed2
commit 873cdd1336
12 changed files with 93 additions and 80 deletions

View file

@ -3750,12 +3750,26 @@ impl Document {
.collect()
}
pub(crate) fn advance_animation_timeline_for_testing(&self, delta: f64) {
pub(crate) fn advance_animation_timeline_for_testing(&self, delta: f64) -> AnimationsUpdate {
self.animation_timeline.borrow_mut().advance_specific(delta);
let current_timeline_value = self.current_animation_timeline_value();
self.animations
.borrow_mut()
.update_for_new_timeline_value(&self.window, current_timeline_value)
}
pub(crate) fn update_animation_timeline(&self) {
self.animation_timeline.borrow_mut().update();
pub(crate) fn update_animation_timeline(&self) -> AnimationsUpdate {
// Only update the time if it isn't being managed by a test.
if !pref!(layout.animations.test.enabled) {
self.animation_timeline.borrow_mut().update();
}
// We still want to update the animations, because our timeline
// value might have been advanced previously via the TestBinding.
let current_timeline_value = self.current_animation_timeline_value();
self.animations
.borrow_mut()
.update_for_new_timeline_value(&self.window, current_timeline_value)
}
pub(crate) fn current_animation_timeline_value(&self) -> f64 {
@ -3766,7 +3780,7 @@ impl Document {
self.animations.borrow()
}
pub(crate) fn update_animations(&self) -> AnimationsUpdate {
pub(crate) fn update_animations_post_reflow(&self) -> AnimationsUpdate {
self.animations
.borrow_mut()
.do_post_reflow_update(&self.window, self.current_animation_timeline_value())

View file

@ -443,6 +443,7 @@ macro_rules! global_event_handlers(
(NoOnload) => (
event_handler!(abort, GetOnabort, SetOnabort);
event_handler!(animationend, GetOnanimationend, SetOnanimationend);
event_handler!(animationiteration, GetOnanimationiteration, SetOnanimationiteration);
event_handler!(cancel, GetOncancel, SetOncancel);
event_handler!(canplay, GetOncanplay, SetOncanplay);
event_handler!(canplaythrough, GetOncanplaythrough, SetOncanplaythrough);

View file

@ -93,6 +93,7 @@ interface mixin GlobalEventHandlers {
// https://drafts.csswg.org/css-animations/#interface-globaleventhandlers-idl
partial interface mixin GlobalEventHandlers {
attribute EventHandler onanimationend;
attribute EventHandler onanimationiteration;
};
// https://drafts.csswg.org/css-transitions/#interface-globaleventhandlers-idl

View file

@ -1578,10 +1578,15 @@ impl Window {
/// Prepares to tick animations and then does a reflow which also advances the
/// layout animation clock.
pub fn advance_animation_clock(&self, delta: i32) {
#[allow(unsafe_code)]
pub fn advance_animation_clock(&self, delta_ms: i32) {
let pipeline_id = self.upcast::<GlobalScope>().pipeline_id();
self.Document()
.advance_animation_timeline_for_testing(delta as f64 / 1000.);
let update = self
.Document()
.advance_animation_timeline_for_testing(delta_ms as f64 / 1000.);
unsafe {
ScriptThread::process_animations_update(update);
}
ScriptThread::handle_tick_all_animations_for_testing(pipeline_id);
}
@ -1747,7 +1752,7 @@ impl Window {
}
}
let update = document.update_animations();
let update = document.update_animations_post_reflow();
unsafe {
ScriptThread::process_animations_update(update);
}