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

Side by Side Diff: Source/core/animation/css/CSSAnimations.cpp

Issue 98663004: Add support for unprefixed CSS Transforms (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase. 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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 return target < reference; 66 return target < reference;
67 } 67 }
68 68
69 bool isLaterPhase(TimedItem::Phase target, TimedItem::Phase reference) 69 bool isLaterPhase(TimedItem::Phase target, TimedItem::Phase reference)
70 { 70 {
71 ASSERT(target != TimedItem::PhaseNone); 71 ASSERT(target != TimedItem::PhaseNone);
72 ASSERT(reference != TimedItem::PhaseNone); 72 ASSERT(reference != TimedItem::PhaseNone);
73 return target > reference; 73 return target > reference;
74 } 74 }
75 75
76 CSSPropertyID propertyForAnimation(CSSPropertyID property)
77 {
78 switch (property) {
79 case CSSPropertyWebkitPerspective:
80 return CSSPropertyPerspective;
81 case CSSPropertyWebkitTransform:
82 return CSSPropertyTransform;
83 case CSSPropertyWebkitPerspectiveOriginX:
84 case CSSPropertyWebkitPerspectiveOriginY:
85 if (RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled())
86 return CSSPropertyPerspectiveOrigin;
87 break;
88 case CSSPropertyWebkitTransformOriginX:
89 case CSSPropertyWebkitTransformOriginY:
90 case CSSPropertyWebkitTransformOriginZ:
91 if (RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled())
92 return CSSPropertyTransformOrigin;
93 break;
94 default:
95 break;
96 }
97 return property;
98 }
99
76 static void resolveKeyframes(StyleResolver* resolver, Element* element, const El ement& parentElement, const RenderStyle& style, RenderStyle* parentStyle, const AtomicString& name, TimingFunction* defaultTimingFunction, 100 static void resolveKeyframes(StyleResolver* resolver, Element* element, const El ement& parentElement, const RenderStyle& style, RenderStyle* parentStyle, const AtomicString& name, TimingFunction* defaultTimingFunction,
77 WillBeHeapVector<KeyframeEffectModel::KeyframeVector>& resolvedKeyframes) 101 WillBeHeapVector<KeyframeEffectModel::KeyframeVector>& resolvedKeyframes)
78 { 102 {
79 // When the element is null, use its parent for scoping purposes. 103 // When the element is null, use its parent for scoping purposes.
80 const Element* elementForScoping = element ? element : &parentElement; 104 const Element* elementForScoping = element ? element : &parentElement;
81 const StyleRuleKeyframes* keyframesRule = CSSAnimations::matchScopedKeyframe sRule(resolver, elementForScoping, name.impl()); 105 const StyleRuleKeyframes* keyframesRule = CSSAnimations::matchScopedKeyframe sRule(resolver, elementForScoping, name.impl());
82 if (!keyframesRule) 106 if (!keyframesRule)
83 return; 107 return;
84 108
85 const Vector<RefPtr<StyleKeyframe> >& styleKeyframes = keyframesRule->keyfra mes(); 109 const Vector<RefPtr<StyleKeyframe> >& styleKeyframes = keyframesRule->keyfra mes();
86 if (styleKeyframes.isEmpty()) 110 if (styleKeyframes.isEmpty())
87 return; 111 return;
88 112
89 // Construct and populate the style for each keyframe 113 // Construct and populate the style for each keyframe
90 PropertySet specifiedProperties; 114 PropertySet specifiedPropertiesForUseCounter;
91 KeyframeEffectModel::KeyframeVector keyframes; 115 KeyframeEffectModel::KeyframeVector keyframes;
92 for (size_t i = 0; i < styleKeyframes.size(); ++i) { 116 for (size_t i = 0; i < styleKeyframes.size(); ++i) {
93 const StyleKeyframe* styleKeyframe = styleKeyframes[i].get(); 117 const StyleKeyframe* styleKeyframe = styleKeyframes[i].get();
94 // It's OK to pass a null element here. 118 // It's OK to pass a null element here.
95 RefPtr<RenderStyle> keyframeStyle = resolver->styleForKeyframe(element, style, parentStyle, styleKeyframe, name); 119 RefPtr<RenderStyle> keyframeStyle = resolver->styleForKeyframe(element, style, parentStyle, styleKeyframe, name);
96 RefPtrWillBeRawPtr<Keyframe> keyframe = Keyframe::create(); 120 RefPtrWillBeRawPtr<Keyframe> keyframe = Keyframe::create();
97 const Vector<double>& offsets = styleKeyframe->keys(); 121 const Vector<double>& offsets = styleKeyframe->keys();
98 ASSERT(!offsets.isEmpty()); 122 ASSERT(!offsets.isEmpty());
99 keyframe->setOffset(offsets[0]); 123 keyframe->setOffset(offsets[0]);
100 keyframe->setEasing(defaultTimingFunction); 124 keyframe->setEasing(defaultTimingFunction);
101 const StylePropertySet& properties = styleKeyframe->properties(); 125 const StylePropertySet& properties = styleKeyframe->properties();
102 for (unsigned j = 0; j < properties.propertyCount(); j++) { 126 for (unsigned j = 0; j < properties.propertyCount(); j++) {
103 CSSPropertyID property = properties.propertyAt(j).id(); 127 specifiedPropertiesForUseCounter.add(properties.propertyAt(j).id());
104 specifiedProperties.add(property); 128 CSSPropertyID property = propertyForAnimation(properties.propertyAt( j).id());
105 if (property == CSSPropertyWebkitAnimationTimingFunction || property == CSSPropertyAnimationTimingFunction) 129 if (property == CSSPropertyWebkitAnimationTimingFunction || property == CSSPropertyAnimationTimingFunction) {
106 keyframe->setEasing(KeyframeValue::timingFunction(*keyframeStyle )); 130 keyframe->setEasing(KeyframeValue::timingFunction(*keyframeStyle ));
107 else if (CSSAnimations::isAnimatableProperty(property)) 131 } else if (CSSAnimations::isAnimatableProperty(property)) {
108 keyframe->setPropertyValue(property, CSSAnimatableValueFactory:: create(property, *keyframeStyle).get()); 132 keyframe->setPropertyValue(property, CSSAnimatableValueFactory:: create(property, *keyframeStyle).get());
133 }
109 } 134 }
110 keyframes.append(keyframe); 135 keyframes.append(keyframe);
111 // The last keyframe specified at a given offset is used. 136 // The last keyframe specified at a given offset is used.
112 for (size_t j = 1; j < offsets.size(); ++j) { 137 for (size_t j = 1; j < offsets.size(); ++j) {
113 keyframes.append(keyframe->cloneWithOffset(offsets[j])); 138 keyframes.append(keyframe->cloneWithOffset(offsets[j]));
114 } 139 }
115 } 140 }
116 ASSERT(!keyframes.isEmpty()); 141 ASSERT(!keyframes.isEmpty());
117 142
118 for (PropertySet::const_iterator iter = specifiedProperties.begin(); iter != specifiedProperties.end(); ++iter) { 143 for (PropertySet::const_iterator iter = specifiedPropertiesForUseCounter.beg in(); iter != specifiedPropertiesForUseCounter.end(); ++iter) {
119 const CSSPropertyID property = *iter; 144 const CSSPropertyID property = *iter;
120 ASSERT(property != CSSPropertyInvalid); 145 ASSERT(property != CSSPropertyInvalid);
121 blink::Platform::current()->histogramSparse("WebCore.Animation.CSSProper ties", UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(property)); 146 blink::Platform::current()->histogramSparse("WebCore.Animation.CSSProper ties", UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(property));
122 } 147 }
123 148
124 // Remove duplicate keyframes. In CSS the last keyframe at a given offset ta kes priority. 149 // Remove duplicate keyframes. In CSS the last keyframe at a given offset ta kes priority.
125 std::stable_sort(keyframes.begin(), keyframes.end(), Keyframe::compareOffset s); 150 std::stable_sort(keyframes.begin(), keyframes.end(), Keyframe::compareOffset s);
126 size_t targetIndex = 0; 151 size_t targetIndex = 0;
127 for (size_t i = 1; i < keyframes.size(); i++) { 152 for (size_t i = 1; i < keyframes.size(); i++) {
128 if (keyframes[i]->offset() != keyframes[targetIndex]->offset()) 153 if (keyframes[i]->offset() != keyframes[targetIndex]->offset())
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 502
478 for (CSSAnimationUpdate::NewTransitionMap::const_iterator iter = update->new Transitions().begin(); iter != update->newTransitions().end(); ++iter) { 503 for (CSSAnimationUpdate::NewTransitionMap::const_iterator iter = update->new Transitions().begin(); iter != update->newTransitions().end(); ++iter) {
479 const CSSAnimationUpdate::NewTransition& newTransition = iter->value; 504 const CSSAnimationUpdate::NewTransition& newTransition = iter->value;
480 505
481 RunningTransition runningTransition; 506 RunningTransition runningTransition;
482 runningTransition.from = newTransition.from; 507 runningTransition.from = newTransition.from;
483 runningTransition.to = newTransition.to; 508 runningTransition.to = newTransition.to;
484 509
485 CSSPropertyID id = newTransition.id; 510 CSSPropertyID id = newTransition.id;
486 InertAnimation* inertAnimation = newTransition.animation.get(); 511 InertAnimation* inertAnimation = newTransition.animation.get();
487 OwnPtr<TransitionEventDelegate> eventDelegate = adoptPtr(new TransitionE ventDelegate(element, id)); 512 OwnPtr<TransitionEventDelegate> eventDelegate = adoptPtr(new TransitionE ventDelegate(element, newTransition.eventId));
488 513
489 RefPtrWillBeRawPtr<AnimationEffect> effect = inertAnimation->effect(); 514 RefPtrWillBeRawPtr<AnimationEffect> effect = inertAnimation->effect();
490 515
491 if (retargetedCompositorTransitions.contains(id)) { 516 if (retargetedCompositorTransitions.contains(id)) {
492 const std::pair<RefPtr<Animation>, double>& oldTransition = retarget edCompositorTransitions.get(id); 517 const std::pair<RefPtr<Animation>, double>& oldTransition = retarget edCompositorTransitions.get(id);
493 RefPtr<Animation> oldAnimation = oldTransition.first; 518 RefPtr<Animation> oldAnimation = oldTransition.first;
494 double oldStartTime = oldTransition.second; 519 double oldStartTime = oldTransition.second;
495 double inheritedTime = isNull(oldStartTime) ? 0 : element->document( ).transitionTimeline().currentTime() - oldStartTime; 520 double inheritedTime = isNull(oldStartTime) ? 0 : element->document( ).transitionTimeline().currentTime() - oldStartTime;
496 oldAnimation->updateInheritedTime(inheritedTime); 521 oldAnimation->updateInheritedTime(inheritedTime);
497 KeyframeEffectModel* oldEffect = toKeyframeEffectModel(inertAnimatio n->effect()); 522 KeyframeEffectModel* oldEffect = toKeyframeEffectModel(inertAnimatio n->effect());
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 startKeyframe->setEasing(timingFunction); 585 startKeyframe->setEasing(timingFunction);
561 keyframes.append(startKeyframe); 586 keyframes.append(startKeyframe);
562 587
563 RefPtrWillBeRawPtr<Keyframe> endKeyframe = Keyframe::create(); 588 RefPtrWillBeRawPtr<Keyframe> endKeyframe = Keyframe::create();
564 endKeyframe->setPropertyValue(id, to.get()); 589 endKeyframe->setPropertyValue(id, to.get());
565 endKeyframe->setOffset(1); 590 endKeyframe->setOffset(1);
566 keyframes.append(endKeyframe); 591 keyframes.append(endKeyframe);
567 592
568 RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create (keyframes); 593 RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create (keyframes);
569 594
570 update->startTransition(id, from.get(), to.get(), InertAnimation::create(eff ect, timing, isPaused)); 595 CSSPropertyID eventId = anim->animationMode() == CSSAnimationData::AnimateAl l ? id : anim->property();
596 update->startTransition(id, eventId, from.get(), to.get(), InertAnimation::c reate(effect, timing, isPaused));
571 ASSERT(!element->activeAnimations() || !element->activeAnimations()->isAnima tionStyleChange()); 597 ASSERT(!element->activeAnimations() || !element->activeAnimations()->isAnima tionStyleChange());
572 } 598 }
573 599
574 void CSSAnimations::calculateTransitionUpdate(CSSAnimationUpdate* update, const Element* element, const RenderStyle& style) 600 void CSSAnimations::calculateTransitionUpdate(CSSAnimationUpdate* update, const Element* element, const RenderStyle& style)
575 { 601 {
576 if (!element) 602 if (!element)
577 return; 603 return;
578 604
579 ActiveAnimations* activeAnimations = element->activeAnimations(); 605 ActiveAnimations* activeAnimations = element->activeAnimations();
580 const TransitionMap* activeTransitions = activeAnimations ? &activeAnimation s->cssAnimations().m_transitions : 0; 606 const TransitionMap* activeTransitions = activeAnimations ? &activeAnimation s->cssAnimations().m_transitions : 0;
(...skipping 21 matching lines...) Expand all
602 bool animateAll = mode == CSSAnimationData::AnimateAll; 628 bool animateAll = mode == CSSAnimationData::AnimateAll;
603 ASSERT(animateAll || mode == CSSAnimationData::AnimateSingleProperty ); 629 ASSERT(animateAll || mode == CSSAnimationData::AnimateSingleProperty );
604 if (animateAll) 630 if (animateAll)
605 anyTransitionHadAnimateAll = true; 631 anyTransitionHadAnimateAll = true;
606 const StylePropertyShorthand& propertyList = animateAll ? CSSAnimati ons::animatableProperties() : shorthandForProperty(anim->property()); 632 const StylePropertyShorthand& propertyList = animateAll ? CSSAnimati ons::animatableProperties() : shorthandForProperty(anim->property());
607 // If not a shorthand we only execute one iteration of this loop, an d refer to the property directly. 633 // If not a shorthand we only execute one iteration of this loop, an d refer to the property directly.
608 for (unsigned j = 0; !j || j < propertyList.length(); ++j) { 634 for (unsigned j = 0; !j || j < propertyList.length(); ++j) {
609 CSSPropertyID id = propertyList.length() ? propertyList.properti es()[j] : anim->property(); 635 CSSPropertyID id = propertyList.length() ? propertyList.properti es()[j] : anim->property();
610 636
611 if (!animateAll) { 637 if (!animateAll) {
638 id = propertyForAnimation(id);
612 if (CSSAnimations::isAnimatableProperty(id)) 639 if (CSSAnimations::isAnimatableProperty(id))
613 listedProperties.set(id); 640 listedProperties.set(id);
614 else 641 else
615 continue; 642 continue;
616 } 643 }
617 644
618 // FIXME: We should transition if an !important property changes even when an animation is running, 645 // FIXME: We should transition if an !important property changes even when an animation is running,
619 // but this is a bit hard to do with the current applyMatchedPro perties system. 646 // but this is a bit hard to do with the current applyMatchedPro perties system.
620 if (!update->activeInterpolationsForAnimations().contains(id) 647 if (!update->activeInterpolationsForAnimations().contains(id)
621 && (!activeAnimations || !activeAnimations->cssAnimations(). m_previousActiveInterpolationsForAnimations.contains(id))) { 648 && (!activeAnimations || !activeAnimations->cssAnimations(). m_previousActiveInterpolationsForAnimations.contains(id))) {
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 const Timing& timing = timedItem->specifiedTiming(); 781 const Timing& timing = timedItem->specifiedTiming();
755 double elapsedTime = timing.iterationDuration; 782 double elapsedTime = timing.iterationDuration;
756 const AtomicString& eventType = EventTypeNames::transitionend; 783 const AtomicString& eventType = EventTypeNames::transitionend;
757 String pseudoElement = PseudoElement::pseudoElementNameForEvents(m_targe t->pseudoId()); 784 String pseudoElement = PseudoElement::pseudoElementNameForEvents(m_targe t->pseudoId());
758 RefPtr<TransitionEvent> event = TransitionEvent::create(eventType, prope rtyName, elapsedTime, pseudoElement); 785 RefPtr<TransitionEvent> event = TransitionEvent::create(eventType, prope rtyName, elapsedTime, pseudoElement);
759 event->setTarget(m_target); 786 event->setTarget(m_target);
760 m_target->document().enqueueAnimationFrameEvent(event); 787 m_target->document().enqueueAnimationFrameEvent(event);
761 } 788 }
762 } 789 }
763 790
764
765 bool CSSAnimations::isAnimatableProperty(CSSPropertyID property) 791 bool CSSAnimations::isAnimatableProperty(CSSPropertyID property)
766 { 792 {
767 switch (property) { 793 switch (property) {
768 case CSSPropertyBackgroundColor: 794 case CSSPropertyBackgroundColor:
769 case CSSPropertyBackgroundImage: 795 case CSSPropertyBackgroundImage:
770 case CSSPropertyBackgroundPositionX: 796 case CSSPropertyBackgroundPositionX:
771 case CSSPropertyBackgroundPositionY: 797 case CSSPropertyBackgroundPositionY:
772 case CSSPropertyBackgroundSize: 798 case CSSPropertyBackgroundSize:
773 case CSSPropertyBaselineShift: 799 case CSSPropertyBaselineShift:
774 case CSSPropertyBorderBottomColor: 800 case CSSPropertyBorderBottomColor:
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 case CSSPropertyWebkitColumnWidth: 877 case CSSPropertyWebkitColumnWidth:
852 case CSSPropertyWebkitFilter: 878 case CSSPropertyWebkitFilter:
853 case CSSPropertyWebkitMaskBoxImageOutset: 879 case CSSPropertyWebkitMaskBoxImageOutset:
854 case CSSPropertyWebkitMaskBoxImageSlice: 880 case CSSPropertyWebkitMaskBoxImageSlice:
855 case CSSPropertyWebkitMaskBoxImageSource: 881 case CSSPropertyWebkitMaskBoxImageSource:
856 case CSSPropertyWebkitMaskBoxImageWidth: 882 case CSSPropertyWebkitMaskBoxImageWidth:
857 case CSSPropertyWebkitMaskImage: 883 case CSSPropertyWebkitMaskImage:
858 case CSSPropertyWebkitMaskPositionX: 884 case CSSPropertyWebkitMaskPositionX:
859 case CSSPropertyWebkitMaskPositionY: 885 case CSSPropertyWebkitMaskPositionY:
860 case CSSPropertyWebkitMaskSize: 886 case CSSPropertyWebkitMaskSize:
861 case CSSPropertyWebkitPerspective: 887 case CSSPropertyPerspective:
862 case CSSPropertyWebkitPerspectiveOriginX:
863 case CSSPropertyWebkitPerspectiveOriginY:
864 case CSSPropertyShapeInside: 888 case CSSPropertyShapeInside:
865 case CSSPropertyShapeOutside: 889 case CSSPropertyShapeOutside:
866 case CSSPropertyShapeMargin: 890 case CSSPropertyShapeMargin:
867 case CSSPropertyShapeImageThreshold: 891 case CSSPropertyShapeImageThreshold:
868 case CSSPropertyWebkitTextStrokeColor: 892 case CSSPropertyWebkitTextStrokeColor:
869 case CSSPropertyWebkitTransform: 893 case CSSPropertyTransform:
870 case CSSPropertyWebkitTransformOriginX:
871 case CSSPropertyWebkitTransformOriginY:
872 case CSSPropertyWebkitTransformOriginZ:
873 case CSSPropertyWidows: 894 case CSSPropertyWidows:
874 case CSSPropertyWidth: 895 case CSSPropertyWidth:
875 case CSSPropertyWordSpacing: 896 case CSSPropertyWordSpacing:
876 case CSSPropertyZIndex: 897 case CSSPropertyZIndex:
877 case CSSPropertyZoom: 898 case CSSPropertyZoom:
878 return true; 899 return true;
900 case CSSPropertyPerspectiveOrigin:
901 case CSSPropertyTransformOrigin:
902 return RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled();
903 case CSSPropertyWebkitPerspectiveOriginX:
904 case CSSPropertyWebkitPerspectiveOriginY:
905 case CSSPropertyWebkitTransformOriginX:
906 case CSSPropertyWebkitTransformOriginY:
907 case CSSPropertyWebkitTransformOriginZ:
908 return !RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled();
879 default: 909 default:
880 return false; 910 return false;
881 } 911 }
882 } 912 }
883 913
884 const StylePropertyShorthand& CSSAnimations::animatableProperties() 914 const StylePropertyShorthand& CSSAnimations::animatableProperties()
885 { 915 {
886 DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, properties, ()); 916 DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, properties, ());
887 DEFINE_STATIC_LOCAL(StylePropertyShorthand, propertyShorthand, ()); 917 DEFINE_STATIC_LOCAL(StylePropertyShorthand, propertyShorthand, ());
888 if (properties.isEmpty()) { 918 if (properties.isEmpty()) {
889 for (int i = firstCSSProperty; i < lastCSSProperty; ++i) { 919 for (int i = firstCSSProperty; i < lastCSSProperty; ++i) {
890 CSSPropertyID id = convertToCSSPropertyID(i); 920 CSSPropertyID id = convertToCSSPropertyID(i);
891 if (isAnimatableProperty(id)) 921 if (isAnimatableProperty(id))
892 properties.append(id); 922 properties.append(id);
893 } 923 }
894 propertyShorthand = StylePropertyShorthand(CSSPropertyInvalid, propertie s.begin(), properties.size()); 924 propertyShorthand = StylePropertyShorthand(CSSPropertyInvalid, propertie s.begin(), properties.size());
895 } 925 }
896 return propertyShorthand; 926 return propertyShorthand;
897 } 927 }
898 928
899 } // namespace WebCore 929 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/animation/css/CSSAnimations.h ('k') | Source/core/animation/css/CSSPropertyEquality.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698