Bug 1436659 - Implement pending playback rate mechanism; r?hiro
This reflects the following changes to the Web Animations specification:
1. https://github.com/w3c/csswg-drafts/commit/5af5e276badf4df0271bcfa0b8e7837fff24133a
2. https://github.com/w3c/csswg-drafts/commit/673f6fc1269829743c707c53dcb04092f958de35
which can be viewed as a merged diff at:
https://gist.github.com/birtles/d147eb2e0e2d4d37fadf217abd709411
MozReview-Commit-ID: 3DoaWUkxBTo
--- a/dom/animation/Animation.cpp
+++ b/dom/animation/Animation.cpp
@@ -268,17 +268,20 @@ Animation::SetStartTime(const Nullable<T
// the already null time to null.
timelineTime = mTimeline->GetCurrentTime();
}
if (timelineTime.IsNull() && !aNewStartTime.IsNull()) {
mHoldTime.SetNull();
}
Nullable<TimeDuration> previousCurrentTime = GetCurrentTime();
+
+ ApplyPendingPlaybackRate();
mStartTime = aNewStartTime;
+
if (!aNewStartTime.IsNull()) {
if (mPlaybackRate != 0.0) {
mHoldTime.SetNull();
}
} else {
mHoldTime = previousCurrentTime;
}
@@ -332,35 +335,39 @@ Animation::SetCurrentTime(const TimeDura
AutoMutationBatchForAnimation mb(*this);
SilentlySetCurrentTime(aSeekTime);
if (mPendingState == PendingState::PausePending) {
// Finish the pause operation
mHoldTime.SetValue(aSeekTime);
+
+ ApplyPendingPlaybackRate();
mStartTime.SetNull();
if (mReady) {
mReady->MaybeResolve(this);
}
CancelPendingTasks();
}
UpdateTiming(SeekFlag::DidSeek, SyncNotifyFlag::Async);
if (IsRelevant()) {
nsNodeUtils::AnimationChanged(this);
}
PostUpdate();
}
-// https://drafts.csswg.org/web-animations/#set-the-animation-playback-rate
+// https://drafts.csswg.org/web-animations/#set-the-playback-rate
void
Animation::SetPlaybackRate(double aPlaybackRate)
{
+ mPendingPlaybackRate.reset();
+
if (aPlaybackRate == mPlaybackRate) {
return;
}
AutoMutationBatchForAnimation mb(*this);
Nullable<TimeDuration> previousTime = GetCurrentTime();
mPlaybackRate = aPlaybackRate;
@@ -378,16 +385,93 @@ Animation::SetPlaybackRate(double aPlayb
// - update the playback rate on animations on layers.
UpdateTiming(SeekFlag::DidSeek, SyncNotifyFlag::Async);
if (IsRelevant()) {
nsNodeUtils::AnimationChanged(this);
}
PostUpdate();
}
+// https://drafts.csswg.org/web-animations/#seamlessly-update-the-playback-rate
+void
+Animation::UpdatePlaybackRate(double aPlaybackRate)
+{
+ if (mPendingPlaybackRate && mPendingPlaybackRate.value() == aPlaybackRate) {
+ return;
+ }
+
+ mPendingPlaybackRate = Some(aPlaybackRate);
+
+ // If we already have a pending task, there is nothing more to do since the
+ // playback rate will be applied then.
+ if (Pending()) {
+ return;
+ }
+
+ AutoMutationBatchForAnimation mb(*this);
+
+ AnimationPlayState playState = PlayState();
+ if (playState == AnimationPlayState::Idle ||
+ playState == AnimationPlayState::Paused) {
+ // We are either idle or paused. In either case we can apply the pending
+ // playback rate immediately.
+ ApplyPendingPlaybackRate();
+
+ // We don't need to update timing or post an update here because:
+ //
+ // * the current time hasn't changed -- it's either unresolved or fixed
+ // with a hold time -- so the output won't have changed
+ // * the finished state won't have changed even if the sign of the
+ // playback rate changed since we're not finished (we're paused or idle)
+ // * the playback rate on layers doesn't need to be updated since we're not
+ // moving. Once we get a start time etc. we'll update the playback rate
+ // then.
+ //
+ // All we need to do is update observers so that, e.g. DevTools, report the
+ // right information.
+ if (IsRelevant()) {
+ nsNodeUtils::AnimationChanged(this);
+ }
+ } else if (playState == AnimationPlayState::Finished) {
+ MOZ_ASSERT(mTimeline && !mTimeline->GetCurrentTime().IsNull(),
+ "If we have no active timeline, we should be idle or paused");
+ if (aPlaybackRate != 0) {
+ // The unconstrained current time can only be unresolved if either we
+ // don't have an active timeline (and we already asserted that is not
+ // true) or we have an unresolved start time (in which case we should be
+ // paused).
+ MOZ_ASSERT(!GetUnconstrainedCurrentTime().IsNull(),
+ "Unconstrained current time should be resolved");
+ TimeDuration unconstrainedCurrentTime =
+ GetUnconstrainedCurrentTime().Value();
+ TimeDuration timelineTime = mTimeline->GetCurrentTime().Value();
+ mStartTime = StartTimeFromTimelineTime(
+ timelineTime, unconstrainedCurrentTime, aPlaybackRate);
+ } else {
+ mStartTime = mTimeline->GetCurrentTime();
+ }
+
+ ApplyPendingPlaybackRate();
+
+ // Even though we preserve the current time, we might now leave the finished
+ // state (e.g. if the playback rate changes sign) so we need to update
+ // timing.
+ UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Async);
+ if (IsRelevant()) {
+ nsNodeUtils::AnimationChanged(this);
+ }
+ PostUpdate();
+ } else {
+ ErrorResult rv;
+ Play(rv, LimitBehavior::Continue);
+ MOZ_ASSERT(!rv.Failed(),
+ "We should only fail to play when using auto-rewind behavior");
+ }
+}
+
// https://drafts.csswg.org/web-animations/#play-state
AnimationPlayState
Animation::PlayState() const
{
if (!nsContentUtils::AnimationsAPIPendingMemberEnabled() && Pending()) {
return AnimationPlayState::Pending;
}
@@ -450,24 +534,28 @@ Animation::Cancel()
CancelNoUpdate();
PostUpdate();
}
// https://drafts.csswg.org/web-animations/#finish-an-animation
void
Animation::Finish(ErrorResult& aRv)
{
- if (mPlaybackRate == 0 ||
- (mPlaybackRate > 0 && EffectEnd() == TimeDuration::Forever())) {
+ double effectivePlaybackRate = CurrentOrPendingPlaybackRate();
+
+ if (effectivePlaybackRate == 0 ||
+ (effectivePlaybackRate > 0 && EffectEnd() == TimeDuration::Forever())) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
AutoMutationBatchForAnimation mb(*this);
+ ApplyPendingPlaybackRate();
+
// Seek to the end
TimeDuration limit =
mPlaybackRate > 0 ? TimeDuration(EffectEnd()) : TimeDuration(0);
bool didChange = GetCurrentTime() != Nullable<TimeDuration>(limit);
SilentlySetCurrentTime(limit);
// If we are paused or play-pending we need to fill in the start time in
// order to transition to the finished state.
@@ -525,35 +613,34 @@ Animation::Pause(ErrorResult& aRv)
void
Animation::Reverse(ErrorResult& aRv)
{
if (!mTimeline || mTimeline->GetCurrentTime().IsNull()) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
- if (mPlaybackRate == 0.0) {
+ double effectivePlaybackRate = CurrentOrPendingPlaybackRate();
+
+ if (effectivePlaybackRate == 0.0) {
return;
}
- AutoMutationBatchForAnimation mb(*this);
+ Maybe<double> originalPendingPlaybackRate = mPendingPlaybackRate;
- SilentlySetPlaybackRate(-mPlaybackRate);
+ mPendingPlaybackRate = Some(-effectivePlaybackRate);
+
Play(aRv, LimitBehavior::AutoRewind);
// If Play() threw, restore state and don't report anything to mutation
// observers.
if (aRv.Failed()) {
- SilentlySetPlaybackRate(-mPlaybackRate);
- return;
+ mPendingPlaybackRate = originalPendingPlaybackRate;
}
- if (IsRelevant()) {
- nsNodeUtils::AnimationChanged(this);
- }
// Play(), above, unconditionally calls PostUpdate so we don't need to do
// it here.
}
// ---------------------------------------------------------------------------
//
// JS wrappers for Animation interface:
//
@@ -673,16 +760,37 @@ Animation::TriggerNow()
FinishPendingAt(mTimeline->GetCurrentTime().Value());
}
Nullable<TimeDuration>
Animation::GetCurrentOrPendingStartTime() const
{
Nullable<TimeDuration> result;
+ // If we have a pending playback rate, work out what start time we will use
+ // when we come to updating that playback rate.
+ //
+ // This logic roughly shadows that in ResumeAt but is just different enough
+ // that it is difficult to extract out the common functionality (and
+ // extracting that functionality out would make it harder to match ResumeAt up
+ // against the spec).
+ if (mPendingPlaybackRate && !mPendingReadyTime.IsNull() &&
+ !mStartTime.IsNull()) {
+ // If we have a hold time, use it as the current time to match.
+ TimeDuration currentTimeToMatch =
+ !mHoldTime.IsNull()
+ ? mHoldTime.Value()
+ : CurrentTimeFromTimelineTime(
+ mPendingReadyTime.Value(), mStartTime.Value(), mPlaybackRate);
+
+ result = StartTimeFromTimelineTime(
+ mPendingReadyTime.Value(), currentTimeToMatch, *mPendingPlaybackRate);
+ return result;
+ }
+
if (!mStartTime.IsNull()) {
result = mStartTime;
return result;
}
if (mPendingReadyTime.IsNull() || mHoldTime.IsNull()) {
return result;
}
@@ -758,26 +866,16 @@ Animation::SilentlySetCurrentTime(const
} else {
mStartTime = StartTimeFromTimelineTime(
mTimeline->GetCurrentTime().Value(), aSeekTime, mPlaybackRate);
}
mPreviousCurrentTime.SetNull();
}
-void
-Animation::SilentlySetPlaybackRate(double aPlaybackRate)
-{
- Nullable<TimeDuration> previousTime = GetCurrentTime();
- mPlaybackRate = aPlaybackRate;
- if (!previousTime.IsNull()) {
- SilentlySetCurrentTime(previousTime.Value());
- }
-}
-
// https://drafts.csswg.org/web-animations/#cancel-an-animation
void
Animation::CancelNoUpdate()
{
if (PlayState() != AnimationPlayState::Idle) {
ResetPendingTasks();
if (mFinished) {
@@ -1031,48 +1129,57 @@ Animation::NotifyGeometricAnimationsStar
// https://drafts.csswg.org/web-animations/#play-an-animation
void
Animation::PlayNoUpdate(ErrorResult& aRv, LimitBehavior aLimitBehavior)
{
AutoMutationBatchForAnimation mb(*this);
bool abortedPause = mPendingState == PendingState::PausePending;
+ double effectivePlaybackRate = CurrentOrPendingPlaybackRate();
+
Nullable<TimeDuration> currentTime = GetCurrentTime();
- if (mPlaybackRate > 0.0 &&
+ if (effectivePlaybackRate > 0.0 &&
(currentTime.IsNull() ||
(aLimitBehavior == LimitBehavior::AutoRewind &&
(currentTime.Value() < TimeDuration() ||
currentTime.Value() >= EffectEnd())))) {
mHoldTime.SetValue(TimeDuration(0));
- } else if (mPlaybackRate < 0.0 &&
+ } else if (effectivePlaybackRate < 0.0 &&
(currentTime.IsNull() ||
(aLimitBehavior == LimitBehavior::AutoRewind &&
(currentTime.Value() <= TimeDuration() ||
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()) {
+ } else if (effectivePlaybackRate == 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
- // asynchronous start even though we already have a resolved start time).
- if (mHoldTime.IsNull() && !abortedPause) {
+ // If the hold time is null then we're already playing normally and,
+ // typically, we can bail out here.
+ //
+ // However, there are two cases where we can't do that:
+ //
+ // (a) If we just aborted a pause. In this case, for consistency, we need to
+ // go through the motions of doing an asynchronous start.
+ //
+ // (b) If we have timing changes (specifically a change to the playbackRate)
+ // that should be applied asynchronously.
+ //
+ if (mHoldTime.IsNull() && !abortedPause && !mPendingPlaybackRate) {
return;
}
// Clear the start time until we resolve a new one. We do this except
// for the case where we are aborting a pause and don't have a hold time.
//
// If we're aborting a pause and *do* have a hold time (e.g. because
// the animation is finished or we just applied the auto-rewind behavior
@@ -1159,56 +1266,79 @@ Animation::PauseNoUpdate(ErrorResult& aR
}
UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Async);
if (IsRelevant()) {
nsNodeUtils::AnimationChanged(this);
}
}
+// https://drafts.csswg.org/web-animations/#play-an-animation
void
Animation::ResumeAt(const TimeDuration& aReadyTime)
{
// This method is only expected to be called for an animation that is
// waiting to play. We can easily adapt it to handle other states
// but it's currently not necessary.
MOZ_ASSERT(mPendingState == PendingState::PlayPending,
"Expected to resume a play-pending animation");
MOZ_ASSERT(!mHoldTime.IsNull() || !mStartTime.IsNull(),
"An animation in the play-pending state should have either a"
" resolved hold time or resolved start time");
- // If we aborted a pending pause operation we will already have a start time
- // we should use. In all other cases, we resolve it from the ready time.
- if (mStartTime.IsNull()) {
+ AutoMutationBatchForAnimation mb(*this);
+ bool hadPendingPlaybackRate = mPendingPlaybackRate.isSome();
+
+ if (!mHoldTime.IsNull()) {
+ // The hold time is set, so we don't need any special handling to preserve
+ // the current time.
+ ApplyPendingPlaybackRate();
mStartTime =
StartTimeFromTimelineTime(aReadyTime, mHoldTime.Value(), mPlaybackRate);
if (mPlaybackRate != 0) {
mHoldTime.SetNull();
}
+ } else if (!mStartTime.IsNull() && mPendingPlaybackRate) {
+ // Apply any pending playback rate, preserving the current time.
+ TimeDuration currentTimeToMatch = CurrentTimeFromTimelineTime(
+ aReadyTime, mStartTime.Value(), mPlaybackRate);
+ ApplyPendingPlaybackRate();
+ mStartTime =
+ StartTimeFromTimelineTime(aReadyTime, currentTimeToMatch, mPlaybackRate);
+ if (mPlaybackRate == 0) {
+ mHoldTime.SetValue(currentTimeToMatch);
+ }
}
+
mPendingState = PendingState::NotPending;
UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Async);
+ // If we had a pending playback rate, we will have now applied it so we need
+ // to notify observers.
+ if (hadPendingPlaybackRate && IsRelevant()) {
+ nsNodeUtils::AnimationChanged(this);
+ }
+
if (mReady) {
mReady->MaybeResolve(this);
}
}
void
Animation::PauseAt(const TimeDuration& aReadyTime)
{
MOZ_ASSERT(mPendingState == PendingState::PausePending,
"Expected to pause a pause-pending animation");
if (!mStartTime.IsNull() && mHoldTime.IsNull()) {
mHoldTime = CurrentTimeFromTimelineTime(
aReadyTime, mStartTime.Value(), mPlaybackRate);
}
+ ApplyPendingPlaybackRate();
mStartTime.SetNull();
mPendingState = PendingState::NotPending;
UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Async);
if (mReady) {
mReady->MaybeResolve(this);
}
@@ -1346,16 +1476,18 @@ Animation::CancelPendingTasks()
void
Animation::ResetPendingTasks()
{
if (mPendingState == PendingState::NotPending) {
return;
}
CancelPendingTasks();
+ ApplyPendingPlaybackRate();
+
if (mReady) {
mReady->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
mReady = nullptr;
}
}
bool
Animation::IsPossiblyOrphanedPendingAnimation() const
--- a/dom/animation/Animation.h
+++ b/dom/animation/Animation.h
@@ -115,17 +115,17 @@ public:
bool Pending() const { return mPendingState != PendingState::NotPending; }
virtual Promise* GetReady(ErrorResult& aRv);
Promise* GetFinished(ErrorResult& aRv);
void Cancel();
void Finish(ErrorResult& aRv);
virtual void Play(ErrorResult& aRv, LimitBehavior aLimitBehavior);
virtual void Pause(ErrorResult& aRv);
void Reverse(ErrorResult& aRv);
- void UpdatePlaybackRate(double /*aPlaybackRate*/) {}
+ void UpdatePlaybackRate(double aPlaybackRate);
bool IsRunningOnCompositor() const;
IMPL_EVENT_HANDLER(finish);
IMPL_EVENT_HANDLER(cancel);
// Wrapper functions for Animation DOM methods when called
// from script.
//
// We often use the same methods internally and from script but when called
@@ -239,16 +239,25 @@ public:
* animations on the next tick and apply the start time stored here.
*
* This method returns the start time, if resolved. Otherwise, if we have
* a pending ready time, it returns the corresponding start time. If neither
* of those are available, it returns null.
*/
Nullable<TimeDuration> GetCurrentOrPendingStartTime() const;
+ /**
+ * As with the start time, we should use the pending playback rate when
+ * producing layer animations.
+ */
+ double CurrentOrPendingPlaybackRate() const
+ {
+ return mPendingPlaybackRate.valueOr(mPlaybackRate);
+ }
+ bool HasPendingPlaybackRate() const { return mPendingPlaybackRate.isSome(); }
/**
* The following relationship from the definition of the 'current time' is
* re-used in many algorithms so we extract it here into a static method that
* can be re-used:
*
* current time = (timeline time - start time) * playback rate
*
@@ -388,32 +397,38 @@ public:
* 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(const StickyTimeDuration& aActiveTime) {};
protected:
void SilentlySetCurrentTime(const TimeDuration& aNewCurrentTime);
- void SilentlySetPlaybackRate(double aPlaybackRate);
void CancelNoUpdate();
void PlayNoUpdate(ErrorResult& aRv, LimitBehavior aLimitBehavior);
void PauseNoUpdate(ErrorResult& aRv);
void ResumeAt(const TimeDuration& aReadyTime);
void PauseAt(const TimeDuration& aReadyTime);
void FinishPendingAt(const TimeDuration& aReadyTime)
{
if (mPendingState == PendingState::PlayPending) {
ResumeAt(aReadyTime);
} else if (mPendingState == PendingState::PausePending) {
PauseAt(aReadyTime);
} else {
NS_NOTREACHED("Can't finish pending if we're not in a pending state");
}
}
+ void ApplyPendingPlaybackRate()
+ {
+ if (mPendingPlaybackRate) {
+ mPlaybackRate = *mPendingPlaybackRate;
+ mPendingPlaybackRate.reset();
+ }
+ }
/**
* Finishing behavior depends on if changes to timing occurred due
* to a seek or regular playback.
*/
enum class SeekFlag {
NoSeek,
DidSeek
@@ -452,37 +467,47 @@ protected:
/**
* Returns true if this animation is not only play-pending, but has
* yet to be given a pending ready time. This roughly corresponds to
* animations that are waiting to be painted (since we set the pending
* ready time at the end of painting). Identifying such animations is
* useful because in some cases animations that are painted together
* may need to be synchronized.
+ *
+ * We don't, however, want to include animations with a fixed start time such
+ * as animations that are simply having their playbackRate updated or which
+ * are resuming from an aborted pause.
*/
bool IsNewlyStarted() const {
return mPendingState == PendingState::PlayPending &&
- mPendingReadyTime.IsNull();
+ mPendingReadyTime.IsNull() &&
+ mStartTime.IsNull();
}
bool IsPossiblyOrphanedPendingAnimation() const;
StickyTimeDuration EffectEnd() const;
Nullable<TimeDuration> GetCurrentTimeForHoldTime(
const Nullable<TimeDuration>& aHoldTime) const;
+ Nullable<TimeDuration> GetUnconstrainedCurrentTime() const
+ {
+ return GetCurrentTimeForHoldTime(Nullable<TimeDuration>());
+ }
nsIDocument* GetRenderedDocument() const;
RefPtr<AnimationTimeline> mTimeline;
RefPtr<AnimationEffectReadOnly> mEffect;
// The beginning of the delay period.
Nullable<TimeDuration> mStartTime; // Timeline timescale
Nullable<TimeDuration> mHoldTime; // Animation timescale
Nullable<TimeDuration> mPendingReadyTime; // Timeline timescale
Nullable<TimeDuration> mPreviousCurrentTime; // Animation timescale
double mPlaybackRate;
+ Maybe<double> mPendingPlaybackRate;
// 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://drafts.csswg.org/web-animations/#current-ready-promise
RefPtr<Promise> mReady;
// A Promise that is resolved when we reach the end of the effect, or
deleted file mode 100644
--- a/testing/web-platform/meta/web-animations/timing-model/animations/finishing-an-animation.html.ini
+++ /dev/null
@@ -1,13 +0,0 @@
-[finishing-an-animation.html]
- [A pending playback rate should be applied immediately when an animation is finished]
- expected: FAIL
-
- [An exception should be thrown if the effective playback rate is zero]
- expected: FAIL
-
- [An exception should be thrown when finishing if the effective playback rate is positive and the target effect end is infinity]
- expected: FAIL
-
- [An exception is NOT thrown when finishing if the effective playback rate is negative and the target effect end is infinity]
- expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/web-animations/timing-model/animations/playing-an-animation.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[playing-an-animation.html]
- [A pending playback rate is used when determining auto-rewind behavior]
- expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/web-animations/timing-model/animations/reversing-an-animation.html.ini
+++ /dev/null
@@ -1,10 +0,0 @@
-[reversing-an-animation.html]
- [Reversing an animation inverts the playback rate]
- expected: FAIL
-
- [Reversing should use the negative pending playback rate]
- expected: FAIL
-
- [When reversing fails, it should restore any previous pending playback rate]
- expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/web-animations/timing-model/animations/seamlessly-updating-the-playback-rate-of-an-animation.html.ini
+++ /dev/null
@@ -1,19 +0,0 @@
-[seamlessly-updating-the-playback-rate-of-an-animation.html]
- [Updating the playback rate while running makes the animation pending]
- expected: FAIL
-
- [If a pending playback rate is set multiple times, the latest wins]
- expected: FAIL
-
- [In the idle state, the playback rate is applied immediately]
- expected: FAIL
-
- [In the paused state, the playback rate is applied immediately]
- expected: FAIL
-
- [Updating the playback rate on a finished animation maintains the current time]
- expected: FAIL
-
- [Updating the playback rate to zero on a finished animation maintains the current time]
- expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/web-animations/timing-model/animations/setting-the-current-time-of-an-animation.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[setting-the-current-time-of-an-animation.html]
- [Setting the current time of a pausing animation applies a pending playback rate]
- expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/web-animations/timing-model/animations/setting-the-start-time-of-an-animation.html.ini
+++ /dev/null
@@ -1,7 +0,0 @@
-[setting-the-start-time-of-an-animation.html]
- [Setting the start time of a play-pending animation applies a pending playback rate]
- expected: FAIL
-
- [Setting the start time of a playing animation applies a pending playback rate]
- expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/web-animations/timing-model/animations/setting-the-target-effect-of-an-animation.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[setting-the-target-effect-of-an-animation.html]
- [Setting the target effect to null causes a pending playback rate to be applied]
- expected: FAIL
-