mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 23:50:19 +00:00
LibWeb: Implement Animation.cancel()
This commit is contained in:
parent
9abe472928
commit
3c055ff76d
Notes:
sideshowbarker
2024-07-16 17:12:03 +09:00
Author: https://github.com/mattco98 Commit: https://github.com/SerenityOS/serenity/commit/3c055ff76d Pull-request: https://github.com/SerenityOS/serenity/pull/23317
3 changed files with 93 additions and 1 deletions
|
@ -359,6 +359,66 @@ void Animation::set_replace_state(Bindings::AnimationReplaceState value)
|
|||
}
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/web-animations-1/#dom-animation-cancel
|
||||
void Animation::cancel()
|
||||
{
|
||||
auto& realm = this->realm();
|
||||
|
||||
// 1. If animation’s play state is not idle, perform the following steps:
|
||||
if (play_state() != Bindings::AnimationPlayState::Idle) {
|
||||
HTML::TemporaryExecutionContext execution_context { Bindings::host_defined_environment_settings_object(realm) };
|
||||
|
||||
// 1. Run the procedure to reset an animation’s pending tasks on animation.
|
||||
reset_an_animations_pending_tasks();
|
||||
|
||||
// 2. Reject the current finished promise with a DOMException named "AbortError".
|
||||
auto dom_exception = WebIDL::AbortError::create(realm, "Animation was cancelled"_fly_string);
|
||||
WebIDL::reject_promise(realm, current_finished_promise(), dom_exception);
|
||||
|
||||
// 3. Set the [[PromiseIsHandled]] internal slot of the current finished promise to true.
|
||||
WebIDL::mark_promise_as_handled(current_finished_promise());
|
||||
|
||||
// 4. Let current finished promise be a new promise in the relevant Realm of animation.
|
||||
m_current_finished_promise = WebIDL::create_promise(realm);
|
||||
|
||||
// 5. Create an AnimationPlaybackEvent, cancelEvent.
|
||||
// 6. Set cancelEvent’s type attribute to cancel.
|
||||
// 7. Set cancelEvent’s currentTime to null.
|
||||
// 8. Let timeline time be the current time of the timeline with which animation is associated. If animation is
|
||||
// not associated with an active timeline, let timeline time be an unresolved time value.
|
||||
// 9. Set cancelEvent’s timelineTime to timeline time. If timeline time is unresolved, set it to null.
|
||||
AnimationPlaybackEventInit init;
|
||||
init.timeline_time = m_timeline && !m_timeline->is_inactive() ? m_timeline->current_time() : Optional<double> {};
|
||||
auto cancel_event = AnimationPlaybackEvent::create(realm, HTML::EventNames::cancel, init);
|
||||
|
||||
// 10. If animation has a document for timing, then append cancelEvent to its document for timing's pending
|
||||
// animation event queue along with its target, animation. If animation is associated with an active
|
||||
// timeline that defines a procedure to convert timeline times to origin-relative time, let the scheduled
|
||||
// event time be the result of applying that procedure to timeline time. Otherwise, the scheduled event time
|
||||
// is an unresolved time value.
|
||||
// Otherwise, queue a task to dispatch cancelEvent at animation. The task source for this task is the DOM
|
||||
// manipulation task source.
|
||||
if (auto document = document_for_timing()) {
|
||||
Optional<double> scheduled_event_time;
|
||||
if (m_timeline && !m_timeline->is_inactive() && m_timeline->can_convert_a_timeline_time_to_an_origin_relative_time())
|
||||
scheduled_event_time = m_timeline->convert_a_timeline_time_to_an_origin_relative_time(m_timeline->current_time());
|
||||
document->append_pending_animation_event({ cancel_event, *this, scheduled_event_time });
|
||||
} else {
|
||||
HTML::queue_global_task(HTML::Task::Source::DOMManipulation, realm.global_object(), [this, cancel_event]() {
|
||||
dispatch_event(cancel_event);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Make animation’s hold time unresolved.
|
||||
m_hold_time = {};
|
||||
|
||||
// 3. Make animation’s start time unresolved.
|
||||
m_start_time = {};
|
||||
|
||||
invalidate_effect();
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/web-animations-1/#dom-animation-finish
|
||||
WebIDL::ExceptionOr<void> Animation::finish()
|
||||
{
|
||||
|
@ -961,6 +1021,36 @@ void Animation::update_finished_state(DidSeek did_seek, SynchronouslyNotify sync
|
|||
invalidate_effect();
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/web-animations-1/#animation-reset-an-animations-pending-tasks
|
||||
void Animation::reset_an_animations_pending_tasks()
|
||||
{
|
||||
auto& realm = this->realm();
|
||||
|
||||
// 1. If animation does not have a pending play task or a pending pause task, abort this procedure.
|
||||
if (!pending())
|
||||
return;
|
||||
|
||||
// 2. If animation has a pending play task, cancel that task.
|
||||
m_pending_play_task = TaskState::None;
|
||||
|
||||
// 3. If animation has a pending pause task, cancel that task.
|
||||
m_pending_pause_task = TaskState::None;
|
||||
|
||||
// 4. Apply any pending playback rate on animation.
|
||||
apply_any_pending_playback_rate();
|
||||
|
||||
// 5. Reject animation’s current ready promise with a DOMException named "AbortError".
|
||||
auto dom_exception = WebIDL::AbortError::create(realm, "Animation was cancelled"_fly_string);
|
||||
WebIDL::reject_promise(realm, current_ready_promise(), dom_exception);
|
||||
|
||||
// 6. Set the [[PromiseIsHandled]] internal slot of animation’s current ready promise to true.
|
||||
WebIDL::mark_promise_as_handled(current_ready_promise());
|
||||
|
||||
// 7. Let animation’s current ready promise be the result of creating a new resolved Promise object with value
|
||||
// animation in the relevant Realm of animation.
|
||||
m_current_ready_promise = WebIDL::create_resolved_promise(realm, this);
|
||||
}
|
||||
|
||||
// Step 12 of https://www.w3.org/TR/web-animations-1/#playing-an-animation-section
|
||||
void Animation::run_pending_play_task()
|
||||
{
|
||||
|
|
|
@ -70,6 +70,7 @@ public:
|
|||
Yes,
|
||||
No,
|
||||
};
|
||||
void cancel();
|
||||
WebIDL::ExceptionOr<void> finish();
|
||||
WebIDL::ExceptionOr<void> play();
|
||||
WebIDL::ExceptionOr<void> play_an_animation(AutoRewind);
|
||||
|
@ -118,6 +119,7 @@ private:
|
|||
void apply_any_pending_playback_rate();
|
||||
WebIDL::ExceptionOr<void> silently_set_current_time(Optional<double>);
|
||||
void update_finished_state(DidSeek, SynchronouslyNotify);
|
||||
void reset_an_animations_pending_tasks();
|
||||
|
||||
void run_pending_play_task();
|
||||
void run_pending_pause_task();
|
||||
|
|
|
@ -24,7 +24,7 @@ interface Animation : EventTarget {
|
|||
// FIXME: attribute EventHandler oncancel;
|
||||
// FIXME: attribute EventHandler onremove;
|
||||
|
||||
// FIXME: undefined cancel();
|
||||
undefined cancel();
|
||||
undefined finish();
|
||||
undefined play();
|
||||
undefined pause();
|
||||
|
|
Loading…
Reference in a new issue