Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / animation / StringKeyframe.cpp
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.
4
5 #include "config.h"
6 #include "core/animation/StringKeyframe.h"
7
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"
16
17 namespace blink {
18
19 StringKeyframe::StringKeyframe(const StringKeyframe& copyFrom)
20     : Keyframe(copyFrom.m_offset, copyFrom.m_composite, copyFrom.m_easing)
21     , m_propertySet(copyFrom.m_propertySet->mutableCopy())
22 {
23 }
24
25 void StringKeyframe::setPropertyValue(CSSPropertyID property, const String& value, StyleSheetContents* styleSheetContents)
26 {
27     ASSERT(property != CSSPropertyInvalid);
28     if (CSSAnimations::isAllowedAnimation(property))
29         m_propertySet->setProperty(property, value, false, styleSheetContents);
30 }
31
32 PropertySet StringKeyframe::properties() const
33 {
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());
39     return properties;
40 }
41
42 PassRefPtrWillBeRawPtr<Keyframe> StringKeyframe::clone() const
43 {
44     return adoptRefWillBeNoop(new StringKeyframe(*this));
45 }
46 PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::createPropertySpecificKeyframe(CSSPropertyID property) const
47 {
48     return adoptPtrWillBeNoop(new PropertySpecificKeyframe(offset(), &easing(), propertyValue(property), composite()));
49 }
50
51 void StringKeyframe::trace(Visitor* visitor)
52 {
53     visitor->trace(m_propertySet);
54     Keyframe::trace(visitor);
55 }
56
57 StringKeyframe::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, CSSValue* value, AnimationEffect::CompositeOperation op)
58     : Keyframe::PropertySpecificKeyframe(offset, easing, op)
59     , m_value(value)
60 { }
61
62 StringKeyframe::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, CSSValue* value)
63     : Keyframe::PropertySpecificKeyframe(offset, easing, AnimationEffect::CompositeReplace)
64     , m_value(value)
65 {
66     ASSERT(!isNull(m_offset));
67 }
68
69 PassRefPtrWillBeRawPtr<Interpolation> StringKeyframe::PropertySpecificKeyframe::createInterpolation(CSSPropertyID property, Keyframe::PropertySpecificKeyframe* end, Element* element) const
70 {
71     CSSValue* fromCSSValue = m_value.get();
72     CSSValue* toCSSValue = toStringPropertySpecificKeyframe(end)->value();
73     ValueRange range = ValueRangeAll;
74
75     if (!CSSPropertyMetadata::isAnimatableProperty(property))
76         return DefaultStyleInterpolation::create(fromCSSValue, toCSSValue, property);
77
78     switch (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;
99         // Fall through
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:
109     case CSSPropertyTop:
110     case CSSPropertyVerticalAlign:
111     case CSSPropertyWordSpacing:
112         if (LengthStyleInterpolation::canCreateFrom(*fromCSSValue) && LengthStyleInterpolation::canCreateFrom(*toCSSValue))
113             return LengthStyleInterpolation::create(fromCSSValue, toCSSValue, property, range);
114         break;
115     default:
116         break;
117     }
118
119     if (DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(*fromCSSValue) || DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(*toCSSValue))
120         return DeferredLegacyStyleInterpolation::create(fromCSSValue, toCSSValue, property);
121
122     // FIXME: Remove the use of AnimatableValues, RenderStyles and Elements here.
123     // FIXME: Remove this cache
124     ASSERT(element);
125     if (!m_animatableValueCache)
126         m_animatableValueCache = StyleResolver::createAnimatableValueSnapshot(*element, property, *fromCSSValue);
127
128     RefPtrWillBeRawPtr<AnimatableValue> to = StyleResolver::createAnimatableValueSnapshot(*element, property, *toCSSValue);
129     toStringPropertySpecificKeyframe(end)->m_animatableValueCache = to;
130
131     return LegacyStyleInterpolation::create(m_animatableValueCache.get(), to.release(), property);
132 }
133
134 PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::PropertySpecificKeyframe::neutralKeyframe(double offset, PassRefPtr<TimingFunction> easing) const
135 {
136     return adoptPtrWillBeNoop(new PropertySpecificKeyframe(offset, easing, 0, AnimationEffect::CompositeAdd));
137 }
138
139 PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::PropertySpecificKeyframe::cloneWithOffset(double offset) const
140 {
141     Keyframe::PropertySpecificKeyframe* theClone = new PropertySpecificKeyframe(offset, m_easing, m_value.get());
142     toStringPropertySpecificKeyframe(theClone)->m_animatableValueCache = m_animatableValueCache;
143     return adoptPtrWillBeNoop(theClone);
144 }
145
146 void StringKeyframe::PropertySpecificKeyframe::trace(Visitor* visitor)
147 {
148     visitor->trace(m_value);
149     visitor->trace(m_animatableValueCache);
150     Keyframe::PropertySpecificKeyframe::trace(visitor);
151 }
152
153 }