summaryrefslogtreecommitdiff
path: root/Source/WebCore/svg/SVGAnimationElement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/svg/SVGAnimationElement.cpp')
-rw-r--r--Source/WebCore/svg/SVGAnimationElement.cpp212
1 files changed, 110 insertions, 102 deletions
diff --git a/Source/WebCore/svg/SVGAnimationElement.cpp b/Source/WebCore/svg/SVGAnimationElement.cpp
index 6f228f785..b1457f403 100644
--- a/Source/WebCore/svg/SVGAnimationElement.cpp
+++ b/Source/WebCore/svg/SVGAnimationElement.cpp
@@ -5,6 +5,7 @@
* Copyright (C) 2008 Apple Inc. All rights reserved.
* Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au>
* Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,23 +24,23 @@
*/
#include "config.h"
-
-#if ENABLE(SVG)
#include "SVGAnimationElement.h"
-#include "Attribute.h"
#include "CSSComputedStyleDeclaration.h"
-#include "CSSParser.h"
#include "CSSPropertyNames.h"
+#include "CSSPropertyParser.h"
#include "Document.h"
#include "FloatConversion.h"
#include "RenderObject.h"
+#include "SVGAnimateColorElement.h"
#include "SVGAnimateElement.h"
#include "SVGElement.h"
-#include "SVGElementInstance.h"
#include "SVGNames.h"
#include "SVGParserUtilities.h"
+#include "SVGStringList.h"
#include <wtf/MathExtras.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/text/StringView.h>
namespace WebCore {
@@ -53,13 +54,6 @@ END_REGISTER_ANIMATED_PROPERTIES
SVGAnimationElement::SVGAnimationElement(const QualifiedName& tagName, Document& document)
: SVGSMILElement(tagName, document)
- , m_fromPropertyValueType(RegularPropertyValue)
- , m_toPropertyValueType(RegularPropertyValue)
- , m_animationValid(false)
- , m_attributeType(AttributeTypeAuto)
- , m_hasInvalidCSSAttributeType(false)
- , m_calcMode(CalcModeLinear)
- , m_animationMode(NoAnimation)
{
registerAnimatedPropertiesForSVGAnimationElement();
}
@@ -94,7 +88,9 @@ static void parseKeySplines(const String& parse, Vector<UnitBezier>& result)
result.clear();
if (parse.isEmpty())
return;
- const UChar* cur = parse.deprecatedCharacters();
+
+ auto upconvertedCharacters = StringView(parse).upconvertedCharacters();
+ const UChar* cur = upconvertedCharacters;
const UChar* end = cur + parse.length();
skipOptionalSVGSpaces(cur, end);
@@ -142,37 +138,32 @@ static void parseKeySplines(const String& parse, Vector<UnitBezier>& result)
bool SVGAnimationElement::isSupportedAttribute(const QualifiedName& attrName)
{
- DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
- if (supportedAttributes.isEmpty()) {
+ static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes;
+ if (supportedAttributes.get().isEmpty()) {
SVGTests::addSupportedAttributes(supportedAttributes);
SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
- supportedAttributes.add(SVGNames::valuesAttr);
- supportedAttributes.add(SVGNames::keyTimesAttr);
- supportedAttributes.add(SVGNames::keyPointsAttr);
- supportedAttributes.add(SVGNames::keySplinesAttr);
- supportedAttributes.add(SVGNames::attributeTypeAttr);
- supportedAttributes.add(SVGNames::calcModeAttr);
- supportedAttributes.add(SVGNames::fromAttr);
- supportedAttributes.add(SVGNames::toAttr);
- supportedAttributes.add(SVGNames::byAttr);
+ supportedAttributes.get().add(SVGNames::valuesAttr);
+ supportedAttributes.get().add(SVGNames::keyTimesAttr);
+ supportedAttributes.get().add(SVGNames::keyPointsAttr);
+ supportedAttributes.get().add(SVGNames::keySplinesAttr);
+ supportedAttributes.get().add(SVGNames::attributeTypeAttr);
+ supportedAttributes.get().add(SVGNames::calcModeAttr);
+ supportedAttributes.get().add(SVGNames::fromAttr);
+ supportedAttributes.get().add(SVGNames::toAttr);
+ supportedAttributes.get().add(SVGNames::byAttr);
}
- return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
+ return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName);
}
void SVGAnimationElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
- if (!isSupportedAttribute(name)) {
- SVGSMILElement::parseAttribute(name, value);
- return;
- }
-
if (name == SVGNames::valuesAttr) {
// Per the SMIL specification, leading and trailing white space,
// and white space before and after semicolon separators, is allowed and will be ignored.
// http://www.w3.org/TR/SVG11/animate.html#ValuesAttribute
value.string().split(';', m_values);
- for (unsigned i = 0; i < m_values.size(); ++i)
- m_values[i] = m_values[i].stripWhiteSpace();
+ for (auto& value : m_values)
+ value = value.stripWhiteSpace();
updateAnimationMode();
return;
@@ -212,12 +203,9 @@ void SVGAnimationElement::parseAttribute(const QualifiedName& name, const Atomic
return;
}
- if (SVGTests::parseAttribute(name, value))
- return;
- if (SVGExternalResourcesRequired::parseAttribute(name, value))
- return;
-
- ASSERT_NOT_REACHED();
+ SVGSMILElement::parseAttribute(name, value);
+ SVGTests::parseAttribute(name, value);
+ SVGExternalResourcesRequired::parseAttribute(name, value);
}
void SVGAnimationElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -247,7 +235,7 @@ float SVGAnimationElement::getCurrentTime() const
return narrowPrecisionToFloat(elapsed().value());
}
-float SVGAnimationElement::getSimpleDuration(ExceptionCode&) const
+float SVGAnimationElement::getSimpleDuration() const
{
return narrowPrecisionToFloat(simpleDuration().value());
}
@@ -293,66 +281,70 @@ void SVGAnimationElement::updateAnimationMode()
void SVGAnimationElement::setCalcMode(const AtomicString& calcMode)
{
- DEFINE_STATIC_LOCAL(const AtomicString, discrete, ("discrete", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(const AtomicString, linear, ("linear", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(const AtomicString, paced, ("paced", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(const AtomicString, spline, ("spline", AtomicString::ConstructFromLiteral));
+ static NeverDestroyed<const AtomicString> discrete("discrete", AtomicString::ConstructFromLiteral);
+ static NeverDestroyed<const AtomicString> linear("linear", AtomicString::ConstructFromLiteral);
+ static NeverDestroyed<const AtomicString> paced("paced", AtomicString::ConstructFromLiteral);
+ static NeverDestroyed<const AtomicString> spline("spline", AtomicString::ConstructFromLiteral);
if (calcMode == discrete)
- setCalcMode(CalcModeDiscrete);
+ setCalcMode(CalcMode::Discrete);
else if (calcMode == linear)
- setCalcMode(CalcModeLinear);
+ setCalcMode(CalcMode::Linear);
else if (calcMode == paced)
- setCalcMode(CalcModePaced);
+ setCalcMode(CalcMode::Paced);
else if (calcMode == spline)
- setCalcMode(CalcModeSpline);
+ setCalcMode(CalcMode::Spline);
else
- setCalcMode(hasTagName(SVGNames::animateMotionTag) ? CalcModePaced : CalcModeLinear);
+ setCalcMode(hasTagName(SVGNames::animateMotionTag) ? CalcMode::Paced : CalcMode::Linear);
}
void SVGAnimationElement::setAttributeType(const AtomicString& attributeType)
{
- DEFINE_STATIC_LOCAL(const AtomicString, css, ("CSS", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(const AtomicString, xml, ("XML", AtomicString::ConstructFromLiteral));
+ static NeverDestroyed<const AtomicString> css("CSS", AtomicString::ConstructFromLiteral);
+ static NeverDestroyed<const AtomicString> xml("XML", AtomicString::ConstructFromLiteral);
if (attributeType == css)
- m_attributeType = AttributeTypeCSS;
+ m_attributeType = AttributeType::CSS;
else if (attributeType == xml)
- m_attributeType = AttributeTypeXML;
+ m_attributeType = AttributeType::XML;
else
- m_attributeType = AttributeTypeAuto;
+ m_attributeType = AttributeType::Auto;
checkInvalidCSSAttributeType(targetElement());
}
String SVGAnimationElement::toValue() const
{
- return fastGetAttribute(SVGNames::toAttr);
+ return attributeWithoutSynchronization(SVGNames::toAttr);
}
String SVGAnimationElement::byValue() const
{
- return fastGetAttribute(SVGNames::byAttr);
+ return attributeWithoutSynchronization(SVGNames::byAttr);
}
String SVGAnimationElement::fromValue() const
{
- return fastGetAttribute(SVGNames::fromAttr);
+ return attributeWithoutSynchronization(SVGNames::fromAttr);
}
bool SVGAnimationElement::isAdditive() const
{
- DEFINE_STATIC_LOCAL(const AtomicString, sum, ("sum", AtomicString::ConstructFromLiteral));
- const AtomicString& value = fastGetAttribute(SVGNames::additiveAttr);
+ static NeverDestroyed<const AtomicString> sum("sum", AtomicString::ConstructFromLiteral);
+ const AtomicString& value = attributeWithoutSynchronization(SVGNames::additiveAttr);
return value == sum || animationMode() == ByAnimation;
}
bool SVGAnimationElement::isAccumulated() const
{
- DEFINE_STATIC_LOCAL(const AtomicString, sum, ("sum", AtomicString::ConstructFromLiteral));
- const AtomicString& value = fastGetAttribute(SVGNames::accumulateAttr);
+ static NeverDestroyed<const AtomicString> sum("sum", AtomicString::ConstructFromLiteral);
+ const AtomicString& value = attributeWithoutSynchronization(SVGNames::accumulateAttr);
return value == sum && animationMode() != ToAnimation;
}
-bool SVGAnimationElement::isTargetAttributeCSSProperty(SVGElement*, const QualifiedName& attributeName)
+bool SVGAnimationElement::isTargetAttributeCSSProperty(SVGElement* element, const QualifiedName& attributeName)
{
+ if (element->isTextContent()
+ && (attributeName == SVGNames::xAttr || attributeName == SVGNames::yAttr))
+ return false;
+
return SVGElement::isAnimatableCSSProperty(attributeName);
}
@@ -362,11 +354,15 @@ SVGAnimationElement::ShouldApplyAnimation SVGAnimationElement::shouldApplyAnimat
return DontApplyAnimation;
// Always animate CSS properties, using the ApplyCSSAnimation code path, regardless of the attributeType value.
- if (isTargetAttributeCSSProperty(targetElement, attributeName))
+ if (isTargetAttributeCSSProperty(targetElement, attributeName)) {
+ if (targetElement->isPresentationAttributeWithSVGDOM(attributeName))
+ return ApplyXMLandCSSAnimation;
return ApplyCSSAnimation;
+ }
+
// If attributeType="CSS" and attributeName doesn't point to a CSS property, ignore the animation.
- if (attributeType() == AttributeTypeCSS)
+ if (attributeType() == AttributeType::CSS)
return DontApplyAnimation;
return ApplyXMLAnimation;
@@ -374,7 +370,7 @@ SVGAnimationElement::ShouldApplyAnimation SVGAnimationElement::shouldApplyAnimat
void SVGAnimationElement::calculateKeyTimesForCalcModePaced()
{
- ASSERT(calcMode() == CalcModePaced);
+ ASSERT(calcMode() == CalcMode::Paced);
ASSERT(animationMode() == ValuesAnimation);
unsigned valuesCount = m_values.size();
@@ -426,7 +422,7 @@ unsigned SVGAnimationElement::calculateKeyTimesIndex(float percent) const
float SVGAnimationElement::calculatePercentForSpline(float percent, unsigned splineIndex) const
{
- ASSERT(calcMode() == CalcModeSpline);
+ ASSERT(calcMode() == CalcMode::Spline);
ASSERT_WITH_SECURITY_IMPLICATION(splineIndex < m_keySplines.size());
UnitBezier bezier = m_keySplines[splineIndex];
SMILTime duration = simpleDuration();
@@ -438,7 +434,7 @@ float SVGAnimationElement::calculatePercentForSpline(float percent, unsigned spl
float SVGAnimationElement::calculatePercentFromKeyPoints(float percent) const
{
ASSERT(!m_keyPoints.isEmpty());
- ASSERT(calcMode() != CalcModePaced);
+ ASSERT(calcMode() != CalcMode::Paced);
ASSERT(m_keyTimes.size() > 1);
ASSERT(m_keyPoints.size() == m_keyTimes.size());
@@ -451,12 +447,12 @@ float SVGAnimationElement::calculatePercentFromKeyPoints(float percent) const
float fromKeyPoint = m_keyPoints[index];
float toKeyPoint = m_keyPoints[index + 1];
- if (calcMode() == CalcModeDiscrete)
+ if (calcMode() == CalcMode::Discrete)
return fromKeyPoint;
float keyPointPercent = (percent - fromPercent) / (toPercent - fromPercent);
- if (calcMode() == CalcModeSpline) {
+ if (calcMode() == CalcMode::Spline) {
ASSERT(m_keySplines.size() == m_keyPoints.size() - 1);
keyPointPercent = calculatePercentForSpline(keyPointPercent, index);
}
@@ -465,7 +461,7 @@ float SVGAnimationElement::calculatePercentFromKeyPoints(float percent) const
float SVGAnimationElement::calculatePercentForFromTo(float percent) const
{
- if (calcMode() == CalcModeDiscrete && m_keyTimes.size() == 2)
+ if (calcMode() == CalcMode::Discrete && m_keyTimes.size() == 2)
return percent > m_keyTimes[1] ? 1 : 0;
return percent;
@@ -475,7 +471,7 @@ void SVGAnimationElement::currentValuesFromKeyPoints(float percent, float& effec
{
ASSERT(!m_keyPoints.isEmpty());
ASSERT(m_keyPoints.size() == m_keyTimes.size());
- ASSERT(calcMode() != CalcModePaced);
+ ASSERT(calcMode() != CalcMode::Paced);
effectivePercent = calculatePercentFromKeyPoints(percent);
unsigned index = effectivePercent == 1 ? m_values.size() - 2 : static_cast<unsigned>(effectivePercent * (m_values.size() - 1));
from = m_values[index];
@@ -496,16 +492,13 @@ void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float&
}
CalcMode calcMode = this->calcMode();
- if (hasTagName(SVGNames::animateTag) || hasTagName(SVGNames::animateColorTag)) {
- AnimatedPropertyType attributeType = toSVGAnimateElement(this)->determineAnimatedPropertyType(targetElement());
- // Fall back to discrete animations for Strings.
- if (attributeType == AnimatedBoolean
- || attributeType == AnimatedEnumeration
- || attributeType == AnimatedPreserveAspectRatio
- || attributeType == AnimatedString)
- calcMode = CalcModeDiscrete;
+ if (is<SVGAnimateElement>(*this) || is<SVGAnimateColorElement>(*this)) {
+ ASSERT(targetElement());
+ AnimatedPropertyType type = downcast<SVGAnimateElementBase>(*this).determineAnimatedPropertyType(*targetElement());
+ if (type == AnimatedBoolean || type == AnimatedEnumeration || type == AnimatedPreserveAspectRatio || type == AnimatedString)
+ calcMode = CalcMode::Discrete;
}
- if (!m_keyPoints.isEmpty() && calcMode != CalcModePaced)
+ if (!m_keyPoints.isEmpty() && calcMode != CalcMode::Paced)
return currentValuesFromKeyPoints(percent, effectivePercent, from, to);
unsigned keyTimesCount = m_keyTimes.size();
@@ -513,7 +506,7 @@ void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float&
ASSERT(!keyTimesCount || (keyTimesCount > 1 && !m_keyTimes[0]));
unsigned index = calculateKeyTimesIndex(percent);
- if (calcMode == CalcModeDiscrete) {
+ if (calcMode == CalcMode::Discrete) {
if (!keyTimesCount)
index = static_cast<unsigned>(percent * valuesCount);
from = m_values[index];
@@ -540,7 +533,7 @@ void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float&
ASSERT_WITH_SECURITY_IMPLICATION(toPercent > fromPercent);
effectivePercent = (percent - fromPercent) / (toPercent - fromPercent);
- if (calcMode == CalcModeSpline) {
+ if (calcMode == CalcMode::Spline) {
ASSERT(m_keySplines.size() == m_values.size() - 1);
effectivePercent = calculatePercentForSpline(effectivePercent, index);
}
@@ -554,17 +547,17 @@ void SVGAnimationElement::startedActiveInterval()
return;
// These validations are appropriate for all animation modes.
- if (fastHasAttribute(SVGNames::keyPointsAttr) && m_keyPoints.size() != m_keyTimes.size())
+ if (hasAttributeWithoutSynchronization(SVGNames::keyPointsAttr) && m_keyPoints.size() != m_keyTimes.size())
return;
AnimationMode animationMode = this->animationMode();
CalcMode calcMode = this->calcMode();
- if (calcMode == CalcModeSpline) {
+ if (calcMode == CalcMode::Spline) {
unsigned splinesCount = m_keySplines.size();
if (!splinesCount
- || (fastHasAttribute(SVGNames::keyPointsAttr) && m_keyPoints.size() - 1 != splinesCount)
+ || (hasAttributeWithoutSynchronization(SVGNames::keyPointsAttr) && m_keyPoints.size() - 1 != splinesCount)
|| (animationMode == ValuesAnimation && m_values.size() - 1 != splinesCount)
- || (fastHasAttribute(SVGNames::keyTimesAttr) && m_keyTimes.size() - 1 != splinesCount))
+ || (hasAttributeWithoutSynchronization(SVGNames::keyTimesAttr) && m_keyTimes.size() - 1 != splinesCount))
return;
}
@@ -573,6 +566,9 @@ void SVGAnimationElement::startedActiveInterval()
String by = byValue();
if (animationMode == NoAnimation)
return;
+ if ((animationMode == FromToAnimation || animationMode == FromByAnimation || animationMode == ToAnimation || animationMode == ByAnimation)
+ && (hasAttributeWithoutSynchronization(SVGNames::keyPointsAttr) && hasAttributeWithoutSynchronization(SVGNames::keyTimesAttr) && (m_keyTimes.size() < 2 || m_keyTimes.size() != m_keyPoints.size())))
+ return;
if (animationMode == FromToAnimation)
m_animationValid = calculateFromAndToValues(from, to);
else if (animationMode == ToAnimation) {
@@ -585,16 +581,16 @@ void SVGAnimationElement::startedActiveInterval()
m_animationValid = calculateFromAndByValues(emptyString(), by);
else if (animationMode == ValuesAnimation) {
m_animationValid = m_values.size() >= 1
- && (calcMode == CalcModePaced || !fastHasAttribute(SVGNames::keyTimesAttr) || fastHasAttribute(SVGNames::keyPointsAttr) || (m_values.size() == m_keyTimes.size()))
- && (calcMode == CalcModeDiscrete || !m_keyTimes.size() || m_keyTimes.last() == 1)
- && (calcMode != CalcModeSpline || ((m_keySplines.size() && (m_keySplines.size() == m_values.size() - 1)) || m_keySplines.size() == m_keyPoints.size() - 1))
- && (!fastHasAttribute(SVGNames::keyPointsAttr) || (m_keyTimes.size() > 1 && m_keyTimes.size() == m_keyPoints.size()));
+ && (calcMode == CalcMode::Paced || !hasAttributeWithoutSynchronization(SVGNames::keyTimesAttr) || hasAttributeWithoutSynchronization(SVGNames::keyPointsAttr) || (m_values.size() == m_keyTimes.size()))
+ && (calcMode == CalcMode::Discrete || !m_keyTimes.size() || m_keyTimes.last() == 1)
+ && (calcMode != CalcMode::Spline || ((m_keySplines.size() && (m_keySplines.size() == m_values.size() - 1)) || m_keySplines.size() == m_keyPoints.size() - 1))
+ && (!hasAttributeWithoutSynchronization(SVGNames::keyPointsAttr) || (m_keyTimes.size() > 1 && m_keyTimes.size() == m_keyPoints.size()));
if (m_animationValid)
m_animationValid = calculateToAtEndOfDurationValue(m_values.last());
- if (calcMode == CalcModePaced && m_animationValid)
+ if (calcMode == CalcMode::Paced && m_animationValid)
calculateKeyTimesForCalcModePaced();
} else if (animationMode == PathAnimation)
- m_animationValid = calcMode == CalcModePaced || !fastHasAttribute(SVGNames::keyPointsAttr) || (m_keyTimes.size() > 1 && m_keyTimes.size() == m_keyPoints.size());
+ m_animationValid = calcMode == CalcMode::Paced || !hasAttributeWithoutSynchronization(SVGNames::keyPointsAttr) || (m_keyTimes.size() > 1 && m_keyTimes.size() == m_keyPoints.size());
}
void SVGAnimationElement::updateAnimation(float percent, unsigned repeatCount, SVGSMILElement* resultElement)
@@ -616,9 +612,9 @@ void SVGAnimationElement::updateAnimation(float percent, unsigned repeatCount, S
m_lastValuesAnimationFrom = from;
m_lastValuesAnimationTo = to;
}
- } else if (!m_keyPoints.isEmpty() && calcMode != CalcModePaced)
+ } else if (!m_keyPoints.isEmpty() && calcMode != CalcMode::Paced)
effectivePercent = calculatePercentFromKeyPoints(percent);
- else if (m_keyPoints.isEmpty() && calcMode == CalcModeSpline && m_keyTimes.size() > 1)
+ else if (m_keyPoints.isEmpty() && calcMode == CalcMode::Spline && m_keyTimes.size() > 1)
effectivePercent = calculatePercentForSpline(percent, calculateKeyTimesIndex(percent));
else if (animationMode == FromToAnimation || animationMode == ToAnimation)
effectivePercent = calculatePercentForFromTo(percent);
@@ -649,13 +645,13 @@ void SVGAnimationElement::adjustForInheritance(SVGElement* targetElement, const
if (!parent || !parent->isSVGElement())
return;
- SVGElement* svgParent = toSVGElement(parent);
- computeCSSPropertyValue(svgParent, cssPropertyID(attributeName.localName()), value);
+ SVGElement& svgParent = downcast<SVGElement>(*parent);
+ computeCSSPropertyValue(&svgParent, cssPropertyID(attributeName.localName()), value);
}
static bool inheritsFromProperty(SVGElement*, const QualifiedName& attributeName, const String& value)
{
- DEFINE_STATIC_LOCAL(const AtomicString, inherit, ("inherit", AtomicString::ConstructFromLiteral));
+ static NeverDestroyed<const AtomicString> inherit("inherit", AtomicString::ConstructFromLiteral);
if (value.isEmpty() || value != inherit)
return false;
@@ -673,6 +669,11 @@ void SVGAnimationElement::determinePropertyValueTypes(const String& from, const
if (inheritsFromProperty(targetElement, attributeName, to))
m_toPropertyValueType = InheritValue;
}
+void SVGAnimationElement::resetAnimatedPropertyType()
+{
+ m_lastValuesAnimationFrom = String();
+ m_lastValuesAnimationTo = String();
+}
void SVGAnimationElement::setTargetElement(SVGElement* target)
{
@@ -680,17 +681,24 @@ void SVGAnimationElement::setTargetElement(SVGElement* target)
checkInvalidCSSAttributeType(target);
}
-void SVGAnimationElement::setAttributeName(const QualifiedName& attributeName)
+void SVGAnimationElement::checkInvalidCSSAttributeType(SVGElement* target)
{
- SVGSMILElement::setAttributeName(attributeName);
- checkInvalidCSSAttributeType(targetElement());
+ m_hasInvalidCSSAttributeType = target && hasValidAttributeName() && attributeType() == AttributeType::CSS && !isTargetAttributeCSSProperty(target, attributeName());
}
-void SVGAnimationElement::checkInvalidCSSAttributeType(SVGElement* target)
+Ref<SVGStringList> SVGAnimationElement::requiredFeatures()
{
- m_hasInvalidCSSAttributeType = target && hasValidAttributeName() && attributeType() == AttributeTypeCSS && !isTargetAttributeCSSProperty(target, attributeName());
+ return SVGTests::requiredFeatures(*this);
}
+Ref<SVGStringList> SVGAnimationElement::requiredExtensions()
+{
+ return SVGTests::requiredExtensions(*this);
}
-#endif // ENABLE(SVG)
+Ref<SVGStringList> SVGAnimationElement::systemLanguage()
+{
+ return SVGTests::systemLanguage(*this);
+}
+
+}