Commit 7af3d7ad authored by Kevin Ellis's avatar Kevin Ellis Committed by Commit Bot

Prevent early resolution of finished promise

Previously, a finished promise could be resolved if created while the
finish notification task was pending. This fails in the cases where the
play state is only momentarily in the finished state. For example:

anim.currentTime = ANIMATION_DURATION;
anim.finished.then(doSomething);
anim.reverse();
anim.finished.then(doSomethingElse);

In this case, doSomething should not be called.


Bug: 1005861
Change-Id: I4a04c7fc75c2ae9ee719a0444a0d22ba49fb6ead
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1928049
Commit-Queue: Kevin Ellis <kevers@chromium.org>
Reviewed-by: default avatarMajid Valipour <majidvp@chromium.org>
Cr-Commit-Position: refs/heads/master@{#718208}
parent 13055e31
......@@ -1385,7 +1385,11 @@ ScriptPromise Animation::finished(ScriptState* script_state) {
finished_promise_ = MakeGarbageCollected<AnimationPromise>(
ExecutionContext::From(script_state), this,
AnimationPromise::kFinished);
if (PlayStateInternal() == kFinished)
// Defer resolving the finished promise if the finish notification task is
// pending. The finished state could change before the next microtask
// checkpoint.
if (CalculateAnimationPlayState() == kFinished &&
!pending_finish_notification_)
finished_promise_->Resolve(this);
}
return finished_promise_->Promise(script_state->World());
......
This is a testharness.js-based test.
PASS Test pausing then playing does not change the finished promise
PASS Test restarting a finished animation
PASS Test restarting a reversed finished animation
PASS Test redundant finishing of animation
PASS Finished promise does not resolve when paused
PASS Finished promise does not resolve when pause-pending
PASS The finished promise is fulfilled with its Animation
PASS finished promise is rejected when an animation is canceled by calling cancel()
PASS canceling an already-finished animation replaces the finished promise
PASS Test finished promise changes for animation duration changes
PASS Test finished promise changes when playbackRate == 0
PASS Test finished promise resolves when reaching to the natural boundary.
PASS Test finished promise changes when a prior finished promise resolved and the animation falls out finished state
PASS Test no new finished promise generated when finished state is checked asynchronously
PASS Test new finished promise generated when finished state is checked synchronously
PASS Test synchronous finished promise resolved even if finished state is changed soon
PASS Test synchronous finished promise resolved even if asynchronous finished promise happens just before synchronous promise
PASS Test finished promise is not resolved when the animation falls out finished state immediately
FAIL Test finished promise is not resolved once the animation falls out finished state even though the current finished promise is generated soon after animation state became finished assert_unreached: Animation.finished should not be resolved Reached unreachable code
PASS Finished promise should be resolved after the ready promise is resolved
PASS Finished promise should be rejected after the ready promise is rejected
Harness: the test ran to completion.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment