/src/mozilla-central/layout/style/AnimationCommon.h
Line | Count | Source (jump to first uncovered line) |
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/. */ |
6 | | |
7 | | #ifndef mozilla_css_AnimationCommon_h |
8 | | #define mozilla_css_AnimationCommon_h |
9 | | |
10 | | #include "mozilla/AnimationCollection.h" |
11 | | #include "mozilla/LinkedList.h" |
12 | | #include "mozilla/dom/Animation.h" |
13 | | #include "mozilla/Attributes.h" // For MOZ_NON_OWNING_REF |
14 | | #include "mozilla/Assertions.h" |
15 | | #include "mozilla/TimingParams.h" |
16 | | #include "mozilla/dom/Nullable.h" |
17 | | #include "nsContentUtils.h" |
18 | | |
19 | | class nsPresContext; |
20 | | |
21 | | namespace mozilla { |
22 | | enum class CSSPseudoElementType : uint8_t; |
23 | | |
24 | | namespace dom { |
25 | | class Element; |
26 | | } |
27 | | |
28 | | template <class AnimationType> |
29 | | class CommonAnimationManager { |
30 | | public: |
31 | | explicit CommonAnimationManager(nsPresContext *aPresContext) |
32 | | : mPresContext(aPresContext) |
33 | 0 | { |
34 | 0 | } Unexecuted instantiation: mozilla::CommonAnimationManager<mozilla::dom::CSSTransition>::CommonAnimationManager(nsPresContext*) Unexecuted instantiation: mozilla::CommonAnimationManager<mozilla::dom::CSSAnimation>::CommonAnimationManager(nsPresContext*) |
35 | | |
36 | | // NOTE: This can return null after Disconnect(). |
37 | | nsPresContext* PresContext() const { return mPresContext; } |
38 | | |
39 | | /** |
40 | | * Notify the manager that the pres context is going away. |
41 | | */ |
42 | | void Disconnect() |
43 | 0 | { |
44 | 0 | // Content nodes might outlive the transition or animation manager. |
45 | 0 | RemoveAllElementCollections(); |
46 | 0 |
|
47 | 0 | mPresContext = nullptr; |
48 | 0 | } Unexecuted instantiation: mozilla::CommonAnimationManager<mozilla::dom::CSSTransition>::Disconnect() Unexecuted instantiation: mozilla::CommonAnimationManager<mozilla::dom::CSSAnimation>::Disconnect() |
49 | | |
50 | | /** |
51 | | * Stop animations on the element. This method takes the real element |
52 | | * rather than the element for the generated content for animations on |
53 | | * ::before and ::after. |
54 | | */ |
55 | | void StopAnimationsForElement(dom::Element* aElement, |
56 | | CSSPseudoElementType aPseudoType) |
57 | 0 | { |
58 | 0 | MOZ_ASSERT(aElement); |
59 | 0 | AnimationCollection<AnimationType>* collection = |
60 | 0 | AnimationCollection<AnimationType>::GetAnimationCollection(aElement, |
61 | 0 | aPseudoType); |
62 | 0 | if (!collection) { |
63 | 0 | return; |
64 | 0 | } |
65 | 0 | |
66 | 0 | nsAutoAnimationMutationBatch mb(aElement->OwnerDoc()); |
67 | 0 | collection->Destroy(); |
68 | 0 | } Unexecuted instantiation: mozilla::CommonAnimationManager<mozilla::dom::CSSAnimation>::StopAnimationsForElement(mozilla::dom::Element*, mozilla::CSSPseudoElementType) Unexecuted instantiation: mozilla::CommonAnimationManager<mozilla::dom::CSSTransition>::StopAnimationsForElement(mozilla::dom::Element*, mozilla::CSSPseudoElementType) |
69 | | |
70 | | protected: |
71 | | virtual ~CommonAnimationManager() |
72 | 0 | { |
73 | 0 | MOZ_ASSERT(!mPresContext, "Disconnect should have been called"); |
74 | 0 | } Unexecuted instantiation: mozilla::CommonAnimationManager<mozilla::dom::CSSTransition>::~CommonAnimationManager() Unexecuted instantiation: mozilla::CommonAnimationManager<mozilla::dom::CSSAnimation>::~CommonAnimationManager() |
75 | | |
76 | | void AddElementCollection(AnimationCollection<AnimationType>* aCollection) |
77 | 0 | { |
78 | 0 | mElementCollections.insertBack(aCollection); |
79 | 0 | } Unexecuted instantiation: mozilla::CommonAnimationManager<mozilla::dom::CSSAnimation>::AddElementCollection(mozilla::AnimationCollection<mozilla::dom::CSSAnimation>*) Unexecuted instantiation: mozilla::CommonAnimationManager<mozilla::dom::CSSTransition>::AddElementCollection(mozilla::AnimationCollection<mozilla::dom::CSSTransition>*) |
80 | | void RemoveAllElementCollections() |
81 | 0 | { |
82 | 0 | while (AnimationCollection<AnimationType>* head = |
83 | 0 | mElementCollections.getFirst()) { |
84 | 0 | head->Destroy(); // Note: this removes 'head' from mElementCollections. |
85 | 0 | } |
86 | 0 | } Unexecuted instantiation: mozilla::CommonAnimationManager<mozilla::dom::CSSTransition>::RemoveAllElementCollections() Unexecuted instantiation: mozilla::CommonAnimationManager<mozilla::dom::CSSAnimation>::RemoveAllElementCollections() |
87 | | |
88 | | LinkedList<AnimationCollection<AnimationType>> mElementCollections; |
89 | | nsPresContext *mPresContext; // weak (non-null from ctor to Disconnect) |
90 | | }; |
91 | | |
92 | | /** |
93 | | * Utility class for referencing the element that created a CSS animation or |
94 | | * transition. It is non-owning (i.e. it uses a raw pointer) since it is only |
95 | | * expected to be set by the owned animation while it actually being managed |
96 | | * by the owning element. |
97 | | * |
98 | | * This class also abstracts the comparison of an element/pseudo-class pair |
99 | | * for the sake of composite ordering since this logic is common to both CSS |
100 | | * animations and transitions. |
101 | | * |
102 | | * (We call this OwningElementRef instead of just OwningElement so that we can |
103 | | * call the getter on CSSAnimation/CSSTransition OwningElement() without |
104 | | * clashing with this object's contructor.) |
105 | | */ |
106 | | class OwningElementRef final |
107 | | { |
108 | | public: |
109 | 0 | OwningElementRef() = default; |
110 | | |
111 | | explicit OwningElementRef(const NonOwningAnimationTarget& aTarget) |
112 | | : mTarget(aTarget) |
113 | 0 | { } |
114 | | |
115 | | OwningElementRef(dom::Element& aElement, |
116 | | CSSPseudoElementType aPseudoType) |
117 | | : mTarget(&aElement, aPseudoType) |
118 | 0 | { } |
119 | | |
120 | | bool Equals(const OwningElementRef& aOther) const |
121 | 0 | { |
122 | 0 | return mTarget == aOther.mTarget; |
123 | 0 | } |
124 | | |
125 | | bool LessThan(int32_t& aChildIndex, const OwningElementRef& aOther, |
126 | | int32_t& aOtherChildIndex) const |
127 | 0 | { |
128 | 0 | MOZ_ASSERT(mTarget.mElement && aOther.mTarget.mElement, |
129 | 0 | "Elements to compare should not be null"); |
130 | 0 |
|
131 | 0 | if (mTarget.mElement != aOther.mTarget.mElement) { |
132 | 0 | return nsContentUtils::PositionIsBefore(mTarget.mElement, |
133 | 0 | aOther.mTarget.mElement, |
134 | 0 | &aChildIndex, |
135 | 0 | &aOtherChildIndex); |
136 | 0 | } |
137 | 0 | |
138 | 0 | return mTarget.mPseudoType == CSSPseudoElementType::NotPseudo || |
139 | 0 | (mTarget.mPseudoType == CSSPseudoElementType::before && |
140 | 0 | aOther.mTarget.mPseudoType == CSSPseudoElementType::after); |
141 | 0 | } |
142 | | |
143 | 0 | bool IsSet() const { return !!mTarget.mElement; } |
144 | | |
145 | | void GetElement(dom::Element*& aElement, |
146 | | CSSPseudoElementType& aPseudoType) const |
147 | 0 | { |
148 | 0 | aElement = mTarget.mElement; |
149 | 0 | aPseudoType = mTarget.mPseudoType; |
150 | 0 | } |
151 | | |
152 | 0 | const NonOwningAnimationTarget& Target() const { return mTarget; } |
153 | | |
154 | | nsPresContext* GetPresContext() const |
155 | 0 | { |
156 | 0 | return nsContentUtils::GetContextForContent(mTarget.mElement); |
157 | 0 | } |
158 | | |
159 | | private: |
160 | | NonOwningAnimationTarget mTarget; |
161 | | }; |
162 | | |
163 | | // Return the TransitionPhase or AnimationPhase to use when the animation |
164 | | // doesn't have a target effect. |
165 | | template <typename PhaseType> |
166 | | PhaseType GetAnimationPhaseWithoutEffect(const dom::Animation& aAnimation) |
167 | 0 | { |
168 | 0 | MOZ_ASSERT(!aAnimation.GetEffect(), |
169 | 0 | "Should only be called when we do not have an effect"); |
170 | 0 |
|
171 | 0 | // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to |
172 | 0 | // GetTickCount(). |
173 | | #ifdef GetCurrentTime |
174 | | #undef GetCurrentTime |
175 | | #endif |
176 | |
|
177 | 0 | dom::Nullable<TimeDuration> currentTime = aAnimation.GetCurrentTime(); |
178 | 0 | if (currentTime.IsNull()) { |
179 | 0 | return PhaseType::Idle; |
180 | 0 | } |
181 | 0 | |
182 | 0 | // If we don't have a target effect, the duration will be zero so the phase is |
183 | 0 | // 'before' if the current time is less than zero. |
184 | 0 | return currentTime.Value() < TimeDuration() |
185 | 0 | ? PhaseType::Before |
186 | 0 | : PhaseType::After; |
187 | 0 | }; Unexecuted instantiation: mozilla::ComputedTiming::AnimationPhase mozilla::GetAnimationPhaseWithoutEffect<mozilla::ComputedTiming::AnimationPhase>(mozilla::dom::Animation const&) Unexecuted instantiation: mozilla::dom::CSSTransition::TransitionPhase mozilla::GetAnimationPhaseWithoutEffect<mozilla::dom::CSSTransition::TransitionPhase>(mozilla::dom::Animation const&) |
188 | | |
189 | | inline TimingParams |
190 | | TimingParamsFromCSSParams(float aDuration, float aDelay, |
191 | | float aIterationCount, |
192 | | dom::PlaybackDirection aDirection, |
193 | | dom::FillMode aFillMode) |
194 | 0 | { |
195 | 0 | MOZ_ASSERT(aIterationCount >= 0.0 && !IsNaN(aIterationCount), |
196 | 0 | "aIterations should be nonnegative & finite, as ensured by " |
197 | 0 | "CSSParser"); |
198 | 0 |
|
199 | 0 | return TimingParams { |
200 | 0 | aDuration, |
201 | 0 | aDelay, |
202 | 0 | aIterationCount, |
203 | 0 | aDirection, |
204 | 0 | aFillMode |
205 | 0 | }; |
206 | 0 | } |
207 | | |
208 | | } // namespace mozilla |
209 | | |
210 | | #endif /* !defined(mozilla_css_AnimationCommon_h) */ |