Bug 1415780 - Let nsPresContext have AnimationEventDispatcher. r?birtles draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Sat, 27 Jan 2018 21:17:27 +0900
changeset 748025 e7bc4f62b0d26c3a0369145ccbefcde8af3ba70f
parent 748024 3eba7ed427a1b6a5bef1ca2e6affb167d5e66976
child 748026 5f6604e37da8e2cd671b2e87cfa1c8e396347953
push id97048
push userhikezoe@mozilla.com
push dateSat, 27 Jan 2018 12:23:10 +0000
reviewersbirtles
bugs1415780
milestone60.0a1
Bug 1415780 - Let nsPresContext have AnimationEventDispatcher. r?birtles Now we sort CSS animation/transition events by scheduled event time prior to compositor order. SortEvents() will be a private method in the next patch in this patch series. MozReview-Commit-ID: ICkOayquN0f
dom/animation/AnimationEventDispatcher.h
layout/base/PresShell.cpp
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
layout/base/nsRefreshDriver.cpp
layout/style/AnimationCommon.h
layout/style/nsAnimationManager.cpp
layout/style/nsAnimationManager.h
layout/style/nsTransitionManager.cpp
layout/style/nsTransitionManager.h
--- a/dom/animation/AnimationEventDispatcher.h
+++ b/dom/animation/AnimationEventDispatcher.h
@@ -92,71 +92,76 @@ struct AnimationEventInfo
     MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Unexpected event type");
     return nullptr;
   }
 };
 
 class AnimationEventDispatcher final
 {
 public:
-  AnimationEventDispatcher() : mIsSorted(true) { }
+  explicit AnimationEventDispatcher(nsPresContext* aPresContext)
+    : mPresContext(aPresContext)
+    , mIsSorted(true)
+  {
+  }
 
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AnimationEventDispatcher)
   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AnimationEventDispatcher)
 
+  void Disconnect() {
+    mPresContext = nullptr;
+  }
+
   void QueueEvents(nsTArray<AnimationEventInfo>&& aEvents)
   {
     mPendingEvents.AppendElements(Move(aEvents));
     mIsSorted = false;
   }
 
-  // This is exposed as a separate method so that when we are dispatching
-  // *both* transition events and animation events we can sort both lists
-  // once using the current state of the document before beginning any
-  // dispatch.
+  // Sort all pending CSS animation/transition events by scheduled event time
+  // and composite order.
+  // https://drafts.csswg.org/web-animations/#update-animations-and-send-events
   void SortEvents()
   {
     if (mIsSorted) {
       return;
     }
 
     // FIXME: Replace with mPendingEvents.StableSort when bug 1147091 is
     // fixed.
     std::stable_sort(mPendingEvents.begin(), mPendingEvents.end(),
                      AnimationEventInfoLessThan());
     mIsSorted = true;
   }
 
-  // Takes a reference to the owning manager's pres context so it can
-  // detect if the pres context is destroyed while dispatching one of
-  // the events.
-  //
   // This will call SortEvents automatically if it has not already been
   // called.
-  void DispatchEvents(nsPresContext* const & aPresContext)
+  void DispatchEvents()
   {
-    if (!aPresContext || mPendingEvents.IsEmpty()) {
+    if (!mPresContext || mPendingEvents.IsEmpty()) {
       return;
     }
 
     SortEvents();
 
     EventArray events;
     mPendingEvents.SwapElements(events);
     // mIsSorted will be set to true by SortEvents above, and we leave it
     // that way since mPendingEvents is now empty
     for (AnimationEventInfo& info : events) {
       MOZ_ASSERT(!info.AsWidgetEvent()->mFlags.mIsBeingDispatched &&
                  !info.AsWidgetEvent()->mFlags.mDispatchedAtLeastOnce,
                  "The WidgetEvent should be fresh");
       EventDispatcher::Dispatch(info.mElement,
-                                aPresContext,
+                                mPresContext,
                                 info.AsWidgetEvent());
 
-      if (!aPresContext) {
+      // Bail out if our mPresContext was nullified due to destroying the pres
+      // context.
+      if (!mPresContext) {
         break;
       }
     }
   }
 
   void ClearEventQueue()
   {
     mPendingEvents.Clear();
@@ -181,16 +186,17 @@ private:
         }
       }
 
       AnimationPtrComparator<RefPtr<dom::Animation>> comparator;
       return comparator.LessThan(a.mAnimation, b.mAnimation);
     }
   };
 
