mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1166164 part 6 - Make pausing from idle set the current time; r=jwatt, r=smaug
As proposed: https://lists.w3.org/Archives/Public/public-fx/2015AprJun/0013.html (item g) And agreed upon here: https://lists.w3.org/Archives/Public/public-fx/2015AprJun/0031.html
This commit is contained in:
parent
cd6af7c82a
commit
dcf86e771b
@ -267,9 +267,9 @@ Animation::Play(ErrorResult& aRv, LimitBehavior aLimitBehavior)
|
||||
}
|
||||
|
||||
void
|
||||
Animation::Pause()
|
||||
Animation::Pause(ErrorResult& aRv)
|
||||
{
|
||||
DoPause();
|
||||
DoPause(aRv);
|
||||
PostUpdate();
|
||||
}
|
||||
|
||||
@ -639,12 +639,25 @@ Animation::DoPlay(ErrorResult& aRv, LimitBehavior aLimitBehavior)
|
||||
|
||||
// http://w3c.github.io/web-animations/#pause-an-animation
|
||||
void
|
||||
Animation::DoPause()
|
||||
Animation::DoPause(ErrorResult& aRv)
|
||||
{
|
||||
if (IsPausedOrPausing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we are transitioning from idle, fill in the current time
|
||||
if (GetCurrentTime().IsNull()) {
|
||||
if (mPlaybackRate >= 0.0) {
|
||||
mHoldTime.SetValue(TimeDuration(0));
|
||||
} else {
|
||||
if (EffectEnd() == TimeDuration::Forever()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
mHoldTime.SetValue(TimeDuration(EffectEnd()));
|
||||
}
|
||||
}
|
||||
|
||||
bool reuseReadyPromise = false;
|
||||
if (mPendingState == PendingState::PlayPending) {
|
||||
CancelPendingTasks();
|
||||
|
@ -102,7 +102,7 @@ public:
|
||||
void Cancel();
|
||||
virtual void Finish(ErrorResult& aRv);
|
||||
virtual void Play(ErrorResult& aRv, LimitBehavior aLimitBehavior);
|
||||
virtual void Pause();
|
||||
virtual void Pause(ErrorResult& aRv);
|
||||
bool IsRunningOnCompositor() const { return mIsRunningOnCompositor; }
|
||||
|
||||
// Wrapper functions for Animation DOM methods when called
|
||||
@ -126,7 +126,7 @@ public:
|
||||
* in future we will likely have to flush style in
|
||||
* CSSAnimation::PauseFromJS so we leave it for now.
|
||||
*/
|
||||
void PauseFromJS() { Pause(); }
|
||||
void PauseFromJS(ErrorResult& aRv) { Pause(aRv); }
|
||||
// Wrapper functions for Animation DOM methods when called from style.
|
||||
//
|
||||
// Typically these DOM methods also notify style of changes but when
|
||||
@ -284,7 +284,7 @@ protected:
|
||||
void SilentlySetPlaybackRate(double aPlaybackRate);
|
||||
void DoCancel();
|
||||
void DoPlay(ErrorResult& aRv, LimitBehavior aLimitBehavior);
|
||||
void DoPause();
|
||||
void DoPause(ErrorResult& aRv);
|
||||
void ResumeAt(const TimeDuration& aReadyTime);
|
||||
void PauseAt(const TimeDuration& aReadyTime);
|
||||
void FinishPendingAt(const TimeDuration& aReadyTime)
|
||||
@ -337,7 +337,7 @@ protected:
|
||||
Nullable<TimeDuration> mPreviousCurrentTime; // Animation timescale
|
||||
double mPlaybackRate;
|
||||
|
||||
// A Promise that is replaced on each call to Play() (and in future Pause())
|
||||
// A Promise that is replaced on each call to Play()
|
||||
// and fulfilled when Play() is successfully completed.
|
||||
// This object is lazily created by GetReady.
|
||||
// See http://w3c.github.io/web-animations/#current-ready-promise
|
||||
|
@ -203,6 +203,60 @@ async_test(function(t) {
|
||||
}));
|
||||
}, 'Setting the current time completes a pending pause');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 1000s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
// Go to idle state then pause
|
||||
animation.cancel();
|
||||
animation.pause();
|
||||
|
||||
assert_equals(animation.currentTime, 0, 'currentTime is set to 0');
|
||||
assert_equals(animation.startTime, null, 'startTime is not set');
|
||||
assert_equals(animation.playState, 'pending', 'initially pause-pending');
|
||||
|
||||
// Check it still resolves as expected
|
||||
animation.ready.then(t.step_func(function() {
|
||||
assert_equals(animation.playState, 'paused',
|
||||
'resolves to paused state asynchronously');
|
||||
assert_equals(animation.currentTime, 0,
|
||||
'keeps the initially set currentTime');
|
||||
t.done();
|
||||
}));
|
||||
}, 'pause() from idle');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 1000s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.cancel();
|
||||
animation.playbackRate = -1;
|
||||
animation.pause();
|
||||
|
||||
assert_equals(animation.currentTime, 1000 * 1000,
|
||||
'currentTime is set to the effect end');
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
assert_equals(animation.currentTime, 1000 * 1000,
|
||||
'keeps the initially set currentTime');
|
||||
t.done();
|
||||
}));
|
||||
}, 'pause() from idle with a negative playbackRate');
|
||||
|
||||
test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 1000s infinite' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.cancel();
|
||||
animation.playbackRate = -1;
|
||||
|
||||
assert_throws('InvalidStateError',
|
||||
function () { animation.pause(); },
|
||||
'Expect InvalidStateError exception on calling pause() ' +
|
||||
'from idle with a negative playbackRate and ' +
|
||||
'infinite-duration animation');
|
||||
}, 'pause() from idle with a negative playbackRate and endless effect');
|
||||
|
||||
done();
|
||||
</script>
|
||||
</body>
|
||||
|
@ -35,7 +35,7 @@ interface Animation {
|
||||
void finish ();
|
||||
[Throws, BinaryName="playFromJS"]
|
||||
void play ();
|
||||
[BinaryName="pauseFromJS"]
|
||||
[Throws, BinaryName="pauseFromJS"]
|
||||
void pause ();
|
||||
/*
|
||||
void reverse ();
|
||||
|
@ -44,10 +44,10 @@ CSSAnimation::Play(ErrorResult &aRv, LimitBehavior aLimitBehavior)
|
||||
}
|
||||
|
||||
void
|
||||
CSSAnimation::Pause()
|
||||
CSSAnimation::Pause(ErrorResult& aRv)
|
||||
{
|
||||
mPauseShouldStick = true;
|
||||
Animation::Pause();
|
||||
Animation::Pause(aRv);
|
||||
}
|
||||
|
||||
AnimationPlayState
|
||||
@ -89,7 +89,20 @@ CSSAnimation::PauseFromStyle()
|
||||
}
|
||||
|
||||
mIsStylePaused = true;
|
||||
DoPause();
|
||||
ErrorResult rv;
|
||||
DoPause(rv);
|
||||
// pause() should only throw when *all* of the following conditions are true:
|
||||
// - we are in the idle state, and
|
||||
// - we have a negative playback rate, and
|
||||
// - we have an infinitely repeating animation
|
||||
// The first two conditions will never happen under regular style processing
|
||||
// but could happen if an author made modifications to the Animation object
|
||||
// and then updated animation-play-state. It's an unusual case and there's
|
||||
// no obvious way to pass on the exception information so we just silently
|
||||
// fail for now.
|
||||
if (rv.Failed()) {
|
||||
NS_WARNING("Unexpected exception pausing animation - silently failing");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -66,7 +66,7 @@ public:
|
||||
|
||||
virtual dom::Promise* GetReady(ErrorResult& aRv) override;
|
||||
virtual void Play(ErrorResult& aRv, LimitBehavior aLimitBehavior) override;
|
||||
virtual void Pause() override;
|
||||
virtual void Pause(ErrorResult& aRv) override;
|
||||
|
||||
virtual dom::AnimationPlayState PlayStateFromJS() const override;
|
||||
virtual void PlayFromJS(ErrorResult& aRv) override;
|
||||
|
Loading…
Reference in New Issue
Block a user