diff options
Diffstat (limited to 'dom/animation')
-rw-r--r-- | dom/animation/Animation.cpp | 23 | ||||
-rw-r--r-- | dom/animation/Animation.h | 10 |
2 files changed, 33 insertions, 0 deletions
diff --git a/dom/animation/Animation.cpp b/dom/animation/Animation.cpp index 6dd583ed1..cefdbb76d 100644 --- a/dom/animation/Animation.cpp +++ b/dom/animation/Animation.cpp @@ -230,6 +230,10 @@ Animation::SetTimelineNoUpdate(AnimationTimeline* aTimeline) return; } + StickyTimeDuration activeTime = mEffect + ? mEffect->GetComputedTiming().mActiveTime + : StickyTimeDuration(); + RefPtr<AnimationTimeline> oldTimeline = mTimeline; if (oldTimeline) { oldTimeline->RemoveAnimation(this); @@ -240,6 +244,9 @@ Animation::SetTimelineNoUpdate(AnimationTimeline* aTimeline) mHoldTime.SetNull(); } + if (!aTimeline) { + MaybeQueueCancelEvent(activeTime); + } UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Async); } @@ -771,6 +778,10 @@ Animation::CancelNoUpdate() DispatchPlaybackEvent(NS_LITERAL_STRING("cancel")); + StickyTimeDuration activeTime = mEffect + ? mEffect->GetComputedTiming().mActiveTime + : StickyTimeDuration(); + mHoldTime.SetNull(); mStartTime.SetNull(); @@ -779,6 +790,7 @@ Animation::CancelNoUpdate() if (mTimeline) { mTimeline->RemoveAnimation(this); } + MaybeQueueCancelEvent(activeTime); } void @@ -819,6 +831,17 @@ Animation::HasLowerCompositeOrderThan(const Animation& aOther) const return thisTransition->HasLowerCompositeOrderThan(*otherTransition); } if (thisTransition || otherTransition) { + // Cancelled transitions no longer have an owning element. To be strictly + // correct we should store a strong reference to the owning element + // so that if we arrive here while sorting cancel events, we can sort + // them in the correct order. + // + // However, given that cancel events are almost always queued + // synchronously in some deterministic manner, we can be fairly sure + // that cancel events will be dispatched in a deterministic order + // (which is our only hard requirement until specs say otherwise). + // Furthermore, we only reach here when we have events with equal + // timestamps so this is an edge case we can probably ignore for now. return thisTransition; } } diff --git a/dom/animation/Animation.h b/dom/animation/Animation.h index c59d7d6ce..3263b30c4 100644 --- a/dom/animation/Animation.h +++ b/dom/animation/Animation.h @@ -326,6 +326,16 @@ public: void NotifyEffectTimingUpdated(); + /** + * Used by subclasses to synchronously queue a cancel event in situations + * where the Animation may have been cancelled. + * + * We need to do this synchronously because after a CSS animation/transition + * is canceled, it will be released by its owning element and may not still + * exist when we would normally go to queue events on the next tick. + */ + virtual void MaybeQueueCancelEvent(StickyTimeDuration aActiveTime) {}; + protected: void SilentlySetCurrentTime(const TimeDuration& aNewCurrentTime); void SilentlySetPlaybackRate(double aPlaybackRate); |