Bug 1123523 - Part 8: Dispatch nsIAnimationObserver notifications when an animation is added or removed. r=birtles
authorCameron McCormack <cam@mcc.id.au>
Sat, 14 Mar 2015 16:34:40 +1100
changeset 251925 1067ec3655aa0866c8dbe33a85e711fc2648eba5
parent 251924 77bb5ac2e1f69466e613dfae68a707eac1b8a42c
child 251926 5f29af1f9c800d4f4ee29252dc1a649bbe4389cd
push id7860
push userjlund@mozilla.com
push dateMon, 30 Mar 2015 18:46:02 +0000
treeherdermozilla-aurora@8ac636cd51f3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbirtles
bugs1123523
milestone39.0a1
Bug 1123523 - Part 8: Dispatch nsIAnimationObserver notifications when an animation is added or removed. r=birtles
dom/animation/AnimationPlayer.cpp
layout/style/nsAnimationManager.cpp
layout/style/nsTransitionManager.cpp
--- a/dom/animation/AnimationPlayer.cpp
+++ b/dom/animation/AnimationPlayer.cpp
@@ -330,17 +330,25 @@ AnimationPlayer::IsRunning() const
 
   ComputedTiming computedTiming = GetSource()->GetComputedTiming();
   return computedTiming.mPhase == ComputedTiming::AnimationPhase_Active;
 }
 
 void
 AnimationPlayer::UpdateRelevance()
 {
+  bool wasRelevant = mIsRelevant;
   mIsRelevant = HasCurrentSource() || HasInEffectSource();
+
+  // Notify animation observers.
+  if (wasRelevant && !mIsRelevant) {
+    nsNodeUtils::AnimationRemoved(this);
+  } else if (!wasRelevant && mIsRelevant) {
+    nsNodeUtils::AnimationAdded(this);
+  }
 }
 
 bool
 AnimationPlayer::CanThrottle() const
 {
   if (!mSource ||
       mSource->IsFinishedTransition() ||
       mSource->Properties().IsEmpty()) {
--- a/layout/style/nsAnimationManager.cpp
+++ b/layout/style/nsAnimationManager.cpp
@@ -13,16 +13,17 @@
 #include "nsPresContext.h"
 #include "nsStyleSet.h"
 #include "nsStyleChangeList.h"
 #include "nsCSSRules.h"
 #include "RestyleManager.h"
 #include "nsLayoutUtils.h"
 #include "nsIFrame.h"
 #include "nsIDocument.h"
+#include "nsDOMMutationObserver.h"
 #include <math.h>
 
 using namespace mozilla;
 using namespace mozilla::css;
 using mozilla::dom::Animation;
 using mozilla::dom::AnimationPlayer;
 using mozilla::CSSAnimationPlayer;
 
@@ -255,16 +256,18 @@ nsAnimationManager::CheckAnimationRule(n
   AnimationPlayerCollection* collection =
     GetAnimationPlayers(aElement, aStyleContext->GetPseudoType(), false);
   if (!collection &&
       disp->mAnimationNameCount == 1 &&
       disp->mAnimations[0].GetName().IsEmpty()) {
     return nullptr;
   }
 
+  nsAutoAnimationMutationBatch mb(aElement);
+
   // build the animations list
   dom::AnimationTimeline* timeline = aElement->OwnerDoc()->Timeline();
   AnimationPlayerPtrArray newPlayers;
   BuildAnimations(aStyleContext, aElement, timeline, newPlayers);
 
   if (newPlayers.IsEmpty()) {
     if (collection) {
       collection->Destroy();
@@ -709,16 +712,19 @@ nsAnimationManager::FlushAnimations(Flus
   // the refresh driver (but leave the animations!).
   TimeStamp now = mPresContext->RefreshDriver()->MostRecentRefresh();
   bool didThrottle = false;
   for (PRCList *l = PR_LIST_HEAD(&mElementCollections);
        l != &mElementCollections;
        l = PR_NEXT_LINK(l)) {
     AnimationPlayerCollection* collection =
       static_cast<AnimationPlayerCollection*>(l);
+
+    nsAutoAnimationMutationBatch mb(collection->mElement);
+
     collection->Tick();
     bool canThrottleTick = aFlags == Can_Throttle &&
       collection->CanPerformOnCompositorThread(
         AnimationPlayerCollection::CanAnimateFlags(0)) &&
       collection->CanThrottleAnimation(now);
 
     nsRefPtr<css::AnimValuesStyleRule> oldStyleRule = collection->mStyleRule;
     UpdateStyleAndEvents(collection, now, canThrottleTick
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -23,16 +23,17 @@
 #include "mozilla/dom/Element.h"
 #include "nsIFrame.h"
 #include "Layers.h"
 #include "FrameLayerBuilder.h"
 #include "nsDisplayList.h"
 #include "nsStyleChangeList.h"
 #include "nsStyleSet.h"
 #include "RestyleManager.h"
+#include "nsDOMMutationObserver.h"
 
 using mozilla::TimeStamp;
 using mozilla::TimeDuration;
 using mozilla::dom::AnimationPlayer;
 using mozilla::dom::Animation;
 
 using namespace mozilla;
 using namespace mozilla::layers;
@@ -213,16 +214,18 @@ nsTransitionManager::StyleContextChanged
     nsStyleSet* styleSet = mPresContext->StyleSet();
     afterChangeStyle =
       styleSet->ResolveStyleWithoutAnimation(aElement, newStyleContext,
                                              eRestyle_CSSTransitions);
   } else {
     afterChangeStyle = newStyleContext;
   }
 
+  nsAutoAnimationMutationBatch mb(aElement);
+
   // Per http://lists.w3.org/Archives/Public/www-style/2009Aug/0109.html
   // I'll consider only the transitions from the number of items in
   // 'transition-property' on down, and later ones will override earlier
   // ones (tracked using |whichStarted|).
   bool startedAny = false;
   nsCSSPropertySet whichStarted;
   for (uint32_t i = disp->mTransitionPropertyCount; i-- != 0; ) {
     const StyleTransition& t = disp->mTransitions[i];
@@ -671,16 +674,18 @@ nsTransitionManager::FlushTransitions(Fl
   // are still transitioning, and start transitions with delays.
   {
     PRCList *next = PR_LIST_HEAD(&mElementCollections);
     while (next != &mElementCollections) {
       AnimationPlayerCollection* collection =
         static_cast<AnimationPlayerCollection*>(next);
       next = PR_NEXT_LINK(next);
 
+      nsAutoAnimationMutationBatch mb(collection->mElement);
+
       collection->Tick();
       bool canThrottleTick = aFlags == Can_Throttle &&
         collection->CanPerformOnCompositorThread(
           AnimationPlayerCollection::CanAnimateFlags(0)) &&
         collection->CanThrottleAnimation(now);
 
       MOZ_ASSERT(collection->mElement->GetCrossShadowCurrentDoc() ==
                    mPresContext->Document(),