summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--third_party/WebKit/LayoutTests/animations/css-animation-overrides-svg-presentation-attribute-animation-expected.txt4
-rw-r--r--third_party/WebKit/LayoutTests/animations/css-animation-overrides-svg-presentation-attribute-animation.html14
-rw-r--r--third_party/WebKit/LayoutTests/animations/svg-presentation-attribute-animation.html86
-rw-r--r--third_party/WebKit/Source/core/animation/AnimationInputHelpers.cpp185
-rw-r--r--third_party/WebKit/Source/core/animation/AnimationInputHelpers.h5
-rw-r--r--third_party/WebKit/Source/core/animation/AnimationInputHelpersTest.cpp36
-rw-r--r--third_party/WebKit/Source/core/animation/EffectInput.cpp164
-rw-r--r--third_party/WebKit/Source/core/animation/EffectInput.h1
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&);
};