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.
6 #include "core/animation/StringKeyframe.h"
8 #include "core/animation/DefaultStyleInterpolation.h"
9 #include "core/animation/DeferredLegacyStyleInterpolation.h"
10 #include "core/animation/LegacyStyleInterpolation.h"
11 #include "core/animation/LengthStyleInterpolation.h"
12 #include "core/animation/css/CSSAnimations.h"
13 #include "core/css/CSSPropertyMetadata.h"
14 #include "core/css/resolver/StyleResolver.h"
15 #include "core/rendering/style/RenderStyle.h"
19 StringKeyframe::StringKeyframe(const StringKeyframe& copyFrom)
20 : Keyframe(copyFrom.m_offset, copyFrom.m_composite, copyFrom.m_easing)
21 , m_propertySet(copyFrom.m_propertySet->mutableCopy())
25 void StringKeyframe::setPropertyValue(CSSPropertyID property, const String& value, StyleSheetContents* styleSheetContents)
27 ASSERT(property != CSSPropertyInvalid);
28 if (CSSAnimations::isAllowedAnimation(property))
29 m_propertySet->setProperty(property, value, false, styleSheetContents);
32 PropertySet StringKeyframe::properties() const
34 // This is not used in time-critical code, so we probably don't need to
35 // worry about caching this result.
36 PropertySet properties;
37 for (unsigned i = 0; i < m_propertySet->propertyCount(); ++i)
38 properties.add(m_propertySet->propertyAt(i).id());
42 PassRefPtrWillBeRawPtr<Keyframe> StringKeyframe::clone() const
44 return adoptRefWillBeNoop(new StringKeyframe(*this));
46 PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::createPropertySpecificKeyframe(CSSPropertyID property) const
48 return adoptPtrWillBeNoop(new PropertySpecificKeyframe(offset(), &easing(), propertyValue(property), composite()));
51 void StringKeyframe::trace(Visitor* visitor)
53 visitor->trace(m_propertySet);
54 Keyframe::trace(visitor);
57 StringKeyframe::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, CSSValue* value, AnimationEffect::CompositeOperation op)
58 : Keyframe::PropertySpecificKeyframe(offset, easing, op)
62 StringKeyframe::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, CSSValue* value)
63 : Keyframe::PropertySpecificKeyframe(offset, easing, AnimationEffect::CompositeReplace)
66 ASSERT(!isNull(m_offset));
69 PassRefPtrWillBeRawPtr<Interpolation> StringKeyframe::PropertySpecificKeyframe::createInterpolation(CSSPropertyID property, Keyframe::PropertySpecificKeyframe* end, Element* element) const
71 CSSValue* fromCSSValue = m_value.get();
72 CSSValue* toCSSValue = toStringPropertySpecificKeyframe(end)->value();
73 ValueRange range = ValueRangeAll;
75 if (!CSSPropertyMetadata::isAnimatableProperty(property))
76 return DefaultStyleInterpolation::create(fromCSSValue, toCSSValue, property);
79 case CSSPropertyBorderBottomWidth:
80 case CSSPropertyBorderLeftWidth:
81 case CSSPropertyBorderRightWidth:
82 case CSSPropertyBorderTopWidth:
83 case CSSPropertyFontSize:
84 case CSSPropertyHeight:
85 case CSSPropertyLineHeight:
86 case CSSPropertyMaxHeight:
87 case CSSPropertyMaxWidth:
88 case CSSPropertyMinHeight:
89 case CSSPropertyMinWidth:
90 case CSSPropertyOutlineWidth:
91 case CSSPropertyPaddingBottom:
92 case CSSPropertyPaddingLeft:
93 case CSSPropertyPaddingRight:
94 case CSSPropertyPaddingTop:
95 case CSSPropertyPerspective:
96 case CSSPropertyShapeMargin:
97 case CSSPropertyWidth:
98 range = ValueRangeNonNegative;
100 case CSSPropertyBottom:
101 case CSSPropertyLeft:
102 case CSSPropertyLetterSpacing:
103 case CSSPropertyMarginBottom:
104 case CSSPropertyMarginLeft:
105 case CSSPropertyMarginRight:
106 case CSSPropertyMarginTop:
107 case CSSPropertyOutlineOffset:
108 case CSSPropertyRight:
110 case CSSPropertyVerticalAlign:
111 case CSSPropertyWordSpacing:
112 if (LengthStyleInterpolation::canCreateFrom(*fromCSSValue) && LengthStyleInterpolation::canCreateFrom(*toCSSValue))
113 return LengthStyleInterpolation::create(fromCSSValue, toCSSValue, property, range);
119 if (DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(*fromCSSValue) || DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(*toCSSValue))
120 return DeferredLegacyStyleInterpolation::create(fromCSSValue, toCSSValue, property);
122 // FIXME: Remove the use of AnimatableValues, RenderStyles and Elements here.
123 // FIXME: Remove this cache
125 if (!m_animatableValueCache)
126 m_animatableValueCache = StyleResolver::createAnimatableValueSnapshot(*element, property, *fromCSSValue);
128 RefPtrWillBeRawPtr<AnimatableValue> to = StyleResolver::createAnimatableValueSnapshot(*element, property, *toCSSValue);
129 toStringPropertySpecificKeyframe(end)->m_animatableValueCache = to;
131 return LegacyStyleInterpolation::create(m_animatableValueCache.get(), to.release(), property);
134 PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::PropertySpecificKeyframe::neutralKeyframe(double offset, PassRefPtr<TimingFunction> easing) const
136 return adoptPtrWillBeNoop(new PropertySpecificKeyframe(offset, easing, 0, AnimationEffect::CompositeAdd));
139 PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::PropertySpecificKeyframe::cloneWithOffset(double offset) const
141 Keyframe::PropertySpecificKeyframe* theClone = new PropertySpecificKeyframe(offset, m_easing, m_value.get());
142 toStringPropertySpecificKeyframe(theClone)->m_animatableValueCache = m_animatableValueCache;
143 return adoptPtrWillBeNoop(theClone);
146 void StringKeyframe::PropertySpecificKeyframe::trace(Visitor* visitor)
148 visitor->trace(m_value);
149 visitor->trace(m_animatableValueCache);
150 Keyframe::PropertySpecificKeyframe::trace(visitor);