+  nsPresContext* mPresContext;
   typedef nsTArray<AnimationEventInfo> EventArray;
   EventArray mPendingEvents;
   bool mIsSorted;
 };
 
 } // namespace mozilla
 
 #endif // mozilla_AnimationEventDispatcher_h
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -3,16 +3,17 @@
 /* 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/. */
 
 /* a presentation of a document, part 2 */
 
 #include "mozilla/PresShell.h"
 
+#include "mozilla/AnimationEventDispatcher.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/StyleSheetInlines.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/MemoryReporting.h"
@@ -1357,18 +1358,17 @@ PresShell::Destroy()
       mDocument->GetAnimationController()->NotifyRefreshDriverDestroying(rd);
     }
     for (DocumentTimeline* timeline : mDocument->Timelines()) {
       timeline->NotifyRefreshDriverDestroying(rd);
     }
   }
 
   if (mPresContext) {
-    mPresContext->AnimationManager()->ClearEventQueue();
-    mPresContext->TransitionManager()->ClearEventQueue();
+    mPresContext->AnimationEventDispatcher()->ClearEventQueue();
   }
 
   // Revoke any pending events.  We need to do this and cancel pending reflows
   // before we destroy the frame manager, since apparently frame destruction
   // sometimes spins the event queue when plug-ins are involved(!).
   if (mResizeEventPending) {
     rd->RemoveResizeEventFlushObserver(this);
   }
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -43,16 +43,17 @@
 #include "mozilla/RestyleManager.h"
 #include "mozilla/RestyleManagerInlines.h"
 #include "SurfaceCacheUtils.h"
 #include "nsMediaFeatures.h"
 #include "nsRuleNode.h"
 #include "gfxPlatform.h"
 #include "nsCSSRules.h"
 #include "nsFontFaceLoader.h"
+#include "mozilla/AnimationEventDispatcher.h"
 #include "mozilla/EffectCompositor.h"
 #include "mozilla/EventListenerManager.h"
 #include "prenv.h"
 #include "nsPluginFrame.h"
 #include "nsTransitionManager.h"
 #include "nsAnimationManager.h"
 #include "CounterStyleManager.h"
 #include "mozilla/MemoryReporting.h"
@@ -437,33 +438,31 @@ nsPresContext::LastRelease()
   if (mMissingFonts) {
     mMissingFonts->Clear();
   }
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsPresContext)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsPresContext)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAnimationManager);
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTransitionManager);
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAnimationEventDispatcher);
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument);
   // NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mDeviceContext); // not xpcom
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEffectCompositor);
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEventManager);
   // NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mLanguage); // an atom
 
   // NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTheme); // a service
   // NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLangService); // a service
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPrintSettings);
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPrefChangedTimer);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsPresContext)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mAnimationManager);
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mTransitionManager);
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mAnimationEventDispatcher);
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument);
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDeviceContext); // worth bothering?
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mEffectCompositor);
   // NS_RELEASE(tmp->mLanguage); // an atom
   // NS_IMPL_CYCLE_COLLECTION_UNLINK(mTheme); // a service
   // NS_IMPL_CYCLE_COLLECTION_UNLINK(mLangService); // a service
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mPrintSettings);
 
@@ -883,16 +882,17 @@ nsPresContext::Init(nsDeviceContext* aDe
   }
 
   if (mDeviceContext->SetFullZoom(mFullZoom))
     mDeviceContext->FlushFontCache();
   mCurAppUnitsPerDevPixel = AppUnitsPerDevPixel();
 
   mEventManager = new mozilla::EventStateManager();
 
