Commit e193b9ab authored by Kevin Ellis's avatar Kevin Ellis Committed by Commit Bot

Update implementation of animation::cancel.

This patch updates the implementation of cancel for an animation to
align with the spec. A followup patch is required to clean up the use
of some legacy variables that are still required for tracking the play
state of an animation.

Bug: 960944
Change-Id: I4af56c483b7751d18b0439af3beb28ba631cffaa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1824058Reviewed-by: default avatarStephen McGruer <smcgruer@chromium.org>
Commit-Queue: Kevin Ellis <kevers@chromium.org>
Cr-Commit-Position: refs/heads/master@{#700218}
parent 207387f0
...@@ -1268,22 +1268,8 @@ bool Animation::Update(TimingUpdateReason reason) { ...@@ -1268,22 +1268,8 @@ bool Animation::Update(TimingUpdateReason reason) {
if ((idle || Limited()) && !finished_) { if ((idle || Limited()) && !finished_) {
if (reason == kTimingUpdateForAnimationFrame && (idle || start_time_)) { if (reason == kTimingUpdateForAnimationFrame && (idle || start_time_)) {
if (idle) { if (!idle)
const AtomicString& event_type = event_type_names::kCancel;
if (GetExecutionContext() && HasEventListeners(event_type)) {
double event_current_time = NullValue();
// TODO(crbug.com/916117): Handle NaN values for scroll-linked
// animations.
pending_cancelled_event_ =
MakeGarbageCollected<AnimationPlaybackEvent>(
event_type, event_current_time, TimelineTime());
pending_cancelled_event_->SetTarget(this);
pending_cancelled_event_->SetCurrentTarget(this);
document_->EnqueueAnimationFrameEvent(pending_cancelled_event_);
}
} else {
QueueFinishedEvent(); QueueFinishedEvent();
}
finished_ = true; finished_ = true;
} }
} }
...@@ -1348,17 +1334,59 @@ base::Optional<AnimationTimeDelta> Animation::TimeToEffectChange() { ...@@ -1348,17 +1334,59 @@ base::Optional<AnimationTimeDelta> Animation::TimeToEffectChange() {
} }
void Animation::cancel() { void Animation::cancel() {
PlayStateUpdateScope update_scope(*this, kTimingUpdateOnDemand); // TODO(crbug.com/916117): Get rid of internal_play_state_.
internal_play_state_ = kUnset;
AnimationPlayState initial_play_state = CalculateAnimationPlayState();
if (initial_play_state != kIdle) {
if (pending()) {
// TODO(crbug.com/916117): Rejecting the ready promise should be performed
// inside reset pending tasks once aligned with the spec.
if (ready_promise_)
RejectAndResetPromiseMaybeAsync(ready_promise_.Get());
}
ResetPendingTasks();
if (PlayStateInternal() == kIdle) if (finished_promise_) {
return; if (finished_promise_->GetState() == AnimationPromise::kPending)
RejectAndResetPromiseMaybeAsync(finished_promise_.Get());
else
finished_promise_->Reset();
}
const AtomicString& event_type = event_type_names::kCancel;
if (GetExecutionContext() && HasEventListeners(event_type)) {
double event_current_time = NullValue();
// TODO(crbug.com/916117): Handle NaN values for scroll-linked
// animations.
pending_cancelled_event_ = MakeGarbageCollected<AnimationPlaybackEvent>(
event_type, event_current_time, TimelineTime());
pending_cancelled_event_->SetTarget(this);
pending_cancelled_event_->SetCurrentTarget(this);
document_->EnqueueAnimationFrameEvent(pending_cancelled_event_);
}
} else {
// Quietly reset without rejecting promises.
active_playback_rate_ = base::nullopt;
pending_pause_ = pending_play_ = false;
}
hold_time_ = base::nullopt; hold_time_ = base::nullopt;
start_time_ = base::nullopt;
// TODO(crbug.com/958433): Phase out the use of these variables, which are not
// in the spec.
paused_ = false; paused_ = false;
internal_play_state_ = kIdle; internal_play_state_ = kIdle;
start_time_ = base::nullopt;
current_time_pending_ = false; current_time_pending_ = false;
ResetPendingTasks();
animation_play_state_ = kIdle;
// Apply changes synchronously.
SetCompositorPending(/*effect_changed=*/false);
NotifyProbe();
SetOutdated();
// Force dispatch of canceled event.
ForceServiceOnNextFrame(); ForceServiceOnNextFrame();
} }
...@@ -1456,17 +1484,10 @@ Animation::PlayStateUpdateScope::~PlayStateUpdateScope() { ...@@ -1456,17 +1484,10 @@ Animation::PlayStateUpdateScope::~PlayStateUpdateScope() {
// Ordering is important, the ready promise should resolve/reject before // Ordering is important, the ready promise should resolve/reject before
// the finished promise. // the finished promise.
if (animation_->ready_promise_ && new_play_state != old_play_state) { if (animation_->ready_promise_ && new_play_state != old_play_state) {
if (new_play_state == kIdle) { // Transitioning to an idle state is handled in cancel().
if (animation_->ready_promise_->GetState() == DCHECK(new_play_state != kIdle);
AnimationPromise::kPending) {
animation_->RejectAndResetPromiseMaybeAsync( if (old_play_state == kPending) {
animation_->ready_promise_.Get());
} else {
animation_->ready_promise_->Reset();
}
animation_->ResetPendingTasks();
animation_->ResolvePromiseMaybeAsync(animation_->ready_promise_.Get());
} else if (old_play_state == kPending) {
animation_->ResetPendingTasks(); animation_->ResetPendingTasks();
animation_->ResolvePromiseMaybeAsync(animation_->ready_promise_.Get()); animation_->ResolvePromiseMaybeAsync(animation_->ready_promise_.Get());
} else if (new_play_state == kPending) { } else if (new_play_state == kPending) {
...@@ -1477,15 +1498,10 @@ Animation::PlayStateUpdateScope::~PlayStateUpdateScope() { ...@@ -1477,15 +1498,10 @@ Animation::PlayStateUpdateScope::~PlayStateUpdateScope() {
} }
if (animation_->finished_promise_ && new_play_state != old_play_state) { if (animation_->finished_promise_ && new_play_state != old_play_state) {
if (new_play_state == kIdle) { // Transitioning to an idle state is handled in cancel().
if (animation_->finished_promise_->GetState() == DCHECK(new_play_state != kIdle);
AnimationPromise::kPending) {
animation_->RejectAndResetPromiseMaybeAsync( if (new_play_state == kFinished) {
animation_->finished_promise_.Get());
} else {
animation_->finished_promise_->Reset();
}
} else if (new_play_state == kFinished) {
animation_->ResetPendingTasks(); animation_->ResetPendingTasks();
animation_->ResolvePromiseMaybeAsync(animation_->finished_promise_.Get()); animation_->ResolvePromiseMaybeAsync(animation_->finished_promise_.Get());
} else if (old_play_state == kFinished) { } else if (old_play_state == kFinished) {
......
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