OLD | NEW |
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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 } | 66 } |
67 | 67 |
68 bool isLaterPhase(TimedItem::Phase target, TimedItem::Phase reference) | 68 bool isLaterPhase(TimedItem::Phase target, TimedItem::Phase reference) |
69 { | 69 { |
70 ASSERT(target != TimedItem::PhaseNone); | 70 ASSERT(target != TimedItem::PhaseNone); |
71 ASSERT(reference != TimedItem::PhaseNone); | 71 ASSERT(reference != TimedItem::PhaseNone); |
72 return target > reference; | 72 return target > reference; |
73 } | 73 } |
74 | 74 |
75 static void resolveKeyframes(StyleResolver* resolver, Element* element, const El
ement& parentElement, const RenderStyle& style, RenderStyle* parentStyle, const
AtomicString& name, TimingFunction* defaultTimingFunction, | 75 static void resolveKeyframes(StyleResolver* resolver, Element* element, const El
ement& parentElement, const RenderStyle& style, RenderStyle* parentStyle, const
AtomicString& name, TimingFunction* defaultTimingFunction, |
76 WillBeHeapVector<KeyframeEffectModel::KeyframeVector>& resolvedKeyframes) | 76 KeyframeEffectModel::KeyframeVector& keyframes) |
77 { | 77 { |
78 // When the element is null, use its parent for scoping purposes. | 78 // When the element is null, use its parent for scoping purposes. |
79 const Element* elementForScoping = element ? element : &parentElement; | 79 const Element* elementForScoping = element ? element : &parentElement; |
80 const StyleRuleKeyframes* keyframesRule = CSSAnimations::matchScopedKeyframe
sRule(resolver, elementForScoping, name.impl()); | 80 const StyleRuleKeyframes* keyframesRule = CSSAnimations::matchScopedKeyframe
sRule(resolver, elementForScoping, name.impl()); |
81 if (!keyframesRule) | 81 if (!keyframesRule) |
82 return; | 82 return; |
83 | 83 |
84 const WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >& styleKeyframes =
keyframesRule->keyframes(); | 84 const WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >& styleKeyframes =
keyframesRule->keyframes(); |
85 if (styleKeyframes.isEmpty()) | 85 if (styleKeyframes.isEmpty()) |
86 return; | 86 return; |
87 | 87 |
88 // Construct and populate the style for each keyframe | 88 // Construct and populate the style for each keyframe |
89 PropertySet specifiedProperties; | 89 PropertySet specifiedProperties; |
90 KeyframeEffectModel::KeyframeVector keyframes; | |
91 for (size_t i = 0; i < styleKeyframes.size(); ++i) { | 90 for (size_t i = 0; i < styleKeyframes.size(); ++i) { |
92 const StyleKeyframe* styleKeyframe = styleKeyframes[i].get(); | 91 const StyleKeyframe* styleKeyframe = styleKeyframes[i].get(); |
93 // It's OK to pass a null element here. | 92 // It's OK to pass a null element here. |
94 RefPtr<RenderStyle> keyframeStyle = resolver->styleForKeyframe(element,
style, parentStyle, styleKeyframe, name); | 93 RefPtr<RenderStyle> keyframeStyle = resolver->styleForKeyframe(element,
style, parentStyle, styleKeyframe, name); |
95 RefPtrWillBeRawPtr<Keyframe> keyframe = Keyframe::create(); | 94 RefPtrWillBeRawPtr<Keyframe> keyframe = Keyframe::create(); |
96 const Vector<double>& offsets = styleKeyframe->keys(); | 95 const Vector<double>& offsets = styleKeyframe->keys(); |
97 ASSERT(!offsets.isEmpty()); | 96 ASSERT(!offsets.isEmpty()); |
98 keyframe->setOffset(offsets[0]); | 97 keyframe->setOffset(offsets[0]); |
99 keyframe->setEasing(defaultTimingFunction); | 98 keyframe->setEasing(defaultTimingFunction); |
100 const StylePropertySet& properties = styleKeyframe->properties(); | 99 const StylePropertySet& properties = styleKeyframe->properties(); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 continue; | 168 continue; |
170 RefPtrWillBeRawPtr<AnimatableValue> snapshotValue = CSSAnimatableVal
ueFactory::create(property, style); | 169 RefPtrWillBeRawPtr<AnimatableValue> snapshotValue = CSSAnimatableVal
ueFactory::create(property, style); |
171 if (startNeedsValue) | 170 if (startNeedsValue) |
172 startKeyframe->setPropertyValue(property, snapshotValue.get()); | 171 startKeyframe->setPropertyValue(property, snapshotValue.get()); |
173 if (endNeedsValue) | 172 if (endNeedsValue) |
174 endKeyframe->setPropertyValue(property, snapshotValue.get()); | 173 endKeyframe->setPropertyValue(property, snapshotValue.get()); |
175 } | 174 } |
176 } | 175 } |
177 ASSERT(startKeyframe->properties().size() == allProperties.size()); | 176 ASSERT(startKeyframe->properties().size() == allProperties.size()); |
178 ASSERT(endKeyframe->properties().size() == allProperties.size()); | 177 ASSERT(endKeyframe->properties().size() == allProperties.size()); |
179 | |
180 // Determine how many keyframes specify each property. Note that this must | |
181 // be done after we've filled in end keyframes. | |
182 typedef HashCountedSet<CSSPropertyID> PropertyCountedSet; | |
183 PropertyCountedSet propertyCounts; | |
184 for (size_t i = 0; i < numKeyframes; ++i) { | |
185 const PropertySet& properties = keyframes[i]->properties(); | |
186 for (PropertySet::const_iterator iter = properties.begin(); iter != prop
erties.end(); ++iter) | |
187 propertyCounts.add(*iter); | |
188 } | |
189 | |
190 // Split keyframes into groups, where each group contains only keyframes | |
191 // which specify all properties used in that group. Each group is animated | |
192 // in a separate animation, to allow per-keyframe timing functions to be | |
193 // applied correctly. | |
194 for (PropertyCountedSet::const_iterator iter = propertyCounts.begin(); iter
!= propertyCounts.end(); ++iter) { | |
195 const CSSPropertyID property = iter->key; | |
196 const size_t count = iter->value; | |
197 ASSERT(count <= numKeyframes); | |
198 if (count == numKeyframes) | |
199 continue; | |
200 KeyframeEffectModel::KeyframeVector splitOutKeyframes; | |
201 for (size_t i = 0; i < numKeyframes; i++) { | |
202 Keyframe* keyframe = keyframes[i].get(); | |
203 if (!keyframe->properties().contains(property)) { | |
204 ASSERT(i && i != numKeyframes - 1); | |
205 continue; | |
206 } | |
207 RefPtrWillBeRawPtr<Keyframe> clonedKeyframe = Keyframe::create(); | |
208 clonedKeyframe->setOffset(keyframe->offset()); | |
209 clonedKeyframe->setEasing(keyframe->easing()); | |
210 clonedKeyframe->setComposite(keyframe->composite()); | |
211 clonedKeyframe->setPropertyValue(property, keyframe->propertyValue(p
roperty)); | |
212 splitOutKeyframes.append(clonedKeyframe); | |
213 // Note that it's OK if this keyframe ends up having no | |
214 // properties. This can only happen when none of the properties | |
215 // are specified in all keyframes, in which case we won't animate | |
216 // anything with these keyframes. | |
217 keyframe->clearPropertyValue(property); | |
218 } | |
219 ASSERT(!splitOutKeyframes.first()->offset()); | |
220 ASSERT(splitOutKeyframes.last()->offset() == 1); | |
221 #ifndef NDEBUG | |
222 for (size_t j = 0; j < splitOutKeyframes.size(); ++j) | |
223 ASSERT(splitOutKeyframes[j]->properties().size() == 1); | |
224 #endif | |
225 resolvedKeyframes.append(splitOutKeyframes); | |
226 } | |
227 | |
228 unsigned numPropertiesSpecifiedInAllKeyframes = keyframes.first()->propertie
s().size(); | |
229 #ifndef NDEBUG | |
230 for (size_t i = 1; i < numKeyframes; ++i) | |
231 ASSERT(keyframes[i]->properties().size() == numPropertiesSpecifiedInAllK
eyframes); | |
232 #endif | |
233 | |
234 // If the animation specifies any keyframes, we always provide at least one | |
235 // vector of resolved keyframes, even if no properties are animated. | |
236 if (numPropertiesSpecifiedInAllKeyframes || resolvedKeyframes.isEmpty()) | |
237 resolvedKeyframes.append(keyframes); | |
238 } | 178 } |
239 | 179 |
240 // Returns the default timing function. | 180 // Returns the default timing function. |
241 const PassRefPtr<TimingFunction> timingFromAnimationData(const CSSAnimationData*
animationData, Timing& timing, bool& isPaused) | 181 const PassRefPtr<TimingFunction> timingFromAnimationData(const CSSAnimationData*
animationData, Timing& timing, bool& isPaused) |
242 { | 182 { |
243 if (animationData->isDelaySet()) | 183 if (animationData->isDelaySet()) |
244 timing.startDelay = animationData->delay(); | 184 timing.startDelay = animationData->delay(); |
245 if (animationData->isDurationSet()) | 185 if (animationData->isDurationSet()) |
246 timing.iterationDuration = animationData->duration(); | 186 timing.iterationDuration = animationData->duration(); |
247 if (animationData->isIterationCountSet()) { | 187 if (animationData->isIterationCountSet()) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 ASSERT_NOT_REACHED(); | 228 ASSERT_NOT_REACHED(); |
289 } | 229 } |
290 } | 230 } |
291 | 231 |
292 // For CSS, the constraints on the timing properties are tighter than in | 232 // For CSS, the constraints on the timing properties are tighter than in |
293 // the general case of the Web Animations model. | 233 // the general case of the Web Animations model. |
294 timing.assertValid(); | 234 timing.assertValid(); |
295 ASSERT(!timing.iterationStart); | 235 ASSERT(!timing.iterationStart); |
296 ASSERT(timing.playbackRate == 1); | 236 ASSERT(timing.playbackRate == 1); |
297 ASSERT(!std::isinf(timing.iterationDuration)); | 237 ASSERT(!std::isinf(timing.iterationDuration)); |
| 238 ASSERT(timing.timingFunction == LinearTimingFunction::preset()); |
298 | 239 |
299 isPaused = animationData->isPlayStateSet() && animationData->playState() ==
AnimPlayStatePaused; | 240 isPaused = animationData->isPlayStateSet() && animationData->playState() ==
AnimPlayStatePaused; |
300 return animationData->isTimingFunctionSet() ? animationData->timingFunction(
) : CSSAnimationData::initialAnimationTimingFunction(); | 241 return animationData->isTimingFunctionSet() ? animationData->timingFunction(
) : CSSAnimationData::initialAnimationTimingFunction(); |
301 } | 242 } |
302 | 243 |
303 } // namespace | 244 } // namespace |
304 | 245 |
305 const StyleRuleKeyframes* CSSAnimations::matchScopedKeyframesRule(StyleResolver*
resolver, const Element* element, const StringImpl* animationName) | 246 const StyleRuleKeyframes* CSSAnimations::matchScopedKeyframesRule(StyleResolver*
resolver, const Element* element, const StringImpl* animationName) |
306 { | 247 { |
307 if (resolver->styleTreeHasOnlyScopedResolverForDocument()) | 248 if (resolver->styleTreeHasOnlyScopedResolverForDocument()) |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 ASSERT(animationData->isValidAnimation()); | 297 ASSERT(animationData->isValidAnimation()); |
357 AtomicString animationName(animationData->name()); | 298 AtomicString animationName(animationData->name()); |
358 | 299 |
359 // Keyframes and animation properties are snapshotted when the | 300 // Keyframes and animation properties are snapshotted when the |
360 // animation starts, so we don't need to track changes to these, | 301 // animation starts, so we don't need to track changes to these, |
361 // with the exception of play-state. | 302 // with the exception of play-state. |
362 if (cssAnimations) { | 303 if (cssAnimations) { |
363 AnimationMap::const_iterator existing(cssAnimations->m_animation
s.find(animationName)); | 304 AnimationMap::const_iterator existing(cssAnimations->m_animation
s.find(animationName)); |
364 if (existing != cssAnimations->m_animations.end()) { | 305 if (existing != cssAnimations->m_animations.end()) { |
365 inactive.remove(animationName); | 306 inactive.remove(animationName); |
366 const HashSet<RefPtr<AnimationPlayer> >& players = existing-
>value; | 307 AnimationPlayer* player = existing->value.get(); |
367 ASSERT(!players.isEmpty()); | 308 if ((animationData->playState() == AnimPlayStatePaused) != p
layer->paused()) { |
368 bool isFirstAnimationPlayerPaused = (*players.begin())->paus
ed(); | |
369 #ifndef NDEBUG | |
370 for (HashSet<RefPtr<AnimationPlayer> >::const_iterator iter
= players.begin(); iter != players.end(); ++iter) | |
371 ASSERT((*iter)->paused() == isFirstAnimationPlayerPaused
); | |
372 #endif | |
373 if ((animationData->playState() == AnimPlayStatePaused) != i
sFirstAnimationPlayerPaused) { | |
374 ASSERT(!activeAnimations || !activeAnimations->isAnimati
onStyleChange()); | 309 ASSERT(!activeAnimations || !activeAnimations->isAnimati
onStyleChange()); |
375 update->toggleAnimationPaused(animationName); | 310 update->toggleAnimationPaused(animationName); |
376 } | 311 } |
377 continue; | 312 continue; |
378 } | 313 } |
379 } | 314 } |
380 | 315 |
381 Timing timing; | 316 Timing timing; |
382 bool isPaused; | 317 bool isPaused; |
383 RefPtr<TimingFunction> defaultTimingFunction = timingFromAnimationDa
ta(animationData, timing, isPaused); | 318 RefPtr<TimingFunction> keyframeTimingFunction = timingFromAnimationD
ata(animationData, timing, isPaused); |
384 WillBeHeapVector<KeyframeEffectModel::KeyframeVector> resolvedKeyfra
mes; | 319 KeyframeEffectModel::KeyframeVector resolvedKeyframes; |
385 resolveKeyframes(resolver, element, parentElement, style, parentStyl
e, animationName, defaultTimingFunction.get(), resolvedKeyframes); | 320 resolveKeyframes(resolver, element, parentElement, style, parentStyl
e, animationName, keyframeTimingFunction.get(), resolvedKeyframes); |
386 if (!resolvedKeyframes.isEmpty()) { | 321 if (!resolvedKeyframes.isEmpty()) { |
387 HashSet<RefPtr<InertAnimation> > animations; | |
388 for (size_t j = 0; j < resolvedKeyframes.size(); ++j) { | |
389 ASSERT(!resolvedKeyframes[j].isEmpty()); | |
390 timing.timingFunction = LinearTimingFunction::preset(); | |
391 // FIXME: crbug.com/268791 - Keyframes are already normalize
d, perhaps there should be a flag on KeyframeEffectModel to skip normalization. | |
392 animations.add(InertAnimation::create(KeyframeEffectModel::c
reate(resolvedKeyframes[j]), timing, isPaused)); | |
393 } | |
394 ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleC
hange()); | 322 ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleC
hange()); |
395 update->startAnimation(animationName, animations); | 323 update->startAnimation(animationName, InertAnimation::create(Key
frameEffectModel::create(resolvedKeyframes), timing, isPaused)); |
396 } | 324 } |
397 } | 325 } |
398 } | 326 } |
399 | 327 |
400 ASSERT(inactive.isEmpty() || cssAnimations); | 328 ASSERT(inactive.isEmpty() || cssAnimations); |
401 for (HashSet<AtomicString>::const_iterator iter = inactive.begin(); iter !=
inactive.end(); ++iter) { | 329 for (HashSet<AtomicString>::const_iterator iter = inactive.begin(); iter !=
inactive.end(); ++iter) { |
402 ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange())
; | 330 ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange())
; |
403 update->cancelAnimation(*iter, cssAnimations->m_animations.get(*iter)); | 331 update->cancelAnimation(*iter, *cssAnimations->m_animations.get(*iter)); |
404 } | 332 } |
405 } | 333 } |
406 | 334 |
407 void CSSAnimations::maybeApplyPendingUpdate(Element* element) | 335 void CSSAnimations::maybeApplyPendingUpdate(Element* element) |
408 { | 336 { |
409 if (!m_pendingUpdate) { | 337 if (!m_pendingUpdate) { |
410 m_previousActiveInterpolationsForAnimations.clear(); | 338 m_previousActiveInterpolationsForAnimations.clear(); |
411 return; | 339 return; |
412 } | 340 } |
413 | 341 |
414 OwnPtrWillBeRawPtr<CSSAnimationUpdate> update = m_pendingUpdate.release(); | 342 OwnPtrWillBeRawPtr<CSSAnimationUpdate> update = m_pendingUpdate.release(); |
415 | 343 |
416 m_previousActiveInterpolationsForAnimations.swap(update->activeInterpolation
sForAnimations()); | 344 m_previousActiveInterpolationsForAnimations.swap(update->activeInterpolation
sForAnimations()); |
417 | 345 |
418 // FIXME: cancelling, pausing, unpausing animations all query compositingSta
te, which is not necessarily up to date here | 346 // FIXME: cancelling, pausing, unpausing animations all query compositingSta
te, which is not necessarily up to date here |
419 // since we call this from recalc style. | 347 // since we call this from recalc style. |
420 // https://code.google.com/p/chromium/issues/detail?id=339847 | 348 // https://code.google.com/p/chromium/issues/detail?id=339847 |
421 DisableCompositingQueryAsserts disabler; | 349 DisableCompositingQueryAsserts disabler; |
422 | 350 |
423 for (Vector<AtomicString>::const_iterator iter = update->cancelledAnimationN
ames().begin(); iter != update->cancelledAnimationNames().end(); ++iter) { | 351 for (Vector<AtomicString>::const_iterator iter = update->cancelledAnimationN
ames().begin(); iter != update->cancelledAnimationNames().end(); ++iter) { |
424 const HashSet<RefPtr<AnimationPlayer> >& players = m_animations.take(*it
er); | 352 m_animations.take(*iter)->cancel(); |
425 for (HashSet<RefPtr<AnimationPlayer> >::const_iterator iter = players.be
gin(); iter != players.end(); ++iter) | |
426 (*iter)->cancel(); | |
427 } | 353 } |
428 | 354 |
429 for (Vector<AtomicString>::const_iterator iter = update->animationsWithPause
Toggled().begin(); iter != update->animationsWithPauseToggled().end(); ++iter) { | 355 for (Vector<AtomicString>::const_iterator iter = update->animationsWithPause
Toggled().begin(); iter != update->animationsWithPauseToggled().end(); ++iter) { |
430 const HashSet<RefPtr<AnimationPlayer> >& players = m_animations.get(*ite
r); | 356 AnimationPlayer* player = m_animations.get(*iter); |
431 ASSERT(!players.isEmpty()); | 357 if (player->paused()) |
432 bool isFirstAnimationPlayerPaused = (*players.begin())->paused(); | 358 player->unpause(); |
433 for (HashSet<RefPtr<AnimationPlayer> >::const_iterator iter = players.be
gin(); iter != players.end(); ++iter) { | 359 else |
434 AnimationPlayer* player = iter->get(); | 360 player->pause(); |
435 ASSERT(player->paused() == isFirstAnimationPlayerPaused); | |
436 if (isFirstAnimationPlayerPaused) | |
437 player->unpause(); | |
438 else | |
439 player->pause(); | |
440 } | |
441 } | 361 } |
442 | 362 |
443 for (Vector<CSSAnimationUpdate::NewAnimation>::const_iterator iter = update-
>newAnimations().begin(); iter != update->newAnimations().end(); ++iter) { | 363 for (Vector<CSSAnimationUpdate::NewAnimation>::const_iterator iter = update-
>newAnimations().begin(); iter != update->newAnimations().end(); ++iter) { |
| 364 const InertAnimation* inertAnimation = iter->animation.get(); |
444 OwnPtr<AnimationEventDelegate> eventDelegate = adoptPtr(new AnimationEve
ntDelegate(element, iter->name)); | 365 OwnPtr<AnimationEventDelegate> eventDelegate = adoptPtr(new AnimationEve
ntDelegate(element, iter->name)); |
445 HashSet<RefPtr<AnimationPlayer> > players; | 366 RefPtr<Animation> animation = Animation::create(element, inertAnimation-
>effect(), inertAnimation->specifiedTiming(), Animation::DefaultPriority, eventD
elegate.release()); |
446 for (HashSet<RefPtr<InertAnimation> >::const_iterator animationsIter = i
ter->animations.begin(); animationsIter != iter->animations.end(); ++animationsI
ter) { | 367 RefPtr<AnimationPlayer> player = element->document().timeline().createAn
imationPlayer(animation.get()); |
447 const InertAnimation* inertAnimation = animationsIter->get(); | 368 if (inertAnimation->paused()) |
448 // The event delegate is set on the the first animation only. We | 369 player->pause(); |
449 // rely on the behavior of OwnPtr::release() to achieve this. | 370 element->document().cssPendingAnimations().add(player.get()); |
450 RefPtr<Animation> animation = Animation::create(element, inertAnimat
ion->effect(), inertAnimation->specifiedTiming(), Animation::DefaultPriority, ev
entDelegate.release()); | 371 player->update(); |
451 AnimationPlayer* player = element->document().timeline().createAnima
tionPlayer(animation.get()); | 372 m_animations.set(iter->name, player.get()); |
452 if (inertAnimation->paused()) | |
453 player->pause(); | |
454 element->document().cssPendingAnimations().add(player); | |
455 player->update(); | |
456 players.add(player); | |
457 } | |
458 m_animations.set(iter->name, players); | |
459 } | 373 } |
460 | 374 |
461 // Transitions that are run on the compositor only update main-thread state | 375 // Transitions that are run on the compositor only update main-thread state |
462 // lazily. However, we need the new state to know what the from state shoud | 376 // lazily. However, we need the new state to know what the from state shoud |
463 // be when transitions are retargeted. Instead of triggering complete style | 377 // be when transitions are retargeted. Instead of triggering complete style |
464 // recalculation, we find these cases by searching for new transitions that | 378 // recalculation, we find these cases by searching for new transitions that |
465 // have matching cancelled animation property IDs on the compositor. | 379 // have matching cancelled animation property IDs on the compositor. |
466 HashMap<CSSPropertyID, std::pair<RefPtr<Animation>, double> > retargetedComp
ositorTransitions; | 380 HashMap<CSSPropertyID, std::pair<RefPtr<Animation>, double> > retargetedComp
ositorTransitions; |
467 const ActiveAnimations* activeAnimations = element->activeAnimations(); | 381 const ActiveAnimations* activeAnimations = element->activeAnimations(); |
468 for (HashSet<CSSPropertyID>::iterator iter = update->cancelledTransitions().
begin(); iter != update->cancelledTransitions().end(); ++iter) { | 382 for (HashSet<CSSPropertyID>::iterator iter = update->cancelledTransitions().
begin(); iter != update->cancelledTransitions().end(); ++iter) { |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
631 if (timedItem->phase() == TimedItem::PhaseAfter || (!anyTransitionHa
dAnimateAll && !animationStyleRecalc && !listedProperties.get(id))) { | 545 if (timedItem->phase() == TimedItem::PhaseAfter || (!anyTransitionHa
dAnimateAll && !animationStyleRecalc && !listedProperties.get(id))) { |
632 ASSERT(timedItem->phase() == TimedItem::PhaseAfter || !(activeAn
imations && activeAnimations->isAnimationStyleChange())); | 546 ASSERT(timedItem->phase() == TimedItem::PhaseAfter || !(activeAn
imations && activeAnimations->isAnimationStyleChange())); |
633 update->cancelTransition(id); | 547 update->cancelTransition(id); |
634 } | 548 } |
635 } | 549 } |
636 } | 550 } |
637 } | 551 } |
638 | 552 |
639 void CSSAnimations::cancel() | 553 void CSSAnimations::cancel() |
640 { | 554 { |
641 for (AnimationMap::iterator iter = m_animations.begin(); iter != m_animation
s.end(); ++iter) { | 555 for (AnimationMap::iterator iter = m_animations.begin(); iter != m_animation
s.end(); ++iter) |
642 const HashSet<RefPtr<AnimationPlayer> >& players = iter->value; | 556 iter->value->cancel(); |
643 for (HashSet<RefPtr<AnimationPlayer> >::const_iterator animationsIter =
players.begin(); animationsIter != players.end(); ++animationsIter) | |
644 (*animationsIter)->cancel(); | |
645 } | |
646 | 557 |
647 for (TransitionMap::iterator iter = m_transitions.begin(); iter != m_transit
ions.end(); ++iter) | 558 for (TransitionMap::iterator iter = m_transitions.begin(); iter != m_transit
ions.end(); ++iter) |
648 iter->value.transition->player()->cancel(); | 559 iter->value.transition->player()->cancel(); |
649 | 560 |
650 m_animations.clear(); | 561 m_animations.clear(); |
651 m_transitions.clear(); | 562 m_transitions.clear(); |
652 m_pendingUpdate = nullptr; | 563 m_pendingUpdate = nullptr; |
653 } | 564 } |
654 | 565 |
655 void CSSAnimations::calculateAnimationActiveInterpolations(CSSAnimationUpdate* u
pdate, const Element* element) | 566 void CSSAnimations::calculateAnimationActiveInterpolations(CSSAnimationUpdate* u
pdate, const Element* element) |
656 { | 567 { |
657 ActiveAnimations* activeAnimations = element ? element->activeAnimations() :
0; | 568 ActiveAnimations* activeAnimations = element ? element->activeAnimations() :
0; |
658 AnimationStack* animationStack = activeAnimations ? &activeAnimations->defau
ltStack() : 0; | 569 AnimationStack* animationStack = activeAnimations ? &activeAnimations->defau
ltStack() : 0; |
659 | 570 |
660 if (update->newAnimations().isEmpty() && update->cancelledAnimationAnimation
Players().isEmpty()) { | 571 if (update->newAnimations().isEmpty() && update->cancelledAnimationAnimation
Players().isEmpty()) { |
661 WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > act
iveInterpolationsForAnimations(AnimationStack::activeInterpolations(animationSta
ck, 0, 0, Animation::DefaultPriority)); | 572 WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > act
iveInterpolationsForAnimations(AnimationStack::activeInterpolations(animationSta
ck, 0, 0, Animation::DefaultPriority)); |
662 update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAn
imations); | 573 update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAn
imations); |
663 return; | 574 return; |
664 } | 575 } |
665 | 576 |
666 Vector<InertAnimation*> newAnimations; | 577 Vector<InertAnimation*> newAnimations; |
667 for (size_t i = 0; i < update->newAnimations().size(); ++i) { | 578 for (size_t i = 0; i < update->newAnimations().size(); ++i) { |
668 HashSet<RefPtr<InertAnimation> > animations = update->newAnimations()[i]
.animations; | 579 newAnimations.append(update->newAnimations()[i].animation.get()); |
669 for (HashSet<RefPtr<InertAnimation> >::const_iterator animationsIter = a
nimations.begin(); animationsIter != animations.end(); ++animationsIter) | |
670 newAnimations.append(animationsIter->get()); | |
671 } | 580 } |
672 WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > activeI
nterpolationsForAnimations(AnimationStack::activeInterpolations(animationStack,
&newAnimations, &update->cancelledAnimationAnimationPlayers(), Animation::Defaul
tPriority)); | 581 WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > activeI
nterpolationsForAnimations(AnimationStack::activeInterpolations(animationStack,
&newAnimations, &update->cancelledAnimationAnimationPlayers(), Animation::Defaul
tPriority)); |
673 update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimat
ions); | 582 update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimat
ions); |
674 } | 583 } |
675 | 584 |
676 void CSSAnimations::calculateTransitionActiveInterpolations(CSSAnimationUpdate*
update, const Element* element) | 585 void CSSAnimations::calculateTransitionActiveInterpolations(CSSAnimationUpdate*
update, const Element* element) |
677 { | 586 { |
678 ActiveAnimations* activeAnimations = element ? element->activeAnimations() :
0; | 587 ActiveAnimations* activeAnimations = element ? element->activeAnimations() :
0; |
679 AnimationStack* animationStack = activeAnimations ? &activeAnimations->defau
ltStack() : 0; | 588 AnimationStack* animationStack = activeAnimations ? &activeAnimations->defau
ltStack() : 0; |
680 | 589 |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
903 } | 812 } |
904 | 813 |
905 void CSSAnimationUpdate::trace(Visitor* visitor) | 814 void CSSAnimationUpdate::trace(Visitor* visitor) |
906 { | 815 { |
907 visitor->trace(m_newTransitions); | 816 visitor->trace(m_newTransitions); |
908 visitor->trace(m_activeInterpolationsForAnimations); | 817 visitor->trace(m_activeInterpolationsForAnimations); |
909 visitor->trace(m_activeInterpolationsForTransitions); | 818 visitor->trace(m_activeInterpolationsForTransitions); |
910 } | 819 } |
911 | 820 |
912 } // namespace WebCore | 821 } // namespace WebCore |
OLD | NEW |