summaryrefslogtreecommitdiff
path: root/Source/WebCore/svg/SVGAnimationElement.cpp
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@qt.io>2017-05-30 12:48:17 +0200
committerOswald Buddenhagen <oswald.buddenhagen@qt.io>2017-05-30 12:48:17 +0200
commit881da28418d380042aa95a97f0cbd42560a64f7c (patch)
treea794dff3274695e99c651902dde93d934ea7a5af /Source/WebCore/svg/SVGAnimationElement.cpp
parent7e104c57a70fdf551bb3d22a5d637cdcbc69dbea (diff)
parent0fcedcd17cc00d3dd44c718b3cb36c1033319671 (diff)
downloadqtwebkit-881da28418d380042aa95a97f0cbd42560a64f7c.tar.gz
Merge 'wip/next' into dev
Change-Id: Iff9ee5e23bb326c4371ec8ed81d56f2f05d680e9
Diffstat (limited to 'Source/WebCore/svg/SVGAnimationElement.cpp')
-rw-r--r--Source/WebCore/svg/SVGAnimationElement.cpp142
1 files changed, 66 insertions, 76 deletions
diff --git a/Source/WebCore/svg/SVGAnimationElement.cpp b/Source/WebCore/svg/SVGAnimationElement.cpp
index 993f950c1..eb1243e9f 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,11 +24,8 @@
*/
#include "config.h"
-
-#if ENABLE(SVG)
#include "SVGAnimationElement.h"
-#include "Attribute.h"
#include "CSSComputedStyleDeclaration.h"
#include "CSSParser.h"
#include "CSSPropertyNames.h"
@@ -35,11 +33,12 @@
#include "FloatConversion.h"
#include "RenderObject.h"
#include "SVGAnimateElement.h"
-#include "SVGElementInstance.h"
+#include "SVGElement.h"
#include "SVGNames.h"
#include "SVGParserUtilities.h"
-#include "SVGStyledElement.h"
#include <wtf/MathExtras.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/text/StringView.h>
namespace WebCore {
@@ -51,7 +50,7 @@ BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGAnimationElement)
REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTests)
END_REGISTER_ANIMATED_PROPERTIES
-SVGAnimationElement::SVGAnimationElement(const QualifiedName& tagName, Document* document)
+SVGAnimationElement::SVGAnimationElement(const QualifiedName& tagName, Document& document)
: SVGSMILElement(tagName, document)
, m_fromPropertyValueType(RegularPropertyValue)
, m_toPropertyValueType(RegularPropertyValue)
@@ -94,7 +93,9 @@ static void parseKeySplines(const String& parse, Vector<UnitBezier>& result)
result.clear();
if (parse.isEmpty())
return;
- const UChar* cur = parse.characters();
+
+ auto upconvertedCharacters = StringView(parse).upconvertedCharacters();
+ const UChar* cur = upconvertedCharacters;
const UChar* end = cur + parse.length();
skipOptionalSVGSpaces(cur, end);
@@ -142,37 +143,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 +208,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)
@@ -293,10 +286,10 @@ 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);
else if (calcMode == linear)
@@ -311,8 +304,8 @@ void SVGAnimationElement::setCalcMode(const AtomicString& calcMode)
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;
else if (attributeType == xml)
@@ -339,25 +332,25 @@ String SVGAnimationElement::fromValue() const
bool SVGAnimationElement::isAdditive() const
{
- DEFINE_STATIC_LOCAL(const AtomicString, sum, ("sum", AtomicString::ConstructFromLiteral));
+ static NeverDestroyed<const AtomicString> sum("sum", AtomicString::ConstructFromLiteral);
const AtomicString& value = fastGetAttribute(SVGNames::additiveAttr);
return value == sum || animationMode() == ByAnimation;
}
bool SVGAnimationElement::isAccumulated() const
{
- DEFINE_STATIC_LOCAL(const AtomicString, sum, ("sum", AtomicString::ConstructFromLiteral));
+ static NeverDestroyed<const AtomicString> sum("sum", AtomicString::ConstructFromLiteral);
const AtomicString& value = fastGetAttribute(SVGNames::accumulateAttr);
return value == sum && animationMode() != ToAnimation;
}
-bool SVGAnimationElement::isTargetAttributeCSSProperty(SVGElement* targetElement, const QualifiedName& attributeName)
+bool SVGAnimationElement::isTargetAttributeCSSProperty(SVGElement* element, const QualifiedName& attributeName)
{
- ASSERT(targetElement);
- if (!targetElement->isSVGStyledElement())
+ if (element->isTextContent()
+ && (attributeName == SVGNames::xAttr || attributeName == SVGNames::yAttr))
return false;
- return SVGStyledElement::isAnimatableCSSProperty(attributeName);
+ return SVGElement::isAnimatableCSSProperty(attributeName);
}
SVGAnimationElement::ShouldApplyAnimation SVGAnimationElement::shouldApplyAnimation(SVGElement* targetElement, const QualifiedName& attributeName)
@@ -366,8 +359,12 @@ 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)
@@ -500,14 +497,10 @@ void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float&
}
CalcMode calcMode = this->calcMode();
- if (hasTagName(SVGNames::animateTag) || hasTagName(SVGNames::animateColorTag)) {
- SVGAnimateElement* animateElement = static_cast<SVGAnimateElement*>(this);
- AnimatedPropertyType attributeType = animateElement->determineAnimatedPropertyType(targetElement());
- // Fall back to discrete animations for Strings.
- if (attributeType == AnimatedBoolean
- || attributeType == AnimatedEnumeration
- || attributeType == AnimatedPreserveAspectRatio
- || attributeType == AnimatedString)
+ 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 = CalcModeDiscrete;
}
if (!m_keyPoints.isEmpty() && calcMode != CalcModePaced)
@@ -542,7 +535,7 @@ void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float&
--index;
from = m_values[index];
to = m_values[index + 1];
- ASSERT(toPercent > fromPercent);
+ ASSERT_WITH_SECURITY_IMPLICATION(toPercent > fromPercent);
effectivePercent = (percent - fromPercent) / (toPercent - fromPercent);
if (calcMode == CalcModeSpline) {
@@ -565,10 +558,11 @@ void SVGAnimationElement::startedActiveInterval()
AnimationMode animationMode = this->animationMode();
CalcMode calcMode = this->calcMode();
if (calcMode == CalcModeSpline) {
- unsigned splinesCount = m_keySplines.size() + 1;
- if ((fastHasAttribute(SVGNames::keyPointsAttr) && m_keyPoints.size() != splinesCount)
- || (animationMode == ValuesAnimation && m_values.size() != splinesCount)
- || (fastHasAttribute(SVGNames::keyTimesAttr) && m_keyTimes.size() != splinesCount))
+ unsigned splinesCount = m_keySplines.size();
+ if (!splinesCount
+ || (fastHasAttribute(SVGNames::keyPointsAttr) && m_keyPoints.size() - 1 != splinesCount)
+ || (animationMode == ValuesAnimation && m_values.size() - 1 != splinesCount)
+ || (fastHasAttribute(SVGNames::keyTimesAttr) && m_keyTimes.size() - 1 != splinesCount))
return;
}
@@ -577,6 +571,9 @@ void SVGAnimationElement::startedActiveInterval()
String by = byValue();
if (animationMode == NoAnimation)
return;
+ if ((animationMode == FromToAnimation || animationMode == FromByAnimation || animationMode == ToAnimation || animationMode == ByAnimation)
+ && (fastHasAttribute(SVGNames::keyPointsAttr) && fastHasAttribute(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) {
@@ -635,7 +632,6 @@ void SVGAnimationElement::updateAnimation(float percent, unsigned repeatCount, S
void SVGAnimationElement::computeCSSPropertyValue(SVGElement* element, CSSPropertyID id, String& valueString)
{
ASSERT(element);
- ASSERT(element->isSVGStyledElement());
// Don't include any properties resulting from CSS Transitions/Animations or SMIL animations, as we want to retrieve the "base value".
element->setUseOverrideComputedStyle(true);
@@ -654,20 +650,17 @@ void SVGAnimationElement::adjustForInheritance(SVGElement* targetElement, const
if (!parent || !parent->isSVGElement())
return;
- SVGElement* svgParent = toSVGElement(parent);
- if (!svgParent->isSVGStyledElement())
- return;
- computeCSSPropertyValue(svgParent, cssPropertyID(attributeName.localName()), value);
+ SVGElement& svgParent = downcast<SVGElement>(*parent);
+ computeCSSPropertyValue(&svgParent, cssPropertyID(attributeName.localName()), value);
}
-static bool inheritsFromProperty(SVGElement* targetElement, const QualifiedName& attributeName, const String& value)
+static bool inheritsFromProperty(SVGElement*, const QualifiedName& attributeName, const String& value)
{
- ASSERT(targetElement);
- DEFINE_STATIC_LOCAL(const AtomicString, inherit, ("inherit", AtomicString::ConstructFromLiteral));
+ static NeverDestroyed<const AtomicString> inherit("inherit", AtomicString::ConstructFromLiteral);
- if (value.isEmpty() || value != inherit || !targetElement->isSVGStyledElement())
+ if (value.isEmpty() || value != inherit)
return false;
- return SVGStyledElement::isAnimatableCSSProperty(attributeName);
+ return SVGElement::isAnimatableCSSProperty(attributeName);
}
void SVGAnimationElement::determinePropertyValueTypes(const String& from, const String& to)
@@ -681,6 +674,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)
{
@@ -688,17 +686,9 @@ void SVGAnimationElement::setTargetElement(SVGElement* target)
checkInvalidCSSAttributeType(target);
}
-void SVGAnimationElement::setAttributeName(const QualifiedName& attributeName)
-{
- SVGSMILElement::setAttributeName(attributeName);
- checkInvalidCSSAttributeType(targetElement());
-}
-
void SVGAnimationElement::checkInvalidCSSAttributeType(SVGElement* target)
{
m_hasInvalidCSSAttributeType = target && hasValidAttributeName() && attributeType() == AttributeTypeCSS && !isTargetAttributeCSSProperty(target, attributeName());
}
}
-
-#endif // ENABLE(SVG)