Bug 1684463 - [devtools] Part 1: Shorten the _createAttribute function by refactoring...
[gecko.git] / layout / style / AnimationCollection.cpp
blob1226c742029c4f7c93f12007422b3b847405ec74
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
14 namespace mozilla {
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);
21 #ifdef DEBUG
22 MOZ_ASSERT(!collection->mCalledPropertyDtor, "can't call dtor twice");
23 collection->mCalledPropertyDtor = true;
24 #endif
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);
36 delete collection;
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.
45 return nullptr;
48 nsAtom* propName = GetPropertyAtomForPseudoType(aPseudoType);
49 if (!propName) {
50 return nullptr;
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);
63 if (!pseudoElement) {
64 return nullptr;
67 if (!pseudoElement->mElement->MayHaveAnimations()) {
68 return nullptr;
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);
84 MOZ_ASSERT(propName,
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));
90 if (!collection) {
91 // FIXME: Consider arena-allocating?
92 collection = new AnimationCollection<AnimationType>(aElement, propName);
93 nsresult rv = aElement->SetProperty(
94 propName, collection, &AnimationCollection<AnimationType>::PropertyDtor,
95 false);
96 if (NS_FAILED(rv)) {
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);
102 return nullptr;
105 *aCreatedCollection = true;
106 aElement->SetMayHaveAnimations();
109 return collection;
112 template <class AnimationType>
113 /*static*/ nsAtom*
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();
128 return propName;
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