Bug 927349 part 5 - Cancel players that are no longer used; r=jwatt

This patch adds a means of terminating an animation so that is has no effect.
The procedure is defined by Web Animations:

  http://w3c.github.io/web-animations/#cancelling-a-player-section

We don't implement all of this, however, since we don't currently support the
finished promise or custom effects.

In a later bug we will expose this as the cancel() method on AnimationPlayer.

We call this method for terminated animations in nsAnimationManager and
nsTransitionManager to ensure they get removed from the pending player tracker
and so that, for example, the ready promise of CSS Animation player objects is
rejected when the corresponding item is removed from animation-name.
This commit is contained in:
Brian Birtles 2014-12-18 08:42:41 +09:00
Родитель c91b2dea43
Коммит 9fdafb68a4
5 изменённых файлов: 48 добавлений и 11 удалений

Просмотреть файл

@ -160,6 +160,20 @@ AnimationPlayer::ResolveStartTime()
}
}
void
AnimationPlayer::Cancel()
{
if (mIsPending) {
CancelPendingPlay();
if (mReady) {
mReady->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
}
}
mHoldTime.SetNull();
mStartTime.SetNull();
}
bool
AnimationPlayer::IsRunning() const
{
@ -240,18 +254,8 @@ AnimationPlayer::DoPlay()
void
AnimationPlayer::DoPause()
{
// Cancel a pending play
if (mIsPending) {
nsIDocument* doc = GetRenderedDocument();
if (doc) {
PendingPlayerTracker* tracker = doc->GetPendingPlayerTracker();
if (tracker) {
tracker->RemovePlayPending(*this);
}
}
mIsPending = false;
CancelPendingPlay();
// Resolve the ready promise since we currently only use it for
// players that are waiting to play. Later (in bug 1109390), we will
// use this for players waiting to pause as well and then we won't
@ -289,6 +293,24 @@ AnimationPlayer::PostUpdate()
}
}
void
AnimationPlayer::CancelPendingPlay()
{
if (!mIsPending) {
return;
}
nsIDocument* doc = GetRenderedDocument();
if (doc) {
PendingPlayerTracker* tracker = doc->GetPendingPlayerTracker();
if (tracker) {
tracker->RemovePlayPending(*this);
}
}
mIsPending = false;
}
StickyTimeDuration
AnimationPlayer::SourceContentEnd() const
{

Просмотреть файл

@ -92,6 +92,7 @@ public:
// This should only be called on a player that is currently waiting to play
// (and therefore has a null start time but a fixed hold time).
void ResolveStartTime();
void Cancel();
const nsString& Name() const {
return mSource ? mSource->Name() : EmptyString();
@ -132,6 +133,10 @@ protected:
void FlushStyle() const;
void PostUpdate();
// Remove this player from the pending player tracker and resets mIsPending
// as necessary. The caller is responsible for resolving or aborting the
// mReady promise as necessary.
void CancelPendingPlay();
StickyTimeDuration SourceContentEnd() const;
nsIDocument* GetRenderedDocument() const;

Просмотреть файл

@ -234,6 +234,9 @@ struct AnimationPlayerCollection : public PRCList
void Destroy()
{
for (size_t playerIdx = mPlayers.Length(); playerIdx-- != 0; ) {
mPlayers[playerIdx]->Cancel();
}
// This will call our destructor.
mElement->DeleteProperty(mElementProperty);
}

Просмотреть файл

@ -331,6 +331,7 @@ nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext,
// Although we're doing this while iterating this is safe because
// we're not changing the length of newPlayers and we've finished
// iterating over the list of old iterations.
newPlayer->Cancel();
newPlayer = nullptr;
newPlayers.ReplaceElementAt(newIdx, oldPlayer);
collection->mPlayers.RemoveElementAt(oldIdx);
@ -344,6 +345,11 @@ nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext,
collection->mNeedsRefreshes = true;
collection->Tick();
// Cancel removed animations
for (size_t newPlayerIdx = newPlayers.Length(); newPlayerIdx-- != 0; ) {
newPlayers[newPlayerIdx]->Cancel();
}
TimeStamp refreshTime = mPresContext->RefreshDriver()->MostRecentRefresh();
UpdateStyleAndEvents(collection, refreshTime,
EnsureStyleRule_IsNotThrottled);

Просмотреть файл

@ -300,6 +300,7 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
currentValue) ||
currentValue != segment.mToValue) {
// stop the transition
player->Cancel();
players.RemoveElementAt(i);
collection->UpdateAnimationGeneration(mPresContext);
}