OLD | NEW |
| (Empty) |
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 "sky/engine/config.h" | |
6 #include "sky/engine/core/animation/Animation.h" | |
7 | |
8 #include <gtest/gtest.h> | |
9 | |
10 #include "core/testing/DummyPageHolder.h" | |
11 #include "sky/engine/bindings/core/v8/Dictionary.h" | |
12 #include "sky/engine/bindings/core/v8/Nullable.h" | |
13 #include "sky/engine/core/animation/AnimationClock.h" | |
14 #include "sky/engine/core/animation/AnimationHelpers.h" | |
15 #include "sky/engine/core/animation/AnimationNodeTiming.h" | |
16 #include "sky/engine/core/animation/AnimationTestHelper.h" | |
17 #include "sky/engine/core/animation/AnimationTimeline.h" | |
18 #include "sky/engine/core/animation/KeyframeEffectModel.h" | |
19 #include "sky/engine/core/animation/Timing.h" | |
20 #include "sky/engine/core/dom/Document.h" | |
21 #include "v8/include/v8.h" | |
22 | |
23 namespace blink { | |
24 | |
25 class AnimationAnimationTest : public ::testing::Test { | |
26 protected: | |
27 AnimationAnimationTest() | |
28 : pageHolder(DummyPageHolder::create()) | |
29 , document(pageHolder->document()) | |
30 , element(document.createElement("foo", ASSERT_NO_EXCEPTION)) | |
31 { | |
32 document.animationClock().resetTimeForTesting(); | |
33 EXPECT_EQ(0, document.timeline().currentTime()); | |
34 } | |
35 | |
36 OwnPtr<DummyPageHolder> pageHolder; | |
37 Document& document; | |
38 RefPtr<Element> element; | |
39 TrackExceptionState exceptionState; | |
40 }; | |
41 | |
42 class AnimationAnimationV8Test : public AnimationAnimationTest { | |
43 protected: | |
44 AnimationAnimationV8Test() | |
45 : m_isolate(v8::Isolate::GetCurrent()) | |
46 , m_scope(m_isolate) | |
47 { | |
48 } | |
49 | |
50 template<typename T> | |
51 static PassRefPtr<Animation> createAnimation(Element* element, Vector<Dictio
nary> keyframeDictionaryVector, T timingInput, ExceptionState& exceptionState) | |
52 { | |
53 return Animation::create(element, EffectInput::convert(element, keyframe
DictionaryVector, exceptionState), timingInput); | |
54 } | |
55 static PassRefPtr<Animation> createAnimation(Element* element, Vector<Dictio
nary> keyframeDictionaryVector, ExceptionState& exceptionState) | |
56 { | |
57 return Animation::create(element, EffectInput::convert(element, keyframe
DictionaryVector, exceptionState)); | |
58 } | |
59 | |
60 v8::Isolate* m_isolate; | |
61 | |
62 private: | |
63 V8TestingScope m_scope; | |
64 }; | |
65 | |
66 TEST_F(AnimationAnimationV8Test, CanCreateAnAnimation) | |
67 { | |
68 Vector<Dictionary> jsKeyframes; | |
69 v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate); | |
70 v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate); | |
71 | |
72 setV8ObjectPropertyAsString(keyframe1, "width", "100px"); | |
73 setV8ObjectPropertyAsString(keyframe1, "offset", "0"); | |
74 setV8ObjectPropertyAsString(keyframe1, "easing", "ease-in-out"); | |
75 setV8ObjectPropertyAsString(keyframe2, "width", "0px"); | |
76 setV8ObjectPropertyAsString(keyframe2, "offset", "1"); | |
77 setV8ObjectPropertyAsString(keyframe2, "easing", "cubic-bezier(1, 1, 0.3, 0.
3)"); | |
78 | |
79 jsKeyframes.append(Dictionary(keyframe1, m_isolate)); | |
80 jsKeyframes.append(Dictionary(keyframe2, m_isolate)); | |
81 | |
82 String value1; | |
83 ASSERT_TRUE(DictionaryHelper::get(jsKeyframes[0], "width", value1)); | |
84 ASSERT_EQ("100px", value1); | |
85 | |
86 String value2; | |
87 ASSERT_TRUE(DictionaryHelper::get(jsKeyframes[1], "width", value2)); | |
88 ASSERT_EQ("0px", value2); | |
89 | |
90 RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, 0,
exceptionState); | |
91 | |
92 Element* target = animation->target(); | |
93 EXPECT_EQ(*element.get(), *target); | |
94 | |
95 const KeyframeVector keyframes = toKeyframeEffectModelBase(animation->effect
())->getFrames(); | |
96 | |
97 EXPECT_EQ(0, keyframes[0]->offset()); | |
98 EXPECT_EQ(1, keyframes[1]->offset()); | |
99 | |
100 const CSSValue* keyframe1Width = toStringKeyframe(keyframes[0].get())->prope
rtyValue(CSSPropertyWidth); | |
101 const CSSValue* keyframe2Width = toStringKeyframe(keyframes[1].get())->prope
rtyValue(CSSPropertyWidth); | |
102 ASSERT(keyframe1Width); | |
103 ASSERT(keyframe2Width); | |
104 | |
105 EXPECT_EQ("100px", keyframe1Width->cssText()); | |
106 EXPECT_EQ("0px", keyframe2Width->cssText()); | |
107 | |
108 EXPECT_EQ(*(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Eas
eInOut)), keyframes[0]->easing()); | |
109 EXPECT_EQ(*(CubicBezierTimingFunction::create(1, 1, 0.3, 0.3).get()), keyfra
mes[1]->easing()); | |
110 } | |
111 | |
112 TEST_F(AnimationAnimationV8Test, CanSetDuration) | |
113 { | |
114 Vector<Dictionary, 0> jsKeyframes; | |
115 double duration = 2000; | |
116 | |
117 RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, du
ration, exceptionState); | |
118 | |
119 EXPECT_EQ(duration / 1000, animation->specifiedTiming().iterationDuration); | |
120 } | |
121 | |
122 TEST_F(AnimationAnimationV8Test, CanOmitSpecifiedDuration) | |
123 { | |
124 Vector<Dictionary, 0> jsKeyframes; | |
125 RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, ex
ceptionState); | |
126 EXPECT_TRUE(std::isnan(animation->specifiedTiming().iterationDuration)); | |
127 } | |
128 | |
129 TEST_F(AnimationAnimationV8Test, NegativeDurationIsAuto) | |
130 { | |
131 Vector<Dictionary, 0> jsKeyframes; | |
132 RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, -2
, exceptionState); | |
133 EXPECT_TRUE(std::isnan(animation->specifiedTiming().iterationDuration)); | |
134 } | |
135 | |
136 TEST_F(AnimationAnimationV8Test, MismatchedKeyframePropertyRaisesException) | |
137 { | |
138 Vector<Dictionary> jsKeyframes; | |
139 v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate); | |
140 v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate); | |
141 | |
142 setV8ObjectPropertyAsString(keyframe1, "width", "100px"); | |
143 setV8ObjectPropertyAsString(keyframe1, "offset", "0"); | |
144 | |
145 // Height property appears only in keyframe2 | |
146 setV8ObjectPropertyAsString(keyframe2, "height", "100px"); | |
147 setV8ObjectPropertyAsString(keyframe2, "width", "0px"); | |
148 setV8ObjectPropertyAsString(keyframe2, "offset", "1"); | |
149 | |
150 jsKeyframes.append(Dictionary(keyframe1, m_isolate)); | |
151 jsKeyframes.append(Dictionary(keyframe2, m_isolate)); | |
152 | |
153 createAnimation(element.get(), jsKeyframes, 0, exceptionState); | |
154 | |
155 EXPECT_TRUE(exceptionState.hadException()); | |
156 EXPECT_EQ(NotSupportedError, exceptionState.code()); | |
157 } | |
158 | |
159 TEST_F(AnimationAnimationV8Test, MissingOffsetZeroRaisesException) | |
160 { | |
161 Vector<Dictionary> jsKeyframes; | |
162 v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate); | |
163 v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate); | |
164 | |
165 setV8ObjectPropertyAsString(keyframe1, "width", "100px"); | |
166 setV8ObjectPropertyAsString(keyframe1, "offset", "0.1"); | |
167 setV8ObjectPropertyAsString(keyframe2, "width", "0px"); | |
168 setV8ObjectPropertyAsString(keyframe2, "offset", "1"); | |
169 | |
170 jsKeyframes.append(Dictionary(keyframe1, m_isolate)); | |
171 jsKeyframes.append(Dictionary(keyframe2, m_isolate)); | |
172 | |
173 createAnimation(element.get(), jsKeyframes, 0, exceptionState); | |
174 | |
175 EXPECT_TRUE(exceptionState.hadException()); | |
176 EXPECT_EQ(NotSupportedError, exceptionState.code()); | |
177 } | |
178 | |
179 TEST_F(AnimationAnimationV8Test, MissingOffsetOneRaisesException) | |
180 { | |
181 Vector<Dictionary> jsKeyframes; | |
182 v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate); | |
183 v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate); | |
184 | |
185 setV8ObjectPropertyAsString(keyframe1, "width", "100px"); | |
186 setV8ObjectPropertyAsString(keyframe1, "offset", "0"); | |
187 setV8ObjectPropertyAsString(keyframe2, "width", "0px"); | |
188 setV8ObjectPropertyAsString(keyframe2, "offset", "0.1"); | |
189 | |
190 jsKeyframes.append(Dictionary(keyframe1, m_isolate)); | |
191 jsKeyframes.append(Dictionary(keyframe2, m_isolate)); | |
192 | |
193 createAnimation(element.get(), jsKeyframes, 0, exceptionState); | |
194 | |
195 EXPECT_TRUE(exceptionState.hadException()); | |
196 EXPECT_EQ(NotSupportedError, exceptionState.code()); | |
197 } | |
198 | |
199 TEST_F(AnimationAnimationV8Test, MissingOffsetZeroAndOneRaisesException) | |
200 { | |
201 Vector<Dictionary> jsKeyframes; | |
202 v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate); | |
203 v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate); | |
204 | |
205 setV8ObjectPropertyAsString(keyframe1, "width", "100px"); | |
206 setV8ObjectPropertyAsString(keyframe1, "offset", "0.1"); | |
207 setV8ObjectPropertyAsString(keyframe2, "width", "0px"); | |
208 setV8ObjectPropertyAsString(keyframe2, "offset", "0.2"); | |
209 | |
210 jsKeyframes.append(Dictionary(keyframe1, m_isolate)); | |
211 jsKeyframes.append(Dictionary(keyframe2, m_isolate)); | |
212 | |
213 createAnimation(element.get(), jsKeyframes, 0, exceptionState); | |
214 | |
215 EXPECT_TRUE(exceptionState.hadException()); | |
216 EXPECT_EQ(NotSupportedError, exceptionState.code()); | |
217 } | |
218 | |
219 TEST_F(AnimationAnimationV8Test, SpecifiedGetters) | |
220 { | |
221 Vector<Dictionary, 0> jsKeyframes; | |
222 | |
223 v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate); | |
224 setV8ObjectPropertyAsNumber(timingInput, "delay", 2); | |
225 setV8ObjectPropertyAsNumber(timingInput, "endDelay", 0.5); | |
226 setV8ObjectPropertyAsString(timingInput, "fill", "backwards"); | |
227 setV8ObjectPropertyAsNumber(timingInput, "iterationStart", 2); | |
228 setV8ObjectPropertyAsNumber(timingInput, "iterations", 10); | |
229 setV8ObjectPropertyAsNumber(timingInput, "playbackRate", 2); | |
230 setV8ObjectPropertyAsString(timingInput, "direction", "reverse"); | |
231 setV8ObjectPropertyAsString(timingInput, "easing", "step-start"); | |
232 Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(ti
mingInput), m_isolate); | |
233 | |
234 RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, ti
mingInputDictionary, exceptionState); | |
235 | |
236 RefPtr<AnimationNodeTiming> specified = animation->timing(); | |
237 EXPECT_EQ(2, specified->delay()); | |
238 EXPECT_EQ(0.5, specified->endDelay()); | |
239 EXPECT_EQ("backwards", specified->fill()); | |
240 EXPECT_EQ(2, specified->iterationStart()); | |
241 EXPECT_EQ(10, specified->iterations()); | |
242 EXPECT_EQ(2, specified->playbackRate()); | |
243 EXPECT_EQ("reverse", specified->direction()); | |
244 EXPECT_EQ("step-start", specified->easing()); | |
245 } | |
246 | |
247 TEST_F(AnimationAnimationV8Test, SpecifiedDurationGetter) | |
248 { | |
249 Vector<Dictionary, 0> jsKeyframes; | |
250 | |
251 v8::Handle<v8::Object> timingInputWithDuration = v8::Object::New(m_isolate); | |
252 setV8ObjectPropertyAsNumber(timingInputWithDuration, "duration", 2.5); | |
253 Dictionary timingInputDictionaryWithDuration = Dictionary(v8::Handle<v8::Val
ue>::Cast(timingInputWithDuration), m_isolate); | |
254 | |
255 RefPtr<Animation> animationWithDuration = createAnimation(element.get(), jsK
eyframes, timingInputDictionaryWithDuration, exceptionState); | |
256 | |
257 RefPtr<AnimationNodeTiming> specifiedWithDuration = animationWithDuration->t
iming(); | |
258 Nullable<double> numberDuration; | |
259 String stringDuration; | |
260 specifiedWithDuration->getDuration("duration", numberDuration, stringDuratio
n); | |
261 EXPECT_FALSE(numberDuration.isNull()); | |
262 EXPECT_EQ(2.5, numberDuration.get()); | |
263 EXPECT_TRUE(stringDuration.isNull()); | |
264 | |
265 | |
266 v8::Handle<v8::Object> timingInputNoDuration = v8::Object::New(m_isolate); | |
267 Dictionary timingInputDictionaryNoDuration = Dictionary(v8::Handle<v8::Value
>::Cast(timingInputNoDuration), m_isolate); | |
268 | |
269 RefPtr<Animation> animationNoDuration = createAnimation(element.get(), jsKey
frames, timingInputDictionaryNoDuration, exceptionState); | |
270 | |
271 RefPtr<AnimationNodeTiming> specifiedNoDuration = animationNoDuration->timin
g(); | |
272 Nullable<double> numberDuration2; | |
273 String stringDuration2; | |
274 specifiedNoDuration->getDuration("duration", numberDuration2, stringDuration
2); | |
275 EXPECT_TRUE(numberDuration2.isNull()); | |
276 EXPECT_FALSE(stringDuration2.isNull()); | |
277 EXPECT_EQ("auto", stringDuration2); | |
278 } | |
279 | |
280 TEST_F(AnimationAnimationV8Test, SpecifiedSetters) | |
281 { | |
282 Vector<Dictionary, 0> jsKeyframes; | |
283 v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate); | |
284 Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(ti
mingInput), m_isolate); | |
285 RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, ti
mingInputDictionary, exceptionState); | |
286 | |
287 RefPtr<AnimationNodeTiming> specified = animation->timing(); | |
288 | |
289 EXPECT_EQ(0, specified->delay()); | |
290 specified->setDelay(2); | |
291 EXPECT_EQ(2, specified->delay()); | |
292 | |
293 EXPECT_EQ(0, specified->endDelay()); | |
294 specified->setEndDelay(0.5); | |
295 EXPECT_EQ(0.5, specified->endDelay()); | |
296 | |
297 EXPECT_EQ("auto", specified->fill()); | |
298 specified->setFill("backwards"); | |
299 EXPECT_EQ("backwards", specified->fill()); | |
300 | |
301 EXPECT_EQ(0, specified->iterationStart()); | |
302 specified->setIterationStart(2); | |
303 EXPECT_EQ(2, specified->iterationStart()); | |
304 | |
305 EXPECT_EQ(1, specified->iterations()); | |
306 specified->setIterations(10); | |
307 EXPECT_EQ(10, specified->iterations()); | |
308 | |
309 EXPECT_EQ(1, specified->playbackRate()); | |
310 specified->setPlaybackRate(2); | |
311 EXPECT_EQ(2, specified->playbackRate()); | |
312 | |
313 EXPECT_EQ("normal", specified->direction()); | |
314 specified->setDirection("reverse"); | |
315 EXPECT_EQ("reverse", specified->direction()); | |
316 | |
317 EXPECT_EQ("linear", specified->easing()); | |
318 specified->setEasing("step-start"); | |
319 EXPECT_EQ("step-start", specified->easing()); | |
320 } | |
321 | |
322 TEST_F(AnimationAnimationV8Test, SetSpecifiedDuration) | |
323 { | |
324 Vector<Dictionary, 0> jsKeyframes; | |
325 v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate); | |
326 Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(ti
mingInput), m_isolate); | |
327 RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, ti
mingInputDictionary, exceptionState); | |
328 | |
329 RefPtr<AnimationNodeTiming> specified = animation->timing(); | |
330 | |
331 Nullable<double> numberDuration; | |
332 String stringDuration; | |
333 specified->getDuration("duration", numberDuration, stringDuration); | |
334 EXPECT_TRUE(numberDuration.isNull()); | |
335 EXPECT_FALSE(stringDuration.isNull()); | |
336 EXPECT_EQ("auto", stringDuration); | |
337 | |
338 specified->setDuration("duration", 2.5); | |
339 Nullable<double> numberDuration2; | |
340 String stringDuration2; | |
341 specified->getDuration("duration", numberDuration2, stringDuration2); | |
342 EXPECT_FALSE(numberDuration2.isNull()); | |
343 EXPECT_EQ(2.5, numberDuration2.get()); | |
344 EXPECT_TRUE(stringDuration2.isNull()); | |
345 } | |
346 | |
347 TEST_F(AnimationAnimationTest, TimeToEffectChange) | |
348 { | |
349 Timing timing; | |
350 timing.iterationDuration = 100; | |
351 timing.startDelay = 100; | |
352 timing.endDelay = 100; | |
353 timing.fillMode = Timing::FillModeNone; | |
354 RefPtr<Animation> animation = Animation::create(0, nullptr, timing); | |
355 RefPtr<AnimationPlayer> player = document.timeline().play(animation.get()); | |
356 double inf = std::numeric_limits<double>::infinity(); | |
357 | |
358 EXPECT_EQ(100, animation->timeToForwardsEffectChange()); | |
359 EXPECT_EQ(inf, animation->timeToReverseEffectChange()); | |
360 | |
361 player->setCurrentTimeInternal(100); | |
362 EXPECT_EQ(0, animation->timeToForwardsEffectChange()); | |
363 EXPECT_EQ(0, animation->timeToReverseEffectChange()); | |
364 | |
365 player->setCurrentTimeInternal(199); | |
366 EXPECT_EQ(0, animation->timeToForwardsEffectChange()); | |
367 EXPECT_EQ(0, animation->timeToReverseEffectChange()); | |
368 | |
369 player->setCurrentTimeInternal(200); | |
370 // End-exclusive. | |
371 EXPECT_EQ(inf, animation->timeToForwardsEffectChange()); | |
372 EXPECT_EQ(0, animation->timeToReverseEffectChange()); | |
373 | |
374 player->setCurrentTimeInternal(300); | |
375 EXPECT_EQ(inf, animation->timeToForwardsEffectChange()); | |
376 EXPECT_EQ(100, animation->timeToReverseEffectChange()); | |
377 } | |
378 | |
379 TEST_F(AnimationAnimationTest, TimeToEffectChangeWithPlaybackRate) | |
380 { | |
381 Timing timing; | |
382 timing.iterationDuration = 100; | |
383 timing.startDelay = 100; | |
384 timing.endDelay = 100; | |
385 timing.playbackRate = 2; | |
386 timing.fillMode = Timing::FillModeNone; | |
387 RefPtr<Animation> animation = Animation::create(0, nullptr, timing); | |
388 RefPtr<AnimationPlayer> player = document.timeline().play(animation.get()); | |
389 double inf = std::numeric_limits<double>::infinity(); | |
390 | |
391 EXPECT_EQ(100, animation->timeToForwardsEffectChange()); | |
392 EXPECT_EQ(inf, animation->timeToReverseEffectChange()); | |
393 | |
394 player->setCurrentTimeInternal(100); | |
395 EXPECT_EQ(0, animation->timeToForwardsEffectChange()); | |
396 EXPECT_EQ(0, animation->timeToReverseEffectChange()); | |
397 | |
398 player->setCurrentTimeInternal(149); | |
399 EXPECT_EQ(0, animation->timeToForwardsEffectChange()); | |
400 EXPECT_EQ(0, animation->timeToReverseEffectChange()); | |
401 | |
402 player->setCurrentTimeInternal(150); | |
403 // End-exclusive. | |
404 EXPECT_EQ(inf, animation->timeToForwardsEffectChange()); | |
405 EXPECT_EQ(0, animation->timeToReverseEffectChange()); | |
406 | |
407 player->setCurrentTimeInternal(200); | |
408 EXPECT_EQ(inf, animation->timeToForwardsEffectChange()); | |
409 EXPECT_EQ(50, animation->timeToReverseEffectChange()); | |
410 } | |
411 | |
412 TEST_F(AnimationAnimationTest, TimeToEffectChangeWithNegativePlaybackRate) | |
413 { | |
414 Timing timing; | |
415 timing.iterationDuration = 100; | |
416 timing.startDelay = 100; | |
417 timing.endDelay = 100; | |
418 timing.playbackRate = -2; | |
419 timing.fillMode = Timing::FillModeNone; | |
420 RefPtr<Animation> animation = Animation::create(0, nullptr, timing); | |
421 RefPtr<AnimationPlayer> player = document.timeline().play(animation.get()); | |
422 double inf = std::numeric_limits<double>::infinity(); | |
423 | |
424 EXPECT_EQ(100, animation->timeToForwardsEffectChange()); | |
425 EXPECT_EQ(inf, animation->timeToReverseEffectChange()); | |
426 | |
427 player->setCurrentTimeInternal(100); | |
428 EXPECT_EQ(0, animation->timeToForwardsEffectChange()); | |
429 EXPECT_EQ(0, animation->timeToReverseEffectChange()); | |
430 | |
431 player->setCurrentTimeInternal(149); | |
432 EXPECT_EQ(0, animation->timeToForwardsEffectChange()); | |
433 EXPECT_EQ(0, animation->timeToReverseEffectChange()); | |
434 | |
435 player->setCurrentTimeInternal(150); | |
436 EXPECT_EQ(inf, animation->timeToForwardsEffectChange()); | |
437 EXPECT_EQ(0, animation->timeToReverseEffectChange()); | |
438 | |
439 player->setCurrentTimeInternal(200); | |
440 EXPECT_EQ(inf, animation->timeToForwardsEffectChange()); | |
441 EXPECT_EQ(50, animation->timeToReverseEffectChange()); | |
442 } | |
443 | |
444 TEST_F(AnimationAnimationTest, ElementDestructorClearsAnimationTarget) | |
445 { | |
446 // This test expects incorrect behaviour should be removed once Element | |
447 // and Animation are moved to Oilpan. See crbug.com/362404 for context. | |
448 Timing timing; | |
449 timing.iterationDuration = 5; | |
450 RefPtr<Animation> animation = Animation::create(element.get(), nullptr, timi
ng); | |
451 EXPECT_EQ(element.get(), animation->target()); | |
452 document.timeline().play(animation.get()); | |
453 pageHolder.clear(); | |
454 element.clear(); | |
455 #if !ENABLE(OILPAN) | |
456 EXPECT_EQ(0, animation->target()); | |
457 #endif | |
458 } | |
459 | |
460 } // namespace blink | |
OLD | NEW |