+  mAnimationEventDispatcher = new mozilla::AnimationEventDispatcher(this);
   mEffectCompositor = new mozilla::EffectCompositor(this);
   mTransitionManager = new nsTransitionManager(this);
   mAnimationManager = new nsAnimationManager(this);
 
   if (mDocument->GetDisplayDocument()) {
     NS_ASSERTION(mDocument->GetDisplayDocument()->GetShell() &&
                  mDocument->GetDisplayDocument()->GetShell()->GetPresContext(),
                  "Why are we being initialized?");
@@ -1061,16 +1061,20 @@ nsPresContext::DetachShell()
   // this way to preserve the old ordering, but I doubt anything would break.
   if (mCounterStyleManager) {
     mCounterStyleManager->Disconnect();
     mCounterStyleManager = nullptr;
   }
 
   mShell = nullptr;
 
+  if (mAnimationEventDispatcher) {
+    mAnimationEventDispatcher->Disconnect();
+    mAnimationEventDispatcher = nullptr;
+  }
   if (mEffectCompositor) {
     mEffectCompositor->Disconnect();
     mEffectCompositor = nullptr;
   }
   if (mTransitionManager) {
     mTransitionManager->Disconnect();
     mTransitionManager = nullptr;
   }
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -68,16 +68,17 @@ class nsPluginFrame;
 class nsTransitionManager;
 class nsAnimationManager;
 class nsRefreshDriver;
 class nsIWidget;
 class nsDeviceContext;
 class gfxMissingFontRecorder;
 
 namespace mozilla {
+class AnimationEventDispatcher;
 class EffectCompositor;
 class Encoding;
 class EventStateManager;
 class CounterStyleManager;
 class RestyleManager;
 namespace layers {
 class ContainerLayer;
 class LayerManager;
@@ -231,16 +232,20 @@ public:
 #endif
 
   nsFrameManager* FrameManager()
     { return PresShell()->FrameManager(); }
 
   nsCSSFrameConstructor* FrameConstructor()
     { return PresShell()->FrameConstructor(); }
 
+  mozilla::AnimationEventDispatcher* AnimationEventDispatcher()
+  {
+    return mAnimationEventDispatcher;
+  }
   mozilla::EffectCompositor* EffectCompositor() { return mEffectCompositor; }
   nsTransitionManager* TransitionManager() { return mTransitionManager; }
   nsAnimationManager* AnimationManager() { return mAnimationManager; }
 
   nsRefreshDriver* RefreshDriver() { return mRefreshDriver; }
 
   mozilla::RestyleManager* RestyleManager() {
     MOZ_ASSERT(mRestyleManager);
@@ -1291,16 +1296,17 @@ protected:
   nsCOMPtr<nsIDocument> mDocument;
   RefPtr<nsDeviceContext> mDeviceContext; // [STRONG] could be weak, but
                                             // better safe than sorry.
                                             // Cannot reintroduce cycles
                                             // since there is no dependency
                                             // from gfx back to layout.
   RefPtr<mozilla::EventStateManager> mEventManager;
   RefPtr<nsRefreshDriver> mRefreshDriver;
+  RefPtr<mozilla::AnimationEventDispatcher> mAnimationEventDispatcher;
   RefPtr<mozilla::EffectCompositor> mEffectCompositor;
   RefPtr<nsTransitionManager> mTransitionManager;
   RefPtr<nsAnimationManager> mAnimationManager;
   RefPtr<mozilla::RestyleManager> mRestyleManager;
   RefPtr<mozilla::CounterStyleManager> mCounterStyleManager;
   nsAtom* MOZ_UNSAFE_REF("always a static atom") mMedium; // initialized by subclass ctors
   RefPtr<nsAtom> mMediaEmulated;
   RefPtr<gfxFontFeatureValueSet> mFontFeatureValuesLookup;
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -20,16 +20,17 @@
 #ifdef XP_WIN
 #include <windows.h>
 // mmsystem isn't part of WIN32_LEAN_AND_MEAN, so we have
 // to manually include it
 #include <mmsystem.h>
 #include "WinUtils.h"
 #endif
 
+#include "mozilla/AnimationEventDispatcher.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/IntegerRange.h"
 #include "nsHostObjectProtocolHandler.h"
 #include "nsRefreshDriver.h"
 #include "nsITimer.h"
 #include "nsLayoutUtils.h"
 #include "nsPresContext.h"
@@ -1647,26 +1648,17 @@ nsRefreshDriver::DispatchAnimationEvents
       continue;
     }
 
     RefPtr<nsPresContext> context = shell->GetPresContext();
     if (!context || context->RefreshDriver() != this) {
       continue;
     }
 
-    context->TransitionManager()->SortEvents();
-    context->AnimationManager()->SortEvents();
-
-    // Dispatch transition events first since transitions conceptually sit
-    // below animations in terms of compositing order.
-    context->TransitionManager()->DispatchEvents();
-    // Check that the presshell has not been destroyed
-    if (context->GetPresShell()) {
-      context->AnimationManager()->DispatchEvents();
-    }
+    context->AnimationEventDispatcher()->DispatchEvents();
   }
 }
 
 void
 nsRefreshDriver::RunFrameRequestCallbacks(TimeStamp aNowTime)
 {
   // Grab all of our frame request callbacks up front.
   nsTArray<DocumentFrameCallbacks>
--- a/layout/style/AnimationCommon.h
+++ b/layout/style/AnimationCommon.h
@@ -3,42 +3,39 @@
 /* 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
 
 #include "mozilla/AnimationCollection.h"
-#include "mozilla/AnimationEventDispatcher.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/dom/Animation.h"
 #include "mozilla/Attributes.h" // For MOZ_NON_OWNING_REF
 #include "mozilla/Assertions.h"
 #include "mozilla/TimingParams.h"
 #include "nsContentUtils.h"
 
 class nsIFrame;
 class nsPresContext;
 
 namespace mozilla {
 enum class CSSPseudoElementType : uint8_t;
-class AnimationEventDispatcher;
 
 namespace dom {
 class Element;
 }
 
 template <class AnimationType>
 class CommonAnimationManager {
 public:
   explicit CommonAnimationManager(nsPresContext *aPresContext)
     : mPresContext(aPresContext)
   {
-    mEventDispatcher = new AnimationEventDispatcher();
   }
 
   // NOTE:  This can return null after Disconnect().
   nsPresContext* PresContext() const { return mPresContext; }
 
   /**
    * Notify the manager that the pres context is going away.
    */
@@ -65,27 +62,16 @@ public:
     if (!collection) {
       return;
     }
 
     nsAutoAnimationMutationBatch mb(aElement->OwnerDoc());
     collection->Destroy();
   }
 
-  /**
-   * Add pending events.
-   */
-  void QueueEvents(nsTArray<AnimationEventInfo>&& aEvents)
-  {
-    mEventDispatcher->QueueEvents(Move(aEvents));
-  }
-
-  void SortEvents()      { mEventDispatcher->SortEvents(); }
-  void ClearEventQueue() { mEventDispatcher->ClearEventQueue(); }
-
 protected:
   virtual ~CommonAnimationManager()
   {
     MOZ_ASSERT(!mPresContext, "Disconnect should have been called");
   }
 
   void AddElementCollection(AnimationCollection<AnimationType>* aCollection)
   {
@@ -96,18 +82,16 @@ protected:
     while (AnimationCollection<AnimationType>* head =
            mElementCollections.getFirst()) {
       head->Destroy(); // Note: this removes 'head' from mElementCollections.
     }
   }
 
   LinkedList<AnimationCollection<AnimationType>> mElementCollections;
   nsPresContext *mPresContext; // weak (non-null from ctor to Disconnect)
-
-  RefPtr<mozilla::AnimationEventDispatcher> mEventDispatcher;
 };
 
 /**
  * Utility class for referencing the element that created a CSS animation or
  * transition. It is non-owning (i.e. it uses a raw pointer) since it is only
  * expected to be set by the owned animation while it actually being managed
  * by the owning element.
  *
--- a/layout/style/nsAnimationManager.cpp
+++ b/layout/style/nsAnimationManager.cpp
@@ -3,16 +3,17 @@
 /* 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 "nsAnimationManager.h"
 #include "nsTransitionManager.h"
 #include "mozilla/dom/CSSAnimationBinding.h"
 
+#include "mozilla/AnimationEventDispatcher.h"
 #include "mozilla/AnimationTarget.h"
 #include "mozilla/EffectCompositor.h"
 #include "mozilla/EffectSet.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/ServoStyleSet.h"
 #include "mozilla/StyleAnimationValue.h"
 #include "mozilla/dom/DocumentTimeline.h"
 #include "mozilla/dom/KeyframeEffectReadOnly.h"
@@ -294,17 +295,17 @@ CSSAnimation::QueueEvents(const StickyTi
         appendAnimationEvent(eAnimationStart, intervalEndTime, endTimeStamp);
       }
       break;
   }
   mPreviousPhase = currentPhase;
   mPreviousIteration = currentIteration;
 
   if (!events.IsEmpty()) {
-    presContext->AnimationManager()->QueueEvents(Move(events));
+    presContext->AnimationEventDispatcher()->QueueEvents(Move(events));
   }
 }
 
 void
 CSSAnimation::UpdateTiming(SeekFlag aSeekFlag, SyncNotifyFlag aSyncNotifyFlag)
 {
   if (mNeedsNewAnimationIndexWhenRun &&
       PlayState() != AnimationPlayState::Idle) {
@@ -312,21 +313,16 @@ CSSAnimation::UpdateTiming(SeekFlag aSee
     mNeedsNewAnimationIndexWhenRun = false;
   }
 
   Animation::UpdateTiming(aSeekFlag, aSyncNotifyFlag);
 }
 
 ////////////////////////// nsAnimationManager ////////////////////////////
 
-NS_IMPL_CYCLE_COLLECTION(nsAnimationManager, mEventDispatcher)
-
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsAnimationManager, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsAnimationManager, Release)
-
 // Find the matching animation by |aName| in the old list
 // of animations and remove the matched animation from the list.
 static already_AddRefed<CSSAnimation>
 PopExistingAnimation(const nsAtom* aName,
                      nsAnimationManager::CSSAnimationCollection* aCollection)
 {
   if (!aCollection) {
     return nullptr;
--- a/layout/style/nsAnimationManager.h
+++ b/layout/style/nsAnimationManager.h
@@ -9,16 +9,17 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/EventForwards.h"
 #include "AnimationCommon.h"
 #include "mozilla/dom/Animation.h"
 #include "mozilla/Keyframe.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/TimeStamp.h"
+#include "nsISupportsImpl.h"
 
 class nsIGlobalObject;
 class nsStyleContext;
 class ServoComputedData;
 struct nsStyleDisplay;
 
 namespace mozilla {
 namespace css {
@@ -277,18 +278,17 @@ class nsAnimationManager final
   : public mozilla::CommonAnimationManager<mozilla::dom::CSSAnimation>
 {
 public:
   explicit nsAnimationManager(nsPresContext *aPresContext)
     : mozilla::CommonAnimationManager<mozilla::dom::CSSAnimation>(aPresContext)
   {
   }
 
-  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsAnimationManager)
-  NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsAnimationManager)
+  NS_INLINE_DECL_REFCOUNTING(nsAnimationManager)
 
   typedef mozilla::AnimationCollection<mozilla::dom::CSSAnimation>
     CSSAnimationCollection;
   typedef nsTArray<RefPtr<mozilla::dom::CSSAnimation>>
     OwningCSSAnimationPtrArray;
 
   /**
    * Update the set of animations on |aElement| based on |aStyleContext|.
@@ -305,22 +305,16 @@ public:
    * This function does the same thing as the above UpdateAnimations()
    * but with servo's computed values.
    */
   void UpdateAnimations(
     mozilla::dom::Element* aElement,
     mozilla::CSSPseudoElementType aPseudoType,
     const mozilla::ServoStyleContext* aComputedValues);
 
