Bug 1040543 part 1 - Move/Rename ElementAnimations to dom::AnimationPlayer; r=bz
authorBrian Birtles <birtles@gmail.com>
Sun, 10 Aug 2014 17:06:44 +1000
changeset 198783 414eb2e950575e99de58028c2010e6eca236c19e
parent 198782 9bce42c5db257d109fe116fa11bf7b20b329aacb
child 198784 daca3c0d2c85d6deaa0c9332150d9937988067be
push id27286
push usernigelbabu@gmail.com
push dateMon, 11 Aug 2014 06:26:45 +0000
treeherdermozilla-central@8c4a1b3a2a8b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1040543
milestone34.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 1040543 part 1 - Move/Rename ElementAnimations to dom::AnimationPlayer; r=bz This patch renames mozilla::ElementAnimations to mozilla::dom::AnimationPlayer and moves the code from layout/style/AnimationCommon.cpp to dom/animation/AnimationPlayer.cpp. It also moves various helper classes needed by AnimationPlayer to AnimationPlayer.cpp and moves them from the mozilla::css namespace to the mozilla namespace. Beyond that, there are no functional changes contained in this patch. The renaming of various members and variables that used to refer to ElementAnimation objects but now refer to AnimationPlayer objects--to give them a more appropriate name--is performed in a subsequent patch.
content/base/public/Element.h
content/base/src/Element.cpp
dom/animation/AnimationPlayer.cpp
dom/animation/AnimationPlayer.h
dom/animation/moz.build
dom/bindings/Bindings.conf
gfx/layers/Layers.cpp
gfx/layers/Layers.h
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/composite/AsyncCompositionManager.cpp
layout/base/nsDisplayList.cpp
layout/base/nsLayoutUtils.cpp
layout/style/AnimationCommon.cpp
layout/style/AnimationCommon.h
layout/style/nsAnimationManager.cpp
layout/style/nsTransitionManager.cpp
layout/style/nsTransitionManager.h
--- a/content/base/public/Element.h
+++ b/content/base/public/Element.h
@@ -110,25 +110,25 @@ enum {
 };
 
 #undef ELEMENT_FLAG_BIT
 
 // Make sure we have space for our bits
 ASSERT_NODE_FLAGS_SPACE(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET);
 
 namespace mozilla {
-class ElementAnimation;
 class EventChainPostVisitor;
 class EventChainPreVisitor;
 class EventChainVisitor;
 class EventListenerManager;
 class EventStateManager;
 
 namespace dom {
 
+class AnimationPlayer;
 class Link;
 class UndoManager;
 class DOMRect;
 class DOMRectList;
 class DestinationInsertionPointList;
 
 // IID for the dom::Element interface
 #define NS_ELEMENT_IID \
@@ -798,17 +798,17 @@ public:
   {
     return false;
   }
 
   virtual void SetUndoScope(bool aUndoScope, ErrorResult& aError)
   {
   }
 
-  void GetAnimationPlayers(nsTArray<nsRefPtr<ElementAnimation> >& aPlayers);
+  void GetAnimationPlayers(nsTArray<nsRefPtr<AnimationPlayer> >& aPlayers);
 
   NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML);
   virtual void SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError);
   void GetOuterHTML(nsAString& aOuterHTML);
   void SetOuterHTML(const nsAString& aOuterHTML, ErrorResult& aError);
   void InsertAdjacentHTML(const nsAString& aPosition, const nsAString& aText,
                           ErrorResult& aError);
 
--- a/content/base/src/Element.cpp
+++ b/content/base/src/Element.cpp
@@ -9,16 +9,17 @@
  * of DOM Core's nsIDOMElement, implements nsIContent, provides
  * utility methods for subclasses, and so forth.
  */
 
 #include "mozilla/dom/ElementInlines.h"
 
 #include "AnimationCommon.h"
 #include "mozilla/DebugOnly.h"
+#include "mozilla/dom/AnimationPlayer.h"
 #include "mozilla/dom/Attr.h"
 #include "nsDOMAttributeMap.h"
 #include "nsIAtom.h"
 #include "nsIContentInlines.h"
 #include "mozilla/dom/NodeInfo.h"
 #include "nsIDocumentInlines.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMDocument.h"
@@ -2860,32 +2861,32 @@ Element::MozRequestFullScreen()
 
 void
 Element::MozRequestPointerLock()
 {
   OwnerDoc()->RequestPointerLock(this);
 }
 
 void
-Element::GetAnimationPlayers(nsTArray<nsRefPtr<ElementAnimation> >& aPlayers)
+Element::GetAnimationPlayers(nsTArray<nsRefPtr<AnimationPlayer> >& aPlayers)
 {
   nsIAtom* properties[] = { nsGkAtoms::transitionsProperty,
                             nsGkAtoms::animationsProperty };
   for (size_t propIdx = 0; propIdx < MOZ_ARRAY_LENGTH(properties);
        propIdx++) {
     ElementAnimationCollection* collection =
       static_cast<ElementAnimationCollection*>(
         GetProperty(properties[propIdx]));
     if (!collection) {
       continue;
     }
     for (size_t animIdx = 0;
          animIdx < collection->mAnimations.Length();
          animIdx++) {
-      ElementAnimation* anim = collection->mAnimations[animIdx];
+      AnimationPlayer* anim = collection->mAnimations[animIdx];
       if (anim->IsCurrent()) {
         aPlayers.AppendElement(anim);
       }
     }
   }
 }
 
 NS_IMETHODIMP
copy from layout/style/AnimationCommon.cpp
copy to dom/animation/AnimationPlayer.cpp
--- a/layout/style/AnimationCommon.cpp
+++ b/dom/animation/AnimationPlayer.cpp
@@ -1,264 +1,18 @@
 /* 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 "AnimationCommon.h"
-#include "nsTransitionManager.h"
-#include "nsAnimationManager.h"
-
+#include "AnimationPlayer.h"
 #include "mozilla/dom/AnimationPlayerBinding.h"
-#include "ActiveLayerTracker.h"
-#include "gfxPlatform.h"
-#include "nsRuleData.h"
-#include "nsCSSPropertySet.h"
-#include "nsCSSValue.h"
-#include "nsCycleCollectionParticipant.h"
-#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 "RestyleManager.h"
-#include "nsStyleSet.h"
-#include "nsStyleChangeList.h"
-
-
-using mozilla::layers::Layer;
 
 namespace mozilla {
 
-/* static */ bool
-IsGeometricProperty(nsCSSProperty aProperty)
-{
-  switch (aProperty) {
-    case eCSSProperty_bottom:
-    case eCSSProperty_height:
-    case eCSSProperty_left:
-    case eCSSProperty_right:
-    case eCSSProperty_top:
-    case eCSSProperty_width:
-      return true;
-    default:
-      return false;
-  }
-}
-
-namespace css {
-
-CommonAnimationManager::CommonAnimationManager(nsPresContext *aPresContext)
-  : mPresContext(aPresContext)
-{
-  PR_INIT_CLIST(&mElementCollections);
-}
-
-CommonAnimationManager::~CommonAnimationManager()
-{
-  NS_ABORT_IF_FALSE(!mPresContext, "Disconnect should have been called");
-}
-
-void
-CommonAnimationManager::Disconnect()
-{
-  // Content nodes might outlive the transition or animation manager.
-  RemoveAllElementCollections();
-
-  mPresContext = nullptr;
-}
-
-void
-CommonAnimationManager::RemoveAllElementCollections()
-{
-  while (!PR_CLIST_IS_EMPTY(&mElementCollections)) {
-    ElementAnimationCollection* head =
-      static_cast<ElementAnimationCollection*>(
-        PR_LIST_HEAD(&mElementCollections));
-    head->Destroy();
-  }
-}
-
-ElementAnimationCollection*
-CommonAnimationManager::GetAnimationsForCompositor(nsIContent* aContent,
-                                                   nsIAtom* aElementProperty,
-                                                   nsCSSProperty aProperty)
-{
-  if (!aContent->MayHaveAnimations())
-    return nullptr;
-  ElementAnimationCollection* collection =
-    static_cast<ElementAnimationCollection*>(
-      aContent->GetProperty(aElementProperty));
-  if (!collection ||
-      !collection->HasAnimationOfProperty(aProperty) ||
-      !collection->CanPerformOnCompositorThread(
-        ElementAnimationCollection::CanAnimate_AllowPartial)) {
-    return nullptr;
-  }
-
-  // This animation can be done on the compositor.
-  // Mark the frame as active, in case we are able to throttle this animation.
-  nsIFrame* frame = nsLayoutUtils::GetStyleFrame(collection->mElement);
-  if (frame) {
-    if (aProperty == eCSSProperty_opacity) {
-      ActiveLayerTracker::NotifyAnimated(frame, eCSSProperty_opacity);
-    } else if (aProperty == eCSSProperty_transform) {
-      ActiveLayerTracker::NotifyAnimated(frame, eCSSProperty_transform);
-    }
-  }
-
-  return collection;
-}
-
-/*
- * nsISupports implementation
- */
-
-NS_IMPL_ISUPPORTS(CommonAnimationManager, nsIStyleRuleProcessor)
-
-nsRestyleHint
-CommonAnimationManager::HasStateDependentStyle(StateRuleProcessorData* aData)
-{
-  return nsRestyleHint(0);
-}
-
-nsRestyleHint
-CommonAnimationManager::HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData)
-{
-  return nsRestyleHint(0);
-}
-
-bool
-CommonAnimationManager::HasDocumentStateDependentStyle(StateRuleProcessorData* aData)
-{
-  return false;
-}
-
-nsRestyleHint
-CommonAnimationManager::HasAttributeDependentStyle(AttributeRuleProcessorData* aData)
-{
-  return nsRestyleHint(0);
-}
-
-/* virtual */ bool
-CommonAnimationManager::MediumFeaturesChanged(nsPresContext* aPresContext)
-{
-  return false;
-}
-
-/* virtual */ size_t
-CommonAnimationManager::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
-{
-  // Measurement of the following members may be added later if DMD finds it is
-  // worthwhile:
-  // - mElementCollections
-  //
-  // The following members are not measured
-  // - mPresContext, because it's non-owning
-
-  return 0;
-}
-
-/* virtual */ size_t
-CommonAnimationManager::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
-{
-  return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
-}
-
-void
-CommonAnimationManager::AddStyleUpdatesTo(RestyleTracker& aTracker)
-{
-  PRCList* next = PR_LIST_HEAD(&mElementCollections);
-  while (next != &mElementCollections) {
-    ElementAnimationCollection* collection = static_cast<ElementAnimationCollection*>(next);
-    next = PR_NEXT_LINK(next);
-
-    if (!collection->IsForElement()) {
-      // We don't support compositor-driven animation of :before/:after
-      // transitions or animations, so at least skip those.
-      // FIXME: We'll need to handle this before using this for the
-      // transitions redesign.
-      continue;
-    }
-
-    nsRestyleHint rshint = collection->IsForTransitions()
-      ? eRestyle_CSSTransitions : eRestyle_CSSAnimations;
-    aTracker.AddPendingRestyle(collection->mElement, rshint, nsChangeHint(0));
-  }
-}
-
-/* static */ bool
-CommonAnimationManager::ExtractComputedValueForTransition(
-                          nsCSSProperty aProperty,
-                          nsStyleContext* aStyleContext,
-                          StyleAnimationValue& aComputedValue)
-{
-  bool result = StyleAnimationValue::ExtractComputedValue(aProperty,
-                                                          aStyleContext,
-                                                          aComputedValue);
-  if (aProperty == eCSSProperty_visibility) {
-    NS_ABORT_IF_FALSE(aComputedValue.GetUnit() ==
-                        StyleAnimationValue::eUnit_Enumerated,
-                      "unexpected unit");
-    aComputedValue.SetIntValue(aComputedValue.GetIntValue(),
-                               StyleAnimationValue::eUnit_Visibility);
-  }
-  return result;
-}
-
-NS_IMPL_ISUPPORTS(AnimValuesStyleRule, nsIStyleRule)
-
-/* virtual */ void
-AnimValuesStyleRule::MapRuleInfoInto(nsRuleData* aRuleData)
-{
-  nsStyleContext *contextParent = aRuleData->mStyleContext->GetParent();
-  if (contextParent && contextParent->HasPseudoElementData()) {
-    // Don't apply transitions or animations to things inside of
-    // pseudo-elements.
-    // FIXME (Bug 522599): Add tests for this.
-    return;
-  }
-
-  for (uint32_t i = 0, i_end = mPropertyValuePairs.Length(); i < i_end; ++i) {
-    PropertyValuePair &cv = mPropertyValuePairs[i];
-    if (aRuleData->mSIDs & nsCachedStyleData::GetBitForSID(
-                             nsCSSProps::kSIDTable[cv.mProperty]))
-    {
-      nsCSSValue *prop = aRuleData->ValueFor(cv.mProperty);
-      if (prop->GetUnit() == eCSSUnit_Null) {
-#ifdef DEBUG
-        bool ok =
-#endif
-          StyleAnimationValue::UncomputeValue(cv.mProperty, cv.mValue, *prop);
-        NS_ABORT_IF_FALSE(ok, "could not store computed value");
-      }
-    }
-  }
-}
-
-#ifdef DEBUG
-/* virtual */ void
-AnimValuesStyleRule::List(FILE* out, int32_t aIndent) const
-{
-  for (int32_t index = aIndent; --index >= 0; ) fputs("  ", out);
-  fputs("[anim values] { ", out);
-  for (uint32_t i = 0, i_end = mPropertyValuePairs.Length(); i < i_end; ++i) {
-    const PropertyValuePair &pair = mPropertyValuePairs[i];
-    nsAutoString value;
-    StyleAnimationValue::UncomputeValue(pair.mProperty, pair.mValue, value);
-    fprintf(out, "%s: %s; ", nsCSSProps::GetStringValue(pair.mProperty).get(),
-                             NS_ConvertUTF16toUTF8(value).get());
-  }
-  fputs("}\n", out);
-}
-#endif
-
 void
 ComputedTimingFunction::Init(const nsTimingFunction &aFunction)
 {
   mType = aFunction.mType;
   if (mType == nsTimingFunction::Function) {
     mTimingFunction.Init(aFunction.mFunc.mX1, aFunction.mFunc.mY1,
                          aFunction.mFunc.mX2, aFunction.mFunc.mY2);
   } else {
@@ -291,52 +45,51 @@ ComputedTimingFunction::GetValue(double 
     default:
       NS_ABORT_IF_FALSE(false, "bad type");
       // fall through
     case nsTimingFunction::StepEnd:
       return StepEnd(mSteps, aPortion);
   }
 }
 
-} /* end sub-namespace css */
-
 // 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 =
