1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "core/animation/TimingInput.h"
7
8 #include "bindings/v8/Dictionary.h"
9 #include "core/css/parser/BisonCSSParser.h"
10 #include "core/css/resolver/CSSToStyleMap.h"
11
12 namespace WebCore {
13
setStartDelay(Timing & timing,double startDelay)14 void TimingInput::setStartDelay(Timing& timing, double startDelay)
15 {
16 if (std::isfinite(startDelay))
17 timing.startDelay = startDelay / 1000;
18 else
19 timing.startDelay = Timing::defaults().startDelay;
20 }
21
setEndDelay(Timing & timing,double endDelay)22 void TimingInput::setEndDelay(Timing& timing, double endDelay)
23 {
24 if (std::isfinite(endDelay))
25 timing.endDelay = endDelay / 1000;
26 else
27 timing.endDelay = Timing::defaults().endDelay;
28 }
29
setFillMode(Timing & timing,const String & fillMode)30 void TimingInput::setFillMode(Timing& timing, const String& fillMode)
31 {
32 if (fillMode == "none") {
33 timing.fillMode = Timing::FillModeNone;
34 } else if (fillMode == "backwards") {
35 timing.fillMode = Timing::FillModeBackwards;
36 } else if (fillMode == "both") {
37 timing.fillMode = Timing::FillModeBoth;
38 } else if (fillMode == "forwards") {
39 timing.fillMode = Timing::FillModeForwards;
40 } else {
41 timing.fillMode = Timing::defaults().fillMode;
42 }
43 }
44
setIterationStart(Timing & timing,double iterationStart)45 void TimingInput::setIterationStart(Timing& timing, double iterationStart)
46 {
47 if (std::isfinite(iterationStart))
48 timing.iterationStart = std::max<double>(iterationStart, 0);
49 else
50 timing.iterationStart = Timing::defaults().iterationStart;
51 }
52
setIterationCount(Timing & timing,double iterationCount)53 void TimingInput::setIterationCount(Timing& timing, double iterationCount)
54 {
55 if (!std::isnan(iterationCount))
56 timing.iterationCount = std::max<double>(iterationCount, 0);
57 else
58 timing.iterationCount = Timing::defaults().iterationCount;
59 }
60
setIterationDuration(Timing & timing,double iterationDuration)61 void TimingInput::setIterationDuration(Timing& timing, double iterationDuration)
62 {
63 if (!std::isnan(iterationDuration) && iterationDuration >= 0)
64 timing.iterationDuration = iterationDuration / 1000;
65 else
66 timing.iterationDuration = Timing::defaults().iterationDuration;
67 }
68
setPlaybackRate(Timing & timing,double playbackRate)69 void TimingInput::setPlaybackRate(Timing& timing, double playbackRate)
70 {
71 if (std::isfinite(playbackRate))
72 timing.playbackRate = playbackRate;
73 else
74 timing.playbackRate = Timing::defaults().playbackRate;
75 }
76
setPlaybackDirection(Timing & timing,const String & direction)77 void TimingInput::setPlaybackDirection(Timing& timing, const String& direction)
78 {
79 if (direction == "reverse") {
80 timing.direction = Timing::PlaybackDirectionReverse;
81 } else if (direction == "alternate") {
82 timing.direction = Timing::PlaybackDirectionAlternate;
83 } else if (direction == "alternate-reverse") {
84 timing.direction = Timing::PlaybackDirectionAlternateReverse;
85 } else {
86 timing.direction = Timing::defaults().direction;
87 }
88 }
89
setTimingFunction(Timing & timing,const String & timingFunctionString)90 void TimingInput::setTimingFunction(Timing& timing, const String& timingFunctionString)
91 {
92 if (RefPtrWillBeRawPtr<CSSValue> timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue(timingFunctionString))
93 timing.timingFunction = CSSToStyleMap::mapAnimationTimingFunction(timingFunctionValue.get(), true);
94 else
95 timing.timingFunction = Timing::defaults().timingFunction;
96 }
97
convert(const Dictionary & timingInputDictionary)98 Timing TimingInput::convert(const Dictionary& timingInputDictionary)
99 {
100 Timing result;
101
102 // FIXME: This method needs to be refactored to handle invalid
103 // null, NaN, Infinity values better.
104 // See: http://www.w3.org/TR/WebIDL/#es-double
105 double startDelay = Timing::defaults().startDelay;
106 timingInputDictionary.get("delay", startDelay);
107 setStartDelay(result, startDelay);
108
109 double endDelay = Timing::defaults().endDelay;
110 timingInputDictionary.get("endDelay", endDelay);
111 setEndDelay(result, endDelay);
112
113 String fillMode;
114 timingInputDictionary.get("fill", fillMode);
115 setFillMode(result, fillMode);
116
117 double iterationStart = Timing::defaults().iterationStart;
118 timingInputDictionary.get("iterationStart", iterationStart);
119 setIterationStart(result, iterationStart);
120
121 double iterationCount = Timing::defaults().iterationCount;
122 timingInputDictionary.get("iterations", iterationCount);
123 setIterationCount(result, iterationCount);
124
125 double iterationDuration = 0;
126 if (timingInputDictionary.get("duration", iterationDuration)) {
127 setIterationDuration(result, iterationDuration);
128 }
129
130 double playbackRate = Timing::defaults().playbackRate;
131 timingInputDictionary.get("playbackRate", playbackRate);
132 setPlaybackRate(result, playbackRate);
133
134 String direction;
135 timingInputDictionary.get("direction", direction);
136 setPlaybackDirection(result, direction);
137
138 String timingFunctionString;
139 timingInputDictionary.get("easing", timingFunctionString);
140 setTimingFunction(result, timingFunctionString);
141
142 result.assertValid();
143
144 return result;
145 }
146
convert(double duration)147 Timing TimingInput::convert(double duration)
148 {
149 Timing result;
150 setIterationDuration(result, duration);
151 return result;
152 }
153
154 } // namespace WebCore
155