OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "core/animation/StringKeyframe.h" | 6 #include "core/animation/StringKeyframe.h" |
7 | 7 |
8 #include "core/animation/ColorStyleInterpolation.h" | 8 #include "core/animation/InterpolationFactory.h" |
9 #include "core/animation/ConstantStyleInterpolation.h" | 9 #include "core/animation/StyleInterpolation.h" |
10 #include "core/animation/DeferredLegacyStyleInterpolation.h" | |
11 #include "core/animation/DoubleStyleInterpolation.h" | |
12 #include "core/animation/ImageStyleInterpolation.h" | |
13 #include "core/animation/LegacyStyleInterpolation.h" | |
14 #include "core/animation/LengthBoxStyleInterpolation.h" | |
15 #include "core/animation/LengthPairStyleInterpolation.h" | |
16 #include "core/animation/LengthStyleInterpolation.h" | |
17 #include "core/animation/ListStyleInterpolation.h" | |
18 #include "core/animation/SVGLengthStyleInterpolation.h" | |
19 #include "core/animation/ShadowStyleInterpolation.h" | |
20 #include "core/animation/VisibilityStyleInterpolation.h" | |
21 #include "core/animation/css/CSSAnimations.h" | 10 #include "core/animation/css/CSSAnimations.h" |
22 #include "core/css/CSSPropertyMetadata.h" | 11 #include "core/css/CSSPropertyMetadata.h" |
23 #include "core/css/resolver/StyleResolver.h" | 12 #include "core/css/resolver/StyleResolver.h" |
24 #include "core/layout/style/LayoutStyle.h" | 13 #include "core/layout/style/LayoutStyle.h" |
25 | 14 |
26 namespace blink { | 15 namespace blink { |
27 | 16 |
28 StringKeyframe::StringKeyframe(const StringKeyframe& copyFrom) | 17 StringKeyframe::StringKeyframe(const StringKeyframe& copyFrom) |
29 : Keyframe(copyFrom.m_offset, copyFrom.m_composite, copyFrom.m_easing) | 18 : Keyframe(copyFrom.m_offset, copyFrom.m_composite, copyFrom.m_easing) |
30 , m_propertySet(copyFrom.m_propertySet->mutableCopy()) | 19 , m_propertySet(copyFrom.m_propertySet->mutableCopy()) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 , m_value(value) | 57 , m_value(value) |
69 { } | 58 { } |
70 | 59 |
71 StringKeyframe::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset
, PassRefPtr<TimingFunction> easing, CSSValue* value) | 60 StringKeyframe::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset
, PassRefPtr<TimingFunction> easing, CSSValue* value) |
72 : Keyframe::PropertySpecificKeyframe(offset, easing, AnimationEffect::Compos
iteReplace) | 61 : Keyframe::PropertySpecificKeyframe(offset, easing, AnimationEffect::Compos
iteReplace) |
73 , m_value(value) | 62 , m_value(value) |
74 { | 63 { |
75 ASSERT(!isNull(m_offset)); | 64 ASSERT(!isNull(m_offset)); |
76 } | 65 } |
77 | 66 |
78 namespace { | |
79 InterpolationRange setRange(CSSPropertyID id) | |
80 { | |
81 switch (id) { | |
82 case CSSPropertyOrphans: | |
83 case CSSPropertyWebkitColumnCount: | |
84 case CSSPropertyWidows: | |
85 return RangeRoundGreaterThanOrEqualToOne; | |
86 case CSSPropertyWebkitColumnRuleWidth: | |
87 case CSSPropertyZIndex: | |
88 return RangeRound; | |
89 case CSSPropertyFloodOpacity: | |
90 case CSSPropertyStopOpacity: | |
91 case CSSPropertyStrokeOpacity: | |
92 case CSSPropertyShapeImageThreshold: | |
93 return RangeZeroToOne; | |
94 case CSSPropertyFillOpacity: | |
95 case CSSPropertyOpacity: | |
96 return RangeOpacityFIXME; | |
97 case CSSPropertyStrokeMiterlimit: | |
98 return RangeGreaterThanOrEqualToOne; | |
99 case CSSPropertyZoom: | |
100 return RangePositive; | |
101 default: | |
102 ASSERT_NOT_REACHED(); | |
103 return RangeAll; | |
104 } | |
105 } | |
106 | |
107 } // namespace | |
108 | |
109 // FIXME: Refactor this into a generic piece that lives in InterpolationEffect,
and a template parameter specific converter. | 67 // FIXME: Refactor this into a generic piece that lives in InterpolationEffect,
and a template parameter specific converter. |
110 PassRefPtrWillBeRawPtr<Interpolation> StringKeyframe::PropertySpecificKeyframe::
maybeCreateInterpolation(CSSPropertyID property, Keyframe::PropertySpecificKeyfr
ame& end, Element* element) const | 68 PassRefPtrWillBeRawPtr<Interpolation> StringKeyframe::PropertySpecificKeyframe::
maybeCreateInterpolation(CSSPropertyID property, Keyframe::PropertySpecificKeyfr
ame& end, Element* element) const |
111 { | 69 { |
112 CSSValue* fromCSSValue = m_value.get(); | 70 CSSValue* fromCSSValue = m_value.get(); |
113 CSSValue* toCSSValue = toStringPropertySpecificKeyframe(end).value(); | 71 CSSValue* toCSSValue = toStringPropertySpecificKeyframe(end).value(); |
114 InterpolationRange range = RangeAll; | |
115 bool fallBackToLegacy = false; | |
116 | 72 |
117 // FIXME: Remove this flag once we can rely on legacy's behaviour being corr
ect. | 73 return InterpolationFactory::maybeCreateInterpolation(property, fromCSSValue
, toCSSValue, m_composite, toStringPropertySpecificKeyframe(end).m_composite, &m
_animatableValueCache, &toStringPropertySpecificKeyframe(end).m_animatableValueC
ache, element); |
118 bool forceDefaultInterpolation = false; | |
119 | |
120 if (!CSSPropertyMetadata::isAnimatableProperty(property)) { | |
121 if (fromCSSValue == toCSSValue) | |
122 return ConstantStyleInterpolation::create(fromCSSValue, property); | |
123 | |
124 return nullptr; | |
125 } | |
126 | |
127 // FIXME: Generate this giant switch statement. | |
128 switch (property) { | |
129 case CSSPropertyLineHeight: | |
130 if (LengthStyleInterpolation::canCreateFrom(*fromCSSValue) && LengthStyl
eInterpolation::canCreateFrom(*toCSSValue)) | |
131 return LengthStyleInterpolation::create(*fromCSSValue, *toCSSValue,
property, RangeNonNegative); | |
132 | |
133 if (DoubleStyleInterpolation::canCreateFrom(*fromCSSValue) && DoubleStyl
eInterpolation::canCreateFrom(*toCSSValue)) | |
134 return DoubleStyleInterpolation::create(*fromCSSValue, *toCSSValue,
property, CSSPrimitiveValue::CSS_NUMBER, RangeNonNegative); | |
135 | |
136 break; | |
137 case CSSPropertyBorderBottomWidth: | |
138 case CSSPropertyBorderLeftWidth: | |
139 case CSSPropertyBorderRightWidth: | |
140 case CSSPropertyBorderTopWidth: | |
141 case CSSPropertyFlexBasis: | |
142 case CSSPropertyFontSize: | |
143 case CSSPropertyHeight: | |
144 case CSSPropertyMaxHeight: | |
145 case CSSPropertyMaxWidth: | |
146 case CSSPropertyMinHeight: | |
147 case CSSPropertyMinWidth: | |
148 case CSSPropertyMotionPosition: | |
149 case CSSPropertyOutlineWidth: | |
150 case CSSPropertyPaddingBottom: | |
151 case CSSPropertyPaddingLeft: | |
152 case CSSPropertyPaddingRight: | |
153 case CSSPropertyPaddingTop: | |
154 case CSSPropertyPerspective: | |
155 case CSSPropertyShapeMargin: | |
156 case CSSPropertyWebkitBorderHorizontalSpacing: | |
157 case CSSPropertyWebkitBorderVerticalSpacing: | |
158 case CSSPropertyWebkitColumnGap: | |
159 case CSSPropertyWebkitColumnWidth: | |
160 case CSSPropertyWidth: | |
161 range = RangeNonNegative; | |
162 // Fall through | |
163 case CSSPropertyBottom: | |
164 case CSSPropertyLeft: | |
165 case CSSPropertyLetterSpacing: | |
166 case CSSPropertyMarginBottom: | |
167 case CSSPropertyMarginLeft: | |
168 case CSSPropertyMarginRight: | |
169 case CSSPropertyMarginTop: | |
170 case CSSPropertyOutlineOffset: | |
171 case CSSPropertyRight: | |
172 case CSSPropertyTop: | |
173 case CSSPropertyVerticalAlign: | |
174 case CSSPropertyWordSpacing: | |
175 case CSSPropertyWebkitColumnRuleWidth: | |
176 if (LengthStyleInterpolation::canCreateFrom(*fromCSSValue) && LengthStyl
eInterpolation::canCreateFrom(*toCSSValue)) | |
177 return LengthStyleInterpolation::create(*fromCSSValue, *toCSSValue,
property, range); | |
178 | |
179 // FIXME: Handle keywords e.g. 'none'. | |
180 if (property == CSSPropertyPerspective) | |
181 fallBackToLegacy = true; | |
182 // FIXME: Handle keywords e.g. 'smaller', 'larger'. | |
183 if (property == CSSPropertyFontSize) | |
184 fallBackToLegacy = true; | |
185 | |
186 // FIXME: Handle keywords e.g. 'normal' | |
187 if (property == CSSPropertyLetterSpacing) | |
188 fallBackToLegacy = true; | |
189 | |
190 // FIXME: Handle keywords e.g. 'thick' | |
191 if (property == CSSPropertyOutlineWidth || CSSPropertyWebkitColumnRuleWi
dth) | |
192 fallBackToLegacy = true; | |
193 break; | |
194 case CSSPropertyOrphans: | |
195 case CSSPropertyWidows: | |
196 case CSSPropertyZIndex: | |
197 case CSSPropertyWebkitColumnCount: | |
198 case CSSPropertyShapeImageThreshold: | |
199 case CSSPropertyFillOpacity: | |
200 case CSSPropertyFloodOpacity: | |
201 case CSSPropertyOpacity: | |
202 case CSSPropertyStopOpacity: | |
203 case CSSPropertyStrokeOpacity: | |
204 case CSSPropertyStrokeMiterlimit: | |
205 case CSSPropertyZoom: | |
206 if (DoubleStyleInterpolation::canCreateFrom(*fromCSSValue) && DoubleStyl
eInterpolation::canCreateFrom(*toCSSValue)) { | |
207 if (property == CSSPropertyOpacity) | |
208 StringKeyframe::PropertySpecificKeyframe::ensureAnimatableValueC
aches(property, end, element, *fromCSSValue, *toCSSValue); | |
209 return DoubleStyleInterpolation::create(*fromCSSValue, *toCSSValue,
property, toCSSPrimitiveValue(fromCSSValue)->primitiveType(), setRange(property)
); | |
210 } | |
211 break; | |
212 | |
213 case CSSPropertyMotionRotation: { | |
214 RefPtrWillBeRawPtr<Interpolation> interpolation = DoubleStyleInterpolati
on::maybeCreateFromMotionRotation(*fromCSSValue, *toCSSValue, property); | |
215 if (interpolation) | |
216 return interpolation.release(); | |
217 break; | |
218 } | |
219 case CSSPropertyVisibility: | |
220 if (VisibilityStyleInterpolation::canCreateFrom(*fromCSSValue) && Visibi
lityStyleInterpolation::canCreateFrom(*toCSSValue) && (VisibilityStyleInterpolat
ion::isVisible(*fromCSSValue) || VisibilityStyleInterpolation::isVisible(*toCSSV
alue))) | |
221 return VisibilityStyleInterpolation::create(*fromCSSValue, *toCSSVal
ue, property); | |
222 | |
223 break; | |
224 | |
225 case CSSPropertyBackgroundColor: | |
226 case CSSPropertyBorderBottomColor: | |
227 case CSSPropertyBorderLeftColor: | |
228 case CSSPropertyBorderRightColor: | |
229 case CSSPropertyBorderTopColor: | |
230 case CSSPropertyColor: | |
231 case CSSPropertyFloodColor: | |
232 case CSSPropertyLightingColor: | |
233 case CSSPropertyOutlineColor: | |
234 case CSSPropertyStopColor: | |
235 case CSSPropertyTextDecorationColor: | |
236 case CSSPropertyWebkitColumnRuleColor: | |
237 case CSSPropertyWebkitTextStrokeColor: | |
238 { | |
239 RefPtrWillBeRawPtr<Interpolation> interpolation = ColorStyleInterpol
ation::maybeCreateFromColor(*fromCSSValue, *toCSSValue, property); | |
240 if (interpolation) | |
241 return interpolation.release(); | |
242 | |
243 // Current color should use LegacyStyleInterpolation | |
244 if (ColorStyleInterpolation::shouldUseLegacyStyleInterpolation(*from
CSSValue, *toCSSValue)) | |
245 fallBackToLegacy = true; | |
246 | |
247 break; | |
248 } | |
249 | |
250 case CSSPropertyBorderImageSource: | |
251 case CSSPropertyListStyleImage: | |
252 case CSSPropertyWebkitMaskBoxImageSource: | |
253 if (ImageStyleInterpolation::canCreateFrom(*fromCSSValue) && ImageStyleI
nterpolation::canCreateFrom(*toCSSValue)) | |
254 return ImageStyleInterpolation::create(*fromCSSValue, *toCSSValue, p
roperty); | |
255 | |
256 // FIXME: Handle gradients. | |
257 fallBackToLegacy = true; | |
258 break; | |
259 case CSSPropertyBorderBottomLeftRadius: | |
260 case CSSPropertyBorderBottomRightRadius: | |
261 case CSSPropertyBorderTopLeftRadius: | |
262 case CSSPropertyBorderTopRightRadius: | |
263 range = RangeNonNegative; | |
264 // Fall through | |
265 case CSSPropertyObjectPosition: | |
266 if (LengthPairStyleInterpolation::canCreateFrom(*fromCSSValue) && Length
PairStyleInterpolation::canCreateFrom(*toCSSValue)) | |
267 return LengthPairStyleInterpolation::create(*fromCSSValue, *toCSSVal
ue, property, range); | |
268 break; | |
269 | |
270 case CSSPropertyPerspectiveOrigin: | |
271 case CSSPropertyTransformOrigin: { | |
272 RefPtrWillBeRawPtr<Interpolation> interpolation = ListStyleInterpolation
<LengthStyleInterpolation>::maybeCreateFromList(*fromCSSValue, *toCSSValue, prop
erty, range); | |
273 if (interpolation) | |
274 return interpolation.release(); | |
275 break; | |
276 } | |
277 | |
278 case CSSPropertyBoxShadow: | |
279 case CSSPropertyTextShadow: | |
280 case CSSPropertyWebkitBoxShadow: { | |
281 RefPtrWillBeRawPtr<Interpolation> interpolation = ListStyleInterpolation
<ShadowStyleInterpolation>::maybeCreateFromList(*fromCSSValue, *toCSSValue, prop
erty); | |
282 if (interpolation) | |
283 return interpolation.release(); | |
284 | |
285 // FIXME: AnimatableShadow incorrectly animates between inset and non-in
set values so it will never indicate it needs default interpolation | |
286 if (ShadowStyleInterpolation::usesDefaultStyleInterpolation(*fromCSSValu
e, *toCSSValue)) { | |
287 forceDefaultInterpolation = true; | |
288 break; | |
289 } | |
290 | |
291 // FIXME: Handle interpolation from/to none, unspecified color values | |
292 fallBackToLegacy = true; | |
293 | |
294 break; | |
295 | |
296 } | |
297 | |
298 case CSSPropertyClip: | |
299 case CSSPropertyBorderImageSlice: | |
300 case CSSPropertyWebkitMaskBoxImageSlice: { | |
301 RefPtrWillBeRawPtr<Interpolation> interpolation = LengthBoxStyleInterpol
ation::maybeCreateFrom(fromCSSValue, toCSSValue, property); | |
302 if (interpolation) | |
303 return interpolation.release(); | |
304 break; | |
305 } | |
306 | |
307 case CSSPropertyStrokeWidth: | |
308 range = RangeNonNegative; | |
309 // Fall through | |
310 case CSSPropertyBaselineShift: | |
311 case CSSPropertyStrokeDashoffset: { | |
312 RefPtrWillBeRawPtr<Interpolation> interpolation = SVGLengthStyleInterpol
ation::maybeCreate(*fromCSSValue, *toCSSValue, property, range); | |
313 if (interpolation) | |
314 return interpolation.release(); | |
315 | |
316 break; | |
317 } | |
318 | |
319 default: | |
320 // Fall back to LegacyStyleInterpolation. | |
321 fallBackToLegacy = true; | |
322 break; | |
323 } | |
324 | |
325 if (fromCSSValue == toCSSValue) | |
326 return ConstantStyleInterpolation::create(fromCSSValue, property); | |
327 | |
328 if (forceDefaultInterpolation) | |
329 return nullptr; | |
330 | |
331 if (fromCSSValue->isUnsetValue() || fromCSSValue->isInheritedValue() || from
CSSValue->isInitialValue() | |
332 || toCSSValue->isUnsetValue() || toCSSValue->isInheritedValue() || toCSS
Value->isInitialValue()) | |
333 fallBackToLegacy = true; | |
334 | |
335 if (fallBackToLegacy) { | |
336 if (DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(
*fromCSSValue) || DeferredLegacyStyleInterpolation::interpolationRequiresStyleRe
solve(*toCSSValue)) { | |
337 // FIXME: Handle these cases outside of DeferredLegacyStyleInterpola
tion. | |
338 return DeferredLegacyStyleInterpolation::create(fromCSSValue, toCSSV
alue, property); | |
339 } | |
340 | |
341 // FIXME: Remove the use of AnimatableValues, RenderStyles and Elements
here. | |
342 // FIXME: Remove this cache | |
343 ASSERT(element); | |
344 if (!m_animatableValueCache) | |
345 m_animatableValueCache = StyleResolver::createAnimatableValueSnapsho
t(*element, property, *fromCSSValue); | |
346 | |
347 RefPtrWillBeRawPtr<AnimatableValue> to = StyleResolver::createAnimatable
ValueSnapshot(*element, property, *toCSSValue); | |
348 toStringPropertySpecificKeyframe(end).m_animatableValueCache = to; | |
349 | |
350 return LegacyStyleInterpolation::create(m_animatableValueCache.get(), to
.release(), property); | |
351 } | |
352 | |
353 ASSERT(AnimatableValue::usesDefaultInterpolation( | |
354 StyleResolver::createAnimatableValueSnapshot(*element, property, *fromCS
SValue).get(), | |
355 StyleResolver::createAnimatableValueSnapshot(*element, property, *toCSSV
alue).get())); | |
356 | |
357 return nullptr; | |
358 | |
359 } | |
360 // FIXME: Remove the use of AnimatableValues, RenderStyles and Elements here. | |
361 // FIXME: Remove this cache | |
362 void StringKeyframe::PropertySpecificKeyframe::ensureAnimatableValueCaches(CSSPr
opertyID property, Keyframe::PropertySpecificKeyframe& end, Element* element, CS
SValue& fromCSSValue, CSSValue& toCSSValue) const | |
363 { | |
364 ASSERT(element); | |
365 if (!m_animatableValueCache) | |
366 m_animatableValueCache = StyleResolver::createAnimatableValueSnapshot(*e
lement, property, fromCSSValue); | |
367 RefPtrWillBeRawPtr<AnimatableValue> to = StyleResolver::createAnimatableValu
eSnapshot(*element, property, toCSSValue); | |
368 toStringPropertySpecificKeyframe(end).m_animatableValueCache = to; | |
369 } | 74 } |
370 | 75 |
371 PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::Prope
rtySpecificKeyframe::neutralKeyframe(double offset, PassRefPtr<TimingFunction> e
asing) const | 76 PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::Prope
rtySpecificKeyframe::neutralKeyframe(double offset, PassRefPtr<TimingFunction> e
asing) const |
372 { | 77 { |
373 return adoptPtrWillBeNoop(new PropertySpecificKeyframe(offset, easing, 0, An
imationEffect::CompositeAdd)); | 78 return adoptPtrWillBeNoop(new PropertySpecificKeyframe(offset, easing, 0, An
imationEffect::CompositeAdd)); |
374 } | 79 } |
375 | 80 |
376 PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::Prope
rtySpecificKeyframe::cloneWithOffset(double offset) const | 81 PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::Prope
rtySpecificKeyframe::cloneWithOffset(double offset) const |
377 { | 82 { |
378 Keyframe::PropertySpecificKeyframe* theClone = new PropertySpecificKeyframe(
offset, m_easing, m_value.get()); | 83 Keyframe::PropertySpecificKeyframe* theClone = new PropertySpecificKeyframe(
offset, m_easing, m_value.get()); |
379 toStringPropertySpecificKeyframe(theClone)->m_animatableValueCache = m_anima
tableValueCache; | 84 toStringPropertySpecificKeyframe(theClone)->m_animatableValueCache = m_anima
tableValueCache; |
380 return adoptPtrWillBeNoop(theClone); | 85 return adoptPtrWillBeNoop(theClone); |
381 } | 86 } |
382 | 87 |
383 void StringKeyframe::PropertySpecificKeyframe::trace(Visitor* visitor) | 88 void StringKeyframe::PropertySpecificKeyframe::trace(Visitor* visitor) |
384 { | 89 { |
385 visitor->trace(m_value); | 90 visitor->trace(m_value); |
386 visitor->trace(m_animatableValueCache); | 91 visitor->trace(m_animatableValueCache); |
387 Keyframe::PropertySpecificKeyframe::trace(visitor); | 92 Keyframe::PropertySpecificKeyframe::trace(visitor); |
388 } | 93 } |
389 | 94 |
390 } | 95 } |
OLD | NEW |