-  mozilla::PositiveInfinity<double>();
+const double ComputedTiming::kNullTimeFraction = PositiveInfinity<double>();
+
+namespace dom {
 
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ElementAnimation, mTimeline)
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AnimationPlayer, mTimeline)
 
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(ElementAnimation, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(ElementAnimation, Release)
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AnimationPlayer, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AnimationPlayer, Release)
 
 JSObject*
-ElementAnimation::WrapObject(JSContext* aCx)
+AnimationPlayer::WrapObject(JSContext* aCx)
 {
   return dom::AnimationPlayerBinding::Wrap(aCx, this);
 }
 
 double
-ElementAnimation::StartTime() const
+AnimationPlayer::StartTime() const
 {
   Nullable<double> startTime = mTimeline->ToTimelineTime(mStartTime);
   return startTime.IsNull() ? 0.0 : startTime.Value();
 }
 
 double
-ElementAnimation::CurrentTime() const
+AnimationPlayer::CurrentTime() const
 {
   // In Web Animations, AnimationPlayers have a *current* time and Animations
   // have a *local* time. However, since we have a 1:1 correspondence between
   // AnimationPlayers and Animations, and since the startTime of *Animations*
   // (but not AnimationPlayers) is always 0, these are currently identical.
   Nullable<TimeDuration> currentTime = GetLocalTime();
 
-  // The current time is only going to be null when we don't have a refresh
-  // driver or navigation timing object and never did.
+  // The current time is currently only going to be null when don't have a
+  // refresh driver (e.g. because we are in a display:none iframe).
   //
   // Web Animations says that in this case we should use a timeline time of
   // 0 (the "effective timeline time") and calculate the current time from that.
   // Doing that, however, requires storing the start time as an offset rather
   // than a timestamp so for now we just return 0.
   //
   // FIXME: Store player start time and pause start as offsets rather than
   // timestamps and return the appropriate current time when the timeline time
@@ -344,52 +97,52 @@ ElementAnimation::CurrentTime() const
   if (currentTime.IsNull()) {
     return 0.0;
   }
 
   return currentTime.Value().ToMilliseconds();
 }
 
 bool
-ElementAnimation::IsRunning() const
+AnimationPlayer::IsRunning() const
 {
   if (IsPaused() || IsFinishedTransition()) {
     return false;
   }
 
   ComputedTiming computedTiming = GetComputedTiming(mTiming);
   return computedTiming.mPhase == ComputedTiming::AnimationPhase_Active;
 }
 
 bool
-ElementAnimation::IsCurrent() const
+AnimationPlayer::IsCurrent() const
 {
   if (IsFinishedTransition()) {
     return false;
   }
 
   ComputedTiming computedTiming = GetComputedTiming(mTiming);
   return computedTiming.mPhase == ComputedTiming::AnimationPhase_Before ||
          computedTiming.mPhase == ComputedTiming::AnimationPhase_Active;
 }
 
 bool
-ElementAnimation::HasAnimationOfProperty(nsCSSProperty aProperty) const
+AnimationPlayer::HasAnimationOfProperty(nsCSSProperty aProperty) const
 {
   for (uint32_t propIdx = 0, propEnd = mProperties.Length();
        propIdx != propEnd; ++propIdx) {
     if (aProperty == mProperties[propIdx].mProperty) {
       return true;
     }
   }
   return false;
 }
 
 ComputedTiming
-ElementAnimation::GetComputedTimingAt(const Nullable<TimeDuration>& aLocalTime,
+AnimationPlayer::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
@@ -512,457 +265,24 @@ ElementAnimation::GetComputedTimingAt(co
   if (thisIterationReverse) {
     result.mTimeFraction = 1.0 - result.mTimeFraction;
   }
 
   return result;
 }
 
 TimeDuration
-ElementAnimation::ActiveDuration(const AnimationTiming& aTiming)
+AnimationPlayer::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 TimeDuration zeroDuration;
     return aTiming.mIterationDuration == zeroDuration
            ? zeroDuration
            : TimeDuration::Forever();
   }
   return aTiming.mIterationDuration.MultDouble(aTiming.mIterationCount);
 }
 
