зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1412765 - Add Animation.pending member; r=bz,hiro
This reflects the change made to the Web Animations specification in:9e2053f553
1c3415f4cc
(I got it wrong the first time. The second commit fixes the first.) And discussed in: https://github.com/w3c/web-animations/issues/196 In summary, we are splitting the "pending" play state out into a separate boolean member so that it is possible to distinguish between "play-pending" and "pause-pending" and because most of the time when you check for animation.playState === 'running' you also really want to include play-pending animations. MozReview-Commit-ID: IJSNoZTKW2I --HG-- extra : rebase_source : 5d17239fd087cfe3cce1c9697eff97d062b6dd4b
This commit is contained in:
Родитель
bad7dc839d
Коммит
e83e1a5e71
|
@ -386,21 +386,23 @@ Animation::SetPlaybackRate(double aPlaybackRate)
|
|||
AnimationPlayState
|
||||
Animation::PlayState() const
|
||||
{
|
||||
if (mPendingState != PendingState::NotPending) {
|
||||
if (!nsContentUtils::AnimationsAPIPendingMemberEnabled() && Pending()) {
|
||||
return AnimationPlayState::Pending;
|
||||
}
|
||||
|
||||
Nullable<TimeDuration> currentTime = GetCurrentTime();
|
||||
if (currentTime.IsNull()) {
|
||||
if (currentTime.IsNull() && !Pending()) {
|
||||
return AnimationPlayState::Idle;
|
||||
}
|
||||
|
||||
if (mStartTime.IsNull()) {
|
||||
if (mPendingState == PendingState::PausePending ||
|
||||
(mStartTime.IsNull() && !Pending())) {
|
||||
return AnimationPlayState::Paused;
|
||||
}
|
||||
|
||||
if ((mPlaybackRate > 0.0 && currentTime.Value() >= EffectEnd()) ||
|
||||
(mPlaybackRate < 0.0 && currentTime.Value() <= TimeDuration())) {
|
||||
if (!currentTime.IsNull() &&
|
||||
((mPlaybackRate > 0.0 && currentTime.Value() >= EffectEnd()) ||
|
||||
(mPlaybackRate < 0.0 && currentTime.Value() <= TimeDuration()))) {
|
||||
return AnimationPlayState::Finished;
|
||||
}
|
||||
|
||||
|
@ -418,7 +420,7 @@ Animation::GetReady(ErrorResult& aRv)
|
|||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
if (PlayState() != AnimationPlayState::Pending) {
|
||||
if (!Pending()) {
|
||||
mReady->MaybeResolve(this);
|
||||
}
|
||||
return mReady;
|
||||
|
@ -638,7 +640,7 @@ Animation::TriggerOnNextTick(const Nullable<TimeDuration>& aReadyTime)
|
|||
// due to the handling of possibly orphaned animations in Tick(), this
|
||||
// animation got started whilst still being in another document's pending
|
||||
// animation map.
|
||||
if (PlayState() != AnimationPlayState::Pending) {
|
||||
if (!Pending()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -654,7 +656,7 @@ Animation::TriggerNow()
|
|||
// is cancelled and its rendered document can't be reached, we can end up
|
||||
// with the animation still in a pending player tracker even after it is
|
||||
// no longer pending.
|
||||
if (PlayState() != AnimationPlayState::Pending) {
|
||||
if (!Pending()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -994,13 +996,11 @@ Animation::ComposeStyle(ComposeAnimationResult&& aComposeResult,
|
|||
// immediately before updating the style rule and then restore it immediately
|
||||
// afterwards. This is purely to prevent visual flicker. Other behavior
|
||||
// such as dispatching events continues to rely on the regular timeline time.
|
||||
AnimationPlayState playState = PlayState();
|
||||
bool pending = Pending();
|
||||
{
|
||||
AutoRestore<Nullable<TimeDuration>> restoreHoldTime(mHoldTime);
|
||||
|
||||
if (playState == AnimationPlayState::Pending &&
|
||||
mHoldTime.IsNull() &&
|
||||
!mStartTime.IsNull()) {
|
||||
if (pending && mHoldTime.IsNull() && !mStartTime.IsNull()) {
|
||||
Nullable<TimeDuration> timeToUse = mPendingReadyTime;
|
||||
if (timeToUse.IsNull() &&
|
||||
mTimeline &&
|
||||
|
@ -1020,8 +1020,8 @@ Animation::ComposeStyle(ComposeAnimationResult&& aComposeResult,
|
|||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(playState == PlayState(),
|
||||
"Play state should not change during the course of compositing");
|
||||
MOZ_ASSERT(pending == Pending(),
|
||||
"Pending state should not change during the course of compositing");
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -110,6 +110,7 @@ public:
|
|||
double PlaybackRate() const { return mPlaybackRate; }
|
||||
void SetPlaybackRate(double aPlaybackRate);
|
||||
AnimationPlayState PlayState() const;
|
||||
bool Pending() const { return mPendingState != PendingState::NotPending; }
|
||||
virtual Promise* GetReady(ErrorResult& aRv);
|
||||
virtual Promise* GetFinished(ErrorResult& aRv);
|
||||
void Cancel();
|
||||
|
@ -133,6 +134,7 @@ public:
|
|||
void SetCurrentTimeAsDouble(const Nullable<double>& aCurrentTime,
|
||||
ErrorResult& aRv);
|
||||
virtual AnimationPlayState PlayStateFromJS() const { return PlayState(); }
|
||||
virtual bool PendingFromJS() const { return Pending(); }
|
||||
virtual void PlayFromJS(ErrorResult& aRv)
|
||||
{
|
||||
Play(aRv, LimitBehavior::AutoRewind);
|
||||
|
@ -153,9 +155,7 @@ public:
|
|||
virtual void Tick();
|
||||
bool NeedsTicks() const
|
||||
{
|
||||
AnimationPlayState playState = PlayState();
|
||||
return playState == AnimationPlayState::Running ||
|
||||
playState == AnimationPlayState::Pending;
|
||||
return Pending() || PlayState() == AnimationPlayState::Running;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -263,6 +263,12 @@ public:
|
|||
|
||||
bool IsPausedOrPausing() const
|
||||
{
|
||||
// FIXME: Once we drop the dom.animations-api.pending-member.enabled pref we
|
||||
// can simplify the following check to just:
|
||||
//
|
||||
// return PlayState() == AnimationPlayState::Paused;
|
||||
//
|
||||
// And at that point we might not need this method at all.
|
||||
return PlayState() == AnimationPlayState::Paused ||
|
||||
mPendingState == PendingState::PausePending;
|
||||
}
|
||||
|
@ -278,6 +284,10 @@ public:
|
|||
|
||||
bool IsPlaying() const
|
||||
{
|
||||
// FIXME: Once we drop the dom.animations-api.pending-member.enabled pref we
|
||||
// can simplify the last two conditions to just:
|
||||
//
|
||||
// PlayState() == AnimationPlayState::Running
|
||||
return mPlaybackRate != 0.0 &&
|
||||
mTimeline &&
|
||||
!mTimeline->GetCurrentTime().IsNull() &&
|
||||
|
|
|
@ -29,6 +29,8 @@ interface Animation : EventTarget {
|
|||
attribute double playbackRate;
|
||||
[BinaryName="playStateFromJS"]
|
||||
readonly attribute AnimationPlayState playState;
|
||||
[Pref="dom.animations-api.pending-member.enabled", BinaryName="pendingFromJS"]
|
||||
readonly attribute boolean pending;
|
||||
[Func="nsDocument::IsWebAnimationsEnabled", Throws]
|
||||
readonly attribute Promise<Animation> ready;
|
||||
[Func="nsDocument::IsWebAnimationsEnabled", Throws]
|
||||
|
|
|
@ -731,9 +731,8 @@ AddAnimationsForProperty(nsIFrame* aFrame, nsDisplayListBuilder* aBuilder,
|
|||
// Currently this only happens when the timeline is driven by a refresh
|
||||
// driver under test control. In this case, the next time the refresh
|
||||
// driver is advanced it will trigger any pending animations.
|
||||
if (anim->PlayState() == AnimationPlayState::Pending &&
|
||||
(anim->GetTimeline() &&
|
||||
!anim->GetTimeline()->TracksWallclockTime())) {
|
||||
if (anim->Pending() &&
|
||||
(anim->GetTimeline() && !anim->GetTimeline()->TracksWallclockTime())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -89,6 +89,15 @@ CSSAnimation::PlayStateFromJS() const
|
|||
return Animation::PlayStateFromJS();
|
||||
}
|
||||
|
||||
bool
|
||||
CSSAnimation::PendingFromJS() const
|
||||
{
|
||||
// Flush style since, for example, if the animation-play-state was just
|
||||
// changed its possible we should now be pending.
|
||||
FlushStyle();
|
||||
return Animation::PendingFromJS();
|
||||
}
|
||||
|
||||
void
|
||||
CSSAnimation::PlayFromJS(ErrorResult& aRv)
|
||||
{
|
||||
|
|
|
@ -122,8 +122,9 @@ public:
|
|||
// specifies that reading playState does *not* flush style (and we drop the
|
||||
// following override), then we should update tabbrowser.xml to check
|
||||
// the playState instead.
|
||||
virtual AnimationPlayState PlayStateFromJS() const override;
|
||||
virtual void PlayFromJS(ErrorResult& aRv) override;
|
||||
AnimationPlayState PlayStateFromJS() const override;
|
||||
bool PendingFromJS() const override;
|
||||
void PlayFromJS(ErrorResult& aRv) override;
|
||||
|
||||
void PlayFromStyle();
|
||||
void PauseFromStyle();
|
||||
|
|
|
@ -176,6 +176,19 @@ CSSTransition::PlayStateFromJS() const
|
|||
return Animation::PlayStateFromJS();
|
||||
}
|
||||
|
||||
bool
|
||||
CSSTransition::PendingFromJS() const
|
||||
{
|
||||
// Transitions don't become pending again after they start running but, if
|
||||
// while the transition is still pending, style is updated in such a way
|
||||
// that the transition will be canceled, we need to report false here.
|
||||
// Hence we need to flush, but only when we're pending.
|
||||
if (Pending()) {
|
||||
FlushStyle();
|
||||
}
|
||||
return Animation::PendingFromJS();
|
||||
}
|
||||
|
||||
void
|
||||
CSSTransition::PlayFromJS(ErrorResult& aRv)
|
||||
{
|
||||
|
|
|
@ -139,8 +139,9 @@ public:
|
|||
void GetTransitionProperty(nsString& aRetVal) const;
|
||||
|
||||
// Animation interface overrides
|
||||
virtual AnimationPlayState PlayStateFromJS() const override;
|
||||
virtual void PlayFromJS(ErrorResult& aRv) override;
|
||||
AnimationPlayState PlayStateFromJS() const override;
|
||||
bool PendingFromJS() const override;
|
||||
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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче