| 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 3889eeab57bbe6c6b7334b718a19fa38f0140775..6a34ed5ed3b7f5a5d35a81febae89e9899359206 100644
|
| --- a/third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp
|
| +++ b/third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp
|
| @@ -23,18 +23,49 @@
|
| #include "core/svg/SVGAnimateElement.h"
|
|
|
| #include "core/CSSPropertyNames.h"
|
| +#include "core/css/CSSComputedStyleDeclaration.h"
|
| #include "core/css/StylePropertySet.h"
|
| #include "core/dom/Document.h"
|
| #include "core/dom/QualifiedName.h"
|
| #include "core/dom/StyleChangeReason.h"
|
| -#include "core/svg/SVGAnimatedTypeAnimator.h"
|
| #include "core/svg/properties/SVGProperty.h"
|
|
|
| namespace blink {
|
|
|
| +namespace {
|
| +
|
| +String computeCSSPropertyValue(SVGElement* element, CSSPropertyID id) {
|
| + DCHECK(element);
|
| + // TODO(fs): StyleEngine doesn't support document without a frame.
|
| + // Refer to comment in Element::computedStyle.
|
| + DCHECK(element->inActiveDocument());
|
| +
|
| + // Don't include any properties resulting from CSS Transitions/Animations or
|
| + // SMIL animations, as we want to retrieve the "base value".
|
| + element->setUseOverrideComputedStyle(true);
|
| + String value =
|
| + CSSComputedStyleDeclaration::create(element)->getPropertyValue(id);
|
| + element->setUseOverrideComputedStyle(false);
|
| + return value;
|
| +}
|
| +
|
| +AnimatedPropertyValueType propertyValueType(const QualifiedName& attributeName,
|
| + const String& value) {
|
| + DEFINE_STATIC_LOCAL(const AtomicString, inherit, ("inherit"));
|
| + if (value.isEmpty() || value != inherit ||
|
| + !SVGElement::isAnimatableCSSProperty(attributeName))
|
| + return RegularPropertyValue;
|
| + return InheritValue;
|
| +}
|
| +
|
| +} // unnamed namespace
|
| +
|
| SVGAnimateElement::SVGAnimateElement(const QualifiedName& tagName,
|
| Document& document)
|
| - : SVGAnimationElement(tagName, document), m_animator(this) {}
|
| + : SVGAnimationElement(tagName, document),
|
| + m_animator(this),
|
| + m_fromPropertyValueType(RegularPropertyValue),
|
| + m_toPropertyValueType(RegularPropertyValue) {}
|
|
|
| SVGAnimateElement* SVGAnimateElement::create(Document& document) {
|
| return new SVGAnimateElement(SVGNames::animateTag, document);
|
| @@ -81,22 +112,23 @@ bool SVGAnimateElement::hasValidAttributeType() {
|
| !hasInvalidCSSAttributeType();
|
| }
|
|
|
| -namespace {
|
| -
|
| -class ParsePropertyFromString {
|
| - STACK_ALLOCATED();
|
| -
|
| - public:
|
| - explicit ParsePropertyFromString(SVGAnimatedTypeAnimator* animator)
|
| - : m_animator(animator) {}
|
| -
|
| - SVGPropertyBase* operator()(SVGAnimationElement*, const String& value) {
|
| - return m_animator->createPropertyForAnimation(value);
|
| - }
|
| -
|
| - private:
|
| - SVGAnimatedTypeAnimator* m_animator;
|
| -};
|
| +SVGPropertyBase* SVGAnimateElement::adjustForInheritance(
|
| + SVGPropertyBase* propertyValue,
|
| + AnimatedPropertyValueType valueType) const {
|
| + if (valueType != InheritValue)
|
| + return propertyValue;
|
| + // TODO(fs): At the moment the computed style gets returned as a String and
|
| + // needs to get parsed again. In the future we might want to work with the
|
| + // value type directly to avoid the String parsing.
|
| + DCHECK(targetElement());
|
| + Element* parent = targetElement()->parentElement();
|
| + if (!parent || !parent->isSVGElement())
|
| + return propertyValue;
|
| + SVGElement* svgParent = toSVGElement(parent);
|
| + // Replace 'inherit' by its computed property value.
|
| + String value = computeCSSPropertyValue(
|
| + svgParent, cssPropertyID(attributeName().localName()));
|
| + return m_animator.createPropertyForAnimation(value);
|
| }
|
|
|
| void SVGAnimateElement::calculateAnimatedValue(float percentage,
|
| @@ -140,12 +172,8 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage,
|
| SVGPropertyBase* toValue = m_toProperty;
|
|
|
| // Apply CSS inheritance rules.
|
| - ParsePropertyFromString parsePropertyFromString(&m_animator);
|
| - adjustForInheritance<SVGPropertyBase*, ParsePropertyFromString>(
|
| - parsePropertyFromString, fromPropertyValueType(), fromValue,
|
| - targetElement);
|
| - adjustForInheritance<SVGPropertyBase*, ParsePropertyFromString>(
|
| - parsePropertyFromString, toPropertyValueType(), toValue, targetElement);
|
| + fromValue = adjustForInheritance(fromValue, m_fromPropertyValueType);
|
| + toValue = adjustForInheritance(toValue, m_toPropertyValueType);
|
|
|
| animatedValue->calculateAnimatedValue(this, percentage, repeatCount,
|
| fromValue, toValue,
|
| @@ -167,9 +195,10 @@ bool SVGAnimateElement::calculateFromAndToValues(const String& fromString,
|
| if (!targetElement)
|
| return false;
|
|
|
| - determinePropertyValueTypes(fromString, toString);
|
| m_fromProperty = m_animator.createPropertyForAnimation(fromString);
|
| + m_fromPropertyValueType = propertyValueType(attributeName(), fromString);
|
| m_toProperty = m_animator.createPropertyForAnimation(toString);
|
| + m_toPropertyValueType = propertyValueType(attributeName(), toString);
|
| return true;
|
| }
|
|
|
| @@ -182,16 +211,18 @@ bool SVGAnimateElement::calculateFromAndByValues(const String& fromString,
|
| if (getAnimationMode() == ByAnimation && !isAdditive())
|
| return false;
|
|
|
| - // from-by animation may only be used with attributes that support addition (e.g. most numeric attributes).
|
| + // from-by animation may only be used with attributes that support addition
|
| + // (e.g. most numeric attributes).
|
| if (getAnimationMode() == FromByAnimation &&
|
| !animatedPropertyTypeSupportsAddition())
|
| return false;
|
|
|
| - ASSERT(!isSVGSetElement(*this));
|
| + DCHECK(!isSVGSetElement(*this));
|
|
|
| - determinePropertyValueTypes(fromString, byString);
|
| m_fromProperty = m_animator.createPropertyForAnimation(fromString);
|
| + m_fromPropertyValueType = propertyValueType(attributeName(), fromString);
|
| m_toProperty = m_animator.createPropertyForAnimation(byString);
|
| + m_toPropertyValueType = propertyValueType(attributeName(), byString);
|
| m_toProperty->add(m_fromProperty, targetElement);
|
| return true;
|
| }
|
| @@ -216,11 +247,9 @@ void SVGAnimateElement::resetAnimatedType() {
|
| DCHECK_EQ(shouldApply, ApplyCSSAnimation);
|
|
|
| // CSS properties animation code-path.
|
| - String baseValue;
|
| DCHECK(isTargetAttributeCSSProperty(targetElement, attributeName));
|
| - computeCSSPropertyValue(targetElement,
|
| - cssPropertyID(attributeName.localName()), baseValue);
|
| -
|
| + String baseValue = computeCSSPropertyValue(
|
| + targetElement, cssPropertyID(attributeName.localName()));
|
| m_animatedProperty = m_animator.createPropertyForAnimation(baseValue);
|
| }
|
|
|
| @@ -228,9 +257,10 @@ void SVGAnimateElement::clearAnimatedType() {
|
| if (!m_animatedProperty)
|
| return;
|
|
|
| - // The animated property lock is held for the "result animation" (see SMILTimeContainer::updateAnimations())
|
| - // while we're processing an animation group. We will very likely crash later if we clear the animated type
|
| - // while the lock is held. See crbug.com/581546.
|
| + // The animated property lock is held for the "result animation" (see
|
| + // SMILTimeContainer::updateAnimations()) while we're processing an animation
|
| + // group. We will very likely crash later if we clear the animated type while
|
| + // the lock is held. See crbug.com/581546.
|
| DCHECK(!animatedTypeIsLocked());
|
|
|
| SVGElement* targetElement = this->targetElement();
|
| @@ -269,11 +299,13 @@ void SVGAnimateElement::applyResultsToTarget() {
|
| isSVGAnimateTransformElement(*this));
|
| ASSERT(animatedPropertyType() != AnimatedUnknown);
|
|
|
| - // Early exit if our animated type got destructed by a previous endedActiveInterval().
|
| + // Early exit if our animated type got destructed by a previous
|
| + // endedActiveInterval().
|
| if (!m_animatedProperty)
|
| return;
|
|
|
| - // We do update the style and the animation property independent of each other.
|
| + // We do update the style and the animation property independent of each
|
| + // other.
|
| ShouldApplyAnimationType shouldApply =
|
| shouldApplyAnimation(targetElement(), attributeName());
|
| if (shouldApply == DontApplyAnimation)
|
| @@ -281,7 +313,8 @@ void SVGAnimateElement::applyResultsToTarget() {
|
| if (shouldApply == ApplyXMLandCSSAnimation ||
|
| m_animator.isAnimatingCSSProperty()) {
|
| // CSS properties animation code-path.
|
| - // Convert the result of the animation to a String and apply it as CSS property on the target.
|
| + // Convert the result of the animation to a String and apply it as CSS
|
| + // property on the target.
|
| CSSPropertyID id = cssPropertyID(attributeName().localName());
|
| MutableStylePropertySet* propertySet =
|
| targetElement()->ensureAnimatedSMILStyleProperties();
|
| @@ -301,7 +334,7 @@ void SVGAnimateElement::applyResultsToTarget() {
|
| }
|
|
|
| bool SVGAnimateElement::animatedPropertyTypeSupportsAddition() {
|
| - // Spec: http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties.
|
| + // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties.
|
| switch (animatedPropertyType()) {
|
| case AnimatedBoolean:
|
| case AnimatedEnumeration:
|
| @@ -326,7 +359,8 @@ bool SVGAnimateElement::isAdditive() {
|
|
|
| float SVGAnimateElement::calculateDistance(const String& fromString,
|
| const String& toString) {
|
| - // FIXME: A return value of float is not enough to support paced animations on lists.
|
| + // FIXME: A return value of float is not enough to support paced animations on
|
| + // lists.
|
| SVGElement* targetElement = this->targetElement();
|
| if (!targetElement)
|
| return -1;
|
|
|