-  void DispatchEvents()
-  {
-    RefPtr<nsAnimationManager> kungFuDeathGrip(this);
-    mEventDispatcher->DispatchEvents(mPresContext);
-  }
-
   // Utility function to walk through |aIter| to find the Keyframe with
   // matching offset and timing function but stopping as soon as the offset
   // differs from |aOffset| (i.e. it assumes a sorted iterator).
   //
   // If a matching Keyframe is found,
   //   Returns true and sets |aIndex| to the index of the matching Keyframe
   //   within |aIter|.
   //
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -14,16 +14,17 @@
 #include "nsContentUtils.h"
 #include "nsStyleContext.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/TimeStamp.h"
 #include "nsRefreshDriver.h"
 #include "nsRuleProcessorData.h"
 #include "nsRuleWalker.h"
 #include "nsCSSPropertyIDSet.h"
+#include "mozilla/AnimationEventDispatcher.h"
 #include "mozilla/EffectCompositor.h"
 #include "mozilla/EffectSet.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/ServoBindings.h"
 #include "mozilla/StyleAnimationValue.h"
 #include "mozilla/dom/DocumentTimeline.h"
 #include "mozilla/dom/Element.h"
 #include "nsIFrame.h"
@@ -331,17 +332,17 @@ CSSTransition::QueueEvents(const StickyT
                               intervalStartTime,
                               endTimeStamp);
       }
       break;
   }
   mPreviousTransitionPhase = currentPhase;
 
   if (!events.IsEmpty()) {
-    presContext->TransitionManager()->QueueEvents(Move(events));
+    presContext->AnimationEventDispatcher()->QueueEvents(Move(events));
   }
 }
 
 void
 CSSTransition::Tick()
 {
   Animation::Tick();
   QueueEvents();
@@ -417,21 +418,16 @@ CSSTransition::SetEffectFromStyle(dom::A
   if (eCSSProperty_UNKNOWN == mTransitionProperty && pt) {
     mTransitionProperty = pt->TransitionProperty();
     mTransitionToValue = pt->ToValue();
   }
 }
 
 ////////////////////////// nsTransitionManager ////////////////////////////
 
-NS_IMPL_CYCLE_COLLECTION(nsTransitionManager, mEventDispatcher)
-
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsTransitionManager, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsTransitionManager, Release)
-
 static inline bool
 ExtractNonDiscreteComputedValue(nsCSSPropertyID aProperty,
                                 GeckoStyleContext* aStyleContext,
                                 AnimationValue& aAnimationValue)
 {
   return (nsCSSProps::kAnimTypeTable[aProperty] != eStyleAnimType_Discrete ||
           aProperty == eCSSProperty_visibility) &&
          StyleAnimationValue::ExtractComputedValue(aProperty, aStyleContext,
--- a/layout/style/nsTransitionManager.h
+++ b/layout/style/nsTransitionManager.h
@@ -9,16 +9,17 @@
 #ifndef nsTransitionManager_h_
 #define nsTransitionManager_h_
 
 #include "mozilla/ComputedTiming.h"
 #include "mozilla/EffectCompositor.h" // For EffectCompositor::CascadeLevel
 #include "mozilla/dom/Animation.h"
 #include "mozilla/dom/KeyframeEffectReadOnly.h"
 #include "AnimationCommon.h"
+#include "nsISupportsImpl.h"
 
 class nsIGlobalObject;
 class nsStyleContext;
 class nsPresContext;
 class nsCSSPropertyIDSet;
 
 namespace mozilla {
 enum class CSSPseudoElementType : uint8_t;
@@ -305,18 +306,17 @@ class nsTransitionManager final
 {
 public:
   explicit nsTransitionManager(nsPresContext *aPresContext)
     : mozilla::CommonAnimationManager<mozilla::dom::CSSTransition>(aPresContext)
     , mInAnimationOnlyStyleUpdate(false)
   {
   }
 
-  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsTransitionManager)
-  NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsTransitionManager)
+  NS_INLINE_DECL_REFCOUNTING(nsTransitionManager)
 
   typedef mozilla::AnimationCollection<mozilla::dom::CSSTransition>
     CSSTransitionCollection;
 
   /**
    * StyleContextChanged
    *
    * To be called from RestyleManager::TryInitiatingTransition when the
@@ -358,22 +358,16 @@ public:
   void SetInAnimationOnlyStyleUpdate(bool aInAnimationOnlyUpdate) {
     mInAnimationOnlyStyleUpdate = aInAnimationOnlyUpdate;
   }
 
   bool InAnimationOnlyStyleUpdate() const {
     return mInAnimationOnlyStyleUpdate;
   }
 
-  void DispatchEvents()
-  {
-    RefPtr<nsTransitionManager> kungFuDeathGrip(this);
-    mEventDispatcher->DispatchEvents(mPresContext);
-  }
-
 protected:
   virtual ~nsTransitionManager() {}
 
   typedef nsTArray<RefPtr<mozilla::dom::CSSTransition>>
     OwningCSSTransitionPtrArray;
 
   // Update transitions. This will start new transitions,
   // replace existing transitions, and stop existing transitions