PassRefPtr<Interpolation> AnimatableValueKeyframe::PropertySpecificKeyframe::createInterpolation( PropertyHandle property, const Keyframe::PropertySpecificKeyframe& end) const { return LegacyStyleInterpolation::create( value(), toAnimatableValuePropertySpecificKeyframe(end).value(), property.cssProperty()); }
PassRefPtr<Interpolation> StringKeyframe::CSSPropertySpecificKeyframe::maybeCreateInterpolation(PropertyHandle propertyHandle, Keyframe::PropertySpecificKeyframe& end, Element* element, const ComputedStyle* baseStyle) const { const InterpolationTypes* applicableTypes = applicableTypesForProperty(propertyHandle); if (applicableTypes) return InvalidatableInterpolation::create(propertyHandle, *applicableTypes, *this, 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. CSSPropertyID property = propertyHandle.isCSSProperty() ? propertyHandle.cssProperty() : propertyHandle.presentationAttribute(); CSSValue* fromCSSValue = m_value.get(); CSSValue* toCSSValue = toCSSPropertySpecificKeyframe(end).value(); InterpolationRange range = RangeAll; // 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; } if (fromCSSValue->isCSSWideKeyword() || toCSSValue->isCSSWideKeyword()) return createLegacyStyleInterpolation(property, end, element, baseStyle); switch (property) { case CSSPropertyFontSize: if (LengthStyleInterpolation::canCreateFrom(*fromCSSValue) && LengthStyleInterpolation::canCreateFrom(*toCSSValue)) return LengthStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, RangeNonNegative); // FIXME: Handle keywords e.g. 'smaller', 'larger'. if (property == CSSPropertyFontSize) return createLegacyStyleInterpolation(property, end, element, baseStyle); // FIXME: Handle keywords e.g. 'baseline', 'sub'. if (property == CSSPropertyBaselineShift) return createLegacyStyleInterpolation(property, end, element, baseStyle); break; case CSSPropertyMotionRotation: { RefPtr<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 CSSPropertyBorderBottomLeftRadius: case CSSPropertyBorderBottomRightRadius: case CSSPropertyBorderTopLeftRadius: case CSSPropertyBorderTopRightRadius: if (LengthPairStyleInterpolation::canCreateFrom(*fromCSSValue) && LengthPairStyleInterpolation::canCreateFrom(*toCSSValue)) return LengthPairStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, RangeNonNegative); break; case CSSPropertyPerspectiveOrigin: case CSSPropertyTransformOrigin: { RefPtr<Interpolation> interpolation = ListStyleInterpolation<LengthStyleInterpolation>::maybeCreateFromList(*fromCSSValue, *toCSSValue, property, range); if (interpolation) return interpolation.release(); // FIXME: Handle keywords: top, right, left, center, bottom return createLegacyStyleInterpolation(property, end, element, baseStyle); } case CSSPropertyClip: { if (LengthBoxStyleInterpolation::usesDefaultInterpolation(*fromCSSValue, *toCSSValue)) { forceDefaultInterpolation = true; break; } RefPtr<Interpolation> interpolation = LengthBoxStyleInterpolation::maybeCreateFrom(*fromCSSValue, *toCSSValue, property); if (interpolation) return interpolation.release(); break; } case CSSPropertyBorderImageSlice: case CSSPropertyWebkitMaskBoxImageSlice: { RefPtr<Interpolation> interpolation = ImageSliceStyleInterpolation::maybeCreate(*fromCSSValue, *toCSSValue, property); if (interpolation) return interpolation.release(); if (ImageSliceStyleInterpolation::usesDefaultInterpolation(*fromCSSValue, *toCSSValue)) forceDefaultInterpolation = true; break; } case CSSPropertyWebkitFilter: case CSSPropertyBackdropFilter: { RefPtr<Interpolation> interpolation = FilterStyleInterpolation::maybeCreateList(*fromCSSValue, *toCSSValue, property); if (interpolation) return interpolation.release(); // FIXME: Support drop shadow interpolation. return createLegacyStyleInterpolation(property, end, element, baseStyle); break; } case CSSPropertyTranslate: { RefPtr<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. return createLegacyStyleInterpolation(property, end, element, baseStyle); break; } case CSSPropertyScale: { RefPtr<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. return createLegacyStyleInterpolation(property, end, element, baseStyle); break; } default: // Fall back to LegacyStyleInterpolation. return createLegacyStyleInterpolation(property, end, element, baseStyle); break; } if (fromCSSValue == toCSSValue) return ConstantStyleInterpolation::create(fromCSSValue, property); if (!forceDefaultInterpolation) { ASSERT(AnimatableValue::usesDefaultInterpolation( StyleResolver::createAnimatableValueSnapshot(*element, baseStyle, property, fromCSSValue).get(), StyleResolver::createAnimatableValueSnapshot(*element, baseStyle, property, toCSSValue).get())); } return nullptr; }
PassOwnPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::createPropertySpecificKeyframe(PropertyHandle property) const { if (property.isCSSProperty()) return adoptPtr(new CSSPropertySpecificKeyframe(offset(), &easing(), cssPropertyValue(property.cssProperty()), composite())); if (property.isPresentationAttribute()) return adoptPtr(new CSSPropertySpecificKeyframe(offset(), &easing(), presentationAttributeValue(property.presentationAttribute()), composite())); ASSERT(property.isSVGAttribute()); return adoptPtr(new SVGPropertySpecificKeyframe(offset(), &easing(), svgPropertyValue(property.svgAttribute()), composite())); }
PassRefPtr<Keyframe::PropertySpecificKeyframe> AnimatableValueKeyframe::createPropertySpecificKeyframe(PropertyHandle property) const { return PropertySpecificKeyframe::create(offset(), &easing(), propertyValue(property.cssProperty()), composite()); }
PassRefPtr<Interpolation> AnimatableValueKeyframe::PropertySpecificKeyframe::maybeCreateInterpolation(PropertyHandle property, Keyframe::PropertySpecificKeyframe& end, Element*, const ComputedStyle*) const { AnimatableValuePropertySpecificKeyframe& to = toAnimatableValuePropertySpecificKeyframe(end); return LegacyStyleInterpolation::create(value(), to.value(), property.cssProperty()); }
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; // 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; } if (fromCSSValue->isCSSWideKeyword() || toCSSValue->isCSSWideKeyword()) return createLegacyStyleInterpolation(property, end, element, baseStyle); 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, true, 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) return createLegacyStyleInterpolation(property, end, element, baseStyle); // FIXME: Handle keywords e.g. 'baseline', 'sub'. if (property == CSSPropertyBaselineShift) return createLegacyStyleInterpolation(property, end, element, baseStyle); 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)->isNumber(), 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)) return createLegacyStyleInterpolation(property, end, element, baseStyle); 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 return createLegacyStyleInterpolation(property, end, element, baseStyle); } 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 return createLegacyStyleInterpolation(property, end, element, baseStyle); } 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. return createLegacyStyleInterpolation(property, end, element, baseStyle); 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. return createLegacyStyleInterpolation(property, end, element, baseStyle); 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. return createLegacyStyleInterpolation(property, end, element, baseStyle); break; } default: // Fall back to LegacyStyleInterpolation. return createLegacyStyleInterpolation(property, end, element, baseStyle); break; } if (fromCSSValue == toCSSValue) return ConstantStyleInterpolation::create(fromCSSValue, property); if (!forceDefaultInterpolation) { ASSERT(AnimatableValue::usesDefaultInterpolation( StyleResolver::createAnimatableValueSnapshot(*element, baseStyle, property, fromCSSValue).get(), StyleResolver::createAnimatableValueSnapshot(*element, baseStyle, property, toCSSValue).get())); } return nullptr; }