-bool
-ElementAnimationCollection::CanAnimatePropertyOnCompositor(
-  const dom::Element *aElement,
-  nsCSSProperty aProperty,
-  CanAnimateFlags aFlags)
-{
-  bool shouldLog = nsLayoutUtils::IsAnimationLoggingEnabled();
-  if (!gfxPlatform::OffMainThreadCompositingEnabled()) {
-    if (shouldLog) {
-      nsCString message;
-      message.AppendLiteral("Performance warning: Compositor disabled");
-      LogAsyncAnimationFailure(message);
-    }
-    return false;
-  }
-
-  nsIFrame* frame = nsLayoutUtils::GetStyleFrame(aElement);
-  if (IsGeometricProperty(aProperty)) {
-    if (shouldLog) {
-      nsCString message;
-      message.AppendLiteral("Performance warning: Async animation of geometric property '");
-      message.Append(nsCSSProps::GetStringValue(aProperty));
-      message.AppendLiteral("' is disabled");
-      LogAsyncAnimationFailure(message, aElement);
-    }
-    return false;
-  }
-  if (aProperty == eCSSProperty_transform) {
-    if (frame->Preserves3D() &&
-        frame->Preserves3DChildren()) {
-      if (shouldLog) {
-        nsCString message;
-        message.AppendLiteral("Gecko bug: Async animation of 'preserve-3d' transforms is not supported.  See bug 779598");
-        LogAsyncAnimationFailure(message, aElement);
-      }
-      return false;
-    }
-    if (frame->IsSVGTransformed()) {
-      if (shouldLog) {
-        nsCString message;
-        message.AppendLiteral("Gecko bug: Async 'transform' animations of frames with SVG transforms is not supported.  See bug 779599");
-        LogAsyncAnimationFailure(message, aElement);
-      }
-      return false;
-    }
-    if (aFlags & CanAnimate_HasGeometricProperty) {
-      if (shouldLog) {
-        nsCString message;
-        message.AppendLiteral("Performance warning: Async animation of 'transform' not possible due to presence of geometric properties");
-        LogAsyncAnimationFailure(message, aElement);
-      }
-      return false;
-    }
-  }
-  bool enabled = nsLayoutUtils::AreAsyncAnimationsEnabled();
-  if (!enabled && shouldLog) {
-    nsCString message;
-    message.AppendLiteral("Performance warning: Async animations are disabled");
-    LogAsyncAnimationFailure(message);
-  }
-  bool propertyAllowed = (aProperty == eCSSProperty_transform) ||
-                         (aProperty == eCSSProperty_opacity) ||
-                         (aFlags & CanAnimate_AllowPartial);
-  return enabled && propertyAllowed;
-}
-
-/* static */ bool
-ElementAnimationCollection::IsCompositorAnimationDisabledForFrame(
-  nsIFrame* aFrame)
-{
-  void* prop = aFrame->Properties().Get(nsIFrame::RefusedAsyncAnimation());
-  return bool(reinterpret_cast<intptr_t>(prop));
-}
-
-bool
-ElementAnimationCollection::CanPerformOnCompositorThread(
-  CanAnimateFlags aFlags) const
-{
-  nsIFrame* frame = nsLayoutUtils::GetStyleFrame(mElement);
-  if (!frame) {
-    return false;
-  }
-
-  if (mElementProperty != nsGkAtoms::transitionsProperty &&
-      mElementProperty != nsGkAtoms::animationsProperty) {
-    if (nsLayoutUtils::IsAnimationLoggingEnabled()) {
-      nsCString message;
-      message.AppendLiteral("Gecko bug: Async animation of pseudoelements"
-                            " not supported.  See bug 771367 (");
-      message.Append(nsAtomCString(mElementProperty));
-      message.Append(")");
-      LogAsyncAnimationFailure(message, mElement);
-    }
-    return false;
-  }
-
-  for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
-    const ElementAnimation* anim = mAnimations[animIdx];
-    bool isRunning = anim->IsRunning();
-    for (uint32_t propIdx = 0, propEnd = anim->mProperties.Length();
-         propIdx != propEnd; ++propIdx) {
-      if (IsGeometricProperty(anim->mProperties[propIdx].mProperty) &&
-          isRunning) {
-        aFlags = CanAnimateFlags(aFlags | CanAnimate_HasGeometricProperty);
-        break;
-      }
-    }
-  }
-
-  bool existsProperty = false;
-  for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
-    const ElementAnimation* anim = mAnimations[animIdx];
-    if (!anim->IsRunning()) {
-      continue;
-    }
-
-    existsProperty = true;
-
-    for (uint32_t propIdx = 0, propEnd = anim->mProperties.Length();
-         propIdx != propEnd; ++propIdx) {
-      const AnimationProperty& prop = anim->mProperties[propIdx];
-      if (!CanAnimatePropertyOnCompositor(mElement,
-                                          prop.mProperty,
-                                          aFlags) ||
-          IsCompositorAnimationDisabledForFrame(frame)) {
-        return false;
-      }
-    }
-  }
-
-  // No properties to animate
-  if (!existsProperty) {
-    return false;
-  }
-
-  return true;
-}
-
-bool
-ElementAnimationCollection::HasAnimationOfProperty(
-  nsCSSProperty aProperty) const
-{
-  for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
-    const ElementAnimation* anim = mAnimations[animIdx];
-    if (anim->HasAnimationOfProperty(aProperty) &&
-        !anim->IsFinishedTransition()) {
-      return true;
-    }
-  }
-  return false;
-}
-
-/* static */ void
-ElementAnimationCollection::LogAsyncAnimationFailure(nsCString& aMessage,
-                                                     const nsIContent* aContent)
-{
-  if (aContent) {
-    aMessage.AppendLiteral(" [");
-    aMessage.Append(nsAtomCString(aContent->Tag()));
-
-    nsIAtom* id = aContent->GetID();
-    if (id) {
-      aMessage.AppendLiteral(" with id '");
-      aMessage.Append(nsAtomCString(aContent->GetID()));
-      aMessage.Append('\'');
-    }
-    aMessage.Append(']');
-  }
-  aMessage.Append('\n');
-  printf_stderr(aMessage.get());
-}
-
-/*static*/ void
-ElementAnimationCollection::PropertyDtor(void *aObject, nsIAtom *aPropertyName,
-                                         void *aPropertyValue, void *aData)
-{
-  ElementAnimationCollection* collection =
-    static_cast<ElementAnimationCollection*>(aPropertyValue);
-#ifdef DEBUG
-  NS_ABORT_IF_FALSE(!collection->mCalledPropertyDtor, "can't call dtor twice");
-  collection->mCalledPropertyDtor = true;
-#endif
-  delete collection;
-}
-
-void
-ElementAnimationCollection::EnsureStyleRuleFor(TimeStamp aRefreshTime,
-                                               EnsureStyleRuleFlags aFlags)
-{
-  if (!mNeedsRefreshes) {
-    mStyleRuleRefreshTime = aRefreshTime;
-    return;
-  }
-
-  // If we're performing animations on the compositor thread, then we can skip
-  // most of the work in this method. But even if we are throttled, then we
-  // have to do the work if an animation is ending in order to get correct end
-  // of animation behaviour (the styles of the animation disappear, or the fill
-  // mode behaviour). This loop checks for any finishing animations and forces
-  // the style recalculation if we find any.
-  if (aFlags == EnsureStyleRule_IsThrottled) {
-    for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
-      ElementAnimation* anim = mAnimations[animIdx];
-
-      // Skip finished transitions or animations whose @keyframes rule
-      // is empty.
-      if (anim->IsFinishedTransition() || anim->mProperties.IsEmpty()) {
-        continue;
-      }
-
-      // The GetLocalTime() call here handles pausing.  But:
-      // FIXME: avoid recalculating every time when paused.
-      ComputedTiming computedTiming = anim->GetComputedTiming(anim->mTiming);
-
-      // XXX We shouldn't really be using mLastNotification as a general
-      // indicator that the animation has finished, it should be reserved for
-      // events. If we use it differently in the future this use might need
-      // changing.
-      if (!anim->mIsRunningOnCompositor ||
-          (computedTiming.mPhase == ComputedTiming::AnimationPhase_After &&
-           anim->mLastNotification != ElementAnimation::LAST_NOTIFICATION_END))
-      {
-        aFlags = EnsureStyleRule_IsNotThrottled;
-        break;
-      }
-    }
-  }
-
-  if (aFlags == EnsureStyleRule_IsThrottled) {
-    return;
-  }
-
-  // mStyleRule may be null and valid, if we have no style to apply.
-  if (mStyleRuleRefreshTime.IsNull() ||
-      mStyleRuleRefreshTime != aRefreshTime) {
-    mStyleRuleRefreshTime = aRefreshTime;
-    mStyleRule = nullptr;
-    // We'll set mNeedsRefreshes to true below in all cases where we need them.
-    mNeedsRefreshes = false;
-
-    // FIXME(spec): assume that properties in higher animations override
-    // those in lower ones.
-    // Therefore, we iterate from last animation to first.
-    nsCSSPropertySet properties;
-
-    for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
-      ElementAnimation* anim = mAnimations[animIdx];
-
-      if (anim->IsFinishedTransition()) {
-        continue;
-      }
-
-      // The GetLocalTime() call here handles pausing.  But:
-      // FIXME: avoid recalculating every time when paused.
-      ComputedTiming computedTiming = anim->GetComputedTiming(anim->mTiming);
-
-      if ((computedTiming.mPhase == ComputedTiming::AnimationPhase_Before ||
-           computedTiming.mPhase == ComputedTiming::AnimationPhase_Active) &&
-          !anim->IsPaused()) {
-        mNeedsRefreshes = true;
-      }
-
-      // 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) {
-        continue;
-      }
-
-      NS_ABORT_IF_FALSE(0.0 <= computedTiming.mTimeFraction &&
-                        computedTiming.mTimeFraction <= 1.0,
-                        "timing fraction should be in [0-1]");
-
-      for (uint32_t propIdx = 0, propEnd = anim->mProperties.Length();
-           propIdx != propEnd; ++propIdx)
-      {
-        const AnimationProperty &prop = anim->mProperties[propIdx];
-
-        NS_ABORT_IF_FALSE(prop.mSegments[0].mFromKey == 0.0,
-                          "incorrect first from key");
-        NS_ABORT_IF_FALSE(prop.mSegments[prop.mSegments.Length() - 1].mToKey
-                            == 1.0,
-                          "incorrect last to key");
-
-        if (properties.HasProperty(prop.mProperty)) {
-          // A later animation already set this property.
-          continue;
-        }
-        properties.AddProperty(prop.mProperty);
-
-        NS_ABORT_IF_FALSE(prop.mSegments.Length() > 0,
-                          "property should not be in animations if it "
-                          "has no segments");
-
-        // FIXME: Maybe cache the current segment?
-        const AnimationPropertySegment *segment = prop.mSegments.Elements(),
-                               *segmentEnd = segment + prop.mSegments.Length();
-        while (segment->mToKey < computedTiming.mTimeFraction) {
-          NS_ABORT_IF_FALSE(segment->mFromKey < segment->mToKey,
-                            "incorrect keys");
-          ++segment;
-          if (segment == segmentEnd) {
-            NS_ABORT_IF_FALSE(false, "incorrect time fraction");
-            break; // in order to continue in outer loop (just below)
-          }
-          NS_ABORT_IF_FALSE(segment->mFromKey == (segment-1)->mToKey,
-                            "incorrect keys");
-        }
-        if (segment == segmentEnd) {
-          continue;
-        }
-        NS_ABORT_IF_FALSE(segment->mFromKey < segment->mToKey,
-                          "incorrect keys");
-        NS_ABORT_IF_FALSE(segment >= prop.mSegments.Elements() &&
-                          size_t(segment - prop.mSegments.Elements()) <
-                            prop.mSegments.Length(),
-                          "out of array bounds");
-
-        if (!mStyleRule) {
-          // Allocate the style rule now that we know we have animation data.
-          mStyleRule = new css::AnimValuesStyleRule();
-        }
-
-        double positionInSegment =
-          (computedTiming.mTimeFraction - segment->mFromKey) /
-          (segment->mToKey - segment->mFromKey);
-        double valuePosition =
-          segment->mTimingFunction.GetValue(positionInSegment);
-
-        StyleAnimationValue *val =
-          mStyleRule->AddEmptyValue(prop.mProperty);
-
-#ifdef DEBUG
-        bool result =
-#endif
-          StyleAnimationValue::Interpolate(prop.mProperty,
-                                           segment->mFromValue,
-                                           segment->mToValue,
-                                           valuePosition, *val);
-        NS_ABORT_IF_FALSE(result, "interpolate must succeed now");
-      }
-    }
-  }
-}
-
-
-bool
-ElementAnimationCollection::CanThrottleTransformChanges(TimeStamp aTime)
-{
-  if (!nsLayoutUtils::AreAsyncAnimationsEnabled()) {
-    return false;
-  }
-
-  // If we know that the animation cannot cause overflow,
-  // we can just disable flushes for this animation.
-
-  // If we don't show scrollbars, we don't care about overflow.
-  if (LookAndFeel::GetInt(LookAndFeel::eIntID_ShowHideScrollbars) == 0) {
-    return true;
-  }
-
-  // If this animation can cause overflow, we can throttle some of the ticks.
-  if ((aTime - mStyleRuleRefreshTime) < TimeDuration::FromMilliseconds(200)) {
-    return true;
-  }
-
-  // If the nearest scrollable ancestor has overflow:hidden,
-  // we don't care about overflow.
-  nsIScrollableFrame* scrollable = nsLayoutUtils::GetNearestScrollableFrame(
-                                     nsLayoutUtils::GetStyleFrame(mElement));
-  if (!scrollable) {
-    return true;
-  }
-
-  ScrollbarStyles ss = scrollable->GetScrollbarStyles();
-  if (ss.mVertical == NS_STYLE_OVERFLOW_HIDDEN &&
-      ss.mHorizontal == NS_STYLE_OVERFLOW_HIDDEN &&
-      scrollable->GetLogicalScrollPosition() == nsPoint(0, 0)) {
-    return true;
-  }
-
-  return false;
-}
-
-bool
-ElementAnimationCollection::CanThrottleAnimation(TimeStamp aTime)
-{
-  nsIFrame* frame = nsLayoutUtils::GetStyleFrame(mElement);
-  if (!frame) {
-    return false;
-  }
-
-  bool hasTransform = HasAnimationOfProperty(eCSSProperty_transform);
-  bool hasOpacity = HasAnimationOfProperty(eCSSProperty_opacity);
-  if (hasOpacity) {
-    Layer* layer = FrameLayerBuilder::GetDedicatedLayer(
-                     frame, nsDisplayItem::TYPE_OPACITY);
-    if (!layer || mAnimationGeneration > layer->GetAnimationGeneration()) {
-      return false;
-    }
-  }
-
-  if (!hasTransform) {
-    return true;
-  }
-
-  Layer* layer = FrameLayerBuilder::GetDedicatedLayer(
-                   frame, nsDisplayItem::TYPE_TRANSFORM);
-  if (!layer || mAnimationGeneration > layer->GetAnimationGeneration()) {
-    return false;
-  }
-
-  return CanThrottleTransformChanges(aTime);
-}
-
-void
-ElementAnimationCollection::UpdateAnimationGeneration(
-  nsPresContext* aPresContext)
-{
-  mAnimationGeneration =
-    aPresContext->RestyleManager()->GetAnimationGeneration();
-}
-
-bool
-ElementAnimationCollection::HasCurrentAnimations()
-{
-  for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
-    if (mAnimations[animIdx]->IsCurrent()) {
-      return true;
-    }
-  }
-
-  return false;
-}
-
-}
+} // namespace dom
+} // namespace mozilla
copy from layout/style/AnimationCommon.h
copy to dom/animation/AnimationPlayer.h
--- a/layout/style/AnimationCommon.h
+++ b/dom/animation/AnimationPlayer.h
@@ -1,154 +1,37 @@
 /* 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_css_AnimationCommon_h
-#define mozilla_css_AnimationCommon_h
+#ifndef mozilla_dom_AnimationPlayer_h
+#define mozilla_dom_AnimationPlayer_h
 
-#include "nsIStyleRuleProcessor.h"
-#include "nsIStyleRule.h"
-#include "nsRefreshDriver.h"
-#include "prclist.h"
-#include "nsCSSProperty.h"
-#include "mozilla/MemoryReporting.h"
-#include "mozilla/StyleAnimationValue.h"
-#include "mozilla/dom/AnimationTimeline.h"
-#include "mozilla/dom/Element.h"
-#include "mozilla/dom/Nullable.h"
-#include "nsSMILKeySpline.h"
-#include "nsStyleStruct.h"
+#include <algorithm> // for std::max
+#include "nsWrapperCache.h"
+#include "nsCycleCollectionParticipant.h"
 #include "mozilla/Attributes.h"
-#include "mozilla/FloatingPoint.h"
-#include "nsCSSPseudoElements.h"
-#include "nsCycleCollectionParticipant.h"
-
-class nsIFrame;
-class nsPresContext;
-class nsStyleChangeList;
+#include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue
+#include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration
+#include "mozilla/dom/AnimationTimeline.h" // for AnimationTimeline
+#include "nsCSSProperty.h" // for nsCSSProperty
+#include "nsSMILKeySpline.h" // for nsSMILKeySpline
+#include "nsStyleStruct.h" // for nsTimingFunction
 
 // X11 has a #define for CurrentTime.
 #ifdef CurrentTime
 #undef CurrentTime
 #endif
 
+struct JSContext;
+
 namespace mozilla {
 
-class RestyleTracker;
-class StyleAnimationValue;
 struct ElementPropertyTransition;
-struct ElementAnimationCollection;
-
-namespace css {
-
-bool IsGeometricProperty(nsCSSProperty aProperty);
-
-class CommonAnimationManager : public nsIStyleRuleProcessor,
-                               public nsARefreshObserver {
-public:
-  CommonAnimationManager(nsPresContext *aPresContext);
-
-  // nsISupports
-  NS_DECL_ISUPPORTS
-
-  // nsIStyleRuleProcessor (parts)
-  virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData) MOZ_OVERRIDE;
-  virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) MOZ_OVERRIDE;
-  virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) MOZ_OVERRIDE;
-  virtual nsRestyleHint
-    HasAttributeDependentStyle(AttributeRuleProcessorData* aData) MOZ_OVERRIDE;
-  virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) MOZ_OVERRIDE;
-  virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf)
-    const MOZ_MUST_OVERRIDE MOZ_OVERRIDE;
-  virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
-    const MOZ_MUST_OVERRIDE MOZ_OVERRIDE;
-
-  /**
-   * Notify the manager that the pres context is going away.
-   */
-  void Disconnect();
-
-  // Tell the restyle tracker about all the styles that we're currently
-  // animating, so that it can update the animation rule for these
-  // elements.
-  void AddStyleUpdatesTo(mozilla::RestyleTracker& aTracker);
-
-  enum FlushFlags {
-    Can_Throttle,
-    Cannot_Throttle
-  };
-
-  static bool ExtractComputedValueForTransition(
-                  nsCSSProperty aProperty,
-                  nsStyleContext* aStyleContext,
-                  mozilla::StyleAnimationValue& aComputedValue);
-protected:
-  virtual ~CommonAnimationManager();
-
-  // For ElementCollectionRemoved
-  friend struct mozilla::ElementAnimationCollection;
-
-  virtual void
-  AddElementCollection(ElementAnimationCollection* aCollection) = 0;
-  virtual void ElementCollectionRemoved() = 0;
-  void RemoveAllElementCollections();
-
-  // When this returns a value other than nullptr, it also,
-  // as a side-effect, notifies the ActiveLayerTracker.
-  static ElementAnimationCollection*
-  GetAnimationsForCompositor(nsIContent* aContent,
-                             nsIAtom* aElementProperty,
-                             nsCSSProperty aProperty);
-
-  PRCList mElementCollections;
-  nsPresContext *mPresContext; // weak (non-null from ctor to Disconnect)
-};
-
-/**
- * A style rule that maps property-StyleAnimationValue pairs.
- */
-class AnimValuesStyleRule MOZ_FINAL : public nsIStyleRule
-{
-public:
-  // nsISupports implementation
-  NS_DECL_ISUPPORTS
-
-  // nsIStyleRule implementation
-  virtual void MapRuleInfoInto(nsRuleData* aRuleData) MOZ_OVERRIDE;
-#ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
-#endif
-
-  void AddValue(nsCSSProperty aProperty,
-                mozilla::StyleAnimationValue &aStartValue)
-  {
-    PropertyValuePair v = { aProperty, aStartValue };
-    mPropertyValuePairs.AppendElement(v);
-  }
-
-  // Caller must fill in returned value.
-  mozilla::StyleAnimationValue* AddEmptyValue(nsCSSProperty aProperty)
-  {
-    PropertyValuePair *p = mPropertyValuePairs.AppendElement();
-    p->mProperty = aProperty;
-    return &p->mValue;
-  }
-
-  struct PropertyValuePair {
-    nsCSSProperty mProperty;
-    mozilla::StyleAnimationValue mValue;
-  };
-
-private:
-  ~AnimValuesStyleRule() {}
-
-  InfallibleTArray<PropertyValuePair> mPropertyValuePairs;
-};
 
 class ComputedTimingFunction {
 public:
   typedef nsTimingFunction::Type Type;
   void Init(const nsTimingFunction &aFunction);
   double GetValue(double aPortion) const;
   const nsSMILKeySpline* GetFunction() const {
     NS_ASSERTION(mType == nsTimingFunction::Function, "Type mismatch");
@@ -157,23 +40,21 @@ public:
   Type GetType() const { return mType; }
   uint32_t GetSteps() const { return mSteps; }
 private:
   Type mType;
   nsSMILKeySpline mTimingFunction;
   uint32_t mSteps;
 };
 
-} /* end css sub-namespace */
-
 struct AnimationPropertySegment
 {
   float mFromKey, mToKey;
-  mozilla::StyleAnimationValue mFromValue, mToValue;
-  mozilla::css::ComputedTimingFunction mTimingFunction;
+  StyleAnimationValue mFromValue, mToValue;
+  ComputedTimingFunction mTimingFunction;
 };
 
 struct AnimationProperty
 {
   nsCSSProperty mProperty;
   InfallibleTArray<AnimationPropertySegment> mSegments;
 };
 
