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/DeferredLegacyStyleInterpolation.h"
8 #include "core/animation/ElementAnimations.h"
9 #include "core/animation/css/CSSAnimatableValueFactory.h"
10 #include "core/css/CSSBasicShapes.h"
11 #include "core/css/CSSImageValue.h"
12 #include "core/css/CSSPrimitiveValue.h"
13 #include "core/css/CSSQuadValue.h"
14 #include "core/css/CSSSVGDocumentValue.h"
15 #include "core/css/CSSShadowValue.h"
16 #include "core/css/CSSValueList.h"
17 #include "core/css/CSSValuePair.h"
18 #include "core/css/resolver/StyleResolver.h"
19 #include "core/css/resolver/StyleResolverState.h"
23 void DeferredLegacyStyleInterpolation::apply(StyleResolverState
& state
) const
25 if (m_outdated
|| !state
.element()->elementAnimations() || !state
.element()->elementAnimations()->isAnimationStyleChange()) {
26 RefPtr
<AnimatableValue
> startAnimatableValue
;
27 RefPtr
<AnimatableValue
> endAnimatableValue
;
29 // Snapshot underlying values for neutral keyframes first because non-neutral keyframes will mutate the StyleResolverState.
31 endAnimatableValue
= StyleResolver::createAnimatableValueSnapshot(state
, m_id
, m_endCSSValue
.get());
32 startAnimatableValue
= StyleResolver::createAnimatableValueSnapshot(state
, m_id
, m_startCSSValue
.get());
34 startAnimatableValue
= StyleResolver::createAnimatableValueSnapshot(state
, m_id
, m_startCSSValue
.get());
35 endAnimatableValue
= StyleResolver::createAnimatableValueSnapshot(state
, m_id
, m_endCSSValue
.get());
38 m_innerInterpolation
= LegacyStyleInterpolation::create(startAnimatableValue
, endAnimatableValue
, m_id
);
42 m_innerInterpolation
->interpolate(m_cachedIteration
, m_cachedFraction
);
43 m_innerInterpolation
->apply(state
);
46 bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSValue
& value
)
48 // FIXME: should not require resolving styles for inherit/initial/unset.
49 if (value
.isCSSWideKeyword())
51 if (value
.isPrimitiveValue())
52 return interpolationRequiresStyleResolve(toCSSPrimitiveValue(value
));
53 if (value
.isQuadValue())
54 return interpolationRequiresStyleResolve(toCSSQuadValue(value
));
55 if (value
.isValueList())
56 return interpolationRequiresStyleResolve(toCSSValueList(value
));
57 if (value
.isValuePair())
58 return interpolationRequiresStyleResolve(toCSSValuePair(value
));
59 if (value
.isImageValue())
60 return interpolationRequiresStyleResolve(toCSSImageValue(value
));
61 if (value
.isShadowValue())
62 return interpolationRequiresStyleResolve(toCSSShadowValue(value
));
63 if (value
.isSVGDocumentValue())
64 return interpolationRequiresStyleResolve(toCSSSVGDocumentValue(value
));
65 // FIXME: consider other custom types.
69 bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSPrimitiveValue
& primitiveValue
)
71 // FIXME: consider other types.
72 if (primitiveValue
.isNumber() || primitiveValue
.isPercentage() || primitiveValue
.isAngle() || primitiveValue
.isRGBColor() || primitiveValue
.isURI())
75 if (primitiveValue
.isLength())
76 return primitiveValue
.isFontRelativeLength() || primitiveValue
.isViewportPercentageLength();
78 if (primitiveValue
.isCalculated()) {
79 CSSLengthArray
lengthArray(CSSPrimitiveValue::LengthUnitTypeCount
);
80 primitiveValue
.accumulateLengthArray(lengthArray
);
81 return lengthArray
[CSSPrimitiveValue::UnitTypeFontSize
] != 0
82 || lengthArray
[CSSPrimitiveValue::UnitTypeFontXSize
] != 0
83 || lengthArray
[CSSPrimitiveValue::UnitTypeRootFontSize
] != 0
84 || lengthArray
[CSSPrimitiveValue::UnitTypeZeroCharacterWidth
] != 0
85 || lengthArray
[CSSPrimitiveValue::UnitTypeViewportWidth
] != 0
86 || lengthArray
[CSSPrimitiveValue::UnitTypeViewportHeight
] != 0
87 || lengthArray
[CSSPrimitiveValue::UnitTypeViewportMin
] != 0
88 || lengthArray
[CSSPrimitiveValue::UnitTypeViewportMax
] != 0;
91 if (primitiveValue
.isShape())
92 return interpolationRequiresStyleResolve(*primitiveValue
.getShapeValue());
94 CSSValueID id
= primitiveValue
.getValueID();
95 bool isColor
= ((id
>= CSSValueAqua
&& id
<= CSSValueTransparent
)
96 || (id
>= CSSValueAliceblue
&& id
<= CSSValueYellowgreen
)
97 || id
== CSSValueGrey
);
98 return (id
!= CSSValueNone
) && !isColor
;
101 bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSImageValue
& imageValue
)
106 bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSShadowValue
& shadowValue
)
108 return (shadowValue
.x
&& interpolationRequiresStyleResolve(*shadowValue
.x
))
109 || (shadowValue
.y
&& interpolationRequiresStyleResolve(*shadowValue
.y
))
110 || (shadowValue
.blur
&& interpolationRequiresStyleResolve(*shadowValue
.blur
))
111 || (shadowValue
.spread
&& interpolationRequiresStyleResolve(*shadowValue
.spread
))
112 || (shadowValue
.style
&& interpolationRequiresStyleResolve(*shadowValue
.style
))
113 || (shadowValue
.color
&& interpolationRequiresStyleResolve(*shadowValue
.color
));
116 bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSSVGDocumentValue
& documentValue
)
121 bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSValueList
& valueList
)
123 size_t length
= valueList
.length();
124 for (size_t index
= 0; index
< length
; ++index
) {
125 if (interpolationRequiresStyleResolve(*valueList
.item(index
)))
131 bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSValuePair
& pair
)
133 return interpolationRequiresStyleResolve(pair
.first())
134 || interpolationRequiresStyleResolve(pair
.second());
137 bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSBasicShape
& shape
)
139 // FIXME: Should determine the specific shape, and inspect the members.
143 bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSQuadValue
& quad
)
145 return interpolationRequiresStyleResolve(*quad
.top())
146 || interpolationRequiresStyleResolve(*quad
.right())
147 || interpolationRequiresStyleResolve(*quad
.bottom())
148 || interpolationRequiresStyleResolve(*quad
.left());