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 file,
5 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "mozilla/dom/KeyframeEffect.h"
8 :
9 : #include "mozilla/dom/KeyframeAnimationOptionsBinding.h"
10 : // For UnrestrictedDoubleOrKeyframeAnimationOptions
11 : #include "mozilla/dom/AnimationEffectTiming.h"
12 : #include "mozilla/dom/KeyframeEffectBinding.h"
13 : #include "nsDOMMutationObserver.h" // For nsAutoAnimationMutationBatch
14 :
15 : namespace mozilla {
16 : namespace dom {
17 :
18 0 : KeyframeEffect::KeyframeEffect(nsIDocument* aDocument,
19 : const Maybe<OwningAnimationTarget>& aTarget,
20 : const TimingParams& aTiming,
21 0 : const KeyframeEffectParams& aOptions)
22 : : KeyframeEffectReadOnly(aDocument, aTarget,
23 0 : new AnimationEffectTiming(aDocument, aTiming, this),
24 0 : aOptions)
25 : {
26 0 : }
27 :
28 : JSObject*
29 0 : KeyframeEffect::WrapObject(JSContext* aCx,
30 : JS::Handle<JSObject*> aGivenProto)
31 : {
32 0 : return KeyframeEffectBinding::Wrap(aCx, this, aGivenProto);
33 : }
34 :
35 : /* static */ already_AddRefed<KeyframeEffect>
36 0 : KeyframeEffect::Constructor(
37 : const GlobalObject& aGlobal,
38 : const Nullable<ElementOrCSSPseudoElement>& aTarget,
39 : JS::Handle<JSObject*> aKeyframes,
40 : const UnrestrictedDoubleOrKeyframeEffectOptions& aOptions,
41 : ErrorResult& aRv)
42 : {
43 : return ConstructKeyframeEffect<KeyframeEffect>(aGlobal, aTarget, aKeyframes,
44 0 : aOptions, aRv);
45 : }
46 :
47 : /* static */ already_AddRefed<KeyframeEffect>
48 0 : KeyframeEffect::Constructor(const GlobalObject& aGlobal,
49 : KeyframeEffectReadOnly& aSource,
50 : ErrorResult& aRv)
51 : {
52 0 : return ConstructKeyframeEffect<KeyframeEffect>(aGlobal, aSource, aRv);
53 : }
54 :
55 : /* static */ already_AddRefed<KeyframeEffect>
56 0 : KeyframeEffect::Constructor(
57 : const GlobalObject& aGlobal,
58 : const Nullable<ElementOrCSSPseudoElement>& aTarget,
59 : JS::Handle<JSObject*> aKeyframes,
60 : const UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions,
61 : ErrorResult& aRv)
62 : {
63 : return ConstructKeyframeEffect<KeyframeEffect>(aGlobal, aTarget, aKeyframes,
64 0 : aOptions, aRv);
65 : }
66 :
67 : void
68 0 : KeyframeEffect::NotifySpecifiedTimingUpdated()
69 : {
70 : // Use the same document for a pseudo element and its parent element.
71 : // Use nullptr if we don't have mTarget, so disable the mutation batch.
72 0 : nsAutoAnimationMutationBatch mb(mTarget ? mTarget->mElement->OwnerDoc()
73 0 : : nullptr);
74 :
75 0 : if (mAnimation) {
76 0 : mAnimation->NotifyEffectTimingUpdated();
77 :
78 0 : if (mAnimation->IsRelevant()) {
79 0 : nsNodeUtils::AnimationChanged(mAnimation);
80 : }
81 :
82 0 : RequestRestyle(EffectCompositor::RestyleType::Layer);
83 : }
84 0 : }
85 :
86 : void
87 0 : KeyframeEffect::SetTarget(const Nullable<ElementOrCSSPseudoElement>& aTarget)
88 : {
89 0 : Maybe<OwningAnimationTarget> newTarget = ConvertTarget(aTarget);
90 0 : if (mTarget == newTarget) {
91 : // Assign the same target, skip it.
92 0 : return;
93 : }
94 :
95 0 : if (mTarget) {
96 0 : UnregisterTarget();
97 0 : ResetIsRunningOnCompositor();
98 :
99 0 : RequestRestyle(EffectCompositor::RestyleType::Layer);
100 :
101 0 : nsAutoAnimationMutationBatch mb(mTarget->mElement->OwnerDoc());
102 0 : if (mAnimation) {
103 0 : nsNodeUtils::AnimationRemoved(mAnimation);
104 : }
105 : }
106 :
107 0 : mTarget = newTarget;
108 :
109 0 : if (mTarget) {
110 0 : UpdateTargetRegistration();
111 0 : RefPtr<nsStyleContext> styleContext = GetTargetStyleContext();
112 0 : if (styleContext) {
113 0 : UpdateProperties(styleContext);
114 : }
115 :
116 0 : MaybeUpdateFrameForCompositor();
117 :
118 0 : RequestRestyle(EffectCompositor::RestyleType::Layer);
119 :
120 0 : nsAutoAnimationMutationBatch mb(mTarget->mElement->OwnerDoc());
121 0 : if (mAnimation) {
122 0 : nsNodeUtils::AnimationAdded(mAnimation);
123 : }
124 : }
125 :
126 : // If the new target frame is also oversized we should probably record that
127 : // too so we have a more complete picture of the type of frame sizes we
128 : // encounter, hence we reset the telemetry flag here.
129 0 : mRecordedContentTooLarge = false;
130 0 : mRecordedFrameSize = false;
131 : }
132 :
133 : void
134 0 : KeyframeEffect::SetIterationComposite(
135 : const IterationCompositeOperation& aIterationComposite,
136 : CallerType aCallerType)
137 : {
138 : // Ignore iterationComposite if the Web Animations API is not enabled,
139 : // then the default value 'Replace' will be used.
140 0 : if (!AnimationUtils::IsCoreAPIEnabledForCaller(aCallerType)) {
141 0 : return;
142 : }
143 :
144 0 : if (mEffectOptions.mIterationComposite == aIterationComposite) {
145 0 : return;
146 : }
147 :
148 0 : if (mAnimation && mAnimation->IsRelevant()) {
149 0 : nsNodeUtils::AnimationChanged(mAnimation);
150 : }
151 :
152 0 : mEffectOptions.mIterationComposite = aIterationComposite;
153 0 : RequestRestyle(EffectCompositor::RestyleType::Layer);
154 : }
155 :
156 : void
157 0 : KeyframeEffect::SetComposite(const CompositeOperation& aComposite)
158 : {
159 0 : if (mEffectOptions.mComposite == aComposite) {
160 0 : return;
161 : }
162 :
163 0 : mEffectOptions.mComposite = aComposite;
164 :
165 0 : if (mAnimation && mAnimation->IsRelevant()) {
166 0 : nsNodeUtils::AnimationChanged(mAnimation);
167 : }
168 :
169 0 : if (mTarget) {
170 0 : RefPtr<nsStyleContext> styleContext = GetTargetStyleContext();
171 0 : if (styleContext) {
172 0 : UpdateProperties(styleContext);
173 : }
174 : }
175 : }
176 :
177 : } // namespace dom
178 : } // namespace mozilla
|