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/dom/AnimationEffectTiming.h"
8 
9 #include "mozilla/dom/AnimatableBinding.h"
10 #include "mozilla/dom/AnimationEffectTimingBinding.h"
11 #include "mozilla/dom/KeyframeEffect.h"
12 #include "mozilla/TimingParams.h"
13 #include "nsAString.h"
14 
15 namespace mozilla {
16 namespace dom {
17 
WrapObject(JSContext * aCx,JS::Handle<JSObject * > aGivenProto)18 JSObject* AnimationEffectTiming::WrapObject(JSContext* aCx,
19                                             JS::Handle<JSObject*> aGivenProto) {
20   return AnimationEffectTimingBinding::Wrap(aCx, this, aGivenProto);
21 }
22 
PostSpecifiedTimingUpdated(KeyframeEffect * aEffect)23 static inline void PostSpecifiedTimingUpdated(KeyframeEffect* aEffect) {
24   if (aEffect) {
25     aEffect->NotifySpecifiedTimingUpdated();
26   }
27 }
28 
SetDelay(double aDelay)29 void AnimationEffectTiming::SetDelay(double aDelay) {
30   TimeDuration delay = TimeDuration::FromMilliseconds(aDelay);
31   if (mTiming.Delay() == delay) {
32     return;
33   }
34   mTiming.SetDelay(delay);
35 
36   PostSpecifiedTimingUpdated(mEffect);
37 }
38 
SetEndDelay(double aEndDelay)39 void AnimationEffectTiming::SetEndDelay(double aEndDelay) {
40   TimeDuration endDelay = TimeDuration::FromMilliseconds(aEndDelay);
41   if (mTiming.EndDelay() == endDelay) {
42     return;
43   }
44   mTiming.SetEndDelay(endDelay);
45 
46   PostSpecifiedTimingUpdated(mEffect);
47 }
48 
SetFill(const FillMode & aFill)49 void AnimationEffectTiming::SetFill(const FillMode& aFill) {
50   if (mTiming.Fill() == aFill) {
51     return;
52   }
53   mTiming.SetFill(aFill);
54 
55   PostSpecifiedTimingUpdated(mEffect);
56 }
57 
SetIterationStart(double aIterationStart,ErrorResult & aRv)58 void AnimationEffectTiming::SetIterationStart(double aIterationStart,
59                                               ErrorResult& aRv) {
60   if (mTiming.IterationStart() == aIterationStart) {
61     return;
62   }
63 
64   TimingParams::ValidateIterationStart(aIterationStart, aRv);
65   if (aRv.Failed()) {
66     return;
67   }
68 
69   mTiming.SetIterationStart(aIterationStart);
70 
71   PostSpecifiedTimingUpdated(mEffect);
72 }
73 
SetIterations(double aIterations,ErrorResult & aRv)74 void AnimationEffectTiming::SetIterations(double aIterations,
75                                           ErrorResult& aRv) {
76   if (mTiming.Iterations() == aIterations) {
77     return;
78   }
79 
80   TimingParams::ValidateIterations(aIterations, aRv);
81   if (aRv.Failed()) {
82     return;
83   }
84 
85   mTiming.SetIterations(aIterations);
86 
87   PostSpecifiedTimingUpdated(mEffect);
88 }
89 
SetDuration(const UnrestrictedDoubleOrString & aDuration,ErrorResult & aRv)90 void AnimationEffectTiming::SetDuration(
91     const UnrestrictedDoubleOrString& aDuration, ErrorResult& aRv) {
92   Maybe<StickyTimeDuration> newDuration =
93       TimingParams::ParseDuration(aDuration, aRv);
94   if (aRv.Failed()) {
95     return;
96   }
97 
98   if (mTiming.Duration() == newDuration) {
99     return;
100   }
101 
102   mTiming.SetDuration(Move(newDuration));
103 
104   PostSpecifiedTimingUpdated(mEffect);
105 }
106 
SetDirection(const PlaybackDirection & aDirection)107 void AnimationEffectTiming::SetDirection(const PlaybackDirection& aDirection) {
108   if (mTiming.Direction() == aDirection) {
109     return;
110   }
111 
112   mTiming.SetDirection(aDirection);
113 
114   PostSpecifiedTimingUpdated(mEffect);
115 }
116 
SetEasing(const nsAString & aEasing,ErrorResult & aRv)117 void AnimationEffectTiming::SetEasing(const nsAString& aEasing,
118                                       ErrorResult& aRv) {
119   Maybe<ComputedTimingFunction> newFunction =
120       TimingParams::ParseEasing(aEasing, mDocument, aRv);
121   if (aRv.Failed()) {
122     return;
123   }
124 
125   if (mTiming.TimingFunction() == newFunction) {
126     return;
127   }
128 
129   mTiming.SetTimingFunction(Move(newFunction));
130 
131   PostSpecifiedTimingUpdated(mEffect);
132 }
133 
134 }  // namespace dom
135 }  // namespace mozilla
136