Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(688)

Unified Diff: third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp

Issue 2595393002: Fold SVGAnimatedTypeAnimator into SVGAnimateElement (Closed)
Patch Set: More ASSERT to DCHECK Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp
diff --git a/third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp b/third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp
index 67e710b6f227f0a0e333521b3583384e95d910cb..ee425ba764a2deff0e630de1dccfb53d2b05cb4f 100644
--- a/third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp
@@ -27,6 +27,12 @@
#include "core/dom/Document.h"
#include "core/dom/QualifiedName.h"
#include "core/dom/StyleChangeReason.h"
+#include "core/svg/SVGAnimatedColor.h"
+#include "core/svg/SVGLength.h"
+#include "core/svg/SVGLengthList.h"
+#include "core/svg/SVGNumber.h"
+#include "core/svg/SVGString.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
#include "core/svg/properties/SVGProperty.h"
namespace blink {
@@ -68,7 +74,8 @@ AnimatedPropertyValueType propertyValueType(const QualifiedName& attributeName,
SVGAnimateElement::SVGAnimateElement(const QualifiedName& tagName,
Document& document)
: SVGAnimationElement(tagName, document),
- m_animator(this),
+ m_type(AnimatedUnknown),
+ m_cssPropertyId(CSSPropertyInvalid),
m_fromPropertyValueType(RegularPropertyValue),
m_toPropertyValueType(RegularPropertyValue),
m_attributeType(AttributeTypeAuto),
@@ -120,12 +127,40 @@ void SVGAnimateElement::svgAttributeChanged(const QualifiedName& attrName) {
SVGAnimationElement::svgAttributeChanged(attrName);
}
+void SVGAnimateElement::resolveTargetProperty() {
+ DCHECK(targetElement());
+ m_targetProperty = targetElement()->propertyFromAttribute(attributeName());
+ if (m_targetProperty) {
+ m_type = m_targetProperty->type();
+ m_cssPropertyId = m_targetProperty->cssPropertyId();
+
+ // Only <animateTransform> is allowed to animate AnimatedTransformList.
+ // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties
+ if (m_type == AnimatedTransformList) {
+ m_type = AnimatedUnknown;
+ m_cssPropertyId = CSSPropertyInvalid;
+ }
+ } else {
+ m_type = SVGElement::animatedPropertyTypeForCSSAttribute(attributeName());
+ m_cssPropertyId = m_type != AnimatedUnknown
+ ? cssPropertyID(attributeName().localName())
+ : CSSPropertyInvalid;
+ }
+ DCHECK(m_type != AnimatedPoint && m_type != AnimatedStringList &&
+ m_type != AnimatedTransform && m_type != AnimatedTransformList);
+}
+
+void SVGAnimateElement::clearTargetProperty() {
+ m_targetProperty = nullptr;
+ m_type = AnimatedUnknown;
+ m_cssPropertyId = CSSPropertyInvalid;
+}
+
AnimatedPropertyType SVGAnimateElement::animatedPropertyType() {
if (!targetElement())
return AnimatedUnknown;
-
- m_animator.reset(*targetElement());
- return m_animator.type();
+ resolveTargetProperty();
+ return m_type;
}
bool SVGAnimateElement::hasValidTarget() {
@@ -160,6 +195,81 @@ bool SVGAnimateElement::shouldApplyAnimation(
return getAttributeType() != AttributeTypeCSS;
}
+SVGPropertyBase* SVGAnimateElement::createPropertyForAttributeAnimation(
+ const String& value) const {
+ // SVG DOM animVal animation code-path.
+ // TransformList must be animated via <animateTransform>, and its
+ // {from,by,to} attribute values needs to be parsed w.r.t. its "type"
+ // attribute. Spec:
+ // http://www.w3.org/TR/SVG/single-page.html#animate-AnimateTransformElement
+ DCHECK_NE(m_type, AnimatedTransformList);
+ DCHECK(m_targetProperty);
+ return m_targetProperty->currentValueBase()->cloneForAnimation(value);
+}
+
+SVGPropertyBase* SVGAnimateElement::createPropertyForCSSAnimation(
+ const String& value) const {
+ // CSS properties animation code-path.
+ // Create a basic instance of the corresponding SVG property.
+ // The instance will not have full context info. (e.g. SVGLengthMode)
+ switch (m_type) {
+ case AnimatedColor:
+ return SVGColorProperty::create(value);
+ case AnimatedNumber: {
+ SVGNumber* property = SVGNumber::create();
+ property->setValueAsString(value);
+ return property;
+ }
+ case AnimatedLength: {
+ SVGLength* property = SVGLength::create();
+ property->setValueAsString(value);
+ return property;
+ }
+ case AnimatedLengthList: {
+ SVGLengthList* property = SVGLengthList::create();
+ property->setValueAsString(value);
+ return property;
+ }
+ case AnimatedString: {
+ SVGString* property = SVGString::create();
+ property->setValueAsString(value);
+ return property;
+ }
+ // These types don't appear in the table in
+ // SVGElement::animatedPropertyTypeForCSSAttribute() and thus don't need
+ // support.
+ case AnimatedAngle:
+ case AnimatedBoolean:
+ case AnimatedEnumeration:
+ case AnimatedInteger:
+ case AnimatedIntegerOptionalInteger:
+ case AnimatedNumberList:
+ case AnimatedNumberOptionalNumber:
+ case AnimatedPath:
+ case AnimatedPoint:
+ case AnimatedPoints:
+ case AnimatedPreserveAspectRatio:
+ case AnimatedRect:
+ case AnimatedStringList:
+ case AnimatedTransform:
+ case AnimatedTransformList:
+ case AnimatedUnknown:
+ break;
+ default:
+ break;
+ }
+ NOTREACHED();
+ return nullptr;
+}
+
+SVGPropertyBase* SVGAnimateElement::createPropertyForAnimation(
+ const String& value) const {
+ if (isAnimatingSVGDom())
+ return createPropertyForAttributeAnimation(value);
+ DCHECK(isAnimatingCSSProperty());
+ return createPropertyForCSSAnimation(value);
+}
+
SVGPropertyBase* SVGAnimateElement::adjustForInheritance(
SVGPropertyBase* propertyValue,
AnimatedPropertyValueType valueType) const {
@@ -174,8 +284,8 @@ SVGPropertyBase* SVGAnimateElement::adjustForInheritance(
return propertyValue;
SVGElement* svgParent = toSVGElement(parent);
// Replace 'inherit' by its computed property value.
- String value = computeCSSPropertyValue(svgParent, m_animator.cssProperty());
- return m_animator.createPropertyForAnimation(value);
+ String value = computeCSSPropertyValue(svgParent, m_cssPropertyId);
+ return createPropertyForAnimation(value);
}
void SVGAnimateElement::calculateAnimatedValue(float percentage,
@@ -186,19 +296,17 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage,
if (!isSVGAnimateElement(*resultElement))
return;
- ASSERT(percentage >= 0 && percentage <= 1);
- ASSERT(animatedPropertyType() != AnimatedTransformList ||
- isSVGAnimateTransformElement(*this));
- ASSERT(animatedPropertyType() != AnimatedUnknown);
- ASSERT(m_fromProperty);
- ASSERT(m_fromProperty->type() == animatedPropertyType());
- ASSERT(m_toProperty);
+ DCHECK(percentage >= 0 && percentage <= 1);
+ DCHECK_NE(animatedPropertyType(), AnimatedUnknown);
+ DCHECK(m_fromProperty);
+ DCHECK_EQ(m_fromProperty->type(), animatedPropertyType());
+ DCHECK(m_toProperty);
SVGAnimateElement* resultAnimationElement =
toSVGAnimateElement(resultElement);
- ASSERT(resultAnimationElement->m_animatedProperty);
- ASSERT(resultAnimationElement->animatedPropertyType() ==
- animatedPropertyType());
+ DCHECK(resultAnimationElement->m_animatedValue);
+ DCHECK_EQ(resultAnimationElement->animatedPropertyType(),
+ animatedPropertyType());
if (isSVGSetElement(*this))
percentage = 1;
@@ -211,7 +319,7 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage,
// Values-animation accumulates using the last values entry corresponding to
// the end of duration time.
- SVGPropertyBase* animatedValue = resultAnimationElement->m_animatedProperty;
+ SVGPropertyBase* animatedValue = resultAnimationElement->m_animatedValue;
SVGPropertyBase* toAtEndOfDurationValue =
m_toAtEndOfDurationProperty ? m_toAtEndOfDurationProperty : m_toProperty;
SVGPropertyBase* fromValue =
@@ -232,16 +340,16 @@ bool SVGAnimateElement::calculateToAtEndOfDurationValue(
if (toAtEndOfDurationString.isEmpty())
return false;
m_toAtEndOfDurationProperty =
- m_animator.createPropertyForAnimation(toAtEndOfDurationString);
+ createPropertyForAnimation(toAtEndOfDurationString);
return true;
}
bool SVGAnimateElement::calculateFromAndToValues(const String& fromString,
const String& toString) {
DCHECK(targetElement());
- m_fromProperty = m_animator.createPropertyForAnimation(fromString);
+ m_fromProperty = createPropertyForAnimation(fromString);
m_fromPropertyValueType = propertyValueType(attributeName(), fromString);
- m_toProperty = m_animator.createPropertyForAnimation(toString);
+ m_toProperty = createPropertyForAnimation(toString);
m_toPropertyValueType = propertyValueType(attributeName(), toString);
return true;
}
@@ -261,41 +369,41 @@ bool SVGAnimateElement::calculateFromAndByValues(const String& fromString,
DCHECK(!isSVGSetElement(*this));
- m_fromProperty = m_animator.createPropertyForAnimation(fromString);
+ m_fromProperty = createPropertyForAnimation(fromString);
m_fromPropertyValueType = propertyValueType(attributeName(), fromString);
- m_toProperty = m_animator.createPropertyForAnimation(byString);
+ m_toProperty = createPropertyForAnimation(byString);
m_toPropertyValueType = propertyValueType(attributeName(), byString);
m_toProperty->add(m_fromProperty, targetElement());
return true;
}
void SVGAnimateElement::resetAnimatedType() {
+ resolveTargetProperty();
+
SVGElement* targetElement = this->targetElement();
const QualifiedName& attributeName = this->attributeName();
- m_animator.reset(*targetElement);
-
if (!shouldApplyAnimation(*targetElement, attributeName))
return;
- if (m_animator.isAnimatingSVGDom()) {
+ if (isAnimatingSVGDom()) {
// SVG DOM animVal animation code-path.
- m_animatedProperty = m_animator.createAnimatedValue();
- targetElement->setAnimatedAttribute(attributeName, m_animatedProperty);
+ m_animatedValue = m_targetProperty->createAnimatedValue();
+ DCHECK_EQ(m_animatedValue->type(), m_type);
+ targetElement->setAnimatedAttribute(attributeName, m_animatedValue);
return;
}
- DCHECK(m_animator.isAnimatingCSSProperty());
+ DCHECK(isAnimatingCSSProperty());
// Presentation attributes which has an SVG DOM representation should use the
// "SVG DOM" code-path (above.)
DCHECK(SVGElement::isAnimatableCSSProperty(attributeName));
// CSS properties animation code-path.
- String baseValue =
- computeCSSPropertyValue(targetElement, m_animator.cssProperty());
- m_animatedProperty = m_animator.createPropertyForAnimation(baseValue);
+ String baseValue = computeCSSPropertyValue(targetElement, m_cssPropertyId);
+ m_animatedValue = createPropertyForAnimation(baseValue);
}
void SVGAnimateElement::clearAnimatedType() {
- if (!m_animatedProperty)
+ if (!m_animatedValue)
return;
// The animated property lock is held for the "result animation" (see
@@ -306,42 +414,40 @@ void SVGAnimateElement::clearAnimatedType() {
SVGElement* targetElement = this->targetElement();
if (!targetElement) {
- m_animatedProperty.clear();
+ m_animatedValue.clear();
return;
}
bool shouldApply = shouldApplyAnimation(*targetElement, attributeName());
- if (m_animator.isAnimatingCSSProperty()) {
+ if (isAnimatingCSSProperty()) {
// CSS properties animation code-path.
if (shouldApply) {
MutableStylePropertySet* propertySet =
targetElement->ensureAnimatedSMILStyleProperties();
- if (propertySet->removeProperty(m_animator.cssProperty())) {
+ if (propertySet->removeProperty(m_cssPropertyId)) {
targetElement->setNeedsStyleRecalc(
LocalStyleChange,
StyleChangeReasonForTracing::create(StyleChangeReason::Animation));
}
}
}
- if (m_animator.isAnimatingSVGDom()) {
+ if (isAnimatingSVGDom()) {
// SVG DOM animVal animation code-path.
targetElement->clearAnimatedAttribute(attributeName());
if (shouldApply)
targetElement->invalidateAnimatedAttribute(attributeName());
}
- m_animatedProperty.clear();
- m_animator.clear();
+ m_animatedValue.clear();
+ clearTargetProperty();
}
void SVGAnimateElement::applyResultsToTarget() {
- ASSERT(animatedPropertyType() != AnimatedTransformList ||
- isSVGAnimateTransformElement(*this));
- ASSERT(animatedPropertyType() != AnimatedUnknown);
+ DCHECK_NE(animatedPropertyType(), AnimatedUnknown);
// Early exit if our animated type got destructed by a previous
// endedActiveInterval().
- if (!m_animatedProperty)
+ if (!m_animatedValue)
return;
if (!shouldApplyAnimation(*targetElement(), attributeName()))
@@ -349,22 +455,22 @@ void SVGAnimateElement::applyResultsToTarget() {
// We do update the style and the animation property independent of each
// other.
- if (m_animator.isAnimatingCSSProperty()) {
+ if (isAnimatingCSSProperty()) {
// CSS properties animation code-path.
// Convert the result of the animation to a String and apply it as CSS
// property on the target.
MutableStylePropertySet* propertySet =
targetElement()->ensureAnimatedSMILStyleProperties();
if (propertySet
- ->setProperty(m_animator.cssProperty(),
- m_animatedProperty->valueAsString(), false, 0)
+ ->setProperty(m_cssPropertyId, m_animatedValue->valueAsString(),
+ false, 0)
.didChange) {
targetElement()->setNeedsStyleRecalc(
LocalStyleChange,
StyleChangeReasonForTracing::create(StyleChangeReason::Animation));
}
}
- if (m_animator.isAnimatingSVGDom()) {
+ if (isAnimatingSVGDom()) {
// SVG DOM animVal animation code-path.
// At this point the SVG DOM values are already changed, unlike for CSS.
// We only have to trigger update notifications here.
@@ -401,9 +507,8 @@ float SVGAnimateElement::calculateDistance(const String& fromString,
DCHECK(targetElement());
// FIXME: A return value of float is not enough to support paced animations on
// lists.
- SVGPropertyBase* fromValue =
- m_animator.createPropertyForAnimation(fromString);
- SVGPropertyBase* toValue = m_animator.createPropertyForAnimation(toString);
+ SVGPropertyBase* fromValue = createPropertyForAnimation(fromString);
+ SVGPropertyBase* toValue = createPropertyForAnimation(toString);
return fromValue->calculateDistance(toValue, targetElement());
}
@@ -451,19 +556,19 @@ void SVGAnimateElement::checkInvalidCSSAttributeType() {
}
void SVGAnimateElement::resetAnimatedPropertyType() {
- ASSERT(!m_animatedProperty);
+ DCHECK(!m_animatedValue);
m_fromProperty.clear();
m_toProperty.clear();
m_toAtEndOfDurationProperty.clear();
- m_animator.clear();
+ clearTargetProperty();
}
DEFINE_TRACE(SVGAnimateElement) {
visitor->trace(m_fromProperty);
visitor->trace(m_toProperty);
visitor->trace(m_toAtEndOfDurationProperty);
- visitor->trace(m_animatedProperty);
- visitor->trace(m_animator);
+ visitor->trace(m_animatedValue);
+ visitor->trace(m_targetProperty);
SVGAnimationElement::trace(visitor);
}

Powered by Google App Engine
This is Rietveld 408576698