diff options
8 files changed, 313 insertions, 182 deletions
diff --git a/third_party/WebKit/LayoutTests/animations/css-animation-overrides-svg-presentation-attribute-animation-expected.txt b/third_party/WebKit/LayoutTests/animations/css-animation-overrides-svg-presentation-attribute-animation-expected.txt new file mode 100644 index 0000000..d21c991 --- /dev/null +++ b/third_party/WebKit/LayoutTests/animations/css-animation-overrides-svg-presentation-attribute-animation-expected.txt @@ -0,0 +1,4 @@ + This is a testharness.js-based test. +FAIL CSS animations always override SVG presentation attribute animations assert_equals: expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)" +Harness: the test ran to completion. + diff --git a/third_party/WebKit/LayoutTests/animations/css-animation-overrides-svg-presentation-attribute-animation.html b/third_party/WebKit/LayoutTests/animations/css-animation-overrides-svg-presentation-attribute-animation.html new file mode 100644 index 0000000..cd67cbe --- /dev/null +++ b/third_party/WebKit/LayoutTests/animations/css-animation-overrides-svg-presentation-attribute-animation.html @@ -0,0 +1,14 @@ +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> + +<svg> + <rect id="target"/> +</svg> + +<script> +test(() => { + target.animate({color: 'green'}, {fill: 'forwards'}); + target.animate({'svg-color': 'red'}, {fill: 'forwards'}); + assert_equals(getComputedStyle(target).color, 'rgb(0, 128, 0)'); +}, 'CSS animations always override SVG presentation attribute animations'); +</script> diff --git a/third_party/WebKit/LayoutTests/animations/svg-presentation-attribute-animation.html b/third_party/WebKit/LayoutTests/animations/svg-presentation-attribute-animation.html new file mode 100644 index 0000000..2c9ac8e --- /dev/null +++ b/third_party/WebKit/LayoutTests/animations/svg-presentation-attribute-animation.html @@ -0,0 +1,86 @@ +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> + +<svg> + <rect id="target"/> +</svg> + +<script> +'use strict'; + +var testCases = [ + ['alignment-baseline', 'middle'], + ['baseline-shift', '100px'], + ['buffered-rendering', 'dynamic'], + ['clip-path', 'url("#test")'], + ['clip-rule', 'evenodd'], + ['color', 'rgb(1, 2, 3)'], + ['color-interpolation', 'linearRGB'], + ['color-interpolation-filters', 'sRGB'], + ['color-rendering', 'optimizeSpeed'], + ['cursor', 'url("test://uri/"), auto'], + ['dominant-baseline', 'middle'], + ['fill', 'rgb(1, 2, 3)'], + ['fill-opacity', '0.25'], + ['fill-rule', 'evenodd'], + ['filter', 'url("#test")'], + ['flood-color', 'rgb(1, 2, 3)'], + ['flood-opacity', '0.25'], + ['font-family', "'Test Font'"], + ['font-size', '123px'], + ['font-stretch', 'condensed'], + ['font-style', 'italic'], + ['font-variant', 'small-caps'], + ['font-weight', '900'], + ['image-rendering', 'pixelated'], + ['letter-spacing', '123px'], + ['lighting-color', 'rgb(1, 2, 3)'], + ['marker-end', 'url("#test")'], + ['marker-mid', 'url("#test")'], + ['marker-start', 'url("#test")'], + ['mask', 'url("#test")'], + ['mask-type', 'alpha'], + ['opacity', '0.25'], + ['overflow', 'hidden'], + ['paint-order', 'fill markers stroke'], + ['pointer-events', 'all'], + ['shape-rendering', 'geometricPrecision'], + ['stop-color', 'rgb(1, 2, 3)'], + ['stop-opacity', '0.25'], + ['stroke', 'rgb(1, 2, 3)'], + ['stroke-dasharray', '1px, 2px, 3px'], + ['stroke-dashoffset', '123px'], + ['stroke-linecap', 'square'], + ['stroke-linejoin', 'round'], + ['stroke-miterlimit', '123'], + ['stroke-opacity', '0.25'], + ['stroke-width', '123px'], + ['text-anchor', 'middle'], + ['text-decoration', 'underline solid rgb(1, 2, 3)'], + ['text-rendering', 'geometricPrecision'], + ['vector-effect', 'non-scaling-stroke'], + ['visibility', 'collapse'], + ['word-spacing', '123px'], +]; + +function svgPrefix(property) { + return 'svg-' + property; +} + +test(() => { + for (var [property, value] of testCases) { + assert_not_equals(getComputedStyle(target)[property], value, 'Precheck that this test is using a non-default value for ' + property); + } +}, 'Pretest assertions'); + +// Separate animate() and getComputedStyle() into different phases to avoid quadratic animated style recalc churn. +for (var [property, value] of testCases) { + target.animate({[svgPrefix(property)]: value}, {fill: 'forwards'}); +} + +for (var [property, value] of testCases) { + test(() => { + assert_equals(getComputedStyle(target)[property], value); + }, 'Web Animations can target ' + svgPrefix(property)); +} +</script> diff --git a/third_party/WebKit/Source/core/animation/AnimationInputHelpers.cpp b/third_party/WebKit/Source/core/animation/AnimationInputHelpers.cpp index 892df1e..b82ff1f 100644 --- a/third_party/WebKit/Source/core/animation/AnimationInputHelpers.cpp +++ b/third_party/WebKit/Source/core/animation/AnimationInputHelpers.cpp @@ -5,27 +5,198 @@ #include "config.h" #include "core/animation/AnimationInputHelpers.h" +#include "core/SVGNames.h" +#include "core/XLinkNames.h" #include "core/css/CSSValueList.h" #include "core/css/parser/CSSParser.h" #include "core/css/resolver/CSSToStyleMap.h" +#include "core/svg/SVGElement.h" +#include "core/svg/animation/SVGSMILElement.h" #include "wtf/text/StringBuilder.h" namespace blink { -CSSPropertyID AnimationInputHelpers::keyframeAttributeToCSSPropertyID(const String& propertyName) +const char kSVGPrefix[] = "svg-"; +const unsigned kSVGPrefixLength = sizeof(kSVGPrefix) - 1; + +static bool isSVGPrefixed(const String& property) +{ + return property.startsWith(kSVGPrefix); +} + +static String removeSVGPrefix(const String& property) +{ + ASSERT(isSVGPrefixed(property)); + return property.substring(kSVGPrefixLength); +} + +CSSPropertyID AnimationInputHelpers::keyframeAttributeToCSSPropertyID(const String& property, const Element& element) { // Disallow prefixed properties. - if (propertyName[0] == '-' || isASCIIUpper(propertyName[0])) + if (property[0] == '-' || isASCIIUpper(property[0])) return CSSPropertyInvalid; - if (propertyName == "cssFloat") + if (property == "cssFloat") return CSSPropertyFloat; StringBuilder builder; - for (size_t i = 0; i < propertyName.length(); ++i) { - if (isASCIIUpper(propertyName[i])) + for (size_t i = 0; i < property.length(); ++i) { + if (isASCIIUpper(property[i])) builder.append('-'); - builder.append(propertyName[i]); + builder.append(property[i]); + } + + CSSPropertyID result = cssPropertyID(builder.toString()); + if (result != CSSPropertyInvalid || !RuntimeEnabledFeatures::webAnimationsSVGEnabled() || !element.isSVGElement() || !isSVGPrefixed(property)) + return result; + + // TODO(alancutter): Don't alias these as their CSS property counterparts. + // Treat them as their own type of PropertyHandle so they can be applied in + // SVGElement::collectStyleForPresentationAttribute() instead of StyleResolver::applyAnimatedProperties(). + String unprefixedProperty = removeSVGPrefix(property); + if (SVGElement::isAnimatableCSSProperty(QualifiedName(nullAtom, AtomicString(unprefixedProperty), nullAtom))) + return cssPropertyID(unprefixedProperty); + + return CSSPropertyInvalid; +} + +using AttributeNameMap = HashMap<QualifiedName, const QualifiedName*>; + +const AttributeNameMap& getSupportedAttributes() +{ + DEFINE_STATIC_LOCAL(AttributeNameMap, supportedAttributes, ()); + if (supportedAttributes.isEmpty()) { + // Fill the set for the first use. + // Animatable attributes from http://www.w3.org/TR/SVG/attindex.html + const QualifiedName* attributes[] = { + &HTMLNames::classAttr, + &SVGNames::amplitudeAttr, + &SVGNames::azimuthAttr, + &SVGNames::baseFrequencyAttr, + &SVGNames::biasAttr, + &SVGNames::clipPathUnitsAttr, + &SVGNames::cxAttr, + &SVGNames::cyAttr, + &SVGNames::dAttr, + &SVGNames::diffuseConstantAttr, + &SVGNames::divisorAttr, + &SVGNames::dxAttr, + &SVGNames::dyAttr, + &SVGNames::edgeModeAttr, + &SVGNames::elevationAttr, + &SVGNames::exponentAttr, + &SVGNames::filterUnitsAttr, + &SVGNames::fxAttr, + &SVGNames::fyAttr, + &SVGNames::gradientTransformAttr, + &SVGNames::gradientUnitsAttr, + &SVGNames::heightAttr, + &SVGNames::in2Attr, + &SVGNames::inAttr, + &SVGNames::interceptAttr, + &SVGNames::k1Attr, + &SVGNames::k2Attr, + &SVGNames::k3Attr, + &SVGNames::k4Attr, + &SVGNames::kernelMatrixAttr, + &SVGNames::kernelUnitLengthAttr, + &SVGNames::lengthAdjustAttr, + &SVGNames::limitingConeAngleAttr, + &SVGNames::markerHeightAttr, + &SVGNames::markerUnitsAttr, + &SVGNames::markerWidthAttr, + &SVGNames::maskContentUnitsAttr, + &SVGNames::maskUnitsAttr, + &SVGNames::methodAttr, + &SVGNames::modeAttr, + &SVGNames::numOctavesAttr, + &SVGNames::offsetAttr, + &SVGNames::opacityAttr, + &SVGNames::operatorAttr, + &SVGNames::orderAttr, + &SVGNames::orientAttr, + &SVGNames::pathLengthAttr, + &SVGNames::patternContentUnitsAttr, + &SVGNames::patternTransformAttr, + &SVGNames::patternUnitsAttr, + &SVGNames::pointsAtXAttr, + &SVGNames::pointsAtYAttr, + &SVGNames::pointsAtZAttr, + &SVGNames::pointsAttr, + &SVGNames::preserveAlphaAttr, + &SVGNames::preserveAspectRatioAttr, + &SVGNames::primitiveUnitsAttr, + &SVGNames::rAttr, + &SVGNames::radiusAttr, + &SVGNames::refXAttr, + &SVGNames::refYAttr, + &SVGNames::resultAttr, + &SVGNames::rotateAttr, + &SVGNames::rxAttr, + &SVGNames::ryAttr, + &SVGNames::scaleAttr, + &SVGNames::seedAttr, + &SVGNames::slopeAttr, + &SVGNames::spacingAttr, + &SVGNames::specularConstantAttr, + &SVGNames::specularExponentAttr, + &SVGNames::spreadMethodAttr, + &SVGNames::startOffsetAttr, + &SVGNames::stdDeviationAttr, + &SVGNames::stitchTilesAttr, + &SVGNames::surfaceScaleAttr, + &SVGNames::tableValuesAttr, + &SVGNames::targetAttr, + &SVGNames::targetXAttr, + &SVGNames::targetYAttr, + &SVGNames::textLengthAttr, + &SVGNames::transformAttr, + &SVGNames::typeAttr, + &SVGNames::valuesAttr, + &SVGNames::viewBoxAttr, + &SVGNames::widthAttr, + &SVGNames::x1Attr, + &SVGNames::x2Attr, + &SVGNames::xAttr, + &SVGNames::xChannelSelectorAttr, + &SVGNames::y1Attr, + &SVGNames::y2Attr, + &SVGNames::yAttr, + &SVGNames::yChannelSelectorAttr, + &SVGNames::zAttr, + &XLinkNames::hrefAttr, + }; + for (size_t i = 0; i < WTF_ARRAY_LENGTH(attributes); i++) + supportedAttributes.set(*attributes[i], attributes[i]); } - return cssPropertyID(builder.toString()); + return supportedAttributes; +} + +QualifiedName svgAttributeName(const String& property) +{ + ASSERT(!isSVGPrefixed(property)); + + if (property == "href") + return XLinkNames::hrefAttr; + + return QualifiedName(nullAtom, AtomicString(property), nullAtom); +} + +const QualifiedName* AnimationInputHelpers::keyframeAttributeToQualifiedName(const String& property, Element& element) +{ + if (!RuntimeEnabledFeatures::webAnimationsSVGEnabled() || !element.isSVGElement() || !isSVGPrefixed(property)) + return nullptr; + + SVGElement& svgElement = toSVGElement(element); + if (isSVGSMILElement(svgElement)) + return nullptr; + + String unprefixedProperty = removeSVGPrefix(property); + QualifiedName attributeName = svgAttributeName(unprefixedProperty); + const AttributeNameMap& supportedAttributes = getSupportedAttributes(); + auto iter = supportedAttributes.find(attributeName); + if (iter == supportedAttributes.end() || !svgElement.propertyFromAttribute(*iter->value)) + return nullptr; + + return iter->value; } PassRefPtr<TimingFunction> AnimationInputHelpers::parseTimingFunction(const String& string) diff --git a/third_party/WebKit/Source/core/animation/AnimationInputHelpers.h b/third_party/WebKit/Source/core/animation/AnimationInputHelpers.h index d08bc4d..ae4a6fa 100644 --- a/third_party/WebKit/Source/core/animation/AnimationInputHelpers.h +++ b/third_party/WebKit/Source/core/animation/AnimationInputHelpers.h @@ -11,12 +11,15 @@ namespace blink { +class Element; class TimingFunction; +class QualifiedName; class CORE_EXPORT AnimationInputHelpers { STATIC_ONLY(AnimationInputHelpers); public: - static CSSPropertyID keyframeAttributeToCSSPropertyID(const String&); + static CSSPropertyID keyframeAttributeToCSSPropertyID(const String&, const Element&); + static const QualifiedName* keyframeAttributeToQualifiedName(const String&, Element&); static PassRefPtr<TimingFunction> parseTimingFunction(const String&); }; diff --git a/third_party/WebKit/Source/core/animation/AnimationInputHelpersTest.cpp b/third_party/WebKit/Source/core/animation/AnimationInputHelpersTest.cpp index 3f4f718..292bd34 100644 --- a/third_party/WebKit/Source/core/animation/AnimationInputHelpersTest.cpp +++ b/third_party/WebKit/Source/core/animation/AnimationInputHelpersTest.cpp @@ -5,6 +5,7 @@ #include "config.h" #include "core/animation/AnimationInputHelpers.h" +#include "core/testing/DummyPageHolder.h" #include "platform/animation/TimingFunction.h" #include "testing/gtest/include/gtest/gtest.h" @@ -12,23 +13,26 @@ namespace blink { TEST(AnimationAnimationInputHelpersTest, ParseKeyframePropertyAttributes) { - EXPECT_EQ(CSSPropertyLineHeight, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("line-height"))); - EXPECT_EQ(CSSPropertyLineHeight, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("lineHeight"))); - EXPECT_EQ(CSSPropertyBorderTopWidth, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("borderTopWidth"))); - EXPECT_EQ(CSSPropertyBorderTopWidth, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("border-topWidth"))); - EXPECT_EQ(CSSPropertyWidth, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("width"))); - EXPECT_EQ(CSSPropertyFloat, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("float"))); - EXPECT_EQ(CSSPropertyFloat, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("cssFloat"))); + OwnPtr<DummyPageHolder> dummyPageHolder = DummyPageHolder::create(); + const Element& dummyElement = *dummyPageHolder->document().documentElement(); - EXPECT_EQ(CSSPropertyInvalid, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("Width"))); - EXPECT_EQ(CSSPropertyInvalid, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("-epub-text-transform"))); - EXPECT_EQ(CSSPropertyInvalid, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("EpubTextTransform"))); - EXPECT_EQ(CSSPropertyInvalid, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("-internal-marquee-repetition"))); - EXPECT_EQ(CSSPropertyInvalid, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("InternalMarqueeRepetition"))); - EXPECT_EQ(CSSPropertyInvalid, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("-webkit-filter"))); - EXPECT_EQ(CSSPropertyInvalid, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("-webkit-transform"))); - EXPECT_EQ(CSSPropertyInvalid, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("webkitTransform"))); - EXPECT_EQ(CSSPropertyInvalid, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("WebkitTransform"))); + EXPECT_EQ(CSSPropertyLineHeight, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("line-height"), dummyElement)); + EXPECT_EQ(CSSPropertyLineHeight, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("lineHeight"), dummyElement)); + EXPECT_EQ(CSSPropertyBorderTopWidth, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("borderTopWidth"), dummyElement)); + EXPECT_EQ(CSSPropertyBorderTopWidth, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("border-topWidth"), dummyElement)); + EXPECT_EQ(CSSPropertyWidth, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("width"), dummyElement)); + EXPECT_EQ(CSSPropertyFloat, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("float"), dummyElement)); + EXPECT_EQ(CSSPropertyFloat, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("cssFloat"), dummyElement)); + + EXPECT_EQ(CSSPropertyInvalid, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("Width"), dummyElement)); + EXPECT_EQ(CSSPropertyInvalid, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("-epub-text-transform"), dummyElement)); + EXPECT_EQ(CSSPropertyInvalid, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("EpubTextTransform"), dummyElement)); + EXPECT_EQ(CSSPropertyInvalid, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("-internal-marquee-repetition"), dummyElement)); + EXPECT_EQ(CSSPropertyInvalid, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("InternalMarqueeRepetition"), dummyElement)); + EXPECT_EQ(CSSPropertyInvalid, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("-webkit-filter"), dummyElement)); + EXPECT_EQ(CSSPropertyInvalid, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("-webkit-transform"), dummyElement)); + EXPECT_EQ(CSSPropertyInvalid, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("webkitTransform"), dummyElement)); + EXPECT_EQ(CSSPropertyInvalid, AnimationInputHelpers::keyframeAttributeToCSSPropertyID(String("WebkitTransform"), dummyElement)); } static bool timingFunctionRoundTrips(const String& string) diff --git a/third_party/WebKit/Source/core/animation/EffectInput.cpp b/third_party/WebKit/Source/core/animation/EffectInput.cpp index 52138d9..159324a 100644 --- a/third_party/WebKit/Source/core/animation/EffectInput.cpp +++ b/third_party/WebKit/Source/core/animation/EffectInput.cpp @@ -33,170 +33,20 @@ #include "bindings/core/v8/Dictionary.h" #include "bindings/core/v8/UnionTypesCore.h" -#include "core/HTMLNames.h" -#include "core/SVGNames.h" -#include "core/XLinkNames.h" #include "core/animation/AnimationInputHelpers.h" #include "core/animation/KeyframeEffectModel.h" #include "core/animation/StringKeyframe.h" -#include "core/css/resolver/StyleResolver.h" +#include "core/css/CSSStyleSheet.h" #include "core/dom/Document.h" #include "core/dom/Element.h" +#include "core/dom/ExceptionCode.h" #include "core/dom/NodeComputedStyle.h" -#include "core/svg/animation/SVGSMILElement.h" #include "wtf/ASCIICType.h" #include "wtf/HashSet.h" #include "wtf/NonCopyingSort.h" namespace blink { -namespace { - -bool isSVGPrefixed(const String& property) -{ - return property.startsWith("svg-"); -} - -QualifiedName svgAttributeName(String property) -{ - // Replace 'svg-transform' with 'transform', etc. - ASSERT(isSVGPrefixed(property)); - property.remove(0, 4); - - if (property == "href") - return XLinkNames::hrefAttr; - - return QualifiedName(nullAtom, AtomicString(property), SVGNames::amplitudeAttr.namespaceURI()); -} - -using AttributeNameMap = HashMap<QualifiedName, const QualifiedName*>; - -const AttributeNameMap& getSupportedAttributes() -{ - DEFINE_STATIC_LOCAL(AttributeNameMap, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - // Fill the set for the first use. - // Animatable attributes from http://www.w3.org/TR/SVG/attindex.html - const QualifiedName* attributes[] = { - &HTMLNames::classAttr, - &SVGNames::amplitudeAttr, - &SVGNames::azimuthAttr, - &SVGNames::baseFrequencyAttr, - &SVGNames::biasAttr, - &SVGNames::clipPathUnitsAttr, - &SVGNames::cxAttr, - &SVGNames::cyAttr, - &SVGNames::dAttr, - &SVGNames::diffuseConstantAttr, - &SVGNames::divisorAttr, - &SVGNames::dxAttr, - &SVGNames::dyAttr, - &SVGNames::edgeModeAttr, - &SVGNames::elevationAttr, - &SVGNames::exponentAttr, - &SVGNames::filterUnitsAttr, - &SVGNames::fxAttr, - &SVGNames::fyAttr, - &SVGNames::gradientTransformAttr, - &SVGNames::gradientUnitsAttr, - &SVGNames::heightAttr, - &SVGNames::in2Attr, - &SVGNames::inAttr, - &SVGNames::interceptAttr, - &SVGNames::k1Attr, - &SVGNames::k2Attr, - &SVGNames::k3Attr, - &SVGNames::k4Attr, - &SVGNames::kernelMatrixAttr, - &SVGNames::kernelUnitLengthAttr, - &SVGNames::lengthAdjustAttr, - &SVGNames::limitingConeAngleAttr, - &SVGNames::markerHeightAttr, - &SVGNames::markerUnitsAttr, - &SVGNames::markerWidthAttr, - &SVGNames::maskContentUnitsAttr, - &SVGNames::maskUnitsAttr, - &SVGNames::methodAttr, - &SVGNames::modeAttr, - &SVGNames::numOctavesAttr, - &SVGNames::offsetAttr, - &SVGNames::operatorAttr, - &SVGNames::orderAttr, - &SVGNames::orientAttr, - &SVGNames::pathLengthAttr, - &SVGNames::patternContentUnitsAttr, - &SVGNames::patternTransformAttr, - &SVGNames::patternUnitsAttr, - &SVGNames::pointsAtXAttr, - &SVGNames::pointsAtYAttr, - &SVGNames::pointsAtZAttr, - &SVGNames::pointsAttr, - &SVGNames::preserveAlphaAttr, - &SVGNames::preserveAspectRatioAttr, - &SVGNames::primitiveUnitsAttr, - &SVGNames::rAttr, - &SVGNames::radiusAttr, - &SVGNames::refXAttr, - &SVGNames::refYAttr, - &SVGNames::resultAttr, - &SVGNames::rotateAttr, - &SVGNames::rxAttr, - &SVGNames::ryAttr, - &SVGNames::scaleAttr, - &SVGNames::seedAttr, - &SVGNames::slopeAttr, - &SVGNames::spacingAttr, - &SVGNames::specularConstantAttr, - &SVGNames::specularExponentAttr, - &SVGNames::spreadMethodAttr, - &SVGNames::startOffsetAttr, - &SVGNames::stdDeviationAttr, - &SVGNames::stitchTilesAttr, - &SVGNames::surfaceScaleAttr, - &SVGNames::tableValuesAttr, - &SVGNames::targetAttr, - &SVGNames::targetXAttr, - &SVGNames::targetYAttr, - &SVGNames::textLengthAttr, - &SVGNames::transformAttr, - &SVGNames::typeAttr, - &SVGNames::valuesAttr, - &SVGNames::viewBoxAttr, - &SVGNames::widthAttr, - &SVGNames::x1Attr, - &SVGNames::x2Attr, - &SVGNames::xAttr, - &SVGNames::xChannelSelectorAttr, - &SVGNames::y1Attr, - &SVGNames::y2Attr, - &SVGNames::yAttr, - &SVGNames::yChannelSelectorAttr, - &SVGNames::zAttr, - &XLinkNames::hrefAttr, - }; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(attributes); i++) - supportedAttributes.set(*attributes[i], attributes[i]); - } - return supportedAttributes; -} - -const QualifiedName* findSVGAttributeForProperty(const String& property, SVGElement* svgElement) -{ - if (isSVGSMILElement(*svgElement)) - return nullptr; - - QualifiedName attributeName = svgAttributeName(property); - - const AttributeNameMap& supportedAttributes = getSupportedAttributes(); - auto iter = supportedAttributes.find(attributeName); - if (iter == supportedAttributes.end() || !svgElement->propertyFromAttribute(*iter->value)) - return nullptr; - - return iter->value; -} - -} // namespace - EffectModel* EffectInput::convert(Element* element, const Vector<Dictionary>& keyframeDictionaryVector, ExceptionState& exceptionState) { if (!element) @@ -258,7 +108,7 @@ EffectModel* EffectInput::convert(Element* element, const Vector<Dictionary>& ke for (const auto& property : keyframeProperties) { String value; DictionaryHelper::get(keyframeDictionary, property, value); - CSSPropertyID id = AnimationInputHelpers::keyframeAttributeToCSSPropertyID(property); + CSSPropertyID id = AnimationInputHelpers::keyframeAttributeToCSSPropertyID(property, *element); if (id != CSSPropertyInvalid) { keyframe->setPropertyValue(id, value, element, styleSheetContents); continue; @@ -270,12 +120,10 @@ EffectModel* EffectInput::convert(Element* element, const Vector<Dictionary>& ke continue; } - if (!RuntimeEnabledFeatures::webAnimationsSVGEnabled() || !element->isSVGElement() || !isSVGPrefixed(property)) - continue; - - const QualifiedName* qualifiedName = findSVGAttributeForProperty(property, toSVGElement(element)); - if (qualifiedName) + const QualifiedName* qualifiedName = AnimationInputHelpers::keyframeAttributeToQualifiedName(property, *element); + if (qualifiedName) { keyframe->setPropertyValue(*qualifiedName, value); + } } } diff --git a/third_party/WebKit/Source/core/animation/EffectInput.h b/third_party/WebKit/Source/core/animation/EffectInput.h index df4a327..7b026ed 100644 --- a/third_party/WebKit/Source/core/animation/EffectInput.h +++ b/third_party/WebKit/Source/core/animation/EffectInput.h @@ -21,6 +21,7 @@ class ExceptionState; class CORE_EXPORT EffectInput { STATIC_ONLY(EffectInput); public: + // TODO(alancutter): Replace Element* parameter with Document&. static EffectModel* convert(Element*, const Vector<Dictionary>& keyframeDictionaryVector, ExceptionState&); static EffectModel* convert(Element*, const EffectModelOrDictionarySequenceOrDictionary&, ExceptionState&); }; |