@@ -181,18 +62,18 @@ struct AnimationProperty
  * Input timing parameters.
  *
  * Eventually this will represent all the input timing parameters specified
  * by content but for now it encapsulates just the subset of those
  * parameters passed to GetPositionInIteration.
  */
 struct AnimationTiming
 {
-  mozilla::TimeDuration mIterationDuration;
-  mozilla::TimeDuration mDelay;
+  TimeDuration mIterationDuration;
+  TimeDuration mDelay;
   float mIterationCount; // mozilla::PositiveInfinity<float>() means infinite
   uint8_t mDirection;
   uint8_t mFillMode;
 
   bool FillsForwards() const {
     return mFillMode == NS_STYLE_ANIMATION_FILL_MODE_BOTH ||
            mFillMode == NS_STYLE_ANIMATION_FILL_MODE_FORWARDS;
   }
@@ -235,43 +116,41 @@ struct ComputedTiming
     AnimationPhase_Before,
     // Sampled within the active interval
     AnimationPhase_Active,
     // Sampled after (or at) the end of the active interval
     AnimationPhase_After
   } mPhase;
 };
 
-/**
- * Data about one animation (i.e., one of the values of
- * 'animation-name') running on an element.
- */
-class ElementAnimation : public nsWrapperCache
+namespace dom {
+
+class AnimationPlayer : public nsWrapperCache
 {
 protected:
-  virtual ~ElementAnimation() { }
+  virtual ~AnimationPlayer() { }
 
 public:
-  explicit ElementAnimation(dom::AnimationTimeline* aTimeline)
+  explicit AnimationPlayer(AnimationTimeline* aTimeline)
     : mIsRunningOnCompositor(false)
     , mIsFinishedTransition(false)
     , mLastNotification(LAST_NOTIFICATION_NONE)
     , mTimeline(aTimeline)
   {
     SetIsDOMBinding();
   }
 
-  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(ElementAnimation)
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(ElementAnimation)
+  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AnimationPlayer)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(AnimationPlayer)
 
-  dom::AnimationTimeline* GetParentObject() const { return mTimeline; }
+  AnimationTimeline* GetParentObject() const { return mTimeline; }
   virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
 
   // AnimationPlayer methods
-  dom::AnimationTimeline* Timeline() const { return mTimeline; }
+  AnimationTimeline* Timeline() const { return mTimeline; }
   double StartTime() const;
   double CurrentTime() const;
 
   // 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 {
@@ -298,248 +177,83 @@ public:
   bool IsRunning() const;
   bool IsCurrent() const;
 
   // Return the duration since the start of the delay period, taking into
   // account the pause state.  May be negative.
   // Returns a null value if the timeline associated with this object has a
   // current timestamp that is null or if the start time of this object is
   // null.
-  Nullable<mozilla::TimeDuration> GetLocalTime() const {
-    const mozilla::TimeStamp& timelineTime = mTimeline->GetCurrentTimeStamp();
+  Nullable<TimeDuration> GetLocalTime() const {
+    const TimeStamp& timelineTime = mTimeline->GetCurrentTimeStamp();
     // FIXME: In order to support arbitrary timelines we will need to fix
     // the pause logic to handle the timeline time going backwards.
     MOZ_ASSERT(timelineTime.IsNull() || !IsPaused() ||
                timelineTime >= mPauseStart,
                "if paused, any non-null value of aTime must be at least"
                " mPauseStart");
 
-    Nullable<mozilla::TimeDuration> result; // Initializes to null
+    Nullable<TimeDuration> result; // Initializes to null
     if (!timelineTime.IsNull() && !mStartTime.IsNull()) {
       result.SetValue((IsPaused() ? mPauseStart : timelineTime) - mStartTime);
     }
     return result;
   }
 
   // Return the duration from the start the active interval to the point where
   // the animation begins playback. This is zero unless the animation has
   // a negative delay in which case it is the absolute value of the delay.
   // This is used for setting the elapsedTime member of AnimationEvents.
-  mozilla::TimeDuration InitialAdvance() const {
+  TimeDuration InitialAdvance() const {
     return std::max(TimeDuration(), mTiming.mDelay * -1);
   }
 
   // This function takes as input the timing parameters of an animation and
   // returns the computed timing at the specified local time.
   //
   // The local time may be null in which case only static parameters such as the
   // active duration are calculated. All other members of the returned object
   // are given a null/initial value.
   //
   // This function returns ComputedTiming::kNullTimeFraction for the
   // mTimeFraction member of the return value if the animation should not be
   // run (because it is not currently active and is not filling at this time).
   static ComputedTiming
-  GetComputedTimingAt(const Nullable<mozilla::TimeDuration>& aLocalTime,
+  GetComputedTimingAt(const Nullable<TimeDuration>& aLocalTime,
                       const AnimationTiming& aTiming);
 
   // Shortcut for that gets the computed timing using the current local time as
   // calculated from the timeline time.
   ComputedTiming GetComputedTiming(const AnimationTiming& aTiming) const {
     return GetComputedTimingAt(GetLocalTime(), aTiming);
   }
 
   // Return the duration of the active interval for the given timing parameters.
-  static mozilla::TimeDuration ActiveDuration(const AnimationTiming& aTiming);
+  static TimeDuration ActiveDuration(const AnimationTiming& aTiming);
 
   nsString mName;
   AnimationTiming mTiming;
   // The beginning of the delay period.
-  mozilla::TimeStamp mStartTime;
-  mozilla::TimeStamp mPauseStart;
+  TimeStamp mStartTime;
+  TimeStamp mPauseStart;
   uint8_t mPlayState;
   bool mIsRunningOnCompositor;
   // A flag to mark transitions that have finished and are due to
   // be removed on the next throttle-able cycle.
   bool mIsFinishedTransition;
 
   enum {
     LAST_NOTIFICATION_NONE = uint64_t(-1),
     LAST_NOTIFICATION_END = uint64_t(-2)
   };
   // One of the above constants, or an integer for the iteration
   // whose start we last notified on.
   uint64_t mLastNotification;
 
   InfallibleTArray<AnimationProperty> mProperties;
 
-  nsRefPtr<dom::AnimationTimeline> mTimeline;
-};
-
-typedef InfallibleTArray<nsRefPtr<ElementAnimation> > ElementAnimationPtrArray;
-
-enum EnsureStyleRuleFlags {
-  EnsureStyleRule_IsThrottled,
-  EnsureStyleRule_IsNotThrottled
+  nsRefPtr<AnimationTimeline> mTimeline;
 };
 
-struct ElementAnimationCollection : public PRCList
-{
-  ElementAnimationCollection(dom::Element *aElement, nsIAtom *aElementProperty,
-                             mozilla::css::CommonAnimationManager *aManager,
-                             TimeStamp aNow)
-    : mElement(aElement)
-    , mElementProperty(aElementProperty)
-    , mManager(aManager)
-    , mAnimationGeneration(0)
-    , mNeedsRefreshes(true)
-#ifdef DEBUG
-    , mCalledPropertyDtor(false)
-#endif
-  {
-    MOZ_COUNT_CTOR(ElementAnimationCollection);
-    PR_INIT_CLIST(this);
-  }
-  ~ElementAnimationCollection()
-  {
-    NS_ABORT_IF_FALSE(mCalledPropertyDtor,
-                      "must call destructor through element property dtor");
-    MOZ_COUNT_DTOR(ElementAnimationCollection);
-    PR_REMOVE_LINK(this);
-    mManager->ElementCollectionRemoved();
-  }
-
-  void Destroy()
-  {
-    // This will call our destructor.
-    mElement->DeleteProperty(mElementProperty);
-  }
-
-  static void PropertyDtor(void *aObject, nsIAtom *aPropertyName,
-                           void *aPropertyValue, void *aData);
-
-  // This updates mNeedsRefreshes so the caller may need to check
-  // for changes to values (for example, nsAnimationManager provides
-  // CheckNeedsRefresh to register or unregister from observing the refresh
-  // driver when this value changes).
-  void EnsureStyleRuleFor(TimeStamp aRefreshTime, EnsureStyleRuleFlags aFlags);
-
-  bool CanThrottleTransformChanges(mozilla::TimeStamp aTime);
-
-  bool CanThrottleAnimation(mozilla::TimeStamp aTime);
-
-  enum CanAnimateFlags {
-    // Testing for width, height, top, right, bottom, or left.
-    CanAnimate_HasGeometricProperty = 1,
-    // Allow the case where OMTA is allowed in general, but not for the
-    // specified property.
-    CanAnimate_AllowPartial = 2
-  };
-
-  static bool
-  CanAnimatePropertyOnCompositor(const dom::Element *aElement,
-                                 nsCSSProperty aProperty,
-                                 CanAnimateFlags aFlags);
-
-  static bool IsCompositorAnimationDisabledForFrame(nsIFrame* aFrame);
-
-  // True if this animation can be performed on the compositor thread.
-  //
-  // If aFlags contains CanAnimate_AllowPartial, returns whether the
-  // state of this element's animations at the current refresh driver
-  // time contains animation data that can be done on the compositor
-  // thread.  (This is useful for determining whether a layer should be
-  // active, or whether to send data to the layer.)
-  //
-  // If aFlags does not contain CanAnimate_AllowPartial, returns whether
-  // the state of this element's animations at the current refresh driver
-  // time can be fully represented by data sent to the compositor.
-  // (This is useful for determining whether throttle the animation
-  // (suppress main-thread style updates).)
-  bool CanPerformOnCompositorThread(CanAnimateFlags aFlags) const;
-  bool HasAnimationOfProperty(nsCSSProperty aProperty) const;
-
-  bool IsForElement() const { // rather than for a pseudo-element
-    return mElementProperty == nsGkAtoms::animationsProperty ||
-           mElementProperty == nsGkAtoms::transitionsProperty;
-  }
+} // namespace dom
+} // namespace mozilla
 
-  bool IsForTransitions() const {
-    return mElementProperty == nsGkAtoms::transitionsProperty ||
-           mElementProperty == nsGkAtoms::transitionsOfBeforeProperty ||
-           mElementProperty == nsGkAtoms::transitionsOfAfterProperty;
-  }
-
-  bool IsForAnimations() const {
-    return mElementProperty == nsGkAtoms::animationsProperty ||
-           mElementProperty == nsGkAtoms::animationsOfBeforeProperty ||
-           mElementProperty == nsGkAtoms::animationsOfAfterProperty;
-  }
-
-  nsString PseudoElement()
-  {
-    if (IsForElement()) {
-      return EmptyString();
-    } else if (mElementProperty == nsGkAtoms::animationsOfBeforeProperty ||
-               mElementProperty == nsGkAtoms::transitionsOfBeforeProperty) {
-      return NS_LITERAL_STRING("::before");
-    } else {
-      return NS_LITERAL_STRING("::after");
-    }
-  }
-
-  void PostRestyleForAnimation(nsPresContext *aPresContext) {
-    nsRestyleHint styleHint = IsForElement() ? eRestyle_Self : eRestyle_Subtree;
-    aPresContext->PresShell()->RestyleForAnimation(mElement, styleHint);
-  }
-
-  static void LogAsyncAnimationFailure(nsCString& aMessage,
-                                       const nsIContent* aContent = nullptr);
-
-  dom::Element *mElement;
-
-  // the atom we use in mElement's prop table (must be a static atom,
-  // i.e., in an atom list)
-  nsIAtom *mElementProperty;
-
-  mozilla::css::CommonAnimationManager *mManager;
-
-  mozilla::ElementAnimationPtrArray mAnimations;
-
-  // This style rule contains the style data for currently animating
-  // values.  It only matches when styling with animation.  When we
-  // style without animation, we need to not use it so that we can
-  // detect any new changes; if necessary we restyle immediately
-  // afterwards with animation.
-  // NOTE: If we don't need to apply any styles, mStyleRule will be
-  // null, but mStyleRuleRefreshTime will still be valid.
-  nsRefPtr<mozilla::css::AnimValuesStyleRule> mStyleRule;
-
-  // RestyleManager keeps track of the number of animation
-  // 'mini-flushes' (see nsTransitionManager::UpdateAllThrottledStyles()).
-  // mAnimationGeneration is the sequence number of the last flush where a
-  // transition/animation changed.  We keep a similar count on the
-  // corresponding layer so we can check that the layer is up to date with
-  // the animation manager.
-  uint64_t mAnimationGeneration;
-  // Update mAnimationGeneration to nsCSSFrameConstructor's count
-  void UpdateAnimationGeneration(nsPresContext* aPresContext);
-
-  // Returns true if there is an animation in the before or active phase
-  // at the current time.
-  bool HasCurrentAnimations();
-
-  // The refresh time associated with mStyleRule.
-  TimeStamp mStyleRuleRefreshTime;
-
-  // False when we know that our current style rule is valid
-  // indefinitely into the future (because all of our animations are
-  // either completed or paused).  May be invalidated by a style change.
-  bool mNeedsRefreshes;
-
-#ifdef DEBUG
-  bool mCalledPropertyDtor;
-#endif
-};
-
-}
-
-#endif /* !defined(mozilla_css_AnimationCommon_h) */
+#endif // mozilla_dom_AnimationPlayer_h
--- a/dom/animation/moz.build
+++ b/dom/animation/moz.build
@@ -2,18 +2,20 @@
 # vim: set filetype=python:
 # 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']
 
 EXPORTS.mozilla.dom += [
+    'AnimationPlayer.h',
     'AnimationTimeline.h',
 ]
 
 SOURCES += [
+    'AnimationPlayer.cpp',
     'AnimationTimeline.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 FINAL_LIBRARY = 'xul'
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -131,21 +131,16 @@ DOMInterfaces = {
         'channelInterpretation': 'channelInterpretationValue',
     },
 },
 
 'AudioProcessingEvent' : {
     'resultNotAddRefed': [ 'inputBuffer', 'outputBuffer' ],
 },
 
