Bug 1153734 part 2 - Rename Animation to KeyframeEffectReadonly; r=smaug
authorBrian Birtles <birtles@gmail.com>
Wed, 15 Apr 2015 08:48:21 +0900
changeset 239181 1e58cc9b9f9213b0680f9545cae4232aeb82a676
parent 239180 cfcda525dbd32a74e8eaa78bdba8a24b18fdfc0f
child 239182 d1b6e873a6bc52f72ebd56313c94c4ed3035cb49
push id28584
push usercbook@mozilla.com
push dateWed, 15 Apr 2015 12:29:01 +0000
treeherdermozilla-central@b58b07945d30 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1153734
milestone40.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 1153734 part 2 - Rename Animation to KeyframeEffectReadonly; r=smaug We define KeyframeEffectReadonly in KeyframeEffect.cpp since Web Animations also defines KeyframeEffect and when we come to implement that I expect we'll define it in the same class, maybe even using the same object. This patch also adds a few missing includes in places where KeyframeEffectReadonly is used so that we're not just cargo-culting it in.
dom/animation/Animation.cpp
dom/animation/Animation.h
dom/animation/AnimationPlayer.cpp
dom/animation/AnimationPlayer.h
dom/animation/KeyframeEffect.cpp
dom/animation/KeyframeEffect.h
dom/animation/moz.build
dom/animation/test/css-animations/test_animation-name.html
dom/animation/test/css-animations/test_animation-target.html
dom/animation/test/css-animations/test_effect-name.html
dom/animation/test/css-animations/test_effect-target.html
dom/animation/test/css-transitions/test_animation-name.html
dom/animation/test/css-transitions/test_animation-target.html
dom/animation/test/css-transitions/test_effect-name.html
dom/animation/test/css-transitions/test_effect-target.html
dom/animation/test/mochitest.ini
dom/base/nsDOMMutationObserver.cpp
dom/base/nsNodeUtils.cpp
dom/tests/mochitest/general/test_interfaces.html
dom/webidl/Animation.webidl
dom/webidl/AnimationPlayer.webidl
dom/webidl/KeyframeEffect.webidl
dom/webidl/moz.build
gfx/layers/composite/AsyncCompositionManager.cpp
layout/base/nsDisplayList.cpp
layout/base/nsLayoutUtils.cpp
layout/style/AnimationCommon.cpp
layout/style/nsAnimationManager.cpp
layout/style/nsTransitionManager.cpp
layout/style/nsTransitionManager.h
--- a/dom/animation/AnimationPlayer.cpp
+++ b/dom/animation/AnimationPlayer.cpp
@@ -261,17 +261,17 @@ AnimationPlayer::SetCurrentTimeAsDouble(
     }
     return;
   }
 
   return SetCurrentTime(TimeDuration::FromMilliseconds(aCurrentTime.Value()));
 }
 
 void
-AnimationPlayer::SetSource(Animation* aSource)
+AnimationPlayer::SetSource(KeyframeEffectReadonly* aSource)
 {
   if (mSource) {
     mSource->SetParentTime(Nullable<TimeDuration>());
   }
   mSource = aSource;
   if (mSource) {
     mSource->SetParentTime(GetCurrentTime());
   }
--- a/dom/animation/AnimationPlayer.h
+++ b/dom/animation/AnimationPlayer.h
@@ -5,19 +5,19 @@
 
 #ifndef mozilla_dom_AnimationPlayer_h
 #define mozilla_dom_AnimationPlayer_h
 
 #include "nsWrapperCache.h"
 #include "nsCycleCollectionParticipant.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration
-#include "mozilla/dom/Animation.h" // for Animation
 #include "mozilla/dom/AnimationPlayerBinding.h" // for AnimationPlayState
 #include "mozilla/dom/DocumentTimeline.h" // for DocumentTimeline
+#include "mozilla/dom/KeyframeEffect.h" // for KeyframeEffectReadonly
 #include "mozilla/dom/Promise.h" // for Promise
 #include "nsCSSProperty.h" // for nsCSSProperty
 
 // X11 has a #define for CurrentTime.
 #ifdef CurrentTime
 #undef CurrentTime
 #endif
 
@@ -75,17 +75,17 @@ public:
   // Flag to pass to DoPlay to indicate that it should not carry out finishing
   // behavior (reset the current time to the beginning of the active duration).
   enum LimitBehavior {
     AutoRewind = 0,
     Continue = 1
   };
 
   // AnimationPlayer methods
-  Animation* GetSource() const { return mSource; }
+  KeyframeEffectReadonly* GetSource() const { return mSource; }
   DocumentTimeline* Timeline() const { return mTimeline; }
   Nullable<TimeDuration> GetStartTime() const { return mStartTime; }
   void SetStartTime(const Nullable<TimeDuration>& aNewStartTime);
   Nullable<TimeDuration> GetCurrentTime() const;
   void SilentlySetCurrentTime(const TimeDuration& aNewCurrentTime);
   void SetCurrentTime(const TimeDuration& aNewCurrentTime);
   double PlaybackRate() const { return mPlaybackRate; }
   void SetPlaybackRate(double aPlaybackRate);
@@ -108,17 +108,17 @@ public:
                               ErrorResult& aRv);
   virtual AnimationPlayState PlayStateFromJS() const { return PlayState(); }
   virtual void PlayFromJS() { Play(LimitBehavior::AutoRewind); }
   // PauseFromJS is currently only here for symmetry with PlayFromJS but
   // in future we will likely have to flush style in
   // CSSAnimationPlayer::PauseFromJS so we leave it for now.
   void PauseFromJS() { Pause(); }
 
-  void SetSource(Animation* aSource);
+  void SetSource(KeyframeEffectReadonly* aSource);
   void Tick();
 
   /**
    * Set the time to use for starting or pausing a pending player.
    *
    * Typically, when a player is played, it does not start immediately but is
    * added to a table of pending players on the document of its source content.
    * In the meantime it sets its hold time to the time from which playback
@@ -298,17 +298,17 @@ protected:
   StickyTimeDuration SourceContentEnd() const;
 
   nsIDocument* GetRenderedDocument() const;
   nsPresContext* GetPresContext() const;
   virtual css::CommonAnimationManager* GetAnimationManager() const = 0;
   AnimationPlayerCollection* GetCollection() const;
 
   nsRefPtr<DocumentTimeline> mTimeline;
-  nsRefPtr<Animation> mSource;
+  nsRefPtr<KeyframeEffectReadonly> mSource;
   // The beginning of the delay period.
   Nullable<TimeDuration> mStartTime; // Timeline timescale
   Nullable<TimeDuration> mHoldTime;  // Player timescale
   Nullable<TimeDuration> mPendingReadyTime; // Timeline timescale
   Nullable<TimeDuration> mPreviousCurrentTime; // Player timescale
   double mPlaybackRate;
 
   // A Promise that is replaced on each call to Play() (and in future Pause())
rename from dom/animation/Animation.cpp
rename to dom/animation/KeyframeEffect.cpp
--- a/dom/animation/Animation.cpp
+++ b/dom/animation/KeyframeEffect.cpp
@@ -1,15 +1,15 @@
 /* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
 /* 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/. */
 
