Bug 1123523 - Part 9: Dispatch an nsIAnimationObserver notification when an animation is changed. r=birtles
authorCameron McCormack <cam@mcc.id.au>
Sat, 14 Mar 2015 16:34:40 +1100
changeset 251926 5f29af1f9c800d4f4ee29252dc1a649bbe4389cd
parent 251925 1067ec3655aa0866c8dbe33a85e711fc2648eba5
child 251927 94fa4a005c335d30d0de6785b0d723b19030e4e9
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 9: Dispatch an nsIAnimationObserver notification when an animation is changed. r=birtles
dom/animation/Animation.h
dom/smil/nsSMILKeySpline.h
layout/style/nsAnimationManager.cpp
--- a/dom/animation/Animation.h
+++ b/dom/animation/Animation.h
@@ -46,16 +46,26 @@ struct AnimationTiming
   bool FillsForwards() const {
     return mFillMode == NS_STYLE_ANIMATION_FILL_MODE_BOTH ||
            mFillMode == NS_STYLE_ANIMATION_FILL_MODE_FORWARDS;
   }
   bool FillsBackwards() const {
     return mFillMode == NS_STYLE_ANIMATION_FILL_MODE_BOTH ||
            mFillMode == NS_STYLE_ANIMATION_FILL_MODE_BACKWARDS;
   }
+  bool operator==(const AnimationTiming& aOther) const {
+    return mIterationDuration == aOther.mIterationDuration &&
+           mDelay == aOther.mDelay &&
+           mIterationCount == aOther.mIterationCount &&
+           mDirection == aOther.mDirection &&
+           mFillMode == aOther.mFillMode;
+  }
+  bool operator!=(const AnimationTiming& aOther) const {
+    return !(*this == aOther);
+  }
 };
 
 /**
  * Stores the results of calculating the timing properties of an animation
  * at a given sample time.
  */
 struct ComputedTiming
 {
@@ -99,34 +109,61 @@ public:
   void Init(const nsTimingFunction &aFunction);
   double GetValue(double aPortion) const;
   const nsSMILKeySpline* GetFunction() const {
     NS_ASSERTION(mType == nsTimingFunction::Function, "Type mismatch");
     return &mTimingFunction;
   }
   Type GetType() const { return mType; }
   uint32_t GetSteps() const { return mSteps; }
+  bool operator==(const ComputedTimingFunction& aOther) const {
+    return mType == aOther.mType &&
+           mTimingFunction == aOther.mTimingFunction &&
+           mSteps == aOther.mSteps;
+  }
+  bool operator!=(const ComputedTimingFunction& aOther) const {
+    return !(*this == aOther);
+  }
 
 private:
   Type mType;
   nsSMILKeySpline mTimingFunction;
   uint32_t mSteps;
 };
 
 struct AnimationPropertySegment
 {
   float mFromKey, mToKey;
   StyleAnimationValue mFromValue, mToValue;
   ComputedTimingFunction mTimingFunction;
+
+  bool operator==(const AnimationPropertySegment& aOther) const {
+    return mFromKey == aOther.mFromKey &&
+           mToKey == aOther.mToKey &&
+           mFromValue == aOther.mFromValue &&
+           mToValue == aOther.mToValue &&
+           mTimingFunction == aOther.mTimingFunction;
+  }
+  bool operator!=(const AnimationPropertySegment& aOther) const {
+    return !(*this == aOther);
+  }
 };
 
 struct AnimationProperty
 {
   nsCSSProperty mProperty;
   InfallibleTArray<AnimationPropertySegment> mSegments;
+
+  bool operator==(const AnimationProperty& aOther) const {
+    return mProperty == aOther.mProperty &&
+           mSegments == aOther.mSegments;
+  }
+  bool operator!=(const AnimationProperty& aOther) const {
+    return !(*this == aOther);
+  }
 };
 
 struct ElementPropertyTransition;
 
 namespace dom {
 
 class AnimationEffect;
 
--- a/dom/smil/nsSMILKeySpline.h
+++ b/dom/smil/nsSMILKeySpline.h
@@ -1,16 +1,19 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 #ifndef NS_SMILKEYSPLINE_H_
 #define NS_SMILKEYSPLINE_H_
 
+#include "mozilla/ArrayUtils.h"
+#include "mozilla/PodOperations.h"
+
 /**
  * Utility class to provide scaling defined in a keySplines element.
  */
 class nsSMILKeySpline
 {
 public:
   nsSMILKeySpline() { /* caller must call Init later */ }
 
@@ -39,16 +42,26 @@ public:
    *
    * @param aX  The input x value. A floating-point number between 0 and
    *            1 (inclusive).
    */
   double GetSplineValue(double aX) const;
 
   void GetSplineDerivativeValues(double aX, double& aDX, double& aDY) const;
 
+  bool operator==(const nsSMILKeySpline& aOther) const {
+    return mX1 == aOther.mX1 &&
+           mY1 == aOther.mY1 &&
+           mX2 == aOther.mX2 &&
+           mY2 == aOther.mY2;
+  }
+  bool operator!=(const nsSMILKeySpline& aOther) const {
+    return !(*this == aOther);
+  }
+
 private:
   void
   CalcSampleValues();
 
   /**
    * Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
    */
   static double
--- a/layout/style/nsAnimationManager.cpp
+++ b/layout/style/nsAnimationManager.cpp
@@ -312,21 +312,26 @@ nsAnimationManager::CheckAnimationRule(n
             oldPlayer = a;
             break;
           }
         }
         if (!oldPlayer) {
           continue;
         }
 
+        bool animationChanged = false;
+
         // Update the old from the new so we can keep the original object
         // identity (and any expando properties attached to it).
         if (oldPlayer->GetSource() && newPlayer->GetSource()) {
           Animation* oldAnim = oldPlayer->GetSource();
           Animation* newAnim = newPlayer->GetSource();
+          animationChanged =
+            oldAnim->Timing() != newAnim->Timing() ||
+            oldAnim->Properties() != newAnim->Properties();
           oldAnim->Timing() = newAnim->Timing();
           oldAnim->Properties() = newAnim->Properties();
         }
 
         // Reset compositor state so animation will be re-synchronized.
         oldPlayer->ClearIsRunningOnCompositor();
 
         // Handle changes in play state.
@@ -334,18 +339,24 @@ nsAnimationManager::CheckAnimationRule(n
         // for example, if the author has called pause(), that will
         // override the animation-play-state.
         // (We should check newPlayer->IsStylePaused() but that requires
         //  downcasting to CSSAnimationPlayer and we happen to know that
         //  newPlayer will only ever be paused by calling PauseFromStyle
         //  making IsPaused synonymous in this case.)
         if (!oldPlayer->IsStylePaused() && newPlayer->IsPaused()) {
           oldPlayer->PauseFromStyle();
+          animationChanged = true;
         } else if (oldPlayer->IsStylePaused() && !newPlayer->IsPaused()) {
           oldPlayer->PlayFromStyle();
+          animationChanged = true;
+        }
+
+        if (animationChanged) {
+          nsNodeUtils::AnimationChanged(oldPlayer);
         }
 
         // Replace new animation with the (updated) old one and remove the
         // old one from the array so we don't try to match it any more.
         //
         // Although we're doing this while iterating this is safe because
         // we're not changing the length of newPlayers and we've finished
         // iterating over the list of old iterations.