-'AnimationPlayer' : {
-    'nativeType': 'mozilla::ElementAnimation',
-    'headerFile': 'AnimationCommon.h',
-},
-
 'BarProp': {
     'headerFile': 'mozilla/dom/BarProps.h',
 },
 
 'BiquadFilterNode': {
     'resultNotAddRefed': [ 'frequency', 'detune', 'q', 'gain' ],
 },
 
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -2,29 +2,29 @@
  * vim: sw=2 ts=8 et :
  */
 /* 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 "Layers.h"
 #include <algorithm>                    // for max, min
-#include "AnimationCommon.h"            // for ComputedTimingFunction
 #include "CompositableHost.h"           // for CompositableHost
 #include "ImageContainer.h"             // for ImageContainer, etc
 #include "ImageLayers.h"                // for ImageLayer
 #include "LayerSorter.h"                // for SortLayersBy3DZOrder
 #include "LayersLogging.h"              // for AppendToString
 #include "ReadbackLayer.h"              // for ReadbackLayer
 #include "gfxPlatform.h"                // for gfxPlatform
 #include "gfxPrefs.h"
 #include "gfxUtils.h"                   // for gfxUtils, etc
 #include "gfx2DGlue.h"
 #include "mozilla/DebugOnly.h"          // for DebugOnly
 #include "mozilla/Telemetry.h"          // for Accumulate
+#include "mozilla/dom/AnimationPlayer.h" // for ComputedTimingFunction
 #include "mozilla/gfx/2D.h"             // for DrawTarget
 #include "mozilla/gfx/BaseSize.h"       // for BaseSize
 #include "mozilla/gfx/Matrix.h"         // for Matrix4x4
 #include "mozilla/layers/AsyncPanZoomController.h"
 #include "mozilla/layers/Compositor.h"  // for Compositor
 #include "mozilla/layers/CompositorTypes.h"
 #include "mozilla/layers/LayerManagerComposite.h"  // for LayerComposite
 #include "mozilla/layers/LayersMessages.h"  // for TransformFunction, etc
@@ -389,22 +389,23 @@ void
 Layer::SetAnimations(const AnimationArray& aAnimations)
 {
   MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) SetAnimations", this));
 
   mAnimations = aAnimations;
   mAnimationData.Clear();
   for (uint32_t i = 0; i < mAnimations.Length(); i++) {
     AnimData* data = mAnimationData.AppendElement();
-    InfallibleTArray<nsAutoPtr<css::ComputedTimingFunction> >& functions = data->mFunctions;
+    InfallibleTArray<nsAutoPtr<ComputedTimingFunction> >& functions =
+      data->mFunctions;
     const InfallibleTArray<AnimationSegment>& segments =
       mAnimations.ElementAt(i).segments();
     for (uint32_t j = 0; j < segments.Length(); j++) {
       TimingFunction tf = segments.ElementAt(j).sampleFn();
-      css::ComputedTimingFunction* ctf = new css::ComputedTimingFunction();
+      ComputedTimingFunction* ctf = new ComputedTimingFunction();
       switch (tf.type()) {
         case TimingFunction::TCubicBezierFunction: {
           CubicBezierFunction cbf = tf.get_CubicBezierFunction();
           ctf->Init(nsTimingFunction(cbf.x1(), cbf.y1(), cbf.x2(), cbf.y2()));
           break;
         }
         default: {
           NS_ASSERTION(tf.type() == TimingFunction::TStepFunction,
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -47,33 +47,30 @@
 #include "gfx2DGlue.h"
 
 class gfxContext;
 
 extern uint8_t gLayerManagerLayerBuilder;
 
 namespace mozilla {
 
+class ComputedTimingFunction;
 class FrameLayerBuilder;
 class StyleAnimationValue;
 class WebGLContext;
 
 namespace gl {
 class GLContext;
 class SurfaceStream;
 }
 
 namespace gfx {
 class DrawTarget;
 }
 
-namespace css {
-class ComputedTimingFunction;
-}
-
 namespace dom {
 class OverfillCallback;
 }
 
 namespace layers {
 
 class Animation;
 class AnimationData;
@@ -702,17 +699,17 @@ private:
   TimeStamp mTabSwitchStart;
 };
 
 typedef InfallibleTArray<Animation> AnimationArray;
 
 struct AnimData {
   InfallibleTArray<mozilla::StyleAnimationValue> mStartValues;
   InfallibleTArray<mozilla::StyleAnimationValue> mEndValues;
-  InfallibleTArray<nsAutoPtr<mozilla::css::ComputedTimingFunction> > mFunctions;
+  InfallibleTArray<nsAutoPtr<mozilla::ComputedTimingFunction> > mFunctions;
 };
 
 /**
  * A Layer represents anything that can be rendered onto a destination
  * surface.
  */
 class Layer {
   NS_INLINE_DECL_REFCOUNTING(Layer)
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -3,17 +3,16 @@
 /* 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 <math.h>                       // for fabsf, fabs, atan2
 #include <stdint.h>                     // for uint32_t, uint64_t
 #include <sys/types.h>                  // for int32_t
 #include <algorithm>                    // for max, min
-#include "AnimationCommon.h"            // for ComputedTimingFunction
 #include "AsyncPanZoomController.h"     // for AsyncPanZoomController, etc
 #include "Compositor.h"                 // for Compositor
 #include "CompositorParent.h"           // for CompositorParent
 #include "FrameMetrics.h"               // for FrameMetrics, etc
 #include "GestureEventListener.h"       // for GestureEventListener
 #include "InputData.h"                  // for MultiTouchInput, etc
 #include "TouchBlockState.h"            // for TouchBlockState
 #include "Units.h"                      // for CSSRect, CSSPoint, etc
@@ -27,16 +26,17 @@
 #include "mozilla/BasicEvents.h"        // for Modifiers, MODIFIER_*
 #include "mozilla/ClearOnShutdown.h"    // for ClearOnShutdown
 #include "mozilla/Constants.h"          // for M_PI
 #include "mozilla/EventForwards.h"      // for nsEventStatus_*
 #include "mozilla/Preferences.h"        // for Preferences
 #include "mozilla/ReentrantMonitor.h"   // for ReentrantMonitorAutoEnter, etc
 #include "mozilla/StaticPtr.h"          // for StaticAutoPtr
 #include "mozilla/TimeStamp.h"          // for TimeDuration, TimeStamp
+#include "mozilla/dom/AnimationPlayer.h" // for ComputedTimingFunction
 #include "mozilla/dom/Touch.h"          // for Touch
 #include "mozilla/gfx/BasePoint.h"      // for BasePoint
 #include "mozilla/gfx/BaseRect.h"       // for BaseRect
 #include "mozilla/gfx/Point.h"          // for Point, RoundedToInt, etc
 #include "mozilla/gfx/Rect.h"           // for RoundedIn
 #include "mozilla/gfx/ScaleFactor.h"    // for ScaleFactor
 #include "mozilla/layers/APZCTreeManager.h"  // for ScrollableLayerGuid
 #include "mozilla/layers/AsyncCompositionManager.h"  // for ViewTransform
@@ -342,17 +342,17 @@ static const double AXIS_BREAKOUT_ANGLE 
  * Currently used only for touch-action css property stuff and was
  * added to keep behavior consistent with IE.
  */
 static const double ALLOWED_DIRECT_PAN_ANGLE = M_PI / 3.0; // 60 degrees
 
 /**
  * Computed time function used for sampling frames of a zoom to animation.
  */
-StaticAutoPtr<css::ComputedTimingFunction> gComputedTimingFunction;
+StaticAutoPtr<ComputedTimingFunction> gComputedTimingFunction;
 
 /**
  * Maximum zoom amount, always used, even if a page asks for higher.
  */
 static const CSSToScreenScale MAX_ZOOM(8.0f);
 
 /**
  * Minimum zoom amount, always used, even if a page asks for lower.
@@ -695,17 +695,17 @@ AsyncPanZoomController::InitializeGlobal
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   static bool sInitialized = false;
   if (sInitialized)
     return;
   sInitialized = true;
 
-  gComputedTimingFunction = new css::ComputedTimingFunction();
+  gComputedTimingFunction = new ComputedTimingFunction();
   gComputedTimingFunction->Init(
     nsTimingFunction(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE));
   ClearOnShutdown(&gComputedTimingFunction);
 }
 
 AsyncPanZoomController::AsyncPanZoomController(uint64_t aLayersId,
                                                APZCTreeManager* aTreeManager,
                                                GeckoContentController* aGeckoContentController,
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -1,32 +1,31 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set sw=2 ts=2 et tw=80 : */
 /* 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/layers/AsyncCompositionManager.h"
 #include <stdint.h>                     // for uint32_t
-#include "AnimationCommon.h"            // for ComputedTimingFunction
 #include "CompositorParent.h"           // for CompositorParent, etc
 #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 "gfxPoint3D.h"                 // for gfxPoint3D
 #include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue, etc
 #include "mozilla/WidgetUtils.h"        // for ComputeTransformForRotation
+#include "mozilla/dom/AnimationPlayer.h" // for AnimationPlayer
 #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/AsyncPanZoomController.h"
 #include "mozilla/layers/Compositor.h"  // for Compositor
-#include "nsAnimationManager.h"         // for ElementAnimations
 #include "nsCSSPropList.h"
 #include "nsCoord.h"                    // for NSAppUnitsToFloatPixels, etc
 #include "nsDebug.h"                    // for NS_ASSERTION, etc
 #include "nsDeviceContext.h"            // for nsDeviceContext
 #include "nsDisplayList.h"              // for nsDisplayTransform, etc
 #include "nsMathUtils.h"                // for NS_round
 #include "nsPoint.h"                    // for nsPoint
 #include "nsRect.h"                     // for nsIntRect
@@ -446,17 +445,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 =
-      ElementAnimation::GetComputedTimingAt(
+      dom::AnimationPlayer::GetComputedTimingAt(
         Nullable<TimeDuration>(elapsedDuration), timing);
 
     NS_ABORT_IF_FALSE(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
@@ -312,31 +312,31 @@ static void AddTransformFunctions(nsCSSV
       }
       default:
         NS_ERROR("Function not handled yet!");
     }
   }
 }
 
 static TimingFunction
-ToTimingFunction(css::ComputedTimingFunction& aCTF)
+ToTimingFunction(ComputedTimingFunction& aCTF)
 {
   if (aCTF.GetType() == nsTimingFunction::Function) {
     const nsSMILKeySpline* spline = aCTF.GetFunction();
     return TimingFunction(CubicBezierFunction(spline->X1(), spline->Y1(),
                                               spline->X2(), spline->Y2()));
   }
 
   uint32_t type = aCTF.GetType() == nsTimingFunction::StepStart ? 1 : 2;
   return TimingFunction(StepFunction(aCTF.GetSteps(), type));
 }
 
 static void
 AddAnimationForProperty(nsIFrame* aFrame, nsCSSProperty aProperty,
-                        mozilla::ElementAnimation* ea, Layer* aLayer,
+                        AnimationPlayer* ea, Layer* aLayer,
                         AnimationData& aData, bool aPending)
 {
   NS_ASSERTION(aLayer->AsContainerLayer(), "Should only animate ContainerLayer");
   nsStyleContext* styleContext = aFrame->StyleContext();
   nsPresContext* presContext = aFrame->PresContext();
   nsRect bounds = nsDisplayTransform::GetFrameBoundsForTransform(aFrame);
 
   mozilla::layers::Animation* animation =
@@ -386,17 +386,17 @@ AddAnimationForProperty(nsIFrame* aFrame
 }
 
 static void
 AddAnimationsForProperty(nsIFrame* aFrame, nsCSSProperty aProperty,
                          ElementAnimationPtrArray& aAnimations,
                          Layer* aLayer, AnimationData& aData,
                          bool aPending) {
   for (uint32_t animIdx = 0; animIdx < aAnimations.Length(); animIdx++) {
-    mozilla::ElementAnimation* anim = aAnimations[animIdx];
+    AnimationPlayer* anim = aAnimations[animIdx];
     if (!(anim->HasAnimationOfProperty(aProperty) && anim->IsRunning())) {
       continue;
     }
     AddAnimationForProperty(aFrame, aProperty, anim, aLayer, aData, aPending);
     anim->mIsRunningOnCompositor = true;
   }
 }
 
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -466,17 +466,17 @@ GetMinAndMaxScaleForAnimationProperty(ns
 {
   ElementAnimationCollection* collection =
     GetAnimationsOrTransitionsForCompositor(aContent, aAnimationProperty,
                                             eCSSProperty_transform);
   if (!collection)
     return;
 
   for (uint32_t animIdx = collection->mAnimations.Length(); animIdx-- != 0; ) {
-    mozilla::ElementAnimation* anim = collection->mAnimations[animIdx];
+    AnimationPlayer* anim = collection->mAnimations[animIdx];
     if (anim->IsFinishedTransition()) {
       continue;
     }
     for (uint32_t propIdx = anim->mProperties.Length(); propIdx-- != 0; ) {
       AnimationProperty& prop = anim->mProperties[propIdx];
       if (prop.mProperty == eCSSProperty_transform) {
         for (uint32_t segIdx = prop.mSegments.Length(); segIdx-- != 0; ) {
           AnimationPropertySegment& segment = prop.mSegments[segIdx];
--- a/layout/style/AnimationCommon.cpp
+++ b/layout/style/AnimationCommon.cpp
@@ -2,17 +2,16 @@
 /* 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 "AnimationCommon.h"
 #include "nsTransitionManager.h"
 #include "nsAnimationManager.h"
 
-#include "mozilla/dom/AnimationPlayerBinding.h"
 #include "ActiveLayerTracker.h"
 #include "gfxPlatform.h"
 #include "nsRuleData.h"
 #include "nsCSSPropertySet.h"
 #include "nsCSSValue.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsStyleContext.h"
 #include "nsIFrame.h"
@@ -23,16 +22,17 @@
 #include "nsDisplayList.h"
 #include "mozilla/MemoryReporting.h"
 #include "RestyleManager.h"
 #include "nsStyleSet.h"
 #include "nsStyleChangeList.h"
 
 
 using mozilla::layers::Layer;
+using mozilla::dom::AnimationPlayer;
 
 namespace mozilla {
 
 /* static */ bool
 IsGeometricProperty(nsCSSProperty aProperty)
 {
   switch (aProperty) {
     case eCSSProperty_bottom:
@@ -249,293 +249,18 @@ AnimValuesStyleRule::List(FILE* out, int
     StyleAnimationValue::UncomputeValue(pair.mProperty, pair.mValue, value);
     fprintf(out, "%s: %s; ", nsCSSProps::GetStringValue(pair.mProperty).get(),
                              NS_ConvertUTF16toUTF8(value).get());
   }
   fputs("}\n", out);
 }
 #endif
 
-void
-ComputedTimingFunction::Init(const nsTimingFunction &aFunction)
-{
-  mType = aFunction.mType;
-  if (mType == nsTimingFunction::Function) {
-    mTimingFunction.Init(aFunction.mFunc.mX1, aFunction.mFunc.mY1,
-                         aFunction.mFunc.mX2, aFunction.mFunc.mY2);
-  } else {
-    mSteps = aFunction.mSteps;
-  }
-}
-
-static inline double
-StepEnd(uint32_t aSteps, double aPortion)
-{
-  NS_ABORT_IF_FALSE(0.0 <= aPortion && aPortion <= 1.0, "out of range");
-  uint32_t step = uint32_t(aPortion * aSteps); // floor
-  return double(step) / double(aSteps);
-}
-
-double
-ComputedTimingFunction::GetValue(double aPortion) const
-{
-  switch (mType) {
-    case nsTimingFunction::Function:
-      return mTimingFunction.GetSplineValue(aPortion);
-    case nsTimingFunction::StepStart:
-      // There are diagrams in the spec that seem to suggest this check
-      // and the bounds point should not be symmetric with StepEnd, but
-      // should actually step up at rather than immediately after the
-      // fraction points.  However, we rely on rounding negative values
-      // up to zero, so we can't do that.  And it's not clear the spec
-      // really meant it.
-      return 1.0 - StepEnd(mSteps, 1.0 - aPortion);
-    default:
-      NS_ABORT_IF_FALSE(false, "bad type");
-      // fall through
-    case nsTimingFunction::StepEnd:
-      return StepEnd(mSteps, aPortion);
-  }
-}
-
 } /* end sub-namespace css */
 
-// 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 =
-  mozilla::PositiveInfinity<double>();
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ElementAnimation, mTimeline)
-
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(ElementAnimation, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(ElementAnimation, Release)
-
-JSObject*
-ElementAnimation::WrapObject(JSContext* aCx)
-{
-  return dom::AnimationPlayerBinding::Wrap(aCx, this);
-}
-
-double
-ElementAnimation::StartTime() const
-{
-  Nullable<double> startTime = mTimeline->ToTimelineTime(mStartTime);
-  return startTime.IsNull() ? 0.0 : startTime.Value();
-}
-
-double
-ElementAnimation::CurrentTime() const
-{
-  // In Web Animations, AnimationPlayers have a *current* time and Animations
-  // have a *local* time. However, since we have a 1:1 correspondence between
-  // AnimationPlayers and Animations, and since the startTime of *Animations*
-  // (but not AnimationPlayers) is always 0, these are currently identical.
-  Nullable<TimeDuration> currentTime = GetLocalTime();
-
-  // The current time is only going to be null when we don't have a refresh
-  // driver or navigation timing object and never did.
-  //
-  // Web Animations says that in this case we should use a timeline time of
-  // 0 (the "effective timeline time") and calculate the current time from that.
-  // Doing that, however, requires storing the start time as an offset rather
-  // than a timestamp so for now we just return 0.
-  //
-  // FIXME: Store player start time and pause start as offsets rather than
-  // timestamps and return the appropriate current time when the timeline time
-  // is null.
-  if (currentTime.IsNull()) {
-    return 0.0;
-  }
-
-  return currentTime.Value().ToMilliseconds();
-}
-
-bool
-ElementAnimation::IsRunning() const
-{
-  if (IsPaused() || IsFinishedTransition()) {
-    return false;
-  }
-
-  ComputedTiming computedTiming = GetComputedTiming(mTiming);
-  return computedTiming.mPhase == ComputedTiming::AnimationPhase_Active;
-}
-
-bool
-ElementAnimation::IsCurrent() const
-{
-  if (IsFinishedTransition()) {
-    return false;
-  }
-
-  ComputedTiming computedTiming = GetComputedTiming(mTiming);
-  return computedTiming.mPhase == ComputedTiming::AnimationPhase_Before ||
-         computedTiming.mPhase == ComputedTiming::AnimationPhase_Active;
-}
-
-bool
-ElementAnimation::HasAnimationOfProperty(nsCSSProperty aProperty) const
-{
-  for (uint32_t propIdx = 0, propEnd = mProperties.Length();
-       propIdx != propEnd; ++propIdx) {
-    if (aProperty == mProperties[propIdx].mProperty) {
-      return true;
-    }
-  }
-  return false;
-}
-
-ComputedTiming
-ElementAnimation::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.
-  MOZ_ASSERT(aTiming.mIterationDuration >= zeroDuration,
-             "Expecting iteration duration >= 0");
-
-  // Always return the same object to benefit from return-value optimization.
-  ComputedTiming result;
-
-  result.mActiveDuration = ActiveDuration(aTiming);
-
-  // The default constructor for ComputedTiming sets all other members to
-  // values consistent with an animation that has not been sampled.
-  if (aLocalTime.IsNull()) {
-    return result;
-  }
-  const TimeDuration& localTime = aLocalTime.Value();
-
-  // When we finish exactly at the end of an iteration we need to report
-  // the end of the final iteration and not the start of the next iteration
-  // so we set up a flag for that case.
-  bool isEndOfFinalIteration = false;
-
-  // Get the normalized time within the active interval.
-  TimeDuration activeTime;
-  // FIXME: The following check that the active duration is not equal to Forever
-  // is a temporary workaround to avoid overflow and should be removed once
-  // bug 1039924 is fixed.
-  if (result.mActiveDuration != TimeDuration::Forever() &&
-      localTime >= aTiming.mDelay + result.mActiveDuration) {
-    result.mPhase = ComputedTiming::AnimationPhase_After;
-    if (!aTiming.FillsForwards()) {
-      // The animation isn't active or filling at this time.
-      result.mTimeFraction = ComputedTiming::kNullTimeFraction;
-      return result;
-    }
-    activeTime = result.mActiveDuration;
-    // Note that infinity == floor(infinity) so this will also be true when we
-    // have finished an infinitely repeating animation of zero duration.
-    isEndOfFinalIteration =
-      aTiming.mIterationCount != 0.0 &&
-      aTiming.mIterationCount == floor(aTiming.mIterationCount);
-  } else if (localTime < aTiming.mDelay) {
-    result.mPhase = ComputedTiming::AnimationPhase_Before;
-    if (!aTiming.FillsBackwards()) {
-      // The animation isn't active or filling at this time.
-      result.mTimeFraction = ComputedTiming::kNullTimeFraction;
-      return result;
-    }
-    // activeTime is zero
-  } else {
-    MOZ_ASSERT(result.mActiveDuration != zeroDuration,
-               "How can we be in the middle of a zero-duration interval?");
-    result.mPhase = ComputedTiming::AnimationPhase_Active;
-    activeTime = localTime - aTiming.mDelay;
-  }
-
-  // Get the position within the current iteration.
-  TimeDuration iterationTime;
-  if (aTiming.mIterationDuration != zeroDuration) {
-    iterationTime = isEndOfFinalIteration
-                    ? aTiming.mIterationDuration
-                    : activeTime % aTiming.mIterationDuration;
-  } /* else, iterationTime is zero */
-
-  // Determine the 0-based index of the current iteration.
-  if (isEndOfFinalIteration) {
-    result.mCurrentIteration =
-      aTiming.mIterationCount == NS_IEEEPositiveInfinity()
-      ? UINT64_MAX // FIXME: When we return this via the API we'll need
-                   // to make sure it ends up being infinity.
-      : static_cast<uint64_t>(aTiming.mIterationCount) - 1;
-  } else if (activeTime == zeroDuration) {
-    // If the active time is zero we're either in the first iteration
-    // (including filling backwards) or we have finished an animation with an
-    // iteration duration of zero that is filling forwards (but we're not at
-    // the exact end of an iteration since we deal with that above).
-    result.mCurrentIteration =
-      result.mPhase == ComputedTiming::AnimationPhase_After
-      ? static_cast<uint64_t>(aTiming.mIterationCount) // floor
-      : 0;
-  } else {
-    result.mCurrentIteration =
-      static_cast<uint64_t>(activeTime / aTiming.mIterationDuration); // floor
-  }
-
-  // Normalize the iteration time into a fraction of the iteration duration.
-  if (result.mPhase == ComputedTiming::AnimationPhase_Before) {
-    result.mTimeFraction = 0.0;
-  } else if (result.mPhase == ComputedTiming::AnimationPhase_After) {
-    result.mTimeFraction = isEndOfFinalIteration
-                         ? 1.0
-                         : fmod(aTiming.mIterationCount, 1.0f);
-  } else {
-    // We are in the active phase so the iteration duration can't be zero.
-    MOZ_ASSERT(aTiming.mIterationDuration != zeroDuration,
-               "In the active phase of a zero-duration animation?");
-    result.mTimeFraction =
-      aTiming.mIterationDuration == TimeDuration::Forever()
-      ? 0.0
-      : iterationTime / aTiming.mIterationDuration;
-  }
-
-  bool thisIterationReverse = false;
-  switch (aTiming.mDirection) {
-    case NS_STYLE_ANIMATION_DIRECTION_NORMAL:
-      thisIterationReverse = false;
-      break;
-    case NS_STYLE_ANIMATION_DIRECTION_REVERSE:
-      thisIterationReverse = true;
-      break;
-    case NS_STYLE_ANIMATION_DIRECTION_ALTERNATE:
-      thisIterationReverse = (result.mCurrentIteration & 1) == 1;
-      break;
-    case NS_STYLE_ANIMATION_DIRECTION_ALTERNATE_REVERSE:
-      thisIterationReverse = (result.mCurrentIteration & 1) == 0;
-      break;
-  }
-  if (thisIterationReverse) {
-    result.mTimeFraction = 1.0 - result.mTimeFraction;
-  }
-
-  return result;
-}
-
-TimeDuration
-ElementAnimation::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 TimeDuration zeroDuration;
-    return aTiming.mIterationDuration == zeroDuration
-           ? zeroDuration
-           : TimeDuration::Forever();
-  }
-  return aTiming.mIterationDuration.MultDouble(aTiming.mIterationCount);
-}
-
 bool
 ElementAnimationCollection::CanAnimatePropertyOnCompositor(
   const dom::Element *aElement,
   nsCSSProperty aProperty,
   CanAnimateFlags aFlags)
 {
   bool shouldLog = nsLayoutUtils::IsAnimationLoggingEnabled();
   if (!gfxPlatform::OffMainThreadCompositingEnabled()) {
@@ -623,31 +348,31 @@ ElementAnimationCollection::CanPerformOn
       message.Append(nsAtomCString(mElementProperty));
       message.Append(")");
       LogAsyncAnimationFailure(message, mElement);
     }
     return false;
   }
 
   for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