-#include "mozilla/dom/Animation.h"
-#include "mozilla/dom/AnimationBinding.h"
+#include "mozilla/dom/KeyframeEffect.h"
+#include "mozilla/dom/KeyframeEffectBinding.h"
 #include "mozilla/FloatingPoint.h"
 #include "AnimationCommon.h"
 #include "nsCSSPropertySet.h"
 
 namespace mozilla {
 
 void
 ComputedTimingFunction::Init(const nsTimingFunction &aFunction)
@@ -54,36 +54,40 @@ ComputedTimingFunction::GetValue(double 
 }
 
 // In the Web Animations model, the time fraction can be outside the range
 // [0.0, 1.0] but it shouldn't be Infinity.
 const double ComputedTiming::kNullTimeFraction = PositiveInfinity<double>();
 
 namespace dom {
 
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Animation, mDocument, mTarget)
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(KeyframeEffectReadonly,
+                                      mDocument,
+                                      mTarget)
 
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(Animation, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(Animation, Release)
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(KeyframeEffectReadonly, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(KeyframeEffectReadonly, Release)
 
 JSObject*
-Animation::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+KeyframeEffectReadonly::WrapObject(JSContext* aCx,
+                                   JS::Handle<JSObject*> aGivenProto)
 {
-  return AnimationBinding::Wrap(aCx, this, aGivenProto);
+  return KeyframeEffectReadonlyBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
-Animation::SetParentTime(Nullable<TimeDuration> aParentTime)
+KeyframeEffectReadonly::SetParentTime(Nullable<TimeDuration> aParentTime)
 {
   mParentTime = aParentTime;
 }
 
 ComputedTiming
-Animation::GetComputedTimingAt(const Nullable<TimeDuration>& aLocalTime,
-                               const AnimationTiming& aTiming)
+KeyframeEffectReadonly::GetComputedTimingAt(
+                          const Nullable<TimeDuration>& aLocalTime,
+                          const AnimationTiming& aTiming)
 {
   const TimeDuration zeroDuration;
 
   // Currently we expect negative durations to be picked up during CSS
   // parsing but when we start receiving timing parameters from other sources
   // we will need to clamp negative durations here.
   // For now, if we're hitting this it probably means we're overflowing
   // integer arithmetic in mozilla::TimeStamp.
@@ -201,99 +205,101 @@ Animation::GetComputedTimingAt(const Nul
   if (thisIterationReverse) {
     result.mTimeFraction = 1.0 - result.mTimeFraction;
   }
 
   return result;
 }
 
 StickyTimeDuration
-Animation::ActiveDuration(const AnimationTiming& aTiming)
+KeyframeEffectReadonly::ActiveDuration(const AnimationTiming& aTiming)
 {
   if (aTiming.mIterationCount == mozilla::PositiveInfinity<float>()) {
     // An animation that repeats forever has an infinite active duration
     // unless its iteration duration is zero, in which case it has a zero
     // active duration.
     const StickyTimeDuration zeroDuration;
     return aTiming.mIterationDuration == zeroDuration
            ? zeroDuration
            : StickyTimeDuration::Forever();
   }
   return StickyTimeDuration(
     aTiming.mIterationDuration.MultDouble(aTiming.mIterationCount));
 }
 
 // http://w3c.github.io/web-animations/#in-play
 bool
-Animation::IsInPlay(const AnimationPlayer& aPlayer) const
+KeyframeEffectReadonly::IsInPlay(const AnimationPlayer& aPlayer) const
 {
   if (IsFinishedTransition() ||
       aPlayer.PlayState() == AnimationPlayState::Finished) {
     return false;
   }
 
   return GetComputedTiming().mPhase == ComputedTiming::AnimationPhase_Active;
 }
 
 // http://w3c.github.io/web-animations/#current
 bool
-Animation::IsCurrent(const AnimationPlayer& aPlayer) const
+KeyframeEffectReadonly::IsCurrent(const AnimationPlayer& aPlayer) const
 {
   if (IsFinishedTransition() ||
       aPlayer.PlayState() == AnimationPlayState::Finished) {
     return false;
   }
 
   ComputedTiming computedTiming = GetComputedTiming();
   return computedTiming.mPhase == ComputedTiming::AnimationPhase_Before ||
          computedTiming.mPhase == ComputedTiming::AnimationPhase_Active;
 }
 
 bool
-Animation::IsInEffect() const
+KeyframeEffectReadonly::IsInEffect() const
 {
   if (IsFinishedTransition()) {
     return false;
   }
 
   ComputedTiming computedTiming = GetComputedTiming();
   return computedTiming.mTimeFraction != ComputedTiming::kNullTimeFraction;
 }
 
 const AnimationProperty*
-Animation::GetAnimationOfProperty(nsCSSProperty aProperty) const
+KeyframeEffectReadonly::GetAnimationOfProperty(nsCSSProperty aProperty) const
 {
   for (size_t propIdx = 0, propEnd = mProperties.Length();
        propIdx != propEnd; ++propIdx) {
     if (aProperty == mProperties[propIdx].mProperty) {
       const AnimationProperty* result = &mProperties[propIdx];
       if (!result->mWinsInCascade) {
         result = nullptr;
       }
       return result;
     }
   }
   return nullptr;
 }
 
 bool
-Animation::HasAnimationOfProperties(const nsCSSProperty* aProperties,
-                                    size_t aPropertyCount) const
+KeyframeEffectReadonly::HasAnimationOfProperties(
+                          const nsCSSProperty* aProperties,
+                          size_t aPropertyCount) const
 {
   for (size_t i = 0; i < aPropertyCount; i++) {
     if (HasAnimationOfProperty(aProperties[i])) {
       return true;
     }
   }
   return false;
 }
 
 void
-Animation::ComposeStyle(nsRefPtr<css::AnimValuesStyleRule>& aStyleRule,
-                        nsCSSPropertySet& aSetProperties)
+KeyframeEffectReadonly::ComposeStyle(
+                          nsRefPtr<css::AnimValuesStyleRule>& aStyleRule,
+                          nsCSSPropertySet& aSetProperties)
 {
   ComputedTiming computedTiming = GetComputedTiming();
 
   // If the time fraction is null, we don't have fill data for the current
   // time so we shouldn't animate.
   if (computedTiming.mTimeFraction == ComputedTiming::kNullTimeFraction) {
     return;
   }
rename from dom/animation/Animation.h
rename to dom/animation/KeyframeEffect.h
--- a/dom/animation/Animation.h
+++ b/dom/animation/KeyframeEffect.h
@@ -1,15 +1,15 @@
 /* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
 /* 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 mozilla_dom_Animation_h
-#define mozilla_dom_Animation_h
+#ifndef mozilla_dom_KeyframeEffect_h
+#define mozilla_dom_KeyframeEffect_h
 
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsCSSPseudoElements.h"
 #include "nsIDocument.h"
 #include "nsWrapperCache.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/StickyTimeDuration.h"
@@ -179,55 +179,53 @@ struct AnimationProperty
     return !(*this == aOther);
   }
 };
 
 struct ElementPropertyTransition;
 
 namespace dom {
 
-class Animation : public nsWrapperCache
+class KeyframeEffectReadonly : public nsWrapperCache
 {
 public:
-  Animation(nsIDocument* aDocument,
-            Element* aTarget,
-            nsCSSPseudoElements::Type aPseudoType,
-            const AnimationTiming &aTiming,
-            const nsSubstring& aName)
+  KeyframeEffectReadonly(nsIDocument* aDocument,
+                         Element* aTarget,
+                         nsCSSPseudoElements::Type aPseudoType,
+                         const AnimationTiming &aTiming,
+                         const nsSubstring& aName)
     : mDocument(aDocument)
     , mTarget(aTarget)
     , mTiming(aTiming)
     , mName(aName)
     , mIsFinishedTransition(false)
     , mPseudoType(aPseudoType)
   {
     MOZ_ASSERT(aTarget, "null animation target is not yet supported");
   }
 
-  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(Animation)
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(Animation)
+  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(KeyframeEffectReadonly)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(KeyframeEffectReadonly)
 
   nsIDocument* GetParentObject() const { return mDocument; }
-  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+  virtual JSObject* WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aGivenProto) override;
 
-  // FIXME: If we succeed in moving transition-specific code to a type of
-  // AnimationEffect (as per the Web Animations API) we should remove these
-  // virtual methods.
   virtual ElementPropertyTransition* AsTransition() { return nullptr; }
   virtual const ElementPropertyTransition* AsTransition() const {
     return nullptr;
   }
 
-  // Animation interface
+  // KeyframeEffectReadonly interface
   Element* GetTarget() const {
     // Currently we only implement Element.getAnimations() which only
     // returns animations targetting Elements so this should never
     // be called for an animation that targets a pseudo-element.
     MOZ_ASSERT(mPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement,
-               "Requesting the target of an Animation that targets a"
+               "Requesting the target of a KeyframeEffect that targets a"
                " pseudo-element is not yet supported.");
     return mTarget;
   }
   void GetName(nsString& aRetVal) const
   {
     aRetVal = Name();
   }
 
@@ -328,17 +326,17 @@ public:
   // Updates |aStyleRule| with the animation values produced by this
   // Animation for the current time except any properties already contained
   // in |aSetProperties|.
   // Any updated properties are added to |aSetProperties|.
   void ComposeStyle(nsRefPtr<css::AnimValuesStyleRule>& aStyleRule,
                     nsCSSPropertySet& aSetProperties);
 
 protected:
-  virtual ~Animation() { }
+  virtual ~KeyframeEffectReadonly() { }
 
   // We use a document for a parent object since the other likely candidate,
   // the target element, can be empty.
   nsCOMPtr<nsIDocument> mDocument;
   nsCOMPtr<Element> mTarget;
   Nullable<TimeDuration> mParentTime;
 
   AnimationTiming mTiming;
@@ -349,9 +347,9 @@ protected:
   nsCSSPseudoElements::Type mPseudoType;
 
   InfallibleTArray<AnimationProperty> mProperties;
 };
 
 } // namespace dom
 } // namespace mozilla
 
-#endif // mozilla_dom_Animation_h
+#endif // mozilla_dom_KeyframeEffect_h
--- a/dom/animation/moz.build
+++ b/dom/animation/moz.build
@@ -3,30 +3,30 @@
 # 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/.
 
 MOCHITEST_MANIFESTS += ['test/mochitest.ini']
 MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
 
 EXPORTS.mozilla.dom += [
-    'Animation.h',
     'AnimationPlayer.h',
     'AnimationTimeline.h',
     'DocumentTimeline.h',
+    'KeyframeEffect.h',
 ]
 
 EXPORTS.mozilla += [
     'AnimationUtils.h',
     'PendingPlayerTracker.h',
 ]
 
 UNIFIED_SOURCES += [
-    'Animation.cpp',
     'AnimationPlayer.cpp',
     'AnimationTimeline.cpp',
     'DocumentTimeline.cpp',
+    'KeyframeEffect.cpp',
     'PendingPlayerTracker.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 FINAL_LIBRARY = 'xul'
rename from dom/animation/test/css-animations/test_animation-name.html
rename to dom/animation/test/css-animations/test_effect-name.html
rename from dom/animation/test/css-animations/test_animation-target.html
rename to dom/animation/test/css-animations/test_effect-target.html
rename from dom/animation/test/css-transitions/test_animation-name.html
rename to dom/animation/test/css-transitions/test_effect-name.html
rename from dom/animation/test/css-transitions/test_animation-target.html
rename to dom/animation/test/css-transitions/test_effect-target.html
--- a/dom/animation/test/mochitest.ini
+++ b/dom/animation/test/mochitest.ini
@@ -1,27 +1,27 @@
 [DEFAULT]
 support-files =
   testcommon.js
 
 [css-animations/test_animations-dynamic-changes.html]
-[css-animations/test_animation-name.html]
 [css-animations/test_animation-pausing.html]
 [css-animations/test_animation-player-currenttime.html]
 [css-animations/test_animation-player-finished.html]
 [css-animations/test_animation-player-playstate.html]
 [css-animations/test_animation-player-ready.html]
 [css-animations/test_animation-player-starttime.html]
-[css-animations/test_animation-target.html]
+[css-animations/test_effect-name.html]
+[css-animations/test_effect-target.html]
 [css-animations/test_element-get-animation-players.html]
 skip-if = buildapp == 'mulet'
-[css-transitions/test_animation-name.html]
 [css-transitions/test_animation-pausing.html]
 [css-transitions/test_animation-player-currenttime.html]
 [css-transitions/test_animation-player-ready.html]
-[css-transitions/test_animation-target.html]
 [css-transitions/test_animation-player-starttime.html]
+[css-transitions/test_effect-name.html]
+[css-transitions/test_effect-target.html]
 [css-transitions/test_element-get-animation-players.html]
 skip-if = buildapp == 'mulet'
 [document-timeline/test_document-timeline.html]
 [document-timeline/test_request_animation_frame.html]
 skip-if = buildapp == 'mulet'
 [mozilla/test_deferred_start.html]
--- a/dom/base/nsDOMMutationObserver.cpp
+++ b/dom/base/nsDOMMutationObserver.cpp
@@ -9,16 +9,18 @@
 #include "mozilla/dom/OwningNonNull.h"
 #include "nsError.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsContentUtils.h"
 #include "nsThreadUtils.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsTextFragment.h"
 #include "nsServiceManagerUtils.h"
+#include "mozilla/dom/AnimationPlayer.h"
+#include "mozilla/dom/KeyframeEffect.h"
 
 nsAutoTArray<nsRefPtr<nsDOMMutationObserver>, 4>*
   nsDOMMutationObserver::sScheduledMutationObservers = nullptr;
 
 nsDOMMutationObserver* nsDOMMutationObserver::sCurrentObserver = nullptr;
 
 uint32_t nsDOMMutationObserver::sMutationLevel = 0;
 uint64_t nsDOMMutationObserver::sCount = 0;
@@ -321,22 +323,22 @@ void nsMutationReceiver::NodeWillBeDestr
   NS_ASSERTION(!mParent, "Shouldn't have mParent here!");
   Disconnect(true);
 }
 
 void
 nsAnimationReceiver::RecordAnimationMutation(AnimationPlayer* aPlayer,
                                              AnimationMutation aMutationType)
 {
-  Animation* source = aPlayer->GetSource();
-  if (!source) {
+  KeyframeEffectReadonly* effect = aPlayer->GetSource();
+  if (!effect) {
     return;
   }
 
-  Element* animationTarget = source->GetTarget();
+  Element* animationTarget = effect->GetTarget();
   if (!animationTarget) {
     return;
   }
 
   if (!Animations() || !(Subtree() || animationTarget == Target()) ||
       animationTarget->ChromeOnlyAccess()) {
     return;
   }
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -19,18 +19,20 @@
 #include "nsPIDOMWindow.h"
 #include "nsDocument.h"
 #ifdef MOZ_XUL
 #include "nsXULElement.h"
 #endif
 #include "nsBindingManager.h"
 #include "nsGenericHTMLElement.h"
 #include "mozilla/Assertions.h"
+#include "mozilla/dom/AnimationPlayer.h"
 #include "mozilla/dom/HTMLImageElement.h"
 #include "mozilla/dom/HTMLMediaElement.h"
+#include "mozilla/dom/KeyframeEffect.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsObjectLoadingContent.h"
 #include "nsDOMMutationObserver.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/HTMLTemplateElement.h"
 #include "mozilla/dom/ShadowRoot.h"
 
 using namespace mozilla;
@@ -211,33 +213,33 @@ nsNodeUtils::ContentRemoved(nsINode* aCo
   IMPL_MUTATION_NOTIFICATION(ContentRemoved, aContainer,
                              (document, container, aChild, aIndexInContainer,
                               aPreviousSibling));
 }
 
 static inline Element*
 GetTarget(AnimationPlayer* aPlayer)
 {
-  Animation* source = aPlayer->GetSource();
-  if (!source) {
+  KeyframeEffectReadonly* effect = aPlayer->GetSource();
+  if (!effect) {
     return nullptr;
   }
 
   Element* target;
   nsCSSPseudoElements::Type pseudoType;
-  source->GetTarget(target, pseudoType);
+  effect->GetTarget(target, pseudoType);
 
   // If the animation targets a pseudo-element, we don't dispatch
   // notifications for it.  (In the future we will have PseudoElement
   // objects we can use as the target of the notifications.)
   if (pseudoType != nsCSSPseudoElements::ePseudo_NotPseudoElement) {
     return nullptr;
   }
 
-  return source->GetTarget();
+  return effect->GetTarget();
 }
 
 void
 nsNodeUtils::AnimationAdded(AnimationPlayer* aPlayer)
 {
   Element* target = GetTarget(aPlayer);
   if (!target) {
     return;
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -127,18 +127,16 @@ var interfaceNamesInGlobalScope =
     {name: "MozAbortablePromise", pref: "dom.abortablepromise.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "AlarmsManager", pref: "dom.mozAlarms.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "AnalyserNode",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "AnimationEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "Animation", pref: "dom.animations-api.core.enabled"},
-// IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "AnimationPlayer", pref: "dom.animations-api.core.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "AnimationTimeline", pref: "dom.animations-api.core.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "Attr",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "Audio",
 // IMPORTANT: Do not change this list without review from a DOM peer!
@@ -646,16 +644,18 @@ var interfaceNamesInGlobalScope =
     {name: "InputPortManager", b2g: true, pref: "dom.inputport.enabled", permission: ["inputport"]},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "InstallTrigger", b2g: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "KeyEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "KeyboardEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
+    {name: "KeyframeEffectReadonly", pref: "dom.animations-api.core.enabled"},
+// IMPORTANT: Do not change this list without review from a DOM peer!
     "LocalMediaStream",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "Location",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MediaDeviceInfo",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MediaDevices",
 // IMPORTANT: Do not change this list without review from a DOM peer!
--- a/dom/webidl/AnimationPlayer.webidl
+++ b/dom/webidl/AnimationPlayer.webidl
@@ -9,20 +9,21 @@
  * Copyright © 2014 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 enum AnimationPlayState { "idle", "pending", "running", "paused", "finished" };
 
 [Func="nsDocument::IsWebAnimationsEnabled"]
 interface AnimationPlayer {
-  // Bug 1049975
-  //           attribute AnimationNode?     source;
+  // Bug 1049975: Make 'source' writeable
+  // FIXME: In a later patch in this series we'll rename KeyframeEffectReadonly
+  // with AnimationEffectReadonly
   [Pure]
-  readonly attribute Animation? source;
+  readonly attribute KeyframeEffectReadonly? source;
   readonly attribute AnimationTimeline timeline;
   [BinaryName="startTimeAsDouble"]
   attribute double? startTime;
   [SetterThrows, BinaryName="currentTimeAsDouble"]
   attribute double? currentTime;
 
            attribute double             playbackRate;
   [BinaryName="playStateFromJS"]
rename from dom/webidl/Animation.webidl
rename to dom/webidl/KeyframeEffect.webidl
--- a/dom/webidl/Animation.webidl
+++ b/dom/webidl/KeyframeEffect.webidl
@@ -1,18 +1,24 @@
 /* -*- Mode: IDL; 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/.
  *
  * The origin of this IDL file is
- * http://dev.w3.org/fxtf/web-animations/#the-animation-interface
+ * http://w3c.github.io/web-animations/#the-keyframeeffect-interfaces
  *
- * Copyright © 2014 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * Copyright © 2015 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
-[Func="nsDocument::IsWebAnimationsEnabled"]
-interface Animation {
-  // FIXME: This should be writeable (bug 1067769)
+[HeaderFile="mozilla/dom/KeyframeEffect.h",
+ Func="nsDocument::IsWebAnimationsEnabled"]
+interface KeyframeEffectReadonly {
   readonly attribute Element?  target;
   readonly attribute DOMString name;
+  // Not yet implemented:
+  // readonly attribute IterationCompositeOperation iterationComposite;
+  // readonly attribute CompositeOperation          composite;
+  // readonly attribute DOMString                   spacing;
+  // KeyframeEffect             clone();
+  // sequence<ComputedKeyframe> getFrames ();
 };
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -17,17 +17,16 @@ PREPROCESSED_WEBIDL_FILES = [
 
 WEBIDL_FILES = [
     'AbortablePromise.webidl',
     'AbstractWorker.webidl',
     'ActivityRequestHandler.webidl',
     'AlarmsManager.webidl',
     'AnalyserNode.webidl',
     'Animatable.webidl',
-    'Animation.webidl',
     'AnimationEvent.webidl',
     'AnimationPlayer.webidl',
     'AnimationTimeline.webidl',
     'AnonymousContent.webidl',
     'AppInfo.webidl',
     'AppNotificationServiceOptions.webidl',
     'Apps.webidl',
     'APZTestData.webidl',
@@ -258,16 +257,17 @@ WEBIDL_FILES = [
     'InspectorUtils.webidl',
     'InstallEvent.webidl',
     'InterAppConnection.webidl',
     'InterAppConnectionRequest.webidl',
     'InterAppMessagePort.webidl',
     'KeyAlgorithm.webidl',
     'KeyboardEvent.webidl',
     'KeyEvent.webidl',
+    'KeyframeEffect.webidl',
     'LegacyQueryInterface.webidl',
     'LinkStyle.webidl',
     'ListBoxObject.webidl',
     'LocalMediaStream.webidl',
     'Location.webidl',
     'MediaDeviceInfo.webidl',
     'MediaDevices.webidl',
     'MediaElementAudioSourceNode.webidl',
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -9,16 +9,17 @@
 #include "apz/src/AsyncPanZoomController.h"
 #include "FrameMetrics.h"               // for FrameMetrics
 #include "LayerManagerComposite.h"      // for LayerManagerComposite, etc
 #include "Layers.h"                     // for Layer, ContainerLayer, etc
 #include "gfxPoint.h"                   // for gfxPoint, gfxSize
 #include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue, etc
 #include "mozilla/WidgetUtils.h"        // for ComputeTransformForRotation
 #include "mozilla/dom/AnimationPlayer.h" // for AnimationPlayer
+#include "mozilla/dom/KeyframeEffect.h" // for KeyframeEffectReadonly
 #include "mozilla/gfx/BaseRect.h"       // for BaseRect
 #include "mozilla/gfx/Point.h"          // for RoundedToInt, PointTyped
 #include "mozilla/gfx/Rect.h"           // for RoundedToInt, RectTyped
 #include "mozilla/gfx/ScaleFactor.h"    // for ScaleFactor
 #include "mozilla/layers/Compositor.h"  // for Compositor
 #include "mozilla/layers/CompositorParent.h" // for CompositorParent, etc
 #include "mozilla/layers/LayerMetricsWrapper.h" // for LayerMetricsWrapper
 #include "nsCoord.h"                    // for NSAppUnitsToFloatPixels, etc
@@ -476,17 +477,17 @@ SampleAnimations(Layer* aLayer, TimeStam
     timing.mDirection = animation.direction();
     // Animations typically only run on the compositor during their active
     // interval but if we end up sampling them outside that range (for
     // example, while they are waiting to be removed) we currently just
     // assume that we should fill.
     timing.mFillMode = NS_STYLE_ANIMATION_FILL_MODE_BOTH;
 
     ComputedTiming computedTiming =
-      dom::Animation::GetComputedTimingAt(
+      dom::KeyframeEffectReadonly::GetComputedTimingAt(
         Nullable<TimeDuration>(elapsedDuration), timing);
 
     MOZ_ASSERT(0.0 <= computedTiming.mTimeFraction &&
                computedTiming.mTimeFraction <= 1.0,
                "time fraction should be in [0-1]");
 
     int segmentIndex = 0;
     AnimationSegment* segment = animation.segments().Elements();
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -12,16 +12,17 @@
 
 #include "nsDisplayList.h"
 
 #include <stdint.h>
 #include <algorithm>
 
 #include "gfxUtils.h"
 #include "mozilla/dom/TabChild.h"
+#include "mozilla/dom/KeyframeEffect.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/layers/PLayerTransaction.h"
 #include "nsCSSRendering.h"
 #include "nsRenderingContext.h"
 #include "nsISelectionController.h"
 #include "nsIPresShell.h"
 #include "nsRegion.h"
 #include "nsStyleStructInlines.h"
@@ -415,20 +416,20 @@ AddAnimationsForProperty(nsIFrame* aFram
              "inconsistent property flags");
 
   // Add from first to last (since last overrides)
   for (size_t playerIdx = 0; playerIdx < aPlayers.Length(); playerIdx++) {
     AnimationPlayer* player = aPlayers[playerIdx];
     if (!player->IsPlaying()) {
       continue;
     }
-    dom::Animation* anim = player->GetSource();
-    MOZ_ASSERT(anim, "A playing player should have a source animation");
+    dom::KeyframeEffectReadonly* effect = player->GetSource();
+    MOZ_ASSERT(effect, "A playing player should have a target effect");
     const AnimationProperty* property =
-      anim->GetAnimationOfProperty(aProperty);
+      effect->GetAnimationOfProperty(aProperty);
     if (!property) {
       continue;
     }
 
     // Note that if mWinsInCascade on property was  false,
     // GetAnimationOfProperty returns null instead.
     // This is what we want, since if we have an animation or transition
     // that isn't actually winning in the CSS cascade, we don't want to
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -55,16 +55,17 @@
 #include "mozilla/dom/HTMLCanvasElement.h"
 #include "nsICanvasRenderingContextInternal.h"
 #include "gfxPlatform.h"
 #include <algorithm>
 #include <limits>
 #include "mozilla/dom/HTMLVideoElement.h"
 #include "mozilla/dom/HTMLImageElement.h"
 #include "mozilla/dom/DOMRect.h"
+#include "mozilla/dom/KeyframeEffect.h"
 #include "imgIRequest.h"
 #include "nsIImageLoadingContent.h"
 #include "nsCOMPtr.h"
 #include "nsCSSProps.h"
 #include "nsListControlFrame.h"
 #include "mozilla/dom/Element.h"
 #include "nsCanvasFrame.h"
 #include "gfxDrawable.h"
@@ -499,19 +500,19 @@ GetMinAndMaxScaleForAnimationProperty(ns
                                       gfxSize& aMaxScale,
                                       gfxSize& aMinScale)
 {
   for (size_t playerIdx = aPlayers->mPlayers.Length(); playerIdx-- != 0; ) {
     AnimationPlayer* player = aPlayers->mPlayers[playerIdx];
     if (!player->GetSource() || player->GetSource()->IsFinishedTransition()) {
       continue;
     }
-    dom::Animation* anim = player->GetSource();
-    for (size_t propIdx = anim->Properties().Length(); propIdx-- != 0; ) {
-      AnimationProperty& prop = anim->Properties()[propIdx];
+    dom::KeyframeEffectReadonly* effect = player->GetSource();
+    for (size_t propIdx = effect->Properties().Length(); propIdx-- != 0; ) {
+      AnimationProperty& prop = effect->Properties()[propIdx];
       if (prop.mProperty == eCSSProperty_transform) {
         for (uint32_t segIdx = prop.mSegments.Length(); segIdx-- != 0; ) {
           AnimationPropertySegment& segment = prop.mSegments[segIdx];
           gfxSize from = GetScaleForValue(segment.mFromValue,
                                           aContent->GetPrimaryFrame());
           aMaxScale.width = std::max<float>(aMaxScale.width, from.width);
           aMaxScale.height = std::max<float>(aMaxScale.height, from.height);
           aMinScale.width = std::min<float>(aMinScale.width, from.width);
--- a/layout/style/AnimationCommon.cpp
+++ b/layout/style/AnimationCommon.cpp
@@ -16,25 +16,26 @@
 #include "nsStyleContext.h"
 #include "nsIFrame.h"
 #include "nsLayoutUtils.h"
 #include "mozilla/LookAndFeel.h"
 #include "Layers.h"
 #include "FrameLayerBuilder.h"
 #include "nsDisplayList.h"
 #include "mozilla/MemoryReporting.h"
+#include "mozilla/dom/KeyframeEffect.h"
 #include "RestyleManager.h"
 #include "nsRuleProcessorData.h"
 #include "nsStyleSet.h"
 #include "nsStyleChangeList.h"
 
 
 using mozilla::layers::Layer;
 using mozilla::dom::AnimationPlayer;
-using mozilla::dom::Animation;
+using mozilla::dom::KeyframeEffectReadonly;
 
 namespace mozilla {
 
 /* static */ bool
 IsGeometricProperty(nsCSSProperty aProperty)
 {
   switch (aProperty) {
     case eCSSProperty_bottom:
@@ -600,43 +601,43 @@ AnimationPlayerCollection::CanPerformOnC
   }
 
   for (size_t playerIdx = mPlayers.Length(); playerIdx-- != 0; ) {
     const AnimationPlayer* player = mPlayers[playerIdx];
     if (!player->IsPlaying()) {
       continue;
     }
 
-    const Animation* anim = player->GetSource();
-    MOZ_ASSERT(anim, "A playing player should have a source animation");
+    const KeyframeEffectReadonly* effect = player->GetSource();
+    MOZ_ASSERT(effect, "A playing player should have an effect");
 
-    for (size_t propIdx = 0, propEnd = anim->Properties().Length();
+    for (size_t propIdx = 0, propEnd = effect->Properties().Length();
          propIdx != propEnd; ++propIdx) {
-      if (IsGeometricProperty(anim->Properties()[propIdx].mProperty)) {
+      if (IsGeometricProperty(effect->Properties()[propIdx].mProperty)) {
         aFlags = CanAnimateFlags(aFlags | CanAnimate_HasGeometricProperty);
         break;
       }
     }
   }
 
   bool existsProperty = false;
   for (size_t playerIdx = mPlayers.Length(); playerIdx-- != 0; ) {
     const AnimationPlayer* player = mPlayers[playerIdx];
     if (!player->IsPlaying()) {
       continue;
     }
 
-    const Animation* anim = player->GetSource();
-    MOZ_ASSERT(anim, "A playing player should have a source animation");
+    const KeyframeEffectReadonly* effect = player->GetSource();
+    MOZ_ASSERT(effect, "A playing player should have an effect");
 
-    existsProperty = existsProperty || anim->Properties().Length() > 0;
+    existsProperty = existsProperty || effect->Properties().Length() > 0;
 
-    for (size_t propIdx = 0, propEnd = anim->Properties().Length();
+    for (size_t propIdx = 0, propEnd = effect->Properties().Length();
          propIdx != propEnd; ++propIdx) {
-      const AnimationProperty& prop = anim->Properties()[propIdx];
+      const AnimationProperty& prop = effect->Properties()[propIdx];
       if (!CanAnimatePropertyOnCompositor(mElement,
                                           prop.mProperty,
                                           aFlags) ||
           IsCompositorAnimationDisabledForFrame(frame)) {
         return false;
       }
     }
   }
@@ -673,19 +674,19 @@ AnimationPlayerCollection::PostUpdateLay
   }
 }
 
 bool
 AnimationPlayerCollection::HasAnimationOfProperty(
   nsCSSProperty aProperty) const
 {
   for (size_t playerIdx = mPlayers.Length(); playerIdx-- != 0; ) {
-    const Animation* anim = mPlayers[playerIdx]->GetSource();
-    if (anim && anim->HasAnimationOfProperty(aProperty) &&
-        !anim->IsFinishedTransition()) {
+    const KeyframeEffectReadonly* effect = mPlayers[playerIdx]->GetSource();
+    if (effect && effect->HasAnimationOfProperty(aProperty) &&
+        !effect->IsFinishedTransition()) {
       return true;
     }
   }
   return false;
 }
 
 mozilla::dom::Element*
 AnimationPlayerCollection::GetElementToRestyle() const
@@ -923,20 +924,20 @@ AnimationPlayerCollection::HasCurrentAni
 
 bool
 AnimationPlayerCollection::HasCurrentAnimationsForProperties(
                               const nsCSSProperty* aProperties,
                               size_t aPropertyCount) const
 {
   for (size_t playerIdx = mPlayers.Length(); playerIdx-- != 0; ) {
     const AnimationPlayer& player = *mPlayers[playerIdx];
-    const Animation* anim = player.GetSource();
-    if (anim &&
-        anim->IsCurrent(player) &&
-        anim->HasAnimationOfProperties(aProperties, aPropertyCount)) {
+    const KeyframeEffectReadonly* effect = player.GetSource();
+    if (effect &&
+        effect->IsCurrent(player) &&
+        effect->HasAnimationOfProperties(aProperties, aPropertyCount)) {
       return true;
     }
   }
 
   return false;
 }
 
 }
--- a/layout/style/nsAnimationManager.cpp
+++ b/layout/style/nsAnimationManager.cpp
@@ -4,32 +4,33 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsAnimationManager.h"
 #include "nsTransitionManager.h"
 
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/StyleAnimationValue.h"
+#include "mozilla/dom/KeyframeEffect.h"
 
 #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::dom::KeyframeEffectReadonly;
 using mozilla::CSSAnimationPlayer;
 
 mozilla::dom::Promise*
 CSSAnimationPlayer::GetReady(ErrorResult& aRv)
 {
   FlushStyle();
   return AnimationPlayer::GetReady(aRv);
 }
@@ -350,23 +351,23 @@ nsAnimationManager::CheckAnimationRule(n
           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();
+          KeyframeEffectReadonly* oldEffect = oldPlayer->GetSource();
+          KeyframeEffectReadonly* newEffect = newPlayer->GetSource();
           animationChanged =
-            oldAnim->Timing() != newAnim->Timing() ||
-            oldAnim->Properties() != newAnim->Properties();
-          oldAnim->Timing() = newAnim->Timing();
-          oldAnim->Properties() = newAnim->Properties();
+            oldEffect->Timing() != newEffect->Timing() ||
+            oldEffect->Properties() != newEffect->Properties();
+          oldEffect->Timing() = newEffect->Timing();
+          oldEffect->Properties() = newEffect->Properties();
         }
 
         // Reset compositor state so animation will be re-synchronized.
         oldPlayer->ClearIsRunningOnCompositor();
 
         // Handle changes in play state.
         // CSSAnimationPlayer takes care of override behavior so that,
         // for example, if the author has called pause(), that will
@@ -522,20 +523,21 @@ nsAnimationManager::BuildAnimations(nsSt
     AnimationTiming timing;
     timing.mIterationDuration =
       TimeDuration::FromMilliseconds(src.GetDuration());
     timing.mDelay = TimeDuration::FromMilliseconds(src.GetDelay());
     timing.mIterationCount = src.GetIterationCount();
     timing.mDirection = src.GetDirection();
     timing.mFillMode = src.GetFillMode();
 
-    nsRefPtr<Animation> destAnim =
-      new Animation(mPresContext->Document(), aTarget,
-                    aStyleContext->GetPseudoType(), timing, src.GetName());
-    dest->SetSource(destAnim);
+    nsRefPtr<KeyframeEffectReadonly> destEffect =
+      new KeyframeEffectReadonly(mPresContext->Document(), aTarget,
+                                 aStyleContext->GetPseudoType(), timing,
+                                 src.GetName());
+    dest->SetSource(destEffect);
 
     // Even in the case where we call PauseFromStyle below, we still need to
     // call PlayFromStyle first. This is because a newly-created player is idle
     // and has no effect until it is played (or otherwise given a start time).
     dest->PlayFromStyle();
 
     if (src.GetPlayState() == NS_STYLE_ANIMATION_PLAY_STATE_PAUSED) {
       dest->PauseFromStyle();
@@ -621,17 +623,17 @@ nsAnimationManager::BuildAnimations(nsSt
           // Replace previous occurrence of same key.
           keyframesWithProperty[keyframesWithProperty.Length() - 1] = kfIdx;
         } else {
           keyframesWithProperty.AppendElement(kfIdx);
         }
         lastKey = kf.mKey;
       }
 
-      AnimationProperty &propData = *destAnim->Properties().AppendElement();
+      AnimationProperty &propData = *destEffect->Properties().AppendElement();
       propData.mProperty = prop;
       propData.mWinsInCascade = true;
 
       KeyframeData *fromKeyframe = nullptr;
       nsRefPtr<nsStyleContext> fromContext;
       bool interpolated = true;
       for (uint32_t wpIdx = 0, wpEnd = keyframesWithProperty.Length();
            wpIdx != wpEnd; ++wpIdx) {
@@ -684,18 +686,18 @@ nsAnimationManager::BuildAnimations(nsSt
 
       // If we failed to build any segments due to inability to
       // interpolate, remove the property from the animation.  (It's not
       // clear if this is the right thing to do -- we could run some of
       // the segments, but it's really not clear whether we should skip
       // values (which?) or skip segments, so best to skip the whole
       // thing for now.)
       if (!interpolated) {
-        destAnim->Properties().RemoveElementAt(
-          destAnim->Properties().Length() - 1);
+        destEffect->Properties().RemoveElementAt(
+          destEffect->Properties().Length() - 1);
       }
     }
   }
 }
 
 bool
 nsAnimationManager::BuildSegment(InfallibleTArray<AnimationPropertySegment>&
                                    aSegments,
@@ -748,24 +750,24 @@ nsAnimationManager::UpdateCascadeResults
   nsAutoTArray<nsCSSProperty, 2> propertiesToTrack;
 
   {
     nsCSSPropertySet propertiesToTrackAsSet;
 
     for (size_t playerIdx = aElementAnimations->mPlayers.Length();
          playerIdx-- != 0; ) {
       const AnimationPlayer* player = aElementAnimations->mPlayers[playerIdx];
-      const Animation* anim = player->GetSource();
-      if (!anim) {
+      const KeyframeEffectReadonly* effect = player->GetSource();
+      if (!effect) {
         continue;
       }
 
-      for (size_t propIdx = 0, propEnd = anim->Properties().Length();
+      for (size_t propIdx = 0, propEnd = effect->Properties().Length();
            propIdx != propEnd; ++propIdx) {
-        const AnimationProperty& prop = anim->Properties()[propIdx];
+        const AnimationProperty& prop = effect->Properties()[propIdx];
         // We only bother setting mWinsInCascade for properties that we
         // can animate on the compositor.
         if (nsCSSProps::PropHasFlags(prop.mProperty,
                                      CSS_PROPERTY_CAN_ANIMATE_ON_COMPOSITOR)) {
           if (!propertiesToTrackAsSet.HasProperty(prop.mProperty)) {
             propertiesToTrack.AppendElement(prop.mProperty);
             propertiesToTrackAsSet.AddProperty(prop.mProperty);
           }
@@ -797,27 +799,27 @@ nsAnimationManager::UpdateCascadeResults
    * currently in effect.
    */
 
   bool changed = false;
   for (size_t playerIdx = aElementAnimations->mPlayers.Length();
        playerIdx-- != 0; ) {
     CSSAnimationPlayer* player =
       aElementAnimations->mPlayers[playerIdx]->AsCSSAnimationPlayer();
-    Animation* anim = player->GetSource();
+    KeyframeEffectReadonly* effect = player->GetSource();
 
     player->mInEffectForCascadeResults = player->HasInEffectSource();
 
-    if (!anim) {
+    if (!effect) {
       continue;
     }
 
-    for (size_t propIdx = 0, propEnd = anim->Properties().Length();
+    for (size_t propIdx = 0, propEnd = effect->Properties().Length();
          propIdx != propEnd; ++propIdx) {
-      AnimationProperty& prop = anim->Properties()[propIdx];
+      AnimationProperty& prop = effect->Properties()[propIdx];
       // We only bother setting mWinsInCascade for properties that we
       // can animate on the compositor.
       if (nsCSSProps::PropHasFlags(prop.mProperty,
                                    CSS_PROPERTY_CAN_ANIMATE_ON_COMPOSITOR)) {
         bool newWinsInCascade =
           !propertiesOverridden.HasProperty(prop.mProperty);
         if (newWinsInCascade != prop.mWinsInCascade) {
           changed = true;
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -29,30 +29,30 @@
 #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 mozilla::dom::KeyframeEffectReadonly;
 
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::css;
 
 const nsString&
 ElementPropertyTransition::Name() const
 {
    if (!mName.Length()) {
      const_cast<ElementPropertyTransition*>(this)->mName =
        NS_ConvertUTF8toUTF16(nsCSSProps::GetStringValue(TransitionProperty()));
    }
-   return dom::Animation::Name();
+   return dom::KeyframeEffectReadonly::Name();
 }
 
 double
 ElementPropertyTransition::CurrentValuePortion() const
 {
   // It would be easy enough to handle finished transitions by using a time
   // fraction of 1 but currently we should not be called for finished
   // transitions.
@@ -316,22 +316,22 @@ nsTransitionManager::StyleContextChanged
 
     AnimationPlayerPtrArray& players = collection->mPlayers;
     size_t i = players.Length();
     MOZ_ASSERT(i != 0, "empty transitions list?");
     StyleAnimationValue currentValue;
     do {
       --i;
       AnimationPlayer* player = players[i];
-      dom::Animation* anim = player->GetSource();
-      MOZ_ASSERT(anim && anim->Properties().Length() == 1,
+      dom::KeyframeEffectReadonly* effect = player->GetSource();
+      MOZ_ASSERT(effect && effect->Properties().Length() == 1,
                  "Should have one animation property for a transition");
-      MOZ_ASSERT(anim && anim->Properties()[0].mSegments.Length() == 1,
+      MOZ_ASSERT(effect && effect->Properties()[0].mSegments.Length() == 1,
                  "Animation property should have one segment for a transition");
-      const AnimationProperty& prop = anim->Properties()[0];
+      const AnimationProperty& prop = effect->Properties()[0];
       const AnimationPropertySegment& segment = prop.mSegments[0];
           // properties no longer in 'transition-property'
       if ((checkProperties &&
            !allTransitionProperties.HasProperty(prop.mProperty)) ||
           // properties whose computed values changed but for which we
           // did not start a new transition (because delay and
           // duration are both zero, or because the new value is not
           // interpolable); a new transition would have segment.mToValue
--- a/layout/style/nsTransitionManager.h
+++ b/layout/style/nsTransitionManager.h
@@ -5,18 +5,18 @@
 
 /* Code to start and animate CSS transitions. */
 
 #ifndef nsTransitionManager_h_
 #define nsTransitionManager_h_
 
 #include "mozilla/Attributes.h"
 #include "mozilla/MemoryReporting.h"
-#include "mozilla/dom/Animation.h"
 #include "mozilla/dom/AnimationPlayer.h"
+#include "mozilla/dom/KeyframeEffect.h"
 #include "AnimationCommon.h"
 #include "nsCSSPseudoElements.h"
 
 class nsStyleContext;
 class nsPresContext;
 class nsCSSPropertySet;
 struct ElementDependentRuleProcessorData;
 
@@ -25,23 +25,24 @@ struct StyleTransition;
 }
 
 /*****************************************************************************
  * Per-Element data                                                          *
  *****************************************************************************/
 
 namespace mozilla {
 
-struct ElementPropertyTransition : public dom::Animation
+struct ElementPropertyTransition : public dom::KeyframeEffectReadonly
 {
   ElementPropertyTransition(nsIDocument* aDocument,
                             dom::Element* aTarget,
                             nsCSSPseudoElements::Type aPseudoType,
                             const AnimationTiming &aTiming)
-    : dom::Animation(aDocument, aTarget, aPseudoType, aTiming, EmptyString())
+    : dom::KeyframeEffectReadonly(aDocument, aTarget, aPseudoType,
+                                  aTiming, EmptyString())
   { }
 
   virtual ElementPropertyTransition* AsTransition() { return this; }
   virtual const ElementPropertyTransition* AsTransition() const { return this; }
 
   virtual const nsString& Name() const override;
 
   nsCSSProperty TransitionProperty() const {