Bug 1194639 part 1 - Add AutoMutationBatchForAnimation; r=heycam
authorBrian Birtles <birtles@gmail.com>
Thu, 22 Oct 2015 15:16:18 +0900
changeset 304103 0d867dfee95751895e426201113d96901693c2a8
parent 304102 0513d651719bcded74dcd18967f241e8dd16a755
child 304104 90370e8e13f2922a59a57789ffcdaababa20e487
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1194639
milestone44.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 1194639 part 1 - Add AutoMutationBatchForAnimation; r=heycam
dom/animation/Animation.cpp
dom/base/nsNodeUtils.cpp
dom/base/nsNodeUtils.h
--- a/dom/animation/Animation.cpp
+++ b/dom/animation/Animation.cpp
@@ -4,19 +4,21 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "Animation.h"
 #include "AnimationUtils.h"
 #include "mozilla/dom/AnimationBinding.h"
 #include "mozilla/dom/AnimationPlaybackEvent.h"
 #include "mozilla/AutoRestore.h"
-#include "mozilla/AsyncEventDispatcher.h" //For AsyncEventDispatcher
+#include "mozilla/AsyncEventDispatcher.h" // For AsyncEventDispatcher
+#include "mozilla/Maybe.h" // For Maybe
 #include "AnimationCommon.h" // For AnimationCollection,
                              // CommonAnimationManager
+#include "nsDOMMutationObserver.h" // For nsAutoAnimationMutationBatch
 #include "nsIDocument.h" // For nsIDocument
 #include "nsIPresShell.h" // For nsIPresShell
 #include "nsLayoutUtils.h" // For PostRestyleEvent (remove after bug 1073336)
 #include "nsThreadUtils.h" // For nsRunnableMethod and nsRevocableEventPtr
 #include "PendingAnimationTracker.h" // For PendingAnimationTracker
 
 namespace mozilla {
 namespace dom {
@@ -39,16 +41,50 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEvent
 JSObject*
 Animation::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return dom::AnimationBinding::Wrap(aCx, this, aGivenProto);
 }
 
 // ---------------------------------------------------------------------------
 //
+// Utility methods
+//
+// ---------------------------------------------------------------------------
+
+namespace {
+  // A wrapper around nsAutoAnimationMutationBatch that looks up the
+  // appropriate document from the supplied animation.
+  class MOZ_RAII AutoMutationBatchForAnimation {
+  public:
+    explicit AutoMutationBatchForAnimation(const Animation& aAnimation
+                                           MOZ_GUARD_OBJECT_NOTIFIER_PARAM) {
+      MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+      Element* targetElement = nsNodeUtils::GetTargetForAnimation(&aAnimation);
+      if (!targetElement) {
+        return;
+      }
+
+      // For mutation observers, we use the OwnerDoc.
+      nsIDocument* doc = targetElement->OwnerDoc();
+      if (!doc) {
+        return;
+      }
+
+      mAutoBatch.emplace(doc);
+    }
+
+  private:
+    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
+    Maybe<nsAutoAnimationMutationBatch> mAutoBatch;
+  };
+}
+
+// ---------------------------------------------------------------------------
+//
 // Animation interface:
 //
 // ---------------------------------------------------------------------------
 
 void
 Animation::SetEffect(KeyframeEffectReadOnly* aEffect)
 {
   RefPtr<Animation> kungFuDeathGrip(this);
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -221,18 +221,18 @@ nsNodeUtils::ContentRemoved(nsINode* aCo
     document = static_cast<nsIDocument*>(aContainer);
   }
 
   IMPL_MUTATION_NOTIFICATION(ContentRemoved, aContainer,
                              (document, container, aChild, aIndexInContainer,
                               aPreviousSibling));
 }
 
-static inline Element*
-GetTarget(Animation* aAnimation)
+Element*
+nsNodeUtils::GetTargetForAnimation(const Animation* aAnimation)
 {
   KeyframeEffectReadOnly* effect = aAnimation->GetEffect();
   if (!effect) {
     return nullptr;
   }
 
   Element* target;
   nsCSSPseudoElements::Type pseudoType;
@@ -246,45 +246,45 @@ GetTarget(Animation* aAnimation)
   }
 
   return effect->GetTarget();
 }
 
 void
 nsNodeUtils::AnimationAdded(Animation* aAnimation)
 {
-  Element* target = GetTarget(aAnimation);
+  Element* target = GetTargetForAnimation(aAnimation);
   if (!target) {
     return;
   }
   nsIDocument* doc = target->OwnerDoc();
 
   if (doc->MayHaveAnimationObservers()) {
     IMPL_ANIMATION_NOTIFICATION(AnimationAdded, target, (aAnimation));
   }
 }
 
 void
 nsNodeUtils::AnimationChanged(Animation* aAnimation)
 {
-  Element* target = GetTarget(aAnimation);
+  Element* target = GetTargetForAnimation(aAnimation);
   if (!target) {
     return;
   }
   nsIDocument* doc = target->OwnerDoc();
 
   if (doc->MayHaveAnimationObservers()) {
     IMPL_ANIMATION_NOTIFICATION(AnimationChanged, target, (aAnimation));
   }
 }
 
 void
 nsNodeUtils::AnimationRemoved(Animation* aAnimation)
 {
-  Element* target = GetTarget(aAnimation);
+  Element* target = GetTargetForAnimation(aAnimation);
   if (!target) {
     return;
   }
   nsIDocument* doc = target->OwnerDoc();
 
   if (doc->MayHaveAnimationObservers()) {
     IMPL_ANIMATION_NOTIFICATION(AnimationRemoved, target, (aAnimation));
   }
--- a/dom/base/nsNodeUtils.h
+++ b/dom/base/nsNodeUtils.h
@@ -137,16 +137,18 @@ public:
     if (slots && !slots->mMutationObservers.IsEmpty()) {
       NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(slots->mMutationObservers,
                                          nsIMutationObserver,
                                          ParentChainChanged,
                                          (aContent));
     }
   }
 
+  static mozilla::dom::Element*
+    GetTargetForAnimation(const mozilla::dom::Animation* aAnimation);
   static void AnimationAdded(mozilla::dom::Animation* aAnimation);
   static void AnimationChanged(mozilla::dom::Animation* aAnimation);
   static void AnimationRemoved(mozilla::dom::Animation* aAnimation);
 
   /**
    * To be called when reference count of aNode drops to zero.
    * @param aNode The node which is going to be deleted.
    */