From 15a8baee0307f8c9cec7c0ba174e111d4df2d0ac Mon Sep 17 00:00:00 2001 From: Matthew Olsson Date: Thu, 23 May 2024 19:17:52 -0700 Subject: [PATCH] LibWeb: Save time for animationcancel event before transitioning to idle The if statement in the dispatch implies we are in the idle state, so of course the active time will always be undefined. If this was cancelled via a call to cancel(), we can save the time at that point. Otherwise, just send 0. --- .../sending-animationcancel-event-crash.txt | 1 + .../sending-animationcancel-event-crash.html | 27 +++++++++++++++++++ .../Libraries/LibWeb/Animations/Animation.cpp | 4 +++ .../Libraries/LibWeb/Animations/Animation.h | 3 +++ Userland/Libraries/LibWeb/DOM/Document.cpp | 5 ++-- 5 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/css/sending-animationcancel-event-crash.txt create mode 100644 Tests/LibWeb/Text/input/css/sending-animationcancel-event-crash.html diff --git a/Tests/LibWeb/Text/expected/css/sending-animationcancel-event-crash.txt b/Tests/LibWeb/Text/expected/css/sending-animationcancel-event-crash.txt new file mode 100644 index 00000000000..be36d109cd5 --- /dev/null +++ b/Tests/LibWeb/Text/expected/css/sending-animationcancel-event-crash.txt @@ -0,0 +1 @@ + PASS! (Didn't crash) diff --git a/Tests/LibWeb/Text/input/css/sending-animationcancel-event-crash.html b/Tests/LibWeb/Text/input/css/sending-animationcancel-event-crash.html new file mode 100644 index 00000000000..dfa5b6856c7 --- /dev/null +++ b/Tests/LibWeb/Text/input/css/sending-animationcancel-event-crash.html @@ -0,0 +1,27 @@ + + +
+ + diff --git a/Userland/Libraries/LibWeb/Animations/Animation.cpp b/Userland/Libraries/LibWeb/Animations/Animation.cpp index a2a654d7f14..f4fbac63707 100644 --- a/Userland/Libraries/LibWeb/Animations/Animation.cpp +++ b/Userland/Libraries/LibWeb/Animations/Animation.cpp @@ -470,6 +470,10 @@ void Animation::cancel(ShouldInvalidate should_invalidate) // 3. Make animation’s start time unresolved. m_start_time = {}; + // This time is needed for dispatching the animationcancel DOM event + if (auto effect = m_effect) + m_saved_cancel_time = effect->active_time_using_fill(Bindings::FillMode::Both); + if (should_invalidate == ShouldInvalidate::Yes) invalidate_effect(); } diff --git a/Userland/Libraries/LibWeb/Animations/Animation.h b/Userland/Libraries/LibWeb/Animations/Animation.h index f9678d09d77..c06e5010e65 100644 --- a/Userland/Libraries/LibWeb/Animations/Animation.h +++ b/Userland/Libraries/LibWeb/Animations/Animation.h @@ -108,6 +108,8 @@ public: unsigned int global_animation_list_order() const { return m_global_animation_list_order; } + auto release_saved_cancel_time() { return move(m_saved_cancel_time); } + protected: Animation(JS::Realm&); @@ -194,6 +196,7 @@ private: Optional m_saved_play_time; Optional m_saved_pause_time; + Optional m_saved_cancel_time; }; } diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index b6cd64091ee..1b70bc46153 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -2103,8 +2103,9 @@ void Document::dispatch_events_for_animation_if_necessary(JS::NonnullGCPtractive_time_using_fill(Bindings::FillMode::Both).value()); + // FIXME: Calculate a non-zero time when the animation is cancelled by means other than calling cancel() + auto cancel_time = animation->release_saved_cancel_time().value_or(0.0); + dispatch_event(HTML::EventNames::animationcancel, cancel_time); } } effect->set_previous_phase(current_phase);