Bug 1324691 - Part 3: Support AnimationsWithDestroyedFrame for ServoRestyleManager. draft
authorBoris Chiou <boris.chiou@gmail.com>
Fri, 27 Jan 2017 12:45:46 +0800
changeset 467193 2c6439cf6bbb5349469d660df218b0a799fae490
parent 467192 12f1364c9458ba311fb615c1a1f12acfaca7a535
child 467194 ba0ec80ced6f06fe265197c812dc99854a419187
child 467195 7ea7ff832d421adcbdf9e4d2ba93a63387bbf3f2
push id43119
push userbmo:boris.chiou@gmail.com
push dateFri, 27 Jan 2017 10:05:05 +0000
bugs1324691
milestone54.0a1
Bug 1324691 - Part 3: Support AnimationsWithDestroyedFrame for ServoRestyleManager. MozReview-Commit-ID: 4cQ6PoieLLG
layout/base/ServoRestyleManager.cpp
layout/generic/nsFrame.cpp
--- a/layout/base/ServoRestyleManager.cpp
+++ b/layout/base/ServoRestyleManager.cpp
@@ -304,16 +304,21 @@ ServoRestyleManager::ProcessPendingResty
     // handle it for now.
     return;
   }
 
   if (!HasPendingRestyles()) {
     return;
   }
 
+  // Create a AnimationsWithDestroyedFrame during restyling process to
+  // stop animations and transitions on elements that have no frame at the end
+  // of the restyling process.
+  AnimationsWithDestroyedFrame animationsWithDestroyedFrame(this);
+
   ServoStyleSet* styleSet = StyleSet();
   nsIDocument* doc = PresContext()->Document();
 
   // XXXbholley: Should this be while() per bug 1316247?
   if (HasPendingRestyles()) {
     mInStyleRefresh = true;
     styleSet->StyleDocument();
     PresContext()->EffectCompositor()->ClearElementsToRestyle();
@@ -353,16 +358,21 @@ ServoRestyleManager::ProcessPendingResty
     }
     mReentrantChanges = nullptr;
 
     styleSet->AssertTreeIsClean();
     mInStyleRefresh = false;
   }
 
   IncrementRestyleGeneration();
+
+  // Note: We are in the scope of |animationsWithDestroyedFrame|, so
+  //       |mAnimationsWithDestroyedFrame| is still valid.
+  MOZ_ASSERT(mAnimationsWithDestroyedFrame);
+  mAnimationsWithDestroyedFrame->StopAnimationsForElementsWithoutFrames();
 }
 
 void
 ServoRestyleManager::RestyleForInsertOrChange(nsINode* aContainer,
                                               nsIContent* aChild)
 {
   //
   // XXXbholley: We need the Gecko logic here to correctly restyle for things
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -695,26 +695,22 @@ nsFrame::DestroyFrom(nsIFrame* aDestruct
       }
     }
   }
 
   if (HasCSSAnimations() || HasCSSTransitions() ||
       EffectSet::GetEffectSet(this)) {
     // If no new frame for this element is created by the end of the
     // restyling process, stop animations and transitions for this frame
-    if (presContext->RestyleManager()->IsGecko()) {
-      RestyleManagerBase::AnimationsWithDestroyedFrame* adf =
-        presContext->RestyleManager()->AsGecko()
-                   ->GetAnimationsWithDestroyedFrame();
-      // AnimationsWithDestroyedFrame only lives during the restyling process.
-      if (adf) {
-        adf->Put(mContent, mStyleContext);
-      }
-    } else {
-      NS_ERROR("stylo: ServoRestyleManager does not support animations yet");
+    RestyleManagerBase::AnimationsWithDestroyedFrame* adf =
+      presContext->RestyleManager()->AsBase()
+                 ->GetAnimationsWithDestroyedFrame();
+    // AnimationsWithDestroyedFrame only lives during the restyling process.
+    if (adf) {
+      adf->Put(mContent, mStyleContext);
     }
   }
 
   // Disable visibility tracking. Note that we have to do this before calling
   // NotifyDestroyingFrame(), which will clear frame properties and make us lose
   // track of whether we were previously visible or not.
   // XXX(seth): It'd be ideal to assert that we're already marked nonvisible
   // here, but it's unfortunately tricky to guarantee in the face of things like