| 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 24 matching lines...) Expand all Loading... |
| 35 #include "core/animation/ActiveAnimations.h" | 35 #include "core/animation/ActiveAnimations.h" |
| 36 #include "core/animation/DocumentTimeline.h" | 36 #include "core/animation/DocumentTimeline.h" |
| 37 #include "core/animation/KeyframeAnimationEffect.h" | 37 #include "core/animation/KeyframeAnimationEffect.h" |
| 38 #include "core/animation/css/CSSAnimatableValueFactory.h" | 38 #include "core/animation/css/CSSAnimatableValueFactory.h" |
| 39 #include "core/css/CSSKeyframeRule.h" | 39 #include "core/css/CSSKeyframeRule.h" |
| 40 #include "core/css/resolver/StyleResolver.h" | 40 #include "core/css/resolver/StyleResolver.h" |
| 41 #include "core/dom/Element.h" | 41 #include "core/dom/Element.h" |
| 42 #include "core/events/ThreadLocalEventNames.h" | 42 #include "core/events/ThreadLocalEventNames.h" |
| 43 #include "core/events/TransitionEvent.h" | 43 #include "core/events/TransitionEvent.h" |
| 44 #include "core/events/WebKitAnimationEvent.h" | 44 #include "core/events/WebKitAnimationEvent.h" |
| 45 #include "core/frame/UseCounter.h" |
| 45 #include "core/frame/animation/CSSPropertyAnimation.h" | 46 #include "core/frame/animation/CSSPropertyAnimation.h" |
| 46 #include "core/platform/animation/CSSAnimationDataList.h" | 47 #include "core/platform/animation/CSSAnimationDataList.h" |
| 47 #include "core/platform/animation/TimingFunction.h" | 48 #include "core/platform/animation/TimingFunction.h" |
| 48 #include "core/rendering/style/KeyframeList.h" | 49 #include "core/rendering/style/KeyframeList.h" |
| 50 #include "public/platform/Platform.h" |
| 49 #include "wtf/HashSet.h" | 51 #include "wtf/HashSet.h" |
| 50 | 52 |
| 51 namespace WebCore { | 53 namespace WebCore { |
| 52 | 54 |
| 53 struct CandidateTransition { | 55 struct CandidateTransition { |
| 54 CandidateTransition(PassRefPtr<AnimatableValue> from, PassRefPtr<AnimatableV
alue> to, const CSSAnimationData* anim) | 56 CandidateTransition(PassRefPtr<AnimatableValue> from, PassRefPtr<AnimatableV
alue> to, const CSSAnimationData* anim) |
| 55 : from(from) | 57 : from(from) |
| 56 , to(to) | 58 , to(to) |
| 57 , anim(anim) | 59 , anim(anim) |
| 58 { | 60 { |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 ASSERT(RuntimeEnabledFeatures::webAnimationsCSSEnabled()); | 248 ASSERT(RuntimeEnabledFeatures::webAnimationsCSSEnabled()); |
| 247 const StyleRuleKeyframes* keyframesRule = CSSAnimations::matchScopedKeyframe
sRule(resolver, element, name.impl()); | 249 const StyleRuleKeyframes* keyframesRule = CSSAnimations::matchScopedKeyframe
sRule(resolver, element, name.impl()); |
| 248 if (!keyframesRule) | 250 if (!keyframesRule) |
| 249 return; | 251 return; |
| 250 | 252 |
| 251 const Vector<RefPtr<StyleKeyframe> >& styleKeyframes = keyframesRule->keyfra
mes(); | 253 const Vector<RefPtr<StyleKeyframe> >& styleKeyframes = keyframesRule->keyfra
mes(); |
| 252 if (styleKeyframes.isEmpty()) | 254 if (styleKeyframes.isEmpty()) |
| 253 return; | 255 return; |
| 254 | 256 |
| 255 // Construct and populate the style for each keyframe | 257 // Construct and populate the style for each keyframe |
| 258 PropertySet specifiedProperties; |
| 256 KeyframeAnimationEffect::KeyframeVector keyframes; | 259 KeyframeAnimationEffect::KeyframeVector keyframes; |
| 257 HashMap<double, RefPtr<TimingFunction> > perKeyframeTimingFunctions; | 260 HashMap<double, RefPtr<TimingFunction> > perKeyframeTimingFunctions; |
| 258 for (size_t i = 0; i < styleKeyframes.size(); ++i) { | 261 for (size_t i = 0; i < styleKeyframes.size(); ++i) { |
| 259 const StyleKeyframe* styleKeyframe = styleKeyframes[i].get(); | 262 const StyleKeyframe* styleKeyframe = styleKeyframes[i].get(); |
| 260 RefPtr<RenderStyle> keyframeStyle = resolver->styleForKeyframe(element,
style, styleKeyframe); | 263 RefPtr<RenderStyle> keyframeStyle = resolver->styleForKeyframe(element,
style, styleKeyframe); |
| 261 RefPtr<Keyframe> keyframe = Keyframe::create(); | 264 RefPtr<Keyframe> keyframe = Keyframe::create(); |
| 262 const Vector<double>& offsets = styleKeyframe->keys(); | 265 const Vector<double>& offsets = styleKeyframe->keys(); |
| 263 ASSERT(!offsets.isEmpty()); | 266 ASSERT(!offsets.isEmpty()); |
| 264 keyframe->setOffset(offsets[0]); | 267 keyframe->setOffset(offsets[0]); |
| 265 TimingFunction* timingFunction = defaultTimingFunction; | 268 TimingFunction* timingFunction = defaultTimingFunction; |
| 266 const StylePropertySet* properties = styleKeyframe->properties(); | 269 const StylePropertySet* properties = styleKeyframe->properties(); |
| 267 for (unsigned j = 0; j < properties->propertyCount(); j++) { | 270 for (unsigned j = 0; j < properties->propertyCount(); j++) { |
| 268 CSSPropertyID property = properties->propertyAt(j).id(); | 271 CSSPropertyID property = properties->propertyAt(j).id(); |
| 272 specifiedProperties.add(property); |
| 269 if (property == CSSPropertyWebkitAnimationTimingFunction || property
== CSSPropertyAnimationTimingFunction) { | 273 if (property == CSSPropertyWebkitAnimationTimingFunction || property
== CSSPropertyAnimationTimingFunction) { |
| 270 // FIXME: This sometimes gets the wrong timing function. See crb
ug.com/288540. | 274 // FIXME: This sometimes gets the wrong timing function. See crb
ug.com/288540. |
| 271 timingFunction = KeyframeValue::timingFunction(keyframeStyle.get
(), name); | 275 timingFunction = KeyframeValue::timingFunction(keyframeStyle.get
(), name); |
| 272 } else if (CSSAnimations::isAnimatableProperty(property)) { | 276 } else if (CSSAnimations::isAnimatableProperty(property)) { |
| 273 keyframe->setPropertyValue(property, CSSAnimatableValueFactory::
create(property, keyframeStyle.get()).get()); | 277 keyframe->setPropertyValue(property, CSSAnimatableValueFactory::
create(property, keyframeStyle.get()).get()); |
| 274 } | 278 } |
| 275 } | 279 } |
| 276 keyframes.append(keyframe); | 280 keyframes.append(keyframe); |
| 277 // The last keyframe specified at a given offset is used. | 281 // The last keyframe specified at a given offset is used. |
| 278 perKeyframeTimingFunctions.set(offsets[0], timingFunction); | 282 perKeyframeTimingFunctions.set(offsets[0], timingFunction); |
| 279 for (size_t j = 1; j < offsets.size(); ++j) { | 283 for (size_t j = 1; j < offsets.size(); ++j) { |
| 280 keyframes.append(keyframe->cloneWithOffset(offsets[j])); | 284 keyframes.append(keyframe->cloneWithOffset(offsets[j])); |
| 281 perKeyframeTimingFunctions.set(offsets[j], timingFunction); | 285 perKeyframeTimingFunctions.set(offsets[j], timingFunction); |
| 282 } | 286 } |
| 283 } | 287 } |
| 284 ASSERT(!keyframes.isEmpty()); | 288 ASSERT(!keyframes.isEmpty()); |
| 285 | 289 |
| 286 if (!perKeyframeTimingFunctions.contains(0)) | 290 if (!perKeyframeTimingFunctions.contains(0)) |
| 287 perKeyframeTimingFunctions.set(0, defaultTimingFunction); | 291 perKeyframeTimingFunctions.set(0, defaultTimingFunction); |
| 288 | 292 |
| 293 for (PropertySet::const_iterator iter = specifiedProperties.begin(); iter !=
specifiedProperties.end(); ++iter) { |
| 294 const CSSPropertyID property = *iter; |
| 295 ASSERT(property != CSSPropertyInvalid); |
| 296 blink::Platform::current()->histogramSparse("WebCore.Animation.CSSProper
ties", UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(property)); |
| 297 } |
| 298 |
| 289 // Remove duplicate keyframes. In CSS the last keyframe at a given offset ta
kes priority. | 299 // Remove duplicate keyframes. In CSS the last keyframe at a given offset ta
kes priority. |
| 290 std::stable_sort(keyframes.begin(), keyframes.end(), Keyframe::compareOffset
s); | 300 std::stable_sort(keyframes.begin(), keyframes.end(), Keyframe::compareOffset
s); |
| 291 size_t targetIndex = 0; | 301 size_t targetIndex = 0; |
| 292 for (size_t i = 1; i < keyframes.size(); i++) { | 302 for (size_t i = 1; i < keyframes.size(); i++) { |
| 293 if (keyframes[i]->offset() != keyframes[targetIndex]->offset()) | 303 if (keyframes[i]->offset() != keyframes[targetIndex]->offset()) |
| 294 targetIndex++; | 304 targetIndex++; |
| 295 if (targetIndex != i) | 305 if (targetIndex != i) |
| 296 keyframes[targetIndex] = keyframes[i]; | 306 keyframes[targetIndex] = keyframes[i]; |
| 297 } | 307 } |
| 298 keyframes.shrink(targetIndex + 1); | 308 keyframes.shrink(targetIndex + 1); |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 runningTransition.from = newTransition.from; | 541 runningTransition.from = newTransition.from; |
| 532 runningTransition.to = newTransition.to; | 542 runningTransition.to = newTransition.to; |
| 533 | 543 |
| 534 CSSPropertyID id = newTransition.id; | 544 CSSPropertyID id = newTransition.id; |
| 535 InertAnimation* inertAnimation = newTransition.animation.get(); | 545 InertAnimation* inertAnimation = newTransition.animation.get(); |
| 536 OwnPtr<TransitionEventDelegate> eventDelegate = adoptPtr(new TransitionE
ventDelegate(element, id)); | 546 OwnPtr<TransitionEventDelegate> eventDelegate = adoptPtr(new TransitionE
ventDelegate(element, id)); |
| 537 RefPtr<Animation> transition = Animation::create(element, inertAnimation
->effect(), inertAnimation->specified(), Animation::TransitionPriority, eventDel
egate.release()); | 547 RefPtr<Animation> transition = Animation::create(element, inertAnimation
->effect(), inertAnimation->specified(), Animation::TransitionPriority, eventDel
egate.release()); |
| 538 element->document().transitionTimeline()->play(transition.get()); | 548 element->document().transitionTimeline()->play(transition.get()); |
| 539 runningTransition.transition = transition.get(); | 549 runningTransition.transition = transition.get(); |
| 540 m_transitions.set(id, runningTransition); | 550 m_transitions.set(id, runningTransition); |
| 551 ASSERT(id != CSSPropertyInvalid); |
| 552 blink::Platform::current()->histogramSparse("WebCore.Animation.CSSProper
ties", UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(id)); |
| 541 } | 553 } |
| 542 } | 554 } |
| 543 | 555 |
| 544 void CSSAnimations::calculateTransitionUpdateForProperty(CSSAnimationUpdate* upd
ate, CSSPropertyID id, const CandidateTransition& newTransition, const Transitio
nMap* existingTransitions) | 556 void CSSAnimations::calculateTransitionUpdateForProperty(CSSAnimationUpdate* upd
ate, CSSPropertyID id, const CandidateTransition& newTransition, const Transitio
nMap* existingTransitions) |
| 545 { | 557 { |
| 546 if (existingTransitions) { | 558 if (existingTransitions) { |
| 547 TransitionMap::const_iterator existingTransitionIter = existingTransitio
ns->find(id); | 559 TransitionMap::const_iterator existingTransitionIter = existingTransitio
ns->find(id); |
| 548 | 560 |
| 549 if (existingTransitionIter != existingTransitions->end() && !update->can
celledTransitions().contains(id)) { | 561 if (existingTransitionIter != existingTransitions->end() && !update->can
celledTransitions().contains(id)) { |
| 550 const AnimatableValue* existingTo = existingTransitionIter->value.to
; | 562 const AnimatableValue* existingTo = existingTransitionIter->value.to
; |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 CSSPropertyID id = convertToCSSPropertyID(i); | 877 CSSPropertyID id = convertToCSSPropertyID(i); |
| 866 if (isAnimatableProperty(id)) | 878 if (isAnimatableProperty(id)) |
| 867 properties.append(id); | 879 properties.append(id); |
| 868 } | 880 } |
| 869 propertyShorthand = StylePropertyShorthand(CSSPropertyInvalid, propertie
s.begin(), properties.size()); | 881 propertyShorthand = StylePropertyShorthand(CSSPropertyInvalid, propertie
s.begin(), properties.size()); |
| 870 } | 882 } |
| 871 return propertyShorthand; | 883 return propertyShorthand; |
| 872 } | 884 } |
| 873 | 885 |
| 874 } // namespace WebCore | 886 } // namespace WebCore |
| OLD | NEW |