Bug 1282691 - Drop the assertion about an animation that we're making play-pending not already being pause-pending; r?boris draft
authorBrian Birtles <birtles@gmail.com>
Fri, 13 Oct 2017 14:37:51 +0900
changeset 679874 0fe556fbf1146d93b2ca781311070c11400893a2
parent 679629 25aad10380b10b6efa50c2b4d97245f078d870a0
child 735695 c5bddbbf0170f97c6098643cbc051da3c83be7ad
push id84326
push userbmo:bbirtles@mozilla.com
push dateFri, 13 Oct 2017 05:43:54 +0000
reviewersboris
bugs1282691
milestone58.0a1
Bug 1282691 - Drop the assertion about an animation that we're making play-pending not already being pause-pending; r?boris We could handle this case by dropping the animation from the pause-pending table but that's an extra hashtable lookup that so far seems to be unnecessary. I have verified that the crashtest added in this patch fails without the code changes included here. MozReview-Commit-ID: Ed6u7WRLD2t
dom/animation/PendingAnimationTracker.h
dom/animation/test/crashtests/1282691-1.html
dom/animation/test/crashtests/crashtests.list
--- a/dom/animation/PendingAnimationTracker.h
+++ b/dom/animation/PendingAnimationTracker.h
@@ -23,35 +23,43 @@ public:
     : mDocument(aDocument)
   { }
 
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(PendingAnimationTracker)
   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(PendingAnimationTracker)
 
   void AddPlayPending(dom::Animation& aAnimation)
   {
-    MOZ_ASSERT(!IsWaitingToPause(aAnimation),
-               "Animation is already waiting to pause");
+    // We'd like to assert here that IsWaitingToPause(aAnimation) is false but
+    // if |aAnimation| was tracked here as a pause-pending animation when it was
+    // removed from |mDocument|, then re-attached to |mDocument|, and then
+    // played again, we could end up here with IsWaitingToPause returning true.
+    //
+    // However, that should be harmless since all it means is that we'll call
+    // Animation::TriggerOnNextTick or Animation::TriggerNow twice, both of
+    // which will handle the redundant call gracefully.
     AddPending(aAnimation, mPlayPendingSet);
     mHasPlayPendingGeometricAnimations = CheckState::Indeterminate;
   }
   void RemovePlayPending(dom::Animation& aAnimation)
   {
     RemovePending(aAnimation, mPlayPendingSet);
     mHasPlayPendingGeometricAnimations = CheckState::Indeterminate;
   }
   bool IsWaitingToPlay(const dom::Animation& aAnimation) const
   {
     return IsWaiting(aAnimation, mPlayPendingSet);
   }
 
   void AddPausePending(dom::Animation& aAnimation)
   {
-    MOZ_ASSERT(!IsWaitingToPlay(aAnimation),
-               "Animation is already waiting to play");
+    // As with AddPausePending, we'd like to assert that
+    // IsWaitingToPlay(aAnimation) is false but there are some circumstances
+    // where this can be true. Fortunately adding the animation to both pending
+    // sets should be harmless.
     AddPending(aAnimation, mPausePendingSet);
   }
   void RemovePausePending(dom::Animation& aAnimation)
   {
     RemovePending(aAnimation, mPausePendingSet);
   }
   bool IsWaitingToPause(const dom::Animation& aAnimation) const
   {
new file mode 100644
--- /dev/null
+++ b/dom/animation/test/crashtests/1282691-1.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<meta charset=utf-8>
+<script>
+
+function boom() {
+  const div = document.createElement('div');
+  const anim = div.animate([{}], {});
+  document.documentElement.appendChild(div);
+  anim.pause();
+  document.documentElement.removeChild(div);
+
+  requestAnimationFrame(() => {
+    document.documentElement.appendChild(div);
+    anim.play();
+    document.documentElement.className = '';
+  });
+}
+
+</script>
+</head>
+<body onload="boom();"></body>
+</html>
--- a/dom/animation/test/crashtests/crashtests.list
+++ b/dom/animation/test/crashtests/crashtests.list
@@ -5,16 +5,17 @@ pref(dom.animations-api.core.enabled,tru
 pref(dom.animations-api.core.enabled,true) load 1216842-3.html
 pref(dom.animations-api.core.enabled,true) load 1216842-4.html
 pref(dom.animations-api.core.enabled,true) load 1216842-5.html
 pref(dom.animations-api.core.enabled,true) load 1216842-6.html
 pref(dom.animations-api.core.enabled,true) load 1272475-1.html
 pref(dom.animations-api.core.enabled,true) load 1272475-2.html
 pref(dom.animations-api.core.enabled,true) load 1278485-1.html
 pref(dom.animations-api.core.enabled,true) load 1277272-1.html
+pref(dom.animations-api.core.enabled,true) load 1282691-1.html
 pref(dom.animations-api.core.enabled,true) load 1291413-1.html
 pref(dom.animations-api.core.enabled,true) load 1291413-2.html
 pref(dom.animations-api.core.enabled,true) load 1304886-1.html
 pref(dom.animations-api.core.enabled,true) load 1322382-1.html
 pref(dom.animations-api.core.enabled,true) load 1322291-1.html
 pref(dom.animations-api.core.enabled,true) load 1322291-2.html
 pref(dom.animations-api.core.enabled,true) load 1323114-1.html
 pref(dom.animations-api.core.enabled,true) load 1323114-2.html