-    const ElementAnimation* anim = mAnimations[animIdx];
+    const AnimationPlayer* anim = mAnimations[animIdx];
     bool isRunning = anim->IsRunning();
     for (uint32_t propIdx = 0, propEnd = anim->mProperties.Length();
          propIdx != propEnd; ++propIdx) {
       if (IsGeometricProperty(anim->mProperties[propIdx].mProperty) &&
           isRunning) {
         aFlags = CanAnimateFlags(aFlags | CanAnimate_HasGeometricProperty);
         break;
       }
     }
   }
 
   bool existsProperty = false;
   for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
-    const ElementAnimation* anim = mAnimations[animIdx];
+    const AnimationPlayer* anim = mAnimations[animIdx];
     if (!anim->IsRunning()) {
       continue;
     }
 
     existsProperty = true;
 
     for (uint32_t propIdx = 0, propEnd = anim->mProperties.Length();
          propIdx != propEnd; ++propIdx) {
@@ -669,17 +394,17 @@ ElementAnimationCollection::CanPerformOn
   return true;
 }
 
 bool
 ElementAnimationCollection::HasAnimationOfProperty(
   nsCSSProperty aProperty) const
 {
   for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
-    const ElementAnimation* anim = mAnimations[animIdx];
+    const AnimationPlayer* anim = mAnimations[animIdx];
     if (anim->HasAnimationOfProperty(aProperty) &&
         !anim->IsFinishedTransition()) {
       return true;
     }
   }
   return false;
 }
 
