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 #include "mozilla/AnimationCollection.h"
9 #include "mozilla/RestyleManager.h"
10 #include "nsDOMMutationObserver.h" // For nsAutoAnimationMutationBatch
11 #include "mozilla/dom/CSSAnimation.h" // For dom::CSSAnimation
12 #include "mozilla/dom/CSSTransition.h" // For dom::CSSTransition
16 template <class AnimationType
>
17 /* static */ void AnimationCollection
<AnimationType
>::PropertyDtor(
18 void* aObject
, nsAtom
* aPropertyName
, void* aPropertyValue
, void* aData
) {
19 AnimationCollection
* collection
=
20 static_cast<AnimationCollection
*>(aPropertyValue
);
22 MOZ_ASSERT(!collection
->mCalledPropertyDtor
, "can't call dtor twice");
23 collection
->mCalledPropertyDtor
= true;
26 PostRestyleMode postRestyle
= collection
->mCalledDestroy
27 ? PostRestyleMode::IfNeeded
28 : PostRestyleMode::Never
;
30 nsAutoAnimationMutationBatch
mb(collection
->mElement
->OwnerDoc());
32 for (size_t animIdx
= collection
->mAnimations
.Length(); animIdx
-- != 0;) {
33 collection
->mAnimations
[animIdx
]->CancelFromStyle(postRestyle
);
39 template <class AnimationType
>
40 /* static */ AnimationCollection
<AnimationType
>*
41 AnimationCollection
<AnimationType
>::GetAnimationCollection(
42 const dom::Element
* aElement
, PseudoStyleType aPseudoType
) {
43 if (!aElement
->MayHaveAnimations()) {
44 // Early return for the most common case.
48 nsAtom
* propName
= GetPropertyAtomForPseudoType(aPseudoType
);
53 return static_cast<AnimationCollection
<AnimationType
>*>(
54 aElement
->GetProperty(propName
));
57 template <class AnimationType
>
58 /* static */ AnimationCollection
<AnimationType
>*
59 AnimationCollection
<AnimationType
>::GetAnimationCollection(
60 const nsIFrame
* aFrame
) {
61 Maybe
<NonOwningAnimationTarget
> pseudoElement
=
62 EffectCompositor::GetAnimationElementAndPseudoForFrame(aFrame
);
67 if (!pseudoElement
->mElement
->MayHaveAnimations()) {
71 return GetAnimationCollection(pseudoElement
->mElement
,
72 pseudoElement
->mPseudoType
);
75 template <class AnimationType
>
76 /* static */ AnimationCollection
<AnimationType
>*
77 AnimationCollection
<AnimationType
>::GetOrCreateAnimationCollection(
78 dom::Element
* aElement
, PseudoStyleType aPseudoType
,
79 bool* aCreatedCollection
) {
80 MOZ_ASSERT(aCreatedCollection
);
81 *aCreatedCollection
= false;
83 nsAtom
* propName
= GetPropertyAtomForPseudoType(aPseudoType
);
85 "Should only try to create animations for one of the"
86 " recognized pseudo types");
88 auto collection
= static_cast<AnimationCollection
<AnimationType
>*>(
89 aElement
->GetProperty(propName
));
91 // FIXME: Consider arena-allocating?
92 collection
= new AnimationCollection
<AnimationType
>(aElement
, propName
);
93 nsresult rv
= aElement
->SetProperty(
94 propName
, collection
, &AnimationCollection
<AnimationType
>::PropertyDtor
,
97 NS_WARNING("SetProperty failed");
98 // The collection must be destroyed via PropertyDtor, otherwise
99 // mCalledPropertyDtor assertion is triggered in destructor.
100 AnimationCollection
<AnimationType
>::PropertyDtor(aElement
, propName
,
101 collection
, nullptr);
105 *aCreatedCollection
= true;
106 aElement
->SetMayHaveAnimations();
112 template <class AnimationType
>
114 AnimationCollection
<AnimationType
>::GetPropertyAtomForPseudoType(
115 PseudoStyleType aPseudoType
) {
116 nsAtom
* propName
= nullptr;
118 if (aPseudoType
== PseudoStyleType::NotPseudo
) {
119 propName
= TraitsType::ElementPropertyAtom();
120 } else if (aPseudoType
== PseudoStyleType::before
) {
121 propName
= TraitsType::BeforePropertyAtom();
122 } else if (aPseudoType
== PseudoStyleType::after
) {
123 propName
= TraitsType::AfterPropertyAtom();
124 } else if (aPseudoType
== PseudoStyleType::marker
) {
125 propName
= TraitsType::MarkerPropertyAtom();
131 template <class AnimationType
>
132 void AnimationCollection
<AnimationType
>::Destroy() {
133 mCalledDestroy
= true;
135 // This will call our destructor.
136 mElement
->RemoveProperty(mElementProperty
);
139 // Explicit class instantiations
141 template class AnimationCollection
<dom::CSSAnimation
>;
142 template class AnimationCollection
<dom::CSSTransition
>;
144 } // namespace mozilla