PassRefPtr<Interpolation> StringKeyframe::CSSPropertySpecificKeyframe::createLegacyStyleInterpolation(CSSPropertyID property, Keyframe::PropertySpecificKeyframe& end, Element* element, const ComputedStyle* baseStyle) const { CSSValue& fromCSSValue = *m_value.get(); CSSValue& toCSSValue = *toCSSPropertySpecificKeyframe(end).value(); if (DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(fromCSSValue) || DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(toCSSValue)) { // FIXME: Handle these cases outside of DeferredLegacyStyleInterpolation. return DeferredLegacyStyleInterpolation::create(&fromCSSValue, &toCSSValue, property); } // FIXME: Remove the use of AnimatableValues and Elements here. ASSERT(element); populateAnimatableValue(property, *element, baseStyle, false); end.populateAnimatableValue(property, *element, baseStyle, false); return LegacyStyleInterpolation::create(getAnimatableValue(), end.getAnimatableValue(), property); }
PassRefPtrWillBeRawPtr<Interpolation> StringKeyframe::CSSPropertySpecificKeyframe::maybeCreateInterpolation(PropertyHandle propertyHandle, Keyframe::PropertySpecificKeyframe& end, Element* element, const ComputedStyle* baseStyle) const { CSSPropertyID property = propertyHandle.cssProperty(); const Vector<const InterpolationType*>* applicableTypes = applicableTypesForProperty(property); if (applicableTypes) return InvalidatableStyleInterpolation::create(*applicableTypes, *this, toCSSPropertySpecificKeyframe(end)); // TODO(alancutter): Remove the remainder of this function. // FIXME: Refactor this into a generic piece that lives in InterpolationEffect, and a template parameter specific converter. CSSValue* fromCSSValue = m_value.get(); CSSValue* toCSSValue = toCSSPropertySpecificKeyframe(end).value(); InterpolationRange range = RangeAll; bool fallBackToLegacy = false; // FIXME: Remove this flag once we can rely on legacy's behaviour being correct. bool forceDefaultInterpolation = false; // FIXME: Remove this check once neutral keyframes are implemented in StringKeyframes. if (!fromCSSValue || !toCSSValue) return DeferredLegacyStyleInterpolation::create(fromCSSValue, toCSSValue, property); ASSERT(fromCSSValue && toCSSValue); if (!CSSPropertyMetadata::isInterpolableProperty(property)) { if (fromCSSValue == toCSSValue) return ConstantStyleInterpolation::create(fromCSSValue, property); return nullptr; } switch (property) { case CSSPropertyLineHeight: if (LengthStyleInterpolation::canCreateFrom(*fromCSSValue) && LengthStyleInterpolation::canCreateFrom(*toCSSValue)) return LengthStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, RangeNonNegative); if (DoubleStyleInterpolation::canCreateFrom(*fromCSSValue) && DoubleStyleInterpolation::canCreateFrom(*toCSSValue)) return DoubleStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, CSSPrimitiveValue::CSS_NUMBER, RangeNonNegative); break; case CSSPropertyBorderBottomWidth: case CSSPropertyBorderLeftWidth: case CSSPropertyBorderRightWidth: case CSSPropertyBorderTopWidth: case CSSPropertyFlexBasis: case CSSPropertyFontSize: case CSSPropertyHeight: case CSSPropertyMaxHeight: case CSSPropertyMaxWidth: case CSSPropertyMinHeight: case CSSPropertyMinWidth: case CSSPropertyOutlineWidth: case CSSPropertyPaddingBottom: case CSSPropertyPaddingLeft: case CSSPropertyPaddingRight: case CSSPropertyPaddingTop: case CSSPropertyPerspective: case CSSPropertyR: case CSSPropertyRx: case CSSPropertyRy: case CSSPropertyShapeMargin: case CSSPropertyStrokeWidth: case CSSPropertyWebkitBorderHorizontalSpacing: case CSSPropertyWebkitBorderVerticalSpacing: case CSSPropertyWebkitColumnGap: case CSSPropertyWebkitColumnWidth: case CSSPropertyWidth: range = RangeNonNegative; // Fall through case CSSPropertyBaselineShift: case CSSPropertyBottom: case CSSPropertyCx: case CSSPropertyCy: case CSSPropertyLeft: case CSSPropertyLetterSpacing: case CSSPropertyMarginBottom: case CSSPropertyMarginLeft: case CSSPropertyMarginRight: case CSSPropertyMarginTop: case CSSPropertyMotionOffset: case CSSPropertyOutlineOffset: case CSSPropertyRight: case CSSPropertyStrokeDashoffset: case CSSPropertyTop: case CSSPropertyVerticalAlign: case CSSPropertyWordSpacing: case CSSPropertyWebkitColumnRuleWidth: case CSSPropertyWebkitPerspectiveOriginX: case CSSPropertyWebkitPerspectiveOriginY: case CSSPropertyWebkitTransformOriginX: case CSSPropertyWebkitTransformOriginY: case CSSPropertyWebkitTransformOriginZ: case CSSPropertyX: case CSSPropertyY: if (LengthStyleInterpolation::canCreateFrom(*fromCSSValue, property) && LengthStyleInterpolation::canCreateFrom(*toCSSValue, property)) return LengthStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, range); // FIXME: Handle keywords e.g. 'smaller', 'larger'. if (property == CSSPropertyFontSize) fallBackToLegacy = true; // FIXME: Handle keywords e.g. 'baseline', 'sub'. if (property == CSSPropertyBaselineShift) fallBackToLegacy = true; break; case CSSPropertyOrphans: case CSSPropertyWidows: case CSSPropertyZIndex: case CSSPropertyWebkitColumnCount: case CSSPropertyShapeImageThreshold: case CSSPropertyFillOpacity: case CSSPropertyFloodOpacity: case CSSPropertyFontSizeAdjust: case CSSPropertyOpacity: case CSSPropertyStopOpacity: case CSSPropertyStrokeOpacity: case CSSPropertyStrokeMiterlimit: if (DoubleStyleInterpolation::canCreateFrom(*fromCSSValue) && DoubleStyleInterpolation::canCreateFrom(*toCSSValue)) return DoubleStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, toCSSPrimitiveValue(fromCSSValue)->primitiveType(), setRange(property)); break; case CSSPropertyMotionRotation: { RefPtrWillBeRawPtr<Interpolation> interpolation = DoubleStyleInterpolation::maybeCreateFromMotionRotation(*fromCSSValue, *toCSSValue, property); if (interpolation) return interpolation.release(); break; } case CSSPropertyVisibility: if (VisibilityStyleInterpolation::canCreateFrom(*fromCSSValue) && VisibilityStyleInterpolation::canCreateFrom(*toCSSValue) && (VisibilityStyleInterpolation::isVisible(*fromCSSValue) || VisibilityStyleInterpolation::isVisible(*toCSSValue))) return VisibilityStyleInterpolation::create(*fromCSSValue, *toCSSValue, property); break; case CSSPropertyBackgroundColor: case CSSPropertyBorderBottomColor: case CSSPropertyBorderLeftColor: case CSSPropertyBorderRightColor: case CSSPropertyBorderTopColor: case CSSPropertyColor: case CSSPropertyFill: case CSSPropertyFloodColor: case CSSPropertyLightingColor: case CSSPropertyOutlineColor: case CSSPropertyStopColor: case CSSPropertyStroke: case CSSPropertyTextDecorationColor: case CSSPropertyWebkitColumnRuleColor: case CSSPropertyWebkitTextStrokeColor: { RefPtrWillBeRawPtr<Interpolation> interpolation = ColorStyleInterpolation::maybeCreateFromColor(*fromCSSValue, *toCSSValue, property); if (interpolation) return interpolation.release(); // Current color should use LegacyStyleInterpolation if (ColorStyleInterpolation::shouldUseLegacyStyleInterpolation(*fromCSSValue, *toCSSValue)) fallBackToLegacy = true; break; } case CSSPropertyBorderImageSource: case CSSPropertyListStyleImage: case CSSPropertyWebkitMaskBoxImageSource: if (fromCSSValue == toCSSValue) return ConstantStyleInterpolation::create(fromCSSValue, property); if (ImageStyleInterpolation::canCreateFrom(*fromCSSValue) && ImageStyleInterpolation::canCreateFrom(*toCSSValue)) return ImageStyleInterpolation::create(*fromCSSValue, *toCSSValue, property); forceDefaultInterpolation = true; break; case CSSPropertyBorderBottomLeftRadius: case CSSPropertyBorderBottomRightRadius: case CSSPropertyBorderTopLeftRadius: case CSSPropertyBorderTopRightRadius: range = RangeNonNegative; // Fall through case CSSPropertyObjectPosition: if (LengthPairStyleInterpolation::canCreateFrom(*fromCSSValue) && LengthPairStyleInterpolation::canCreateFrom(*toCSSValue)) return LengthPairStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, range); break; case CSSPropertyPerspectiveOrigin: case CSSPropertyTransformOrigin: { RefPtrWillBeRawPtr<Interpolation> interpolation = ListStyleInterpolation<LengthStyleInterpolation>::maybeCreateFromList(*fromCSSValue, *toCSSValue, property, range); if (interpolation) return interpolation.release(); // FIXME: Handle keywords: top, right, left, center, bottom fallBackToLegacy = true; break; } case CSSPropertyBoxShadow: case CSSPropertyTextShadow: { RefPtrWillBeRawPtr<Interpolation> interpolation = ListStyleInterpolation<ShadowStyleInterpolation>::maybeCreateFromList(*fromCSSValue, *toCSSValue, property); if (interpolation) return interpolation.release(); // FIXME: AnimatableShadow incorrectly animates between inset and non-inset values so it will never indicate it needs default interpolation if (ShadowStyleInterpolation::usesDefaultStyleInterpolation(*fromCSSValue, *toCSSValue)) { forceDefaultInterpolation = true; break; } // FIXME: Handle interpolation from/to none, unspecified color values fallBackToLegacy = true; break; } case CSSPropertyClip: { if (LengthBoxStyleInterpolation::usesDefaultInterpolation(*fromCSSValue, *toCSSValue)) { forceDefaultInterpolation = true; break; } RefPtrWillBeRawPtr<Interpolation> interpolation = LengthBoxStyleInterpolation::maybeCreateFrom(*fromCSSValue, *toCSSValue, property); if (interpolation) return interpolation.release(); break; } case CSSPropertyBorderImageSlice: case CSSPropertyWebkitMaskBoxImageSlice: { RefPtrWillBeRawPtr<Interpolation> interpolation = ImageSliceStyleInterpolation::maybeCreate(*fromCSSValue, *toCSSValue, property); if (interpolation) return interpolation.release(); if (ImageSliceStyleInterpolation::usesDefaultInterpolation(*fromCSSValue, *toCSSValue)) forceDefaultInterpolation = true; break; } case CSSPropertyStrokeDasharray: { RefPtrWillBeRawPtr<Interpolation> interpolation = SVGStrokeDasharrayStyleInterpolation::maybeCreate(*fromCSSValue, *toCSSValue, property); if (interpolation) return interpolation.release(); break; } case CSSPropertyWebkitFilter: { RefPtrWillBeRawPtr<Interpolation> interpolation = FilterStyleInterpolation::maybeCreateList(*fromCSSValue, *toCSSValue, property); if (interpolation) return interpolation.release(); // FIXME: Support drop shadow interpolation. fallBackToLegacy = true; break; } case CSSPropertyTranslate: { RefPtrWillBeRawPtr<Interpolation> interpolation = ListStyleInterpolation<LengthStyleInterpolation>::maybeCreateFromList(*fromCSSValue, *toCSSValue, property, range); if (interpolation) return interpolation.release(); // TODO(soonm): Legacy mode is used when from and to cssvaluelist length does not match. fallBackToLegacy = true; break; } case CSSPropertyScale: { RefPtrWillBeRawPtr<Interpolation> interpolation = ListStyleInterpolation<DoubleStyleInterpolation>::maybeCreateFromList(*fromCSSValue, *toCSSValue, property, range); if (interpolation) return interpolation.release(); // TODO(soonm): Legacy mode is used when from and to cssvaluelist length does not match. fallBackToLegacy = true; break; } default: // Fall back to LegacyStyleInterpolation. fallBackToLegacy = true; break; } if (fromCSSValue == toCSSValue) return ConstantStyleInterpolation::create(fromCSSValue, property); if (forceDefaultInterpolation) return nullptr; if (fromCSSValue->isCSSWideKeyword() || toCSSValue->isCSSWideKeyword()) fallBackToLegacy = true; if (fallBackToLegacy) { if (DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(*fromCSSValue) || DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(*toCSSValue)) { // FIXME: Handle these cases outside of DeferredLegacyStyleInterpolation. return DeferredLegacyStyleInterpolation::create(fromCSSValue, toCSSValue, property); } // FIXME: Remove the use of AnimatableValues and Elements here. ASSERT(element); populateAnimatableValue(property, *element, baseStyle); end.populateAnimatableValue(property, *element, baseStyle); return LegacyStyleInterpolation::create(getAnimatableValue(), end.getAnimatableValue(), property); } ASSERT(AnimatableValue::usesDefaultInterpolation( StyleResolver::createAnimatableValueSnapshot(*element, baseStyle, property, fromCSSValue).get(), StyleResolver::createAnimatableValueSnapshot(*element, baseStyle, property, toCSSValue).get())); return nullptr; }