@@ -728,17 +453,17 @@ ElementAnimationCollection::EnsureStyleR
   // If we're performing animations on the compositor thread, then we can skip
   // most of the work in this method. But even if we are throttled, then we
   // have to do the work if an animation is ending in order to get correct end
   // of animation behaviour (the styles of the animation disappear, or the fill
   // mode behaviour). This loop checks for any finishing animations and forces
   // the style recalculation if we find any.
   if (aFlags == EnsureStyleRule_IsThrottled) {
     for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
-      ElementAnimation* anim = mAnimations[animIdx];
+      AnimationPlayer* anim = mAnimations[animIdx];
 
       // Skip finished transitions or animations whose @keyframes rule
       // is empty.
       if (anim->IsFinishedTransition() || anim->mProperties.IsEmpty()) {
         continue;
       }
 
       // The GetLocalTime() call here handles pausing.  But:
@@ -746,17 +471,17 @@ ElementAnimationCollection::EnsureStyleR
       ComputedTiming computedTiming = anim->GetComputedTiming(anim->mTiming);
 
       // XXX We shouldn't really be using mLastNotification as a general
       // indicator that the animation has finished, it should be reserved for
       // events. If we use it differently in the future this use might need
       // changing.
       if (!anim->mIsRunningOnCompositor ||
           (computedTiming.mPhase == ComputedTiming::AnimationPhase_After &&
-           anim->mLastNotification != ElementAnimation::LAST_NOTIFICATION_END))
+           anim->mLastNotification != AnimationPlayer::LAST_NOTIFICATION_END))
       {
         aFlags = EnsureStyleRule_IsNotThrottled;
         break;
       }
     }
   }
 
   if (aFlags == EnsureStyleRule_IsThrottled) {
@@ -772,17 +497,17 @@ ElementAnimationCollection::EnsureStyleR
     mNeedsRefreshes = false;
 
     // FIXME(spec): assume that properties in higher animations override
     // those in lower ones.
     // Therefore, we iterate from last animation to first.
     nsCSSPropertySet properties;
 
     for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
-      ElementAnimation* anim = mAnimations[animIdx];
+      AnimationPlayer* anim = mAnimations[animIdx];
 
       if (anim->IsFinishedTransition()) {
         continue;
       }
 
       // The GetLocalTime() call here handles pausing.  But:
       // FIXME: avoid recalculating every time when paused.
       ComputedTiming computedTiming = anim->GetComputedTiming(anim->mTiming);
--- a/layout/style/AnimationCommon.h
+++ b/layout/style/AnimationCommon.h
@@ -8,40 +8,32 @@
 
 #include "nsIStyleRuleProcessor.h"
 #include "nsIStyleRule.h"
 #include "nsRefreshDriver.h"
 #include "prclist.h"
 #include "nsCSSProperty.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/StyleAnimationValue.h"
-#include "mozilla/dom/AnimationTimeline.h"
+#include "mozilla/dom/AnimationPlayer.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Nullable.h"
-#include "nsSMILKeySpline.h"
 #include "nsStyleStruct.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/FloatingPoint.h"
 #include "nsCSSPseudoElements.h"
 #include "nsCycleCollectionParticipant.h"
 
 class nsIFrame;
 class nsPresContext;
 class nsStyleChangeList;
 
-// X11 has a #define for CurrentTime.
-#ifdef CurrentTime
-#undef CurrentTime
-#endif
-
 namespace mozilla {
 
 class RestyleTracker;
-class StyleAnimationValue;
-struct ElementPropertyTransition;
 struct ElementAnimationCollection;
 
 namespace css {
 
 bool IsGeometricProperty(nsCSSProperty aProperty);
 
 class CommonAnimationManager : public nsIStyleRuleProcessor,
                                public nsARefreshObserver {
@@ -140,246 +132,20 @@ public:
   };
 
 private:
   ~AnimValuesStyleRule() {}
 
   InfallibleTArray<PropertyValuePair> mPropertyValuePairs;
 };
 
-class ComputedTimingFunction {
-public:
-  typedef nsTimingFunction::Type Type;
-  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; }
-private:
-  Type mType;
-  nsSMILKeySpline mTimingFunction;
-  uint32_t mSteps;
-};
-
 } /* end css sub-namespace */
 
