Line data Source code
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 : #include "mozilla/AnimationCollection.h"
8 :
9 : #include "mozilla/RestyleManager.h"
10 : #include "mozilla/RestyleManagerInlines.h"
11 : #include "nsAnimationManager.h" // For dom::CSSAnimation
12 : #include "nsPresContext.h"
13 : #include "nsTransitionManager.h" // For dom::CSSTransition
14 :
15 : namespace mozilla {
16 :
17 : template <class AnimationType>
18 : /* static */ void
19 0 : AnimationCollection<AnimationType>::PropertyDtor(void* aObject,
20 : nsIAtom* aPropertyName,
21 : void* aPropertyValue,
22 : void* aData)
23 : {
24 : AnimationCollection* collection =
25 0 : static_cast<AnimationCollection*>(aPropertyValue);
26 : #ifdef DEBUG
27 0 : MOZ_ASSERT(!collection->mCalledPropertyDtor, "can't call dtor twice");
28 0 : collection->mCalledPropertyDtor = true;
29 : #endif
30 : {
31 0 : nsAutoAnimationMutationBatch mb(collection->mElement->OwnerDoc());
32 :
33 0 : for (size_t animIdx = collection->mAnimations.Length(); animIdx-- != 0; ) {
34 0 : collection->mAnimations[animIdx]->CancelFromStyle();
35 : }
36 : }
37 0 : delete collection;
38 0 : }
39 :
40 : template <class AnimationType>
41 : /* static */ AnimationCollection<AnimationType>*
42 3633 : AnimationCollection<AnimationType>::GetAnimationCollection(
43 : const dom::Element *aElement,
44 : CSSPseudoElementType aPseudoType)
45 : {
46 3633 : if (!aElement->MayHaveAnimations()) {
47 : // Early return for the most common case.
48 3605 : return nullptr;
49 : }
50 :
51 28 : nsIAtom* propName = GetPropertyAtomForPseudoType(aPseudoType);
52 28 : if (!propName) {
53 0 : return nullptr;
54 : }
55 :
56 : return
57 : static_cast<AnimationCollection<AnimationType>*>(aElement->
58 28 : GetProperty(propName));
59 : }
60 :
61 : template <class AnimationType>
62 : /* static */ AnimationCollection<AnimationType>*
63 252 : AnimationCollection<AnimationType>::GetAnimationCollection(
64 : const nsIFrame* aFrame)
65 : {
66 : Maybe<NonOwningAnimationTarget> pseudoElement =
67 504 : EffectCompositor::GetAnimationElementAndPseudoForFrame(aFrame);
68 252 : if (!pseudoElement) {
69 46 : return nullptr;
70 : }
71 :
72 206 : if (!pseudoElement->mElement->MayHaveAnimations()) {
73 202 : return nullptr;
74 : }
75 :
76 4 : return GetAnimationCollection(pseudoElement->mElement,
77 8 : pseudoElement->mPseudoType);
78 : }
79 :
80 : template <class AnimationType>
81 : /* static */ AnimationCollection<AnimationType>*
82 2 : AnimationCollection<AnimationType>::GetOrCreateAnimationCollection(
83 : dom::Element* aElement,
84 : CSSPseudoElementType aPseudoType,
85 : bool* aCreatedCollection)
86 : {
87 2 : MOZ_ASSERT(aCreatedCollection);
88 2 : *aCreatedCollection = false;
89 :
90 2 : nsIAtom* propName = GetPropertyAtomForPseudoType(aPseudoType);
91 2 : MOZ_ASSERT(propName, "Should only try to create animations for one of the"
92 : " recognized pseudo types");
93 :
94 : auto collection = static_cast<AnimationCollection<AnimationType>*>(
95 2 : aElement->GetProperty(propName));
96 2 : if (!collection) {
97 : // FIXME: Consider arena-allocating?
98 2 : collection = new AnimationCollection<AnimationType>(aElement, propName);
99 : nsresult rv =
100 : aElement->SetProperty(propName, collection,
101 : &AnimationCollection<AnimationType>::PropertyDtor,
102 2 : false);
103 2 : if (NS_FAILED(rv)) {
104 0 : NS_WARNING("SetProperty failed");
105 : // The collection must be destroyed via PropertyDtor, otherwise
106 : // mCalledPropertyDtor assertion is triggered in destructor.
107 0 : AnimationCollection<AnimationType>::PropertyDtor(aElement, propName,
108 : collection, nullptr);
109 0 : return nullptr;
110 : }
111 :
112 2 : *aCreatedCollection = true;
113 2 : aElement->SetMayHaveAnimations();
114 : }
115 :
116 2 : return collection;
117 : }
118 :
119 : template <class AnimationType>
120 : /* static */ nsString
121 6 : AnimationCollection<AnimationType>::PseudoTypeAsString(
122 : CSSPseudoElementType aPseudoType)
123 : {
124 6 : switch (aPseudoType) {
125 : case CSSPseudoElementType::before:
126 0 : return NS_LITERAL_STRING("::before");
127 : case CSSPseudoElementType::after:
128 0 : return NS_LITERAL_STRING("::after");
129 : default:
130 6 : MOZ_ASSERT(aPseudoType == CSSPseudoElementType::NotPseudo,
131 : "Unexpected pseudo type");
132 6 : return EmptyString();
133 : }
134 : }
135 :
136 : template <class AnimationType>
137 : void
138 10 : AnimationCollection<AnimationType>::UpdateCheckGeneration(
139 : nsPresContext* aPresContext)
140 : {
141 10 : mCheckGeneration = aPresContext->RestyleManager()->GetAnimationGeneration();
142 10 : }
143 :
144 : template<class AnimationType>
145 : /*static*/ nsIAtom*
146 30 : AnimationCollection<AnimationType>::GetPropertyAtomForPseudoType(
147 : CSSPseudoElementType aPseudoType)
148 : {
149 30 : nsIAtom* propName = nullptr;
150 :
151 30 : if (aPseudoType == CSSPseudoElementType::NotPseudo) {
152 30 : propName = TraitsType::ElementPropertyAtom();
153 0 : } else if (aPseudoType == CSSPseudoElementType::before) {
154 0 : propName = TraitsType::BeforePropertyAtom();
155 0 : } else if (aPseudoType == CSSPseudoElementType::after) {
156 0 : propName = TraitsType::AfterPropertyAtom();
157 : }
158 :
159 30 : return propName;
160 : }
161 :
162 : // Explicit class instantiations
163 :
164 : template class AnimationCollection<dom::CSSAnimation>;
165 : template class AnimationCollection<dom::CSSTransition>;
166 :
167 : } // namespace mozilla
|