Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(97)

Side by Side Diff: Source/core/animation/Animation.cpp

Issue 182063005: Web Animations API: Refactor IDL input conversion out of Animation (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Review changes Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 20 matching lines...) Expand all
31 #include "config.h" 31 #include "config.h"
32 #include "core/animation/Animation.h" 32 #include "core/animation/Animation.h"
33 33
34 #include "bindings/v8/Dictionary.h" 34 #include "bindings/v8/Dictionary.h"
35 #include "core/animation/ActiveAnimations.h" 35 #include "core/animation/ActiveAnimations.h"
36 #include "core/animation/AnimationHelpers.h" 36 #include "core/animation/AnimationHelpers.h"
37 #include "core/animation/CompositorAnimations.h" 37 #include "core/animation/CompositorAnimations.h"
38 #include "core/animation/DocumentTimeline.h" 38 #include "core/animation/DocumentTimeline.h"
39 #include "core/animation/KeyframeEffectModel.h" 39 #include "core/animation/KeyframeEffectModel.h"
40 #include "core/animation/Player.h" 40 #include "core/animation/Player.h"
41 #include "core/css/parser/BisonCSSParser.h"
42 #include "core/css/resolver/StyleResolver.h"
43 #include "core/dom/Element.h" 41 #include "core/dom/Element.h"
44 #include "core/rendering/RenderLayer.h" 42 #include "core/rendering/RenderLayer.h"
45 #include "wtf/text/StringBuilder.h"
46 43
47 namespace WebCore { 44 namespace WebCore {
48 45
49 PassRefPtr<Animation> Animation::create(PassRefPtr<Element> target, PassRefPtrWi llBeRawPtr<AnimationEffect> effect, const Timing& timing, Priority priority, Pas sOwnPtr<EventDelegate> eventDelegate) 46 PassRefPtr<Animation> Animation::create(PassRefPtr<Element> target, PassRefPtrWi llBeRawPtr<AnimationEffect> effect, const Timing& timing, Priority priority, Pas sOwnPtr<EventDelegate> eventDelegate)
50 { 47 {
51 return adoptRef(new Animation(target, effect, timing, priority, eventDelegat e)); 48 return adoptRef(new Animation(target, effect, timing, priority, eventDelegat e));
52 } 49 }
53 50
54 static bool checkDocumentAndRenderer(Element* element) 51 PassRefPtr<Animation> Animation::create(Element* element, PassRefPtrWillBeRawPtr <AnimationEffect> effect, const Dictionary& timingInputDictionary)
55 {
56 if (!element->inActiveDocument())
57 return false;
58 element->document().updateStyleIfNeeded();
59 if (!element->renderer())
60 return false;
61 return true;
62 }
63
64 PassRefPtr<Animation> Animation::create(Element* element, Vector<Dictionary> key frameDictionaryVector, Dictionary timingInput)
65 { 52 {
66 ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled()); 53 ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
67 54 return create(element, effect, TimingInput::convert(timingInputDictionary));
68 // FIXME: This test will not be neccessary once resolution of keyframe value s occurs at
69 // animation application time.
70 if (!checkDocumentAndRenderer(element))
71 return nullptr;
72
73 return createUnsafe(element, keyframeDictionaryVector, timingInput);
74 } 55 }
75 56 PassRefPtr<Animation> Animation::create(Element* element, PassRefPtrWillBeRawPtr <AnimationEffect> effect, double duration)
76 PassRefPtr<Animation> Animation::create(Element* element, Vector<Dictionary> key frameDictionaryVector, double timingInput)
77 { 57 {
78 ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled()); 58 ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
79 59 return create(element, effect, TimingInput::convert(duration));
80 // FIXME: This test will not be neccessary once resolution of keyframe value s occurs at
81 // animation application time.
82 if (!checkDocumentAndRenderer(element))
83 return nullptr;
84
85 return createUnsafe(element, keyframeDictionaryVector, timingInput);
86 } 60 }
87 61 PassRefPtr<Animation> Animation::create(Element* element, PassRefPtrWillBeRawPtr <AnimationEffect> effect)
88 PassRefPtr<Animation> Animation::create(Element* element, Vector<Dictionary> key frameDictionaryVector)
89 { 62 {
90 ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled()); 63 ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
91 64 return create(element, effect, Timing());
92 // FIXME: This test will not be neccessary once resolution of keyframe value s occurs at
93 // animation application time.
94 if (!checkDocumentAndRenderer(element))
95 return nullptr;
96
97 return createUnsafe(element, keyframeDictionaryVector);
98 } 65 }
99 66 PassRefPtr<Animation> Animation::create(Element* element, const Vector<Dictionar y>& keyframeDictionaryVector, const Dictionary& timingInputDictionary)
100 void Animation::setStartDelay(Timing& timing, double startDelay)
101 { 67 {
102 if (std::isfinite(startDelay)) 68 ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
103 timing.startDelay = startDelay; 69 return create(element, EffectInput::convert(element, keyframeDictionaryVecto r), TimingInput::convert(timingInputDictionary));
104 else
105 timing.startDelay = Timing::defaults().startDelay;
106 } 70 }
107 71 PassRefPtr<Animation> Animation::create(Element* element, const Vector<Dictionar y>& keyframeDictionaryVector, double duration)
108 void Animation::setEndDelay(Timing& timing, double endDelay)
109 { 72 {
110 if (std::isfinite(endDelay)) 73 ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
111 timing.endDelay = endDelay; 74 return create(element, EffectInput::convert(element, keyframeDictionaryVecto r), TimingInput::convert(duration));
112 else
113 timing.endDelay = Timing::defaults().endDelay;
114 } 75 }
115 76 PassRefPtr<Animation> Animation::create(Element* element, const Vector<Dictionar y>& keyframeDictionaryVector)
116 void Animation::setFillMode(Timing& timing, String fillMode)
117 { 77 {
118 if (fillMode == "none") { 78 ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
119 timing.fillMode = Timing::FillModeNone; 79 return create(element, EffectInput::convert(element, keyframeDictionaryVecto r), Timing());
120 } else if (fillMode == "backwards") {
121 timing.fillMode = Timing::FillModeBackwards;
122 } else if (fillMode == "both") {
123 timing.fillMode = Timing::FillModeBoth;
124 } else if (fillMode == "forwards") {
125 timing.fillMode = Timing::FillModeForwards;
126 } else {
127 timing.fillMode = Timing::defaults().fillMode;
128 }
129 }
130
131 void Animation::setIterationStart(Timing& timing, double iterationStart)
132 {
133 if (!std::isnan(iterationStart) && !std::isinf(iterationStart))
134 timing.iterationStart = std::max<double>(iterationStart, 0);
135 else
136 timing.iterationStart = Timing::defaults().iterationStart;
137 }
138
139 void Animation::setIterationCount(Timing& timing, double iterationCount)
140 {
141 if (!std::isnan(iterationCount))
142 timing.iterationCount = std::max<double>(iterationCount, 0);
143 else
144 timing.iterationCount = Timing::defaults().iterationCount;
145 }
146
147 void Animation::setIterationDuration(Timing& timing, double iterationDuration)
148 {
149 if (!std::isnan(iterationDuration) && iterationDuration >= 0)
150 timing.iterationDuration = iterationDuration;
151 else
152 timing.iterationDuration = Timing::defaults().iterationDuration;
153 }
154
155 void Animation::setPlaybackRate(Timing& timing, double playbackRate)
156 {
157 if (!std::isnan(playbackRate) && !std::isinf(playbackRate))
158 timing.playbackRate = playbackRate;
159 else
160 timing.playbackRate = Timing::defaults().playbackRate;
161 }
162
163 void Animation::setPlaybackDirection(Timing& timing, String direction)
164 {
165 if (direction == "reverse") {
166 timing.direction = Timing::PlaybackDirectionReverse;
167 } else if (direction == "alternate") {
168 timing.direction = Timing::PlaybackDirectionAlternate;
169 } else if (direction == "alternate-reverse") {
170 timing.direction = Timing::PlaybackDirectionAlternateReverse;
171 } else {
172 timing.direction = Timing::defaults().direction;
173 }
174 }
175
176 void Animation::setTimingFunction(Timing& timing, String timingFunctionString)
177 {
178 RefPtrWillBeRawPtr<CSSValue> timingFunctionValue = BisonCSSParser::parseAnim ationTimingFunctionValue(timingFunctionString);
179 if (timingFunctionValue) {
180 RefPtr<TimingFunction> timingFunction = CSSToStyleMap::animationTimingFu nction(timingFunctionValue.get(), false);
181 if (timingFunction) {
182 timing.timingFunction = timingFunction;
183 return;
184 }
185 }
186 timing.timingFunction = Timing::defaults().timingFunction;
187 }
188
189 void Animation::populateTiming(Timing& timing, Dictionary timingInputDictionary)
190 {
191 // FIXME: This method needs to be refactored to handle invalid
192 // null, NaN, Infinity values better.
193 // See: http://www.w3.org/TR/WebIDL/#es-double
194 double startDelay = 0;
195 timingInputDictionary.get("delay", startDelay);
196 setStartDelay(timing, startDelay);
197
198 double endDelay = 0;
199 timingInputDictionary.get("endDelay", endDelay);
200 setEndDelay(timing, endDelay);
201
202 String fillMode;
203 timingInputDictionary.get("fill", fillMode);
204 setFillMode(timing, fillMode);
205
206 double iterationStart = 0;
207 timingInputDictionary.get("iterationStart", iterationStart);
208 setIterationStart(timing, iterationStart);
209
210 double iterationCount = 1;
211 timingInputDictionary.get("iterations", iterationCount);
212 setIterationCount(timing, iterationCount);
213
214 v8::Local<v8::Value> iterationDurationValue;
215 if (timingInputDictionary.get("duration", iterationDurationValue)) {
216 double iterationDuration = iterationDurationValue->NumberValue();
217 setIterationDuration(timing, iterationDuration);
218 }
219
220 double playbackRate = 1;
221 timingInputDictionary.get("playbackRate", playbackRate);
222 setPlaybackRate(timing, playbackRate);
223
224 String direction;
225 timingInputDictionary.get("direction", direction);
226 setPlaybackDirection(timing, direction);
227
228 String timingFunctionString;
229 timingInputDictionary.get("easing", timingFunctionString);
230 setTimingFunction(timing, timingFunctionString);
231
232 timing.assertValid();
233 }
234
235 static PassRefPtrWillBeRawPtr<KeyframeEffectModel> createKeyframeEffectModel(Ele ment* element, Vector<Dictionary> keyframeDictionaryVector)
236 {
237 KeyframeEffectModel::KeyframeVector keyframes;
238 Vector<RefPtr<MutableStylePropertySet> > propertySetVector;
239
240 for (size_t i = 0; i < keyframeDictionaryVector.size(); ++i) {
241 RefPtr<MutableStylePropertySet> propertySet = MutableStylePropertySet::c reate();
242 propertySetVector.append(propertySet);
243
244 RefPtrWillBeRawPtr<Keyframe> keyframe = Keyframe::create();
245 keyframes.append(keyframe);
246
247 double offset;
248 if (keyframeDictionaryVector[i].get("offset", offset)) {
249 keyframe->setOffset(offset);
250 }
251
252 String compositeString;
253 keyframeDictionaryVector[i].get("composite", compositeString);
254 if (compositeString == "add")
255 keyframe->setComposite(AnimationEffect::CompositeAdd);
256
257 String timingFunctionString;
258 if (keyframeDictionaryVector[i].get("easing", timingFunctionString)) {
259 RefPtrWillBeRawPtr<CSSValue> timingFunctionValue = BisonCSSParser::p arseAnimationTimingFunctionValue(timingFunctionString);
260 if (timingFunctionValue) {
261 keyframe->setEasing(CSSToStyleMap::animationTimingFunction(timin gFunctionValue.get(), false));
262 }
263 }
264
265 Vector<String> keyframeProperties;
266 keyframeDictionaryVector[i].getOwnPropertyNames(keyframeProperties);
267
268 for (size_t j = 0; j < keyframeProperties.size(); ++j) {
269 String property = keyframeProperties[j];
270 CSSPropertyID id = camelCaseCSSPropertyNameToID(property);
271
272 // FIXME: There is no way to store invalid properties or invalid val ues
273 // in a Keyframe object, so for now I just skip over them. Eventuall y we
274 // will need to support getFrames(), which should return exactly the
275 // keyframes that were input through the API. We will add a layer to wrap
276 // KeyframeEffectModel, store input keyframes and implement getFrame s.
277 if (id == CSSPropertyInvalid || !CSSAnimations::isAnimatableProperty (id))
278 continue;
279
280 String value;
281 keyframeDictionaryVector[i].get(property, value);
282 propertySet->setProperty(id, value);
283 }
284 }
285
286 // FIXME: Replace this with code that just parses, when that code is availab le.
287 RefPtrWillBeRawPtr<KeyframeEffectModel> effect = StyleResolver::createKeyfra meEffectModel(*element, propertySetVector, keyframes);
288 return effect;
289 }
290
291 PassRefPtr<Animation> Animation::createUnsafe(Element* element, Vector<Dictionar y> keyframeDictionaryVector, Dictionary timingInput)
292 {
293 RefPtrWillBeRawPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(e lement, keyframeDictionaryVector);
294
295 Timing timing;
296 populateTiming(timing, timingInput);
297
298 return create(element, effect, timing);
299 }
300
301 PassRefPtr<Animation> Animation::createUnsafe(Element* element, Vector<Dictionar y> keyframeDictionaryVector, double timingInput)
302 {
303 RefPtrWillBeRawPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(e lement, keyframeDictionaryVector);
304
305 Timing timing;
306 if (!std::isnan(timingInput))
307 timing.iterationDuration = std::max<double>(timingInput, 0);
308
309 return create(element, effect, timing);
310 }
311
312 PassRefPtr<Animation> Animation::createUnsafe(Element* element, Vector<Dictionar y> keyframeDictionaryVector)
313 {
314 RefPtrWillBeRawPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(e lement, keyframeDictionaryVector);
315 Timing timing;
316
317 return create(element, effect, timing);
318 } 80 }
319 81
320 Animation::Animation(PassRefPtr<Element> target, PassRefPtrWillBeRawPtr<Animatio nEffect> effect, const Timing& timing, Priority priority, PassOwnPtr<EventDelega te> eventDelegate) 82 Animation::Animation(PassRefPtr<Element> target, PassRefPtrWillBeRawPtr<Animatio nEffect> effect, const Timing& timing, Priority priority, PassOwnPtr<EventDelega te> eventDelegate)
321 : TimedItem(timing, eventDelegate) 83 : TimedItem(timing, eventDelegate)
322 , m_target(target) 84 , m_target(target)
323 , m_effect(effect) 85 , m_effect(effect)
324 , m_activeInAnimationStack(false) 86 , m_activeInAnimationStack(false)
325 , m_priority(priority) 87 , m_priority(priority)
326 { 88 {
327 } 89 }
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 void Animation::pauseAnimationForTestingOnCompositor(double pauseTime) 240 void Animation::pauseAnimationForTestingOnCompositor(double pauseTime)
479 { 241 {
480 ASSERT(hasActiveAnimationsOnCompositor()); 242 ASSERT(hasActiveAnimationsOnCompositor());
481 if (!m_target || !m_target->renderer()) 243 if (!m_target || !m_target->renderer())
482 return; 244 return;
483 for (size_t i = 0; i < m_compositorAnimationIds.size(); ++i) 245 for (size_t i = 0; i < m_compositorAnimationIds.size(); ++i)
484 CompositorAnimations::instance()->pauseAnimationForTestingOnCompositor(* m_target.get(), m_compositorAnimationIds[i], pauseTime); 246 CompositorAnimations::instance()->pauseAnimationForTestingOnCompositor(* m_target.get(), m_compositorAnimationIds[i], pauseTime);
485 } 247 }
486 248
487 } // namespace WebCore 249 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698