Bug 678938 - SMIL: Make sure current interval is properly cleared when doing a rewind; r=dholbert
authorBrian Birtles <birtles@gmail.com>
Fri, 02 Sep 2011 08:15:44 +0900
changeset 77740 b6608d4de5f7f225c43cb637e324eb34f190533f
parent 77739 246f74de583c9715c01e94e4450102078f87ff14
child 77741 873989b97eefb7b5564be642b55d0450f921f0b4
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs678938
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 678938 - SMIL: Make sure current interval is properly cleared when doing a rewind; r=dholbert
content/smil/crashtests/678938-1.svg
content/smil/crashtests/crashtests.list
content/smil/nsSMILTimedElement.cpp
new file mode 100644
--- /dev/null
+++ b/content/smil/crashtests/678938-1.svg
@@ -0,0 +1,11 @@
+<svg xmlns="http://www.w3.org/2000/svg" class="reftest-wait">
+<script>
+  window.addEventListener("load", function() {
+    setTimeout(function() {
+      document.documentElement.setCurrentTime(0);
+      document.documentElement.removeAttribute("class");
+    }, 0);
+  }, false);
+</script>
+<set id="c"/><set id="b" begin="c.begin; b.begin"/>
+</svg>
--- a/content/smil/crashtests/crashtests.list
+++ b/content/smil/crashtests/crashtests.list
@@ -32,12 +32,13 @@ load 606101-1.svg
 load 608549-1.svg
 load 608295-1.html
 load 611927-1.svg
 load 615002-1.svg
 load 615872-1.svg
 load 650732-1.svg
 load 665334-1.svg
 load 669225-1.svg
+load 669225-2.svg
 load 670313-1.svg
-load 669225-2.svg
 load 678822-1.svg
 load 678847-1.svg
+load 678938-1.svg
--- a/content/smil/nsSMILTimedElement.cpp
+++ b/content/smil/nsSMILTimedElement.cpp
@@ -753,20 +753,20 @@ nsSMILTimedElement::Rewind()
     mSeekState = mElementState == STATE_ACTIVE ?
                  SEEK_BACKWARD_FROM_ACTIVE :
                  SEEK_BACKWARD_FROM_INACTIVE;
   }
   NS_ABORT_IF_FALSE(mSeekState == SEEK_BACKWARD_FROM_INACTIVE ||
                     mSeekState == SEEK_BACKWARD_FROM_ACTIVE,
                     "Rewind in the middle of a forwards seek?");
 
+  // Putting us in the startup state will ensure we skip doing any interval
+  // updates
+  mElementState = STATE_STARTUP;
   ClearIntervals();
-  // ClearIntervals puts us in to the POSTACTIVE state but we're doing a full
-  // rewind so go back to the startup state
-  mElementState = STATE_STARTUP;
 
   UnsetBeginSpec(RemoveNonDynamic);
   UnsetEndSpec(RemoveNonDynamic);
 
   if (mClient) {
     mClient->Inactivate(PR_FALSE);
   }
 
@@ -779,16 +779,18 @@ nsSMILTimedElement::Rewind()
   if (mAnimationElement->HasAnimAttr(nsGkAtoms::end)) {
     nsAutoString attValue;
     mAnimationElement->GetAnimAttr(nsGkAtoms::end, attValue);
     SetEndSpec(attValue, &mAnimationElement->AsElement(), RemoveNonDynamic);
   }
 
   mPrevRegisteredMilestone = sMaxMilestone;
   RegisterMilestone();
+  NS_ABORT_IF_FALSE(!mCurrentInterval,
+                    "Current interval is set at end of rewind");
 }
 
 namespace
 {
   PRBool
   RemoveNonDOM(nsSMILInstanceTime* aInstanceTime)
   {
     return !aInstanceTime->FromDOM() && !aInstanceTime->ShouldPreserve();
@@ -1327,17 +1329,19 @@ nsSMILTimedElement::ClearSpecs(TimeValue
   aSpecs.Clear();
   RemoveByFunction removeByFunction(aRemove);
   RemoveInstanceTimes(aInstances, removeByFunction);
 }
 
 void
 nsSMILTimedElement::ClearIntervals()
 {
-  mElementState = STATE_POSTACTIVE;
+  if (mElementState != STATE_STARTUP) {
+    mElementState = STATE_POSTACTIVE;
+  }
   mCurrentRepeatIteration = 0;
   ResetCurrentInterval();
 
   // Remove old intervals
   for (PRInt32 i = mOldIntervals.Length() - 1; i >= 0; --i) {
     mOldIntervals[i]->Unlink();
   }
   mOldIntervals.Clear();