Bug 1861709 replace AudioCallbackDriver::ThreadRunning() assertions that mean to...
[gecko.git] / layout / style / AnimationCommon.h
blob0035d9221766daf2952420983eff3a6eb2db12e9
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_css_AnimationCommon_h
8 #define mozilla_css_AnimationCommon_h
10 #include "mozilla/AnimationCollection.h"
11 #include "mozilla/LinkedList.h"
12 #include "mozilla/dom/Animation.h"
13 #include "mozilla/Assertions.h"
14 #include "mozilla/Maybe.h"
15 #include "mozilla/TimingParams.h"
16 #include "mozilla/dom/Nullable.h"
17 #include "nsContentUtils.h"
18 #include "nsDOMMutationObserver.h" // For nsAutoAnimationMutationBatch
20 class nsPresContext;
22 namespace mozilla {
23 enum class PseudoStyleType : uint8_t;
25 namespace dom {
26 class Element;
29 template <class AnimationType>
30 class CommonAnimationManager {
31 public:
32 explicit CommonAnimationManager(nsPresContext* aPresContext)
33 : mPresContext(aPresContext) {}
35 // NOTE: This can return null after Disconnect().
36 nsPresContext* PresContext() const { return mPresContext; }
38 /**
39 * Notify the manager that the pres context is going away.
41 void Disconnect() {
42 // Content nodes might outlive the transition or animation manager.
43 RemoveAllElementCollections();
45 mPresContext = nullptr;
48 /**
49 * Stop animations on the element. This method takes the real element
50 * rather than the element for the generated content for animations on
51 * ::before, ::after and ::marker.
53 void StopAnimationsForElement(dom::Element* aElement,
54 PseudoStyleType aPseudoType) {
55 MOZ_ASSERT(aElement);
56 auto* collection =
57 AnimationCollection<AnimationType>::Get(aElement, aPseudoType);
58 if (!collection) {
59 return;
62 nsAutoAnimationMutationBatch mb(aElement->OwnerDoc());
63 collection->Destroy();
66 protected:
67 virtual ~CommonAnimationManager() {
68 MOZ_ASSERT(!mPresContext, "Disconnect should have been called");
71 void AddElementCollection(AnimationCollection<AnimationType>* aCollection) {
72 mElementCollections.insertBack(aCollection);
74 void RemoveAllElementCollections() {
75 while (AnimationCollection<AnimationType>* head =
76 mElementCollections.getFirst()) {
77 head->Destroy(); // Note: this removes 'head' from mElementCollections.
81 LinkedList<AnimationCollection<AnimationType>> mElementCollections;
82 nsPresContext* mPresContext; // weak (non-null from ctor to Disconnect)
85 /**
86 * Utility class for referencing the element that created a CSS animation or
87 * transition. It is non-owning (i.e. it uses a raw pointer) since it is only
88 * expected to be set by the owned animation while it actually being managed
89 * by the owning element.
91 * This class also abstracts the comparison of an element/pseudo-class pair
92 * for the sake of composite ordering since this logic is common to both CSS
93 * animations and transitions.
95 * (We call this OwningElementRef instead of just OwningElement so that we can
96 * call the getter on CSSAnimation/CSSTransition OwningElement() without
97 * clashing with this object's contructor.)
99 class OwningElementRef final {
100 public:
101 OwningElementRef() = default;
103 explicit OwningElementRef(const NonOwningAnimationTarget& aTarget)
104 : mTarget(aTarget) {}
106 OwningElementRef(dom::Element& aElement, PseudoStyleType aPseudoType)
107 : mTarget(&aElement, aPseudoType) {}
109 bool Equals(const OwningElementRef& aOther) const {
110 return mTarget == aOther.mTarget;
113 bool LessThan(Maybe<uint32_t>& aChildIndex, const OwningElementRef& aOther,
114 Maybe<uint32_t>& aOtherChildIndex) const {
115 MOZ_ASSERT(mTarget.mElement && aOther.mTarget.mElement,
116 "Elements to compare should not be null");
118 if (mTarget.mElement != aOther.mTarget.mElement) {
119 return nsContentUtils::PositionIsBefore(mTarget.mElement,
120 aOther.mTarget.mElement,
121 &aChildIndex, &aOtherChildIndex);
124 return mTarget.mPseudoType == PseudoStyleType::NotPseudo ||
125 (mTarget.mPseudoType == PseudoStyleType::before &&
126 aOther.mTarget.mPseudoType == PseudoStyleType::after) ||
127 (mTarget.mPseudoType == PseudoStyleType::marker &&
128 aOther.mTarget.mPseudoType == PseudoStyleType::before) ||
129 (mTarget.mPseudoType == PseudoStyleType::marker &&
130 aOther.mTarget.mPseudoType == PseudoStyleType::after);
133 bool IsSet() const { return !!mTarget.mElement; }
135 void GetElement(dom::Element*& aElement, PseudoStyleType& aPseudoType) const {
136 aElement = mTarget.mElement;
137 aPseudoType = mTarget.mPseudoType;
140 const NonOwningAnimationTarget& Target() const { return mTarget; }
142 nsPresContext* GetPresContext() const {
143 return nsContentUtils::GetContextForContent(mTarget.mElement);
146 private:
147 NonOwningAnimationTarget mTarget;
150 // Return the TransitionPhase or AnimationPhase to use when the animation
151 // doesn't have a target effect.
152 template <typename PhaseType>
153 PhaseType GetAnimationPhaseWithoutEffect(const dom::Animation& aAnimation) {
154 MOZ_ASSERT(!aAnimation.GetEffect(),
155 "Should only be called when we do not have an effect");
157 dom::Nullable<TimeDuration> currentTime =
158 aAnimation.GetCurrentTimeAsDuration();
159 if (currentTime.IsNull()) {
160 return PhaseType::Idle;
163 // If we don't have a target effect, the duration will be zero so the phase is
164 // 'before' if the current time is less than zero.
165 return currentTime.Value() < TimeDuration() ? PhaseType::Before
166 : PhaseType::After;
169 inline TimingParams TimingParamsFromCSSParams(float aDuration, float aDelay,
170 float aIterationCount,
171 dom::PlaybackDirection aDirection,
172 dom::FillMode aFillMode) {
173 MOZ_ASSERT(aIterationCount >= 0.0 && !std::isnan(aIterationCount),
174 "aIterations should be nonnegative & finite, as ensured by "
175 "CSSParser");
177 return TimingParams{aDuration, aDelay, aIterationCount, aDirection,
178 aFillMode};
181 } // namespace mozilla
183 #endif /* !defined(mozilla_css_AnimationCommon_h) */