Index: Source/core/svg/SVGAnimatedNewPropertyAnimator.cpp |
diff --git a/Source/core/svg/SVGAnimatedNewPropertyAnimator.cpp b/Source/core/svg/SVGAnimatedNewPropertyAnimator.cpp |
index 5ffcfdc43b29759c13208d99ee23daf6d965825c..12d0f522b61243986367688dd378b52e25b44b4e 100644 |
--- a/Source/core/svg/SVGAnimatedNewPropertyAnimator.cpp |
+++ b/Source/core/svg/SVGAnimatedNewPropertyAnimator.cpp |
@@ -33,18 +33,24 @@ |
#include "core/svg/SVGAnimationElement.h" |
#include "core/svg/SVGElementInstance.h" |
+#include "core/svg/SVGLength.h" |
+#include "core/svg/SVGLengthList.h" |
namespace WebCore { |
-SVGAnimatedNewPropertyAnimator::SVGAnimatedNewPropertyAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement) |
- : SVGAnimatedTypeAnimator(AnimatedNewProperty, animationElement, contextElement) |
+SVGAnimatedNewPropertyAnimator::SVGAnimatedNewPropertyAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement, AnimatedPropertyType propertyType) |
+ : SVGAnimatedTypeAnimator(propertyType, animationElement, contextElement) |
+ , m_propertyType(propertyType) |
{ |
ASSERT(m_animationElement); |
ASSERT(m_contextElement); |
const QualifiedName& attributeName = m_animationElement->attributeName(); |
m_animatedProperty = m_contextElement->propertyFromAttribute(attributeName); |
- ASSERT(m_animatedProperty); |
+ |
+ ASSERT(m_propertyType == AnimatedLength |
+ || m_propertyType == AnimatedLengthList |
+ || m_propertyType == AnimatedNewProperty); // FIXME |
} |
SVGAnimatedNewPropertyAnimator::~SVGAnimatedNewPropertyAnimator() |
@@ -53,49 +59,111 @@ SVGAnimatedNewPropertyAnimator::~SVGAnimatedNewPropertyAnimator() |
PassRefPtr<NewSVGPropertyBase> SVGAnimatedNewPropertyAnimator::createPropertyForAnimation(const String& value) |
{ |
- return m_animatedProperty->currentValueBase()->cloneForAnimation(value); |
+ if (m_animatedProperty) { |
+ // SVG DOM animVal animation code-path. |
+ return m_animatedProperty->currentValueBase()->cloneForAnimation(value); |
+ } |
+ |
+ // 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) |
+ if (m_propertyType == AnimatedLength) { |
+ RefPtr<SVGLength> property = SVGLength::create(LengthModeOther); |
+ property->setValueAsString(value, IGNORE_EXCEPTION); |
+ return property.release(); |
+ } |
+ |
+ if (m_propertyType == AnimatedLengthList) { |
+ RefPtr<SVGLengthList> property = SVGLengthList::create(LengthModeOther); |
+ property->setValueAsString(value, IGNORE_EXCEPTION); |
+ return property.release(); |
+ } |
+ |
+ ASSERT_NOT_REACHED(); |
+ return 0; |
} |
PassOwnPtr<SVGAnimatedType> SVGAnimatedNewPropertyAnimator::constructFromString(const String& value) |
{ |
- return SVGAnimatedType::createNewProperty(createPropertyForAnimation(value)); |
+ return SVGAnimatedType::createNewProperty(createPropertyForAnimation(value), m_propertyType); |
} |
-PassOwnPtr<SVGAnimatedType> SVGAnimatedNewPropertyAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList&) |
+namespace { |
+ |
+typedef void (NewSVGAnimatedPropertyBase::*NewSVGAnimatedPropertyMethod)(); |
+ |
+void invokeMethodOnAllTargetProperties(const SVGElementAnimatedPropertyList& list, const QualifiedName& attributeName, NewSVGAnimatedPropertyMethod method) |
+{ |
+ SVGElementAnimatedPropertyList::const_iterator it = list.begin(); |
+ SVGElementAnimatedPropertyList::const_iterator itEnd = list.end(); |
+ for (; it != itEnd; ++it) { |
+ RefPtr<NewSVGAnimatedPropertyBase> animatedProperty = it->element->propertyFromAttribute(attributeName); |
+ (animatedProperty.get()->*method)(); |
+ } |
+} |
+ |
+void setAnimatedValueOnAllTargetProperties(const SVGElementAnimatedPropertyList& list, const QualifiedName& attributeName, PassRefPtr<NewSVGPropertyBase> passValue) |
+{ |
+ RefPtr<NewSVGPropertyBase> value = passValue; |
+ |
+ SVGElementAnimatedPropertyList::const_iterator it = list.begin(); |
+ SVGElementAnimatedPropertyList::const_iterator itEnd = list.end(); |
+ for (; it != itEnd; ++it) { |
+ RefPtr<NewSVGAnimatedPropertyBase> animatedProperty = it->element->propertyFromAttribute(attributeName); |
+ animatedProperty->setAnimatedValue(value); |
+ } |
+} |
+ |
+} |
+ |
+PassRefPtr<NewSVGPropertyBase> SVGAnimatedNewPropertyAnimator::resetAnimation(const SVGElementAnimatedPropertyList& list) |
+{ |
+ ASSERT(m_animatedProperty); |
+ RefPtr<NewSVGPropertyBase> animatedValue = m_animatedProperty->createAnimatedValue(); |
+ setAnimatedValueOnAllTargetProperties(list, m_animatedProperty->attributeName(), animatedValue); |
+ |
+ return animatedValue.release(); |
+} |
+ |
+PassOwnPtr<SVGAnimatedType> SVGAnimatedNewPropertyAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& list) |
{ |
SVGElementInstance::InstanceUpdateBlocker blocker(m_contextElement); |
- m_animatedProperty->animationStarted(); |
- return SVGAnimatedType::createNewProperty(m_animatedProperty->currentValueBase()); |
+ ASSERT(m_animatedProperty); |
+ invokeMethodOnAllTargetProperties(list, m_animatedProperty->attributeName(), &NewSVGAnimatedPropertyBase::animationStarted); |
+ |
+ return SVGAnimatedType::createNewProperty(resetAnimation(list), m_propertyType); |
} |
-void SVGAnimatedNewPropertyAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList&) |
+void SVGAnimatedNewPropertyAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& list) |
{ |
SVGElementInstance::InstanceUpdateBlocker blocker(m_contextElement); |
- m_animatedProperty->animationEnded(); |
+ ASSERT(m_animatedProperty); |
+ invokeMethodOnAllTargetProperties(list, m_animatedProperty->attributeName(), &NewSVGAnimatedPropertyBase::animationEnded); |
} |
-void SVGAnimatedNewPropertyAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType* animated) |
+void SVGAnimatedNewPropertyAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& list, SVGAnimatedType* animated) |
{ |
SVGElementInstance::InstanceUpdateBlocker blocker(m_contextElement); |
- m_animatedProperty->resetToBaseVal(); |
- animated->newProperty() = m_animatedProperty->currentValueBase(); |
+ animated->newProperty() = resetAnimation(list); |
} |
-void SVGAnimatedNewPropertyAnimator::animValWillChange(const SVGElementAnimatedPropertyList&) |
+void SVGAnimatedNewPropertyAnimator::animValWillChange(const SVGElementAnimatedPropertyList& list) |
{ |
SVGElementInstance::InstanceUpdateBlocker blocker(m_contextElement); |
- m_animatedProperty->animValWillChange(); |
+ ASSERT(m_animatedProperty); |
+ invokeMethodOnAllTargetProperties(list, m_animatedProperty->attributeName(), &NewSVGAnimatedPropertyBase::animValWillChange); |
} |
-void SVGAnimatedNewPropertyAnimator::animValDidChange(const SVGElementAnimatedPropertyList&) |
+void SVGAnimatedNewPropertyAnimator::animValDidChange(const SVGElementAnimatedPropertyList& list) |
{ |
SVGElementInstance::InstanceUpdateBlocker blocker(m_contextElement); |
- m_animatedProperty->animValDidChange(); |
+ ASSERT(m_animatedProperty); |
+ invokeMethodOnAllTargetProperties(list, m_animatedProperty->attributeName(), &NewSVGAnimatedPropertyBase::animValDidChange); |
} |
void SVGAnimatedNewPropertyAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to) |