-struct AnimationPropertySegment
-{
-  float mFromKey, mToKey;
-  mozilla::StyleAnimationValue mFromValue, mToValue;
-  mozilla::css::ComputedTimingFunction mTimingFunction;
-};
-
-struct AnimationProperty
-{
-  nsCSSProperty mProperty;
-  InfallibleTArray<AnimationPropertySegment> mSegments;
-};
-
-/**
- * Input timing parameters.
- *
- * Eventually this will represent all the input timing parameters specified
- * by content but for now it encapsulates just the subset of those
- * parameters passed to GetPositionInIteration.
- */
-struct AnimationTiming
-{
-  mozilla::TimeDuration mIterationDuration;
-  mozilla::TimeDuration mDelay;
-  float mIterationCount; // mozilla::PositiveInfinity<float>() means infinite
-  uint8_t mDirection;
-  uint8_t mFillMode;
-
-  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;
-  }
-};
-
-/**
- * Stores the results of calculating the timing properties of an animation
- * at a given sample time.
- */
-struct ComputedTiming
-{
-  ComputedTiming()
-  : mTimeFraction(kNullTimeFraction)
-  , mCurrentIteration(0)
-  , mPhase(AnimationPhase_Null)
-  { }
-
-  static const double kNullTimeFraction;
-
-  // The total duration of the animation including all iterations.
-  // Will equal TimeDuration::Forever() if the animation repeats indefinitely.
-  TimeDuration mActiveDuration;
-
-  // Will be kNullTimeFraction if the animation is neither animating nor
-  // filling at the sampled time.
-  double mTimeFraction;
-
-  // Zero-based iteration index (meaningless if mTimeFraction is
-  // kNullTimeFraction).
-  uint64_t mCurrentIteration;
-
-  enum {
-    // Not sampled (null sample time)
-    AnimationPhase_Null,
-    // Sampled prior to the start of the active interval
-    AnimationPhase_Before,
-    // Sampled within the active interval
-    AnimationPhase_Active,
-    // Sampled after (or at) the end of the active interval
-    AnimationPhase_After
-  } mPhase;
-};
-
-/**
- * Data about one animation (i.e., one of the values of
- * 'animation-name') running on an element.
- */
-class ElementAnimation : public nsWrapperCache
-{
-protected:
-  virtual ~ElementAnimation() { }
-
-public:
-  explicit ElementAnimation(dom::AnimationTimeline* aTimeline)
-    : mIsRunningOnCompositor(false)
-    , mIsFinishedTransition(false)
-    , mLastNotification(LAST_NOTIFICATION_NONE)
-    , mTimeline(aTimeline)
-  {
-    SetIsDOMBinding();
-  }
-
-  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(ElementAnimation)
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(ElementAnimation)
-
-  dom::AnimationTimeline* GetParentObject() const { return mTimeline; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
-
-  // AnimationPlayer methods
-  dom::AnimationTimeline* Timeline() const { return mTimeline; }
-  double StartTime() const;
-  double CurrentTime() const;
-
-  // 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;
-  }
-
-  bool IsPaused() const {
-    return mPlayState == NS_STYLE_ANIMATION_PLAY_STATE_PAUSED;
-  }
-
-  // After transitions finish they need to be retained for one throttle-able
-  // cycle (for reasons see explanation in nsTransitionManager.cpp). In the
-  // meantime, however, they should be ignored.
-  bool IsFinishedTransition() const {
-    return mIsFinishedTransition;
-  }
-  void SetFinishedTransition() {
-    MOZ_ASSERT(AsTransition(),
-               "Calling SetFinishedTransition but it's not a transition");
-    mIsFinishedTransition = true;
-  }
-
-  bool HasAnimationOfProperty(nsCSSProperty aProperty) const;
-  bool IsRunning() const;
-  bool IsCurrent() const;
-
-  // Return the duration since the start of the delay period, taking into
-  // account the pause state.  May be negative.
-  // Returns a null value if the timeline associated with this object has a
-  // current timestamp that is null or if the start time of this object is
-  // null.
-  Nullable<mozilla::TimeDuration> GetLocalTime() const {
-    const mozilla::TimeStamp& timelineTime = mTimeline->GetCurrentTimeStamp();
-    // FIXME: In order to support arbitrary timelines we will need to fix
-    // the pause logic to handle the timeline time going backwards.
-    MOZ_ASSERT(timelineTime.IsNull() || !IsPaused() ||
-               timelineTime >= mPauseStart,
-               "if paused, any non-null value of aTime must be at least"
-               " mPauseStart");
-
-    Nullable<mozilla::TimeDuration> result; // Initializes to null
-    if (!timelineTime.IsNull() && !mStartTime.IsNull()) {
-      result.SetValue((IsPaused() ? mPauseStart : timelineTime) - mStartTime);
-    }
-    return result;
-  }
-
-  // Return the duration from the start the active interval to the point where
-  // the animation begins playback. This is zero unless the animation has
-  // a negative delay in which case it is the absolute value of the delay.
-  // This is used for setting the elapsedTime member of AnimationEvents.
-  mozilla::TimeDuration InitialAdvance() const {
-    return std::max(TimeDuration(), mTiming.mDelay * -1);
-  }
-
-  // This function takes as input the timing parameters of an animation and
-  // returns the computed timing at the specified local time.
-  //
-  // The local time may be null in which case only static parameters such as the
-  // active duration are calculated. All other members of the returned object
-  // are given a null/initial value.
-  //
-  // This function returns ComputedTiming::kNullTimeFraction for the
-  // mTimeFraction member of the return value if the animation should not be
-  // run (because it is not currently active and is not filling at this time).
-  static ComputedTiming
-  GetComputedTimingAt(const Nullable<mozilla::TimeDuration>& aLocalTime,
-                      const AnimationTiming& aTiming);
-
-  // Shortcut for that gets the computed timing using the current local time as
-  // calculated from the timeline time.
-  ComputedTiming GetComputedTiming(const AnimationTiming& aTiming) const {
-    return GetComputedTimingAt(GetLocalTime(), aTiming);
-  }
-
-  // Return the duration of the active interval for the given timing parameters.
-  static mozilla::TimeDuration ActiveDuration(const AnimationTiming& aTiming);
-
-  nsString mName;
-  AnimationTiming mTiming;
-  // The beginning of the delay period.
-  mozilla::TimeStamp mStartTime;
-  mozilla::TimeStamp mPauseStart;
-  uint8_t mPlayState;
-  bool mIsRunningOnCompositor;
-  // A flag to mark transitions that have finished and are due to
-  // be removed on the next throttle-able cycle.
-  bool mIsFinishedTransition;
-
-  enum {
-    LAST_NOTIFICATION_NONE = uint64_t(-1),
-    LAST_NOTIFICATION_END = uint64_t(-2)
-  };
-  // One of the above constants, or an integer for the iteration
-  // whose start we last notified on.
-  uint64_t mLastNotification;
-
-  InfallibleTArray<AnimationProperty> mProperties;
-
-  nsRefPtr<dom::AnimationTimeline> mTimeline;
-};
-
-typedef InfallibleTArray<nsRefPtr<ElementAnimation> > ElementAnimationPtrArray;
+typedef InfallibleTArray<nsRefPtr<dom::AnimationPlayer> >
+  ElementAnimationPtrArray;
 
 enum EnsureStyleRuleFlags {
   EnsureStyleRule_IsThrottled,
   EnsureStyleRule_IsNotThrottled
 };
 
 struct ElementAnimationCollection : public PRCList
 {
--- a/layout/style/nsAnimationManager.cpp
+++ b/layout/style/nsAnimationManager.cpp
@@ -4,30 +4,32 @@
  * 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/AnimationPlayer.h"
 
 #include "nsPresContext.h"
 #include "nsRuleProcessorData.h"
 #include "nsStyleSet.h"
 #include "nsStyleChangeList.h"
 #include "nsCSSRules.h"
 #include "RestyleManager.h"
 #include "nsLayoutUtils.h"
 #include "nsIFrame.h"
 #include "nsIDocument.h"
 #include <math.h>
 
 using namespace mozilla;
 using namespace mozilla::css;
+using mozilla::dom::AnimationPlayer;
 
 void
 nsAnimationManager::UpdateStyleAndEvents(ElementAnimationCollection*
                                            aCollection,
                                          TimeStamp aRefreshTime,
                                          EnsureStyleRuleFlags aFlags)
 {
   aCollection->EnsureStyleRuleFor(aRefreshTime, aFlags);
@@ -36,17 +38,17 @@ nsAnimationManager::UpdateStyleAndEvents
 }
 
 void
 nsAnimationManager::GetEventsForCurrentTime(ElementAnimationCollection*
                                               aCollection,
                                             EventArray& aEventsToDispatch)
 {
   for (uint32_t animIdx = aCollection->mAnimations.Length(); animIdx-- != 0; ) {
-    ElementAnimation* anim = aCollection->mAnimations[animIdx];
+    AnimationPlayer* anim = aCollection->mAnimations[animIdx];
 
     ComputedTiming computedTiming = anim->GetComputedTiming(anim->mTiming);
 
     switch (computedTiming.mPhase) {
       case ComputedTiming::AnimationPhase_Null:
       case ComputedTiming::AnimationPhase_Before:
         // Do nothing
         break;
@@ -56,17 +58,17 @@ nsAnimationManager::GetEventsForCurrentT
         if (computedTiming.mCurrentIteration != anim->mLastNotification) {
           // Notify 'animationstart' even if a negative delay puts us
           // past the first iteration.
           // Note that when somebody changes the animation-duration
           // dynamically, this will fire an extra iteration event
           // immediately in many cases.  It's not clear to me if that's the
           // right thing to do.
           uint32_t message =
-            anim->mLastNotification == ElementAnimation::LAST_NOTIFICATION_NONE
+            anim->mLastNotification == AnimationPlayer::LAST_NOTIFICATION_NONE
               ? NS_ANIMATION_START : NS_ANIMATION_ITERATION;
 
           anim->mLastNotification = computedTiming.mCurrentIteration;
           TimeDuration iterationStart =
             anim->mTiming.mIterationDuration *
             computedTiming.mCurrentIteration;
           TimeDuration elapsedTime =
             std::max(iterationStart, anim->InitialAdvance());
@@ -75,32 +77,32 @@ nsAnimationManager::GetEventsForCurrentT
           aEventsToDispatch.AppendElement(ei);
         }
         break;
 
       case ComputedTiming::AnimationPhase_After:
         // If we skipped the animation interval entirely, dispatch
         // 'animationstart' first
         if (anim->mLastNotification ==
-            ElementAnimation::LAST_NOTIFICATION_NONE) {
+            AnimationPlayer::LAST_NOTIFICATION_NONE) {
           // Notifying for start of 0th iteration.
           // (This is overwritten below but we set it here to maintain
           // internal consistency.)
           anim->mLastNotification = 0;
           TimeDuration elapsedTime =
             std::min(anim->InitialAdvance(), computedTiming.mActiveDuration);
           AnimationEventInfo ei(aCollection->mElement,
                                 anim->mName, NS_ANIMATION_START,
                                 elapsedTime, aCollection->PseudoElement());
           aEventsToDispatch.AppendElement(ei);
         }
         // Dispatch 'animationend' when needed.
         if (anim->mLastNotification !=
-            ElementAnimation::LAST_NOTIFICATION_END) {
-          anim->mLastNotification = ElementAnimation::LAST_NOTIFICATION_END;
+            AnimationPlayer::LAST_NOTIFICATION_END) {
+          anim->mLastNotification = AnimationPlayer::LAST_NOTIFICATION_END;
           AnimationEventInfo ei(aCollection->mElement,
                                 anim->mName, NS_ANIMATION_END,
                                 computedTiming.mActiveDuration,
                                 aCollection->PseudoElement());
           aEventsToDispatch.AppendElement(ei);
         }
         break;
     }
@@ -263,28 +265,28 @@ nsAnimationManager::CheckAnimationRule(n
       // spec says to do, but WebKit seems to honor at least some of
       // them.  See
       // http://lists.w3.org/Archives/Public/www-style/2011Apr/0079.html
       // In order to honor what the spec said, we'd copy more data over
       // (or potentially optimize BuildAnimations to avoid rebuilding it
       // in the first place).
       if (!collection->mAnimations.IsEmpty()) {
         for (size_t newIdx = newAnimations.Length(); newIdx-- != 0;) {
-          ElementAnimation* newAnim = newAnimations[newIdx];
+          AnimationPlayer* newAnim = newAnimations[newIdx];
 
           // Find the matching animation with this name in the old list
           // of animations.  We iterate through both lists in a backwards
           // direction which means that if there are more animations in
           // the new list of animations with a given name than in the old
           // list, it will be the animations towards the of the beginning of
           // the list that do not match and are treated as new animations.
-          nsRefPtr<ElementAnimation> oldAnim;
+          nsRefPtr<AnimationPlayer> oldAnim;
           size_t oldIdx = collection->mAnimations.Length();
           while (oldIdx-- != 0) {
-            ElementAnimation* a = collection->mAnimations[oldIdx];
+            AnimationPlayer* a = collection->mAnimations[oldIdx];
             if (a->mName == newAnim->mName) {
               oldAnim = a;
               break;
             }
           }
           if (!oldAnim) {
             continue;
           }
@@ -414,28 +416,28 @@ nsAnimationManager::BuildAnimations(nsSt
   for (uint32_t animIdx = 0, animEnd = disp->mAnimationNameCount;
        animIdx != animEnd; ++animIdx) {
     const StyleAnimation& src = disp->mAnimations[animIdx];
 
     // CSS Animations whose animation-name does not match a @keyframes rule do
     // not generate animation events. This includes when the animation-name is
     // "none" which is represented by an empty name in the StyleAnimation.
     // Since such animations neither affect style nor dispatch events, we do
-    // not generate a corresponding ElementAnimation for them.
+    // not generate a corresponding AnimationPlayer for them.
     nsCSSKeyframesRule* rule =
       src.GetName().IsEmpty()
       ? nullptr
       : mPresContext->StyleSet()->KeyframesRuleForName(mPresContext,
                                                        src.GetName());
     if (!rule) {
       continue;
     }
 
-    nsRefPtr<ElementAnimation> dest =
-      *aAnimations.AppendElement(new ElementAnimation(aTimeline));
+    nsRefPtr<AnimationPlayer> dest =
+      *aAnimations.AppendElement(new AnimationPlayer(aTimeline));
 
     dest->mName = src.GetName();
 
     dest->mTiming.mIterationDuration =
       TimeDuration::FromMilliseconds(src.GetDuration());
     dest->mTiming.mDelay = TimeDuration::FromMilliseconds(src.GetDelay());
     dest->mTiming.mIterationCount = src.GetIterationCount();
     dest->mTiming.mDirection = src.GetDirection();
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -255,17 +255,17 @@ nsTransitionManager::StyleContextChanged
     }
 
     ElementAnimationPtrArray& animations = collection->mAnimations;
     uint32_t i = animations.Length();
     NS_ABORT_IF_FALSE(i != 0, "empty transitions list?");
     StyleAnimationValue currentValue;
     do {
       --i;
-      ElementAnimation* animation = animations[i];
+      AnimationPlayer* animation = animations[i];
       MOZ_ASSERT(animation->mProperties.Length() == 1,
                  "Should have one animation property for a transition");
       MOZ_ASSERT(animation->mProperties[0].mSegments.Length() == 1,
                  "Animation property should have one segment for a transition");
       const AnimationProperty& prop = animation->mProperties[0];
       const AnimationPropertySegment& segment = prop.mSegments[0];
           // properties no longer in 'transition-property'
       if ((checkProperties &&
@@ -308,17 +308,17 @@ nsTransitionManager::StyleContextChanged
   // results than applying the transition rule immediately would).
   // Our caller is responsible for restyling again using this covering
   // rule.
 
   nsRefPtr<css::AnimValuesStyleRule> coverRule = new css::AnimValuesStyleRule;
 
   ElementAnimationPtrArray& animations = collection->mAnimations;
   for (uint32_t i = 0, i_end = animations.Length(); i < i_end; ++i) {
-    ElementAnimation* animation = animations[i];
+    AnimationPlayer* animation = animations[i];
     MOZ_ASSERT(animation->mProperties.Length() == 1,
                "Should have one animation property for a transition");
     MOZ_ASSERT(animation->mProperties[0].mSegments.Length() == 1,
                "Animation property should have one segment for a transition");
     AnimationProperty& prop = animation->mProperties[0];
     AnimationPropertySegment& segment = prop.mSegments[0];
     if (whichStarted.HasProperty(prop.mProperty)) {
       coverRule->AddValue(prop.mProperty, segment.mFromValue);
@@ -753,17 +753,17 @@ nsTransitionManager::FlushTransitions(Fl
                         "Element::UnbindFromTree should have "
                         "destroyed the element transitions object");
 
       uint32_t i = collection->mAnimations.Length();
       NS_ABORT_IF_FALSE(i != 0, "empty transitions list?");
       bool transitionStartedOrEnded = false;
       do {
         --i;
-        ElementAnimation* anim = collection->mAnimations[i];
+        AnimationPlayer* anim = collection->mAnimations[i];
         if (anim->IsFinishedTransition()) {
           // Actually remove transitions one throttle-able cycle after their
           // completion. We only clear on a throttle-able cycle because that
           // means it is a regular restyle tick and thus it is safe to discard
           // the transition. If the flush is not throttle-able, we might still
           // have new transitions left to process. See comment below.
           if (aFlags == Can_Throttle) {
             collection->mAnimations.RemoveElementAt(i);
--- a/layout/style/nsTransitionManager.h
+++ b/layout/style/nsTransitionManager.h
@@ -5,16 +5,17 @@
 
 /* Code to start and animate CSS transitions. */
 
 #ifndef nsTransitionManager_h_
 #define nsTransitionManager_h_
 
 #include "mozilla/Attributes.h"
 #include "mozilla/MemoryReporting.h"
+#include "mozilla/dom/AnimationPlayer.h"
 #include "AnimationCommon.h"
 #include "nsCSSPseudoElements.h"
 
 class nsStyleContext;
 class nsPresContext;
 class nsCSSPropertySet;
 struct ElementDependentRuleProcessorData;
 
@@ -23,20 +24,20 @@ struct StyleTransition;
 }
 
 /*****************************************************************************
  * Per-Element data                                                          *
  *****************************************************************************/
 
 namespace mozilla {
 
-struct ElementPropertyTransition : public mozilla::ElementAnimation
+struct ElementPropertyTransition : public dom::AnimationPlayer
 {
-  explicit ElementPropertyTransition(mozilla::dom::AnimationTimeline* aTimeline)
-    : mozilla::ElementAnimation(aTimeline) { }
+  explicit ElementPropertyTransition(dom::AnimationTimeline* aTimeline)
+    : dom::AnimationPlayer(aTimeline) { }
 
   virtual ElementPropertyTransition* AsTransition() { return this; }
   virtual const ElementPropertyTransition* AsTransition() const { return this; }
 
   // This is the start value to be used for a check for whether a
   // transition is being reversed.  Normally the same as
   // mProperties[0].mSegments[0].mFromValue, except when this transition
   // started as the reversal of another in-progress transition.