mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1166164 part 5 - Make play() throw when it should seek to the end of an infinite effect; r=jwatt, r=smaug
This commit is contained in:
parent
a233d4f41e
commit
cd6af7c82a
@ -260,9 +260,9 @@ Animation::Finish(ErrorResult& aRv)
|
||||
}
|
||||
|
||||
void
|
||||
Animation::Play(LimitBehavior aLimitBehavior)
|
||||
Animation::Play(ErrorResult& aRv, LimitBehavior aLimitBehavior)
|
||||
{
|
||||
DoPlay(aLimitBehavior);
|
||||
DoPlay(aRv, aLimitBehavior);
|
||||
PostUpdate();
|
||||
}
|
||||
|
||||
@ -563,16 +563,10 @@ Animation::ComposeStyle(nsRefPtr<css::AnimValuesStyleRule>& aStyleRule,
|
||||
|
||||
// http://w3c.github.io/web-animations/#play-an-animation
|
||||
void
|
||||
Animation::DoPlay(LimitBehavior aLimitBehavior)
|
||||
Animation::DoPlay(ErrorResult& aRv, LimitBehavior aLimitBehavior)
|
||||
{
|
||||
bool abortedPause = mPendingState == PendingState::PausePending;
|
||||
|
||||
bool reuseReadyPromise = false;
|
||||
if (mPendingState != PendingState::NotPending) {
|
||||
CancelPendingTasks();
|
||||
reuseReadyPromise = true;
|
||||
}
|
||||
|
||||
Nullable<TimeDuration> currentTime = GetCurrentTime();
|
||||
if (mPlaybackRate > 0.0 &&
|
||||
(currentTime.IsNull() ||
|
||||
@ -585,11 +579,21 @@ Animation::DoPlay(LimitBehavior aLimitBehavior)
|
||||
(aLimitBehavior == LimitBehavior::AutoRewind &&
|
||||
(currentTime.Value().ToMilliseconds() <= 0.0 ||
|
||||
currentTime.Value() > EffectEnd())))) {
|
||||
if (EffectEnd() == TimeDuration::Forever()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
mHoldTime.SetValue(TimeDuration(EffectEnd()));
|
||||
} else if (mPlaybackRate == 0.0 && currentTime.IsNull()) {
|
||||
mHoldTime.SetValue(TimeDuration(0));
|
||||
}
|
||||
|
||||
bool reuseReadyPromise = false;
|
||||
if (mPendingState != PendingState::NotPending) {
|
||||
CancelPendingTasks();
|
||||
reuseReadyPromise = true;
|
||||
}
|
||||
|
||||
// If the hold time is null then we're either already playing normally (and
|
||||
// we can ignore this call) or we aborted a pending pause operation (in which
|
||||
// case, for consistency, we need to go through the motions of doing an
|
||||
|
@ -101,7 +101,7 @@ public:
|
||||
virtual Promise* GetFinished(ErrorResult& aRv);
|
||||
void Cancel();
|
||||
virtual void Finish(ErrorResult& aRv);
|
||||
virtual void Play(LimitBehavior aLimitBehavior);
|
||||
virtual void Play(ErrorResult& aRv, LimitBehavior aLimitBehavior);
|
||||
virtual void Pause();
|
||||
bool IsRunningOnCompositor() const { return mIsRunningOnCompositor; }
|
||||
|
||||
@ -117,7 +117,10 @@ public:
|
||||
void SetCurrentTimeAsDouble(const Nullable<double>& aCurrentTime,
|
||||
ErrorResult& aRv);
|
||||
virtual AnimationPlayState PlayStateFromJS() const { return PlayState(); }
|
||||
virtual void PlayFromJS() { Play(LimitBehavior::AutoRewind); }
|
||||
virtual void PlayFromJS(ErrorResult& aRv)
|
||||
{
|
||||
Play(aRv, LimitBehavior::AutoRewind);
|
||||
}
|
||||
/**
|
||||
* PauseFromJS is currently only here for symmetry with PlayFromJS but
|
||||
* in future we will likely have to flush style in
|
||||
@ -280,7 +283,7 @@ protected:
|
||||
void SilentlySetCurrentTime(const TimeDuration& aNewCurrentTime);
|
||||
void SilentlySetPlaybackRate(double aPlaybackRate);
|
||||
void DoCancel();
|
||||
void DoPlay(LimitBehavior aLimitBehavior);
|
||||
void DoPlay(ErrorResult& aRv, LimitBehavior aLimitBehavior);
|
||||
void DoPause();
|
||||
void ResumeAt(const TimeDuration& aReadyTime);
|
||||
void PauseAt(const TimeDuration& aReadyTime);
|
||||
|
35
dom/animation/test/css-animations/file_animation-play.html
Normal file
35
dom/animation/test/css-animations/file_animation-play.html
Normal file
@ -0,0 +1,35 @@
|
||||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<script src="../testcommon.js"></script>
|
||||
<style>
|
||||
@keyframes abc {
|
||||
to { transform: translate(10px) }
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: abc 100s infinite' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
// Seek to a time outside the active range so that play() will have to
|
||||
// snap back to the start
|
||||
animation.currentTime = -5000;
|
||||
animation.playbackRate = -1;
|
||||
|
||||
assert_throws('InvalidStateError',
|
||||
function () { animation.play(); },
|
||||
'Expect InvalidStateError exception on calling play() ' +
|
||||
'with a negative playbackRate and infinite-duration ' +
|
||||
'animation');
|
||||
t.done();
|
||||
}));
|
||||
}, 'play() throws when seeking an infinite-duration animation played in ' +
|
||||
'reverse');
|
||||
|
||||
done();
|
||||
</script>
|
||||
</body>
|
15
dom/animation/test/css-animations/test_animation-play.html
Normal file
15
dom/animation/test/css-animations/test_animation-play.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
'use strict';
|
||||
setup({explicit_done: true});
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{ "set": [["dom.animations-api.core.enabled", true]]},
|
||||
function() {
|
||||
window.open("file_animation-play.html");
|
||||
});
|
||||
</script>
|
||||
</html>
|
@ -14,6 +14,8 @@ support-files = css-animations/file_animation-finish.html
|
||||
support-files = css-animations/file_animation-finished.html
|
||||
[css-animations/test_animation-pausing.html]
|
||||
support-files = css-animations/file_animation-pausing.html
|
||||
[css-animations/test_animation-play.html]
|
||||
support-files = css-animations/file_animation-play.html
|
||||
[css-animations/test_animation-playstate.html]
|
||||
support-files = css-animations/file_animation-playstate.html
|
||||
[css-animations/test_animation-ready.html]
|
||||
|
@ -80,7 +80,7 @@ function flushComputedStyle(elem) {
|
||||
for (var funcName of ["async_test", "assert_not_equals", "assert_equals",
|
||||
"assert_approx_equals", "assert_less_than_equal",
|
||||
"assert_between_inclusive", "assert_true", "assert_false",
|
||||
"test"]) {
|
||||
"assert_throws", "test"]) {
|
||||
window[funcName] = opener[funcName].bind(opener);
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ interface Animation {
|
||||
void cancel ();
|
||||
[Throws]
|
||||
void finish ();
|
||||
[BinaryName="playFromJS"]
|
||||
[Throws, BinaryName="playFromJS"]
|
||||
void play ();
|
||||
[BinaryName="pauseFromJS"]
|
||||
void pause ();
|
||||
|
@ -37,10 +37,10 @@ CSSAnimation::GetReady(ErrorResult& aRv)
|
||||
}
|
||||
|
||||
void
|
||||
CSSAnimation::Play(LimitBehavior aLimitBehavior)
|
||||
CSSAnimation::Play(ErrorResult &aRv, LimitBehavior aLimitBehavior)
|
||||
{
|
||||
mPauseShouldStick = false;
|
||||
Animation::Play(aLimitBehavior);
|
||||
Animation::Play(aRv, aLimitBehavior);
|
||||
}
|
||||
|
||||
void
|
||||
@ -60,12 +60,12 @@ CSSAnimation::PlayStateFromJS() const
|
||||
}
|
||||
|
||||
void
|
||||
CSSAnimation::PlayFromJS()
|
||||
CSSAnimation::PlayFromJS(ErrorResult& aRv)
|
||||
{
|
||||
// Note that flushing style below might trigger calls to
|
||||
// PlayFromStyle()/PauseFromStyle() on this object.
|
||||
FlushStyle();
|
||||
Animation::PlayFromJS();
|
||||
Animation::PlayFromJS(aRv);
|
||||
}
|
||||
|
||||
void
|
||||
@ -73,7 +73,10 @@ CSSAnimation::PlayFromStyle()
|
||||
{
|
||||
mIsStylePaused = false;
|
||||
if (!mPauseShouldStick) {
|
||||
DoPlay(Animation::LimitBehavior::Continue);
|
||||
ErrorResult rv;
|
||||
DoPlay(rv, Animation::LimitBehavior::Continue);
|
||||
// play() should not throw when LimitBehavior is Continue
|
||||
MOZ_ASSERT(!rv.Failed(), "Unexpected exception playing animation");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,11 +65,11 @@ public:
|
||||
virtual CSSAnimation* AsCSSAnimation() override { return this; }
|
||||
|
||||
virtual dom::Promise* GetReady(ErrorResult& aRv) override;
|
||||
virtual void Play(LimitBehavior aLimitBehavior) override;
|
||||
virtual void Play(ErrorResult& aRv, LimitBehavior aLimitBehavior) override;
|
||||
virtual void Pause() override;
|
||||
|
||||
virtual dom::AnimationPlayState PlayStateFromJS() const override;
|
||||
virtual void PlayFromJS() override;
|
||||
virtual void PlayFromJS(ErrorResult& aRv) override;
|
||||
|
||||
void PlayFromStyle();
|
||||
void PauseFromStyle();
|
||||
|
@ -93,10 +93,10 @@ CSSTransition::PlayStateFromJS() const
|
||||
}
|
||||
|
||||
void
|
||||
CSSTransition::PlayFromJS()
|
||||
CSSTransition::PlayFromJS(ErrorResult& aRv)
|
||||
{
|
||||
FlushStyle();
|
||||
Animation::PlayFromJS();
|
||||
Animation::PlayFromJS(aRv);
|
||||
}
|
||||
|
||||
CommonAnimationManager*
|
||||
|
@ -85,11 +85,17 @@ public:
|
||||
virtual CSSTransition* AsCSSTransition() override { return this; }
|
||||
|
||||
virtual dom::AnimationPlayState PlayStateFromJS() const override;
|
||||
virtual void PlayFromJS() override;
|
||||
virtual void PlayFromJS(ErrorResult& aRv) override;
|
||||
|
||||
// A variant of Play() that avoids posting style updates since this method
|
||||
// is expected to be called whilst already updating style.
|
||||
void PlayFromStyle() { DoPlay(Animation::LimitBehavior::Continue); }
|
||||
void PlayFromStyle()
|
||||
{
|
||||
ErrorResult rv;
|
||||
DoPlay(rv, Animation::LimitBehavior::Continue);
|
||||
// play() should not throw when LimitBehavior is Continue
|
||||
MOZ_ASSERT(!rv.Failed(), "Unexpected exception playing transition");
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~CSSTransition() { }
|
||||
|
Loading…
Reference in New Issue
Block a user