From 1e37ba551589123707e000ae0908300b4c850ff0 Mon Sep 17 00:00:00 2001 From: Matthew Olsson Date: Sat, 3 Feb 2024 18:25:04 -0700 Subject: [PATCH] LibWeb: Expose Animation::is_finished() This will be required to handle forward-fill state in StyleComputer --- .../Libraries/LibWeb/Animations/Animation.cpp | 15 +++++++++------ Userland/Libraries/LibWeb/Animations/Animation.h | 3 ++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Userland/Libraries/LibWeb/Animations/Animation.cpp b/Userland/Libraries/LibWeb/Animations/Animation.cpp index 9967744060..338d607af6 100644 --- a/Userland/Libraries/LibWeb/Animations/Animation.cpp +++ b/Userland/Libraries/LibWeb/Animations/Animation.cpp @@ -703,7 +703,7 @@ void Animation::update_finished_state(DidSeek did_seek, SynchronouslyNotify sync // 5. If current finished state is true and the current finished promise is not yet resolved, perform the following // steps: - if (current_finished_state && !m_current_finished_promise_resolved) { + if (current_finished_state && !m_is_finished) { // 1. Let finish notification steps refer to the following procedure: JS::SafeFunction finish_notification_steps = [&]() { if (m_should_abort_finish_notification_microtask) { @@ -717,8 +717,11 @@ void Animation::update_finished_state(DidSeek did_seek, SynchronouslyNotify sync return; // 2. Resolve animation’s current finished promise object with animation. - WebIDL::resolve_promise(realm(), current_finished_promise(), this); - m_current_finished_promise_resolved = true; + { + HTML::TemporaryExecutionContext execution_context { Bindings::host_defined_environment_settings_object(realm()) }; + WebIDL::resolve_promise(realm(), current_finished_promise(), this); + } + m_is_finished = true; // 3. Create an AnimationPlaybackEvent, finishEvent. // 4. Set finishEvent’s type attribute to finish. @@ -726,7 +729,7 @@ void Animation::update_finished_state(DidSeek did_seek, SynchronouslyNotify sync auto& realm = this->realm(); AnimationPlaybackEventInit init; init.current_time = current_time(); - auto finish_event = heap().allocate(realm, realm, "finish"_fly_string, init); + auto finish_event = AnimationPlaybackEvent::create(realm, "finish"_fly_string, init); // 6. Set finishEvent’s timelineTime attribute to the current time of the timeline with which animation is // associated. If animation is not associated with a timeline, or the timeline is inactive, let @@ -775,9 +778,9 @@ void Animation::update_finished_state(DidSeek did_seek, SynchronouslyNotify sync // 6. If current finished state is false and animation’s current finished promise is already resolved, set // animation’s current finished promise to a new promise in the relevant Realm of animation. - if (!current_finished_state && m_current_finished_promise_resolved) { + if (!current_finished_state && m_is_finished) { m_current_finished_promise = WebIDL::create_promise(realm()); - m_current_finished_promise_resolved = false; + m_is_finished = false; } // Invalidate the style of our target element, if applicable diff --git a/Userland/Libraries/LibWeb/Animations/Animation.h b/Userland/Libraries/LibWeb/Animations/Animation.h index 3b5b675045..6e11f823cc 100644 --- a/Userland/Libraries/LibWeb/Animations/Animation.h +++ b/Userland/Libraries/LibWeb/Animations/Animation.h @@ -61,6 +61,7 @@ public: // https://www.w3.org/TR/web-animations-1/#dom-animation-finished JS::NonnullGCPtr finished() const { return *current_finished_promise()->promise(); } + bool is_finished() const { return m_is_finished; } enum class AutoRewind { Yes, @@ -155,7 +156,7 @@ private: // https://www.w3.org/TR/web-animations-1/#current-finished-promise mutable JS::GCPtr m_current_finished_promise; - bool m_current_finished_promise_resolved { false }; + bool m_is_finished { false }; // https://www.w3.org/TR/web-animations-1/#pending-play-task TaskState m_pending_play_task { TaskState::None };