| 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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 if (RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled()) | 90 if (RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled()) |
| 91 return CSSPropertyTransformOrigin; | 91 return CSSPropertyTransformOrigin; |
| 92 break; | 92 break; |
| 93 default: | 93 default: |
| 94 break; | 94 break; |
| 95 } | 95 } |
| 96 return property; | 96 return property; |
| 97 } | 97 } |
| 98 | 98 |
| 99 static void resolveKeyframes(StyleResolver* resolver, Element* element, const El
ement& parentElement, const RenderStyle& style, RenderStyle* parentStyle, const
AtomicString& name, TimingFunction* defaultTimingFunction, | 99 static void resolveKeyframes(StyleResolver* resolver, Element* element, const El
ement& parentElement, const RenderStyle& style, RenderStyle* parentStyle, const
AtomicString& name, TimingFunction* defaultTimingFunction, |
| 100 KeyframeEffectModel::KeyframeVector& keyframes) | 100 AnimatableValueKeyframeVector& keyframes) |
| 101 { | 101 { |
| 102 // When the element is null, use its parent for scoping purposes. | 102 // When the element is null, use its parent for scoping purposes. |
| 103 const Element* elementForScoping = element ? element : &parentElement; | 103 const Element* elementForScoping = element ? element : &parentElement; |
| 104 const StyleRuleKeyframes* keyframesRule = CSSAnimations::matchScopedKeyframe
sRule(resolver, elementForScoping, name.impl()); | 104 const StyleRuleKeyframes* keyframesRule = CSSAnimations::matchScopedKeyframe
sRule(resolver, elementForScoping, name.impl()); |
| 105 if (!keyframesRule) | 105 if (!keyframesRule) |
| 106 return; | 106 return; |
| 107 | 107 |
| 108 const WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >& styleKeyframes =
keyframesRule->keyframes(); | 108 const WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >& styleKeyframes =
keyframesRule->keyframes(); |
| 109 if (styleKeyframes.isEmpty()) | 109 if (styleKeyframes.isEmpty()) |
| 110 return; | 110 return; |
| 111 | 111 |
| 112 // Construct and populate the style for each keyframe | 112 // Construct and populate the style for each keyframe |
| 113 PropertySet specifiedPropertiesForUseCounter; | 113 PropertySet specifiedPropertiesForUseCounter; |
| 114 for (size_t i = 0; i < styleKeyframes.size(); ++i) { | 114 for (size_t i = 0; i < styleKeyframes.size(); ++i) { |
| 115 const StyleKeyframe* styleKeyframe = styleKeyframes[i].get(); | 115 const StyleKeyframe* styleKeyframe = styleKeyframes[i].get(); |
| 116 // It's OK to pass a null element here. | 116 // It's OK to pass a null element here. |
| 117 RefPtr<RenderStyle> keyframeStyle = resolver->styleForKeyframe(element,
style, parentStyle, styleKeyframe, name); | 117 RefPtr<RenderStyle> keyframeStyle = resolver->styleForKeyframe(element,
style, parentStyle, styleKeyframe, name); |
| 118 RefPtrWillBeRawPtr<Keyframe> keyframe = Keyframe::create(); | 118 RefPtrWillBeRawPtr<AnimatableValueKeyframe> keyframe = AnimatableValueKe
yframe::create(); |
| 119 const Vector<double>& offsets = styleKeyframe->keys(); | 119 const Vector<double>& offsets = styleKeyframe->keys(); |
| 120 ASSERT(!offsets.isEmpty()); | 120 ASSERT(!offsets.isEmpty()); |
| 121 keyframe->setOffset(offsets[0]); | 121 keyframe->setOffset(offsets[0]); |
| 122 keyframe->setEasing(defaultTimingFunction); | 122 keyframe->setEasing(defaultTimingFunction); |
| 123 const StylePropertySet& properties = styleKeyframe->properties(); | 123 const StylePropertySet& properties = styleKeyframe->properties(); |
| 124 for (unsigned j = 0; j < properties.propertyCount(); j++) { | 124 for (unsigned j = 0; j < properties.propertyCount(); j++) { |
| 125 specifiedPropertiesForUseCounter.add(properties.propertyAt(j).id()); | 125 specifiedPropertiesForUseCounter.add(properties.propertyAt(j).id()); |
| 126 CSSPropertyID property = propertyForAnimation(properties.propertyAt(
j).id()); | 126 CSSPropertyID property = propertyForAnimation(properties.propertyAt(
j).id()); |
| 127 if (property == CSSPropertyWebkitAnimationTimingFunction || property
== CSSPropertyAnimationTimingFunction) { | 127 if (property == CSSPropertyWebkitAnimationTimingFunction || property
== CSSPropertyAnimationTimingFunction) { |
| 128 keyframe->setEasing(KeyframeValue::timingFunction(*keyframeStyle
)); | 128 keyframe->setEasing(KeyframeValue::timingFunction(*keyframeStyle
)); |
| 129 } else if (CSSAnimations::isAnimatableProperty(property)) { | 129 } else if (CSSAnimations::isAnimatableProperty(property)) { |
| 130 keyframe->setPropertyValue(property, CSSAnimatableValueFactory::
create(property, *keyframeStyle).get()); | 130 keyframe->setPropertyValue(property, CSSAnimatableValueFactory::
create(property, *keyframeStyle).get()); |
| 131 } | 131 } |
| 132 } | 132 } |
| 133 keyframes.append(keyframe); | 133 keyframes.append(keyframe); |
| 134 // The last keyframe specified at a given offset is used. | 134 // The last keyframe specified at a given offset is used. |
| 135 for (size_t j = 1; j < offsets.size(); ++j) { | 135 for (size_t j = 1; j < offsets.size(); ++j) { |
| 136 keyframes.append(keyframe->cloneWithOffset(offsets[j])); | 136 keyframes.append(toAnimatableValueKeyframe(keyframe->cloneWithOffset
(offsets[j]).get())); |
| 137 } | 137 } |
| 138 } | 138 } |
| 139 ASSERT(!keyframes.isEmpty()); | 139 ASSERT(!keyframes.isEmpty()); |
| 140 | 140 |
| 141 for (PropertySet::const_iterator iter = specifiedPropertiesForUseCounter.beg
in(); iter != specifiedPropertiesForUseCounter.end(); ++iter) { | 141 for (PropertySet::const_iterator iter = specifiedPropertiesForUseCounter.beg
in(); iter != specifiedPropertiesForUseCounter.end(); ++iter) { |
| 142 const CSSPropertyID property = *iter; | 142 const CSSPropertyID property = *iter; |
| 143 ASSERT(property != CSSPropertyInvalid); | 143 ASSERT(property != CSSPropertyInvalid); |
| 144 blink::Platform::current()->histogramSparse("WebCore.Animation.CSSProper
ties", UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(property)); | 144 blink::Platform::current()->histogramSparse("WebCore.Animation.CSSProper
ties", UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(property)); |
| 145 } | 145 } |
| 146 | 146 |
| 147 // Remove duplicate keyframes. In CSS the last keyframe at a given offset ta
kes priority. | 147 // Remove duplicate keyframes. In CSS the last keyframe at a given offset ta
kes priority. |
| 148 std::stable_sort(keyframes.begin(), keyframes.end(), Keyframe::compareOffset
s); | 148 std::stable_sort(keyframes.begin(), keyframes.end(), Keyframe::compareOffset
s); |
| 149 size_t targetIndex = 0; | 149 size_t targetIndex = 0; |
| 150 for (size_t i = 1; i < keyframes.size(); i++) { | 150 for (size_t i = 1; i < keyframes.size(); i++) { |
| 151 if (keyframes[i]->offset() != keyframes[targetIndex]->offset()) | 151 if (keyframes[i]->offset() != keyframes[targetIndex]->offset()) |
| 152 targetIndex++; | 152 targetIndex++; |
| 153 if (targetIndex != i) | 153 if (targetIndex != i) |
| 154 keyframes[targetIndex] = keyframes[i]; | 154 keyframes[targetIndex] = keyframes[i]; |
| 155 } | 155 } |
| 156 keyframes.shrink(targetIndex + 1); | 156 keyframes.shrink(targetIndex + 1); |
| 157 | 157 |
| 158 // Add 0% and 100% keyframes if absent. | 158 // Add 0% and 100% keyframes if absent. |
| 159 RefPtrWillBeRawPtr<Keyframe> startKeyframe = keyframes[0]; | 159 RefPtrWillBeRawPtr<AnimatableValueKeyframe> startKeyframe = keyframes[0]; |
| 160 if (startKeyframe->offset()) { | 160 if (startKeyframe->offset()) { |
| 161 startKeyframe = Keyframe::create(); | 161 startKeyframe = AnimatableValueKeyframe::create(); |
| 162 startKeyframe->setOffset(0); | 162 startKeyframe->setOffset(0); |
| 163 keyframes.prepend(startKeyframe); | 163 keyframes.prepend(startKeyframe); |
| 164 } | 164 } |
| 165 RefPtrWillBeRawPtr<Keyframe> endKeyframe = keyframes[keyframes.size() - 1]; | 165 RefPtrWillBeRawPtr<AnimatableValueKeyframe> endKeyframe = keyframes[keyframe
s.size() - 1]; |
| 166 if (endKeyframe->offset() != 1) { | 166 if (endKeyframe->offset() != 1) { |
| 167 endKeyframe = Keyframe::create(); | 167 endKeyframe = AnimatableValueKeyframe::create(); |
| 168 endKeyframe->setOffset(1); | 168 endKeyframe->setOffset(1); |
| 169 keyframes.append(endKeyframe); | 169 keyframes.append(endKeyframe); |
| 170 } | 170 } |
| 171 ASSERT(keyframes.size() >= 2); | 171 ASSERT(keyframes.size() >= 2); |
| 172 ASSERT(!keyframes.first()->offset()); | 172 ASSERT(!keyframes.first()->offset()); |
| 173 ASSERT(keyframes.last()->offset() == 1); | 173 ASSERT(keyframes.last()->offset() == 1); |
| 174 | 174 |
| 175 // Snapshot current property values for 0% and 100% if missing. | 175 // Snapshot current property values for 0% and 100% if missing. |
| 176 PropertySet allProperties; | 176 PropertySet allProperties; |
| 177 size_t numKeyframes = keyframes.size(); | 177 size_t numKeyframes = keyframes.size(); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 ASSERT(!activeAnimations || !activeAnimations->isAnimati
onStyleChange()); | 334 ASSERT(!activeAnimations || !activeAnimations->isAnimati
onStyleChange()); |
| 335 update->toggleAnimationPaused(animationName); | 335 update->toggleAnimationPaused(animationName); |
| 336 } | 336 } |
| 337 continue; | 337 continue; |
| 338 } | 338 } |
| 339 } | 339 } |
| 340 | 340 |
| 341 Timing timing; | 341 Timing timing; |
| 342 bool isPaused; | 342 bool isPaused; |
| 343 RefPtr<TimingFunction> keyframeTimingFunction = timingFromAnimationD
ata(animationData, timing, isPaused); | 343 RefPtr<TimingFunction> keyframeTimingFunction = timingFromAnimationD
ata(animationData, timing, isPaused); |
| 344 KeyframeEffectModel::KeyframeVector resolvedKeyframes; | 344 AnimatableValueKeyframeVector resolvedKeyframes; |
| 345 resolveKeyframes(resolver, element, parentElement, style, parentStyl
e, animationName, keyframeTimingFunction.get(), resolvedKeyframes); | 345 resolveKeyframes(resolver, element, parentElement, style, parentStyl
e, animationName, keyframeTimingFunction.get(), resolvedKeyframes); |
| 346 if (!resolvedKeyframes.isEmpty()) { | 346 if (!resolvedKeyframes.isEmpty()) { |
| 347 ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleC
hange()); | 347 ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleC
hange()); |
| 348 update->startAnimation(animationName, InertAnimation::create(Key
frameEffectModel::create(resolvedKeyframes), timing, isPaused)); | 348 update->startAnimation(animationName, InertAnimation::create(Ani
matableValueKeyframeEffectModel::create(resolvedKeyframes), timing, isPaused)); |
| 349 } | 349 } |
| 350 } | 350 } |
| 351 } | 351 } |
| 352 | 352 |
| 353 ASSERT(inactive.isEmpty() || cssAnimations); | 353 ASSERT(inactive.isEmpty() || cssAnimations); |
| 354 for (HashSet<AtomicString>::const_iterator iter = inactive.begin(); iter !=
inactive.end(); ++iter) { | 354 for (HashSet<AtomicString>::const_iterator iter = inactive.begin(); iter !=
inactive.end(); ++iter) { |
| 355 ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange())
; | 355 ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange())
; |
| 356 update->cancelAnimation(*iter, *cssAnimations->m_animations.get(*iter)); | 356 update->cancelAnimation(*iter, *cssAnimations->m_animations.get(*iter)); |
| 357 } | 357 } |
| 358 } | 358 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 OwnPtr<TransitionEventDelegate> eventDelegate = adoptPtr(new TransitionE
ventDelegate(element, newTransition.eventId)); | 425 OwnPtr<TransitionEventDelegate> eventDelegate = adoptPtr(new TransitionE
ventDelegate(element, newTransition.eventId)); |
| 426 | 426 |
| 427 RefPtrWillBeRawPtr<AnimationEffect> effect = inertAnimation->effect(); | 427 RefPtrWillBeRawPtr<AnimationEffect> effect = inertAnimation->effect(); |
| 428 | 428 |
| 429 if (retargetedCompositorTransitions.contains(id)) { | 429 if (retargetedCompositorTransitions.contains(id)) { |
| 430 const std::pair<RefPtr<Animation>, double>& oldTransition = retarget
edCompositorTransitions.get(id); | 430 const std::pair<RefPtr<Animation>, double>& oldTransition = retarget
edCompositorTransitions.get(id); |
| 431 RefPtr<Animation> oldAnimation = oldTransition.first; | 431 RefPtr<Animation> oldAnimation = oldTransition.first; |
| 432 double oldStartTime = oldTransition.second; | 432 double oldStartTime = oldTransition.second; |
| 433 double inheritedTime = isNull(oldStartTime) ? 0 : element->document(
).transitionTimeline().currentTime() - oldStartTime; | 433 double inheritedTime = isNull(oldStartTime) ? 0 : element->document(
).transitionTimeline().currentTime() - oldStartTime; |
| 434 oldAnimation->updateInheritedTime(inheritedTime); | 434 oldAnimation->updateInheritedTime(inheritedTime); |
| 435 KeyframeEffectModel* oldEffect = toKeyframeEffectModel(inertAnimatio
n->effect()); | 435 AnimatableValueKeyframeEffectModel* oldEffect = toAnimatableValueKey
frameEffectModel(inertAnimation->effect()); |
| 436 const KeyframeEffectModel::KeyframeVector& frames = oldEffect->getFr
ames(); | 436 const KeyframeVector& frames = oldEffect->getFrames(); |
| 437 KeyframeEffectModel::KeyframeVector newFrames; | 437 AnimatableValueKeyframeVector newFrames; |
| 438 newFrames.append(frames[0]->clone()); | 438 newFrames.append(toAnimatableValueKeyframe(frames[0]->clone().get())
); |
| 439 newFrames[0]->clearPropertyValue(id); | 439 newFrames[0]->clearPropertyValue(id); |
| 440 ASSERT(oldAnimation->activeInterpolations().size() == 1); | 440 ASSERT(oldAnimation->activeInterpolations().size() == 1); |
| 441 const AnimatableValue* value = toLegacyStyleInterpolation(oldAnimati
on->activeInterpolations()[0].get())->currentValue(); | 441 RefPtrWillBeRawPtr<AnimatableValue> value = toLegacyStyleInterpolati
on(oldAnimation->activeInterpolations()[0].get())->currentValue(); |
| 442 newFrames[0]->setPropertyValue(id, value); | 442 newFrames[0]->setPropertyValue(id, value.release()); |
| 443 newFrames.append(frames[1]->clone()); | 443 newFrames.append(toAnimatableValueKeyframe(frames[1]->clone().get())
); |
| 444 effect = KeyframeEffectModel::create(newFrames); | 444 effect = AnimatableValueKeyframeEffectModel::create(newFrames); |
| 445 } | 445 } |
| 446 RefPtr<Animation> transition = Animation::create(element, effect, inertA
nimation->specifiedTiming(), Animation::TransitionPriority, eventDelegate.releas
e()); | 446 RefPtr<Animation> transition = Animation::create(element, effect, inertA
nimation->specifiedTiming(), Animation::TransitionPriority, eventDelegate.releas
e()); |
| 447 RefPtr<AnimationPlayer> player = element->document().transitionTimeline(
).createAnimationPlayer(transition.get()); | 447 RefPtr<AnimationPlayer> player = element->document().transitionTimeline(
).createAnimationPlayer(transition.get()); |
| 448 player->update(); | 448 player->update(); |
| 449 element->document().cssPendingAnimations().add(player.get()); | 449 element->document().cssPendingAnimations().add(player.get()); |
| 450 runningTransition.transition = transition.get(); | 450 runningTransition.transition = transition.get(); |
| 451 m_transitions.set(id, runningTransition); | 451 m_transitions.set(id, runningTransition); |
| 452 ASSERT(id != CSSPropertyInvalid); | 452 ASSERT(id != CSSPropertyInvalid); |
| 453 blink::Platform::current()->histogramSparse("WebCore.Animation.CSSProper
ties", UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(id)); | 453 blink::Platform::current()->histogramSparse("WebCore.Animation.CSSProper
ties", UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(id)); |
| 454 } | 454 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 483 if (AnimatableValue::usesDefaultInterpolation(to.get(), from.get())) | 483 if (AnimatableValue::usesDefaultInterpolation(to.get(), from.get())) |
| 484 return; | 484 return; |
| 485 | 485 |
| 486 Timing timing; | 486 Timing timing; |
| 487 bool isPaused; | 487 bool isPaused; |
| 488 RefPtr<TimingFunction> timingFunction = timingFromAnimationData(anim, timing
, isPaused); | 488 RefPtr<TimingFunction> timingFunction = timingFromAnimationData(anim, timing
, isPaused); |
| 489 ASSERT(!isPaused); | 489 ASSERT(!isPaused); |
| 490 // Note that the backwards part is required for delay to work. | 490 // Note that the backwards part is required for delay to work. |
| 491 timing.fillMode = Timing::FillModeBoth; | 491 timing.fillMode = Timing::FillModeBoth; |
| 492 | 492 |
| 493 KeyframeEffectModel::KeyframeVector keyframes; | 493 AnimatableValueKeyframeVector keyframes; |
| 494 | 494 |
| 495 RefPtrWillBeRawPtr<Keyframe> startKeyframe = Keyframe::create(); | 495 RefPtrWillBeRawPtr<AnimatableValueKeyframe> startKeyframe = AnimatableValueK
eyframe::create(); |
| 496 startKeyframe->setPropertyValue(id, from.get()); | 496 startKeyframe->setPropertyValue(id, from.get()); |
| 497 startKeyframe->setOffset(0); | 497 startKeyframe->setOffset(0); |
| 498 startKeyframe->setEasing(timingFunction); | 498 startKeyframe->setEasing(timingFunction); |
| 499 keyframes.append(startKeyframe); | 499 keyframes.append(startKeyframe); |
| 500 | 500 |
| 501 RefPtrWillBeRawPtr<Keyframe> endKeyframe = Keyframe::create(); | 501 RefPtrWillBeRawPtr<AnimatableValueKeyframe> endKeyframe = AnimatableValueKey
frame::create(); |
| 502 endKeyframe->setPropertyValue(id, to.get()); | 502 endKeyframe->setPropertyValue(id, to.get()); |
| 503 endKeyframe->setOffset(1); | 503 endKeyframe->setOffset(1); |
| 504 keyframes.append(endKeyframe); | 504 keyframes.append(endKeyframe); |
| 505 | 505 |
| 506 RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create
(keyframes); | 506 RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableVa
lueKeyframeEffectModel::create(keyframes); |
| 507 | 507 |
| 508 CSSPropertyID eventId = anim->animationMode() == CSSAnimationData::AnimateAl
l ? id : anim->property(); | 508 CSSPropertyID eventId = anim->animationMode() == CSSAnimationData::AnimateAl
l ? id : anim->property(); |
| 509 update->startTransition(id, eventId, from.get(), to.get(), InertAnimation::c
reate(effect, timing, isPaused)); | 509 update->startTransition(id, eventId, from.get(), to.get(), InertAnimation::c
reate(effect, timing, isPaused)); |
| 510 ASSERT(!element->activeAnimations() || !element->activeAnimations()->isAnima
tionStyleChange()); | 510 ASSERT(!element->activeAnimations() || !element->activeAnimations()->isAnima
tionStyleChange()); |
| 511 } | 511 } |
| 512 | 512 |
| 513 void CSSAnimations::calculateTransitionUpdate(CSSAnimationUpdate* update, const
Element* element, const RenderStyle& style) | 513 void CSSAnimations::calculateTransitionUpdate(CSSAnimationUpdate* update, const
Element* element, const RenderStyle& style) |
| 514 { | 514 { |
| 515 if (!element) | 515 if (!element) |
| 516 return; | 516 return; |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 841 } | 841 } |
| 842 | 842 |
| 843 void CSSAnimationUpdate::trace(Visitor* visitor) | 843 void CSSAnimationUpdate::trace(Visitor* visitor) |
| 844 { | 844 { |
| 845 visitor->trace(m_newTransitions); | 845 visitor->trace(m_newTransitions); |
| 846 visitor->trace(m_activeInterpolationsForAnimations); | 846 visitor->trace(m_activeInterpolationsForAnimations); |
| 847 visitor->trace(m_activeInterpolationsForTransitions); | 847 visitor->trace(m_activeInterpolationsForTransitions); |
| 848 } | 848 } |
| 849 | 849 |
| 850 } // namespace WebCore | 850 } // namespace WebCore |
| OLD | NEW |