Title: [109358] branches/chromium/963

Diff

Copied: branches/chromium/963/LayoutTests/svg/animations/svglength-animation-retarget-crash-expected.txt (from rev 108134, trunk/LayoutTests/svg/animations/svglength-animation-retarget-crash-expected.txt) (0 => 109358)


--- branches/chromium/963/LayoutTests/svg/animations/svglength-animation-retarget-crash-expected.txt	                        (rev 0)
+++ branches/chromium/963/LayoutTests/svg/animations/svglength-animation-retarget-crash-expected.txt	2012-03-01 18:05:41 UTC (rev 109358)
@@ -0,0 +1,5 @@
+This test verifies that SVG animation targets can change during the animation.
+
+TEST PASSED
+
+

Copied: branches/chromium/963/LayoutTests/svg/animations/svglength-animation-retarget-crash.html (from rev 108134, trunk/LayoutTests/svg/animations/svglength-animation-retarget-crash.html) (0 => 109358)


--- branches/chromium/963/LayoutTests/svg/animations/svglength-animation-retarget-crash.html	                        (rev 0)
+++ branches/chromium/963/LayoutTests/svg/animations/svglength-animation-retarget-crash.html	2012-03-01 18:05:41 UTC (rev 109358)
@@ -0,0 +1,25 @@
+<p>This test verifies that SVG animation targets can change during the animation.</p>
+<p id="result"></p>
+<svg id="svg">
+    <text id="text"></text>
+    <animate xlink:href="" id="a" attributeName="y" begin="0.0" from="0" to="1" dur="1s" repeatCount="indefinite">
+</svg>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText()
+    layoutTestController.waitUntilDone()
+}
+
+setTimeout(function() {
+    text = document.getElementById('text')
+    text.id = 'not_text'
+    svg = document.getElementById('svg')
+    svg.id = 'text'
+    svg.appendChild(document.getElementById('a').cloneNode())
+    setTimeout(function() {
+      document.getElementById("result").innerText = "TEST PASSED"
+      if (window.layoutTestController)
+          layoutTestController.notifyDone()
+    }, 0)
+}, 0)
+</script>

Modified: branches/chromium/963/Source/WebCore/svg/SVGAnimateElement.cpp (109357 => 109358)


--- branches/chromium/963/Source/WebCore/svg/SVGAnimateElement.cpp	2012-03-01 17:53:00 UTC (rev 109357)
+++ branches/chromium/963/Source/WebCore/svg/SVGAnimateElement.cpp	2012-03-01 18:05:41 UTC (rev 109358)
@@ -109,7 +109,7 @@
     if (!targetElement)
         return false;
     
-    return determineAnimatedPropertyType(targetElement) != AnimatedUnknown;
+    return m_animatedPropertyType != AnimatedUnknown;
 }
 
 AnimatedPropertyType SVGAnimateElement::determineAnimatedPropertyType(SVGElement* targetElement) const
@@ -159,12 +159,20 @@
 void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement* resultElement)
 {
     ASSERT(resultElement);
+    SVGElement* targetElement = this->targetElement();
+    if (!targetElement)
+        return;
+
+    ASSERT(m_animatedPropertyType == determineAnimatedPropertyType(targetElement));
+
     ASSERT(percentage >= 0 && percentage <= 1);
     ASSERT(m_animatedPropertyType != AnimatedEnumeration);
     ASSERT(m_animatedPropertyType != AnimatedTransformList);
     ASSERT(m_animatedPropertyType != AnimatedUnknown);
     ASSERT(m_animator);
+    ASSERT(m_animator->type() == m_animatedPropertyType);
     ASSERT(m_fromType);
+    ASSERT(m_fromType->type() == m_animatedPropertyType);
     ASSERT(m_toType);
 
     SVGAnimateElement* resultAnimationElement = static_cast<SVGAnimateElement*>(resultElement);
@@ -177,10 +185,6 @@
     if (hasTagName(SVGNames::setTag))
         percentage = 1;
 
-    SVGElement* targetElement = this->targetElement();
-    if (!targetElement)
-        return;
-
     // Target element might have changed.
     m_animator->setContextElement(targetElement);
     m_animator->calculateAnimatedValue(percentage, repeat, m_fromType, m_toType, resultAnimationElement->m_animatedType);
@@ -192,9 +196,8 @@
     if (!targetElement)
         return false;
 
-    m_animatedPropertyType = determineAnimatedPropertyType(targetElement);
-
     ensureAnimator()->calculateFromAndToValues(m_fromType, m_toType, fromString, toString);
+    ASSERT(m_animatedPropertyType == m_animator->type());
     return true;
 }
 
@@ -205,22 +208,19 @@
         return false;
 
     ASSERT(!hasTagName(SVGNames::setTag));
-    m_animatedPropertyType = determineAnimatedPropertyType(targetElement);
 
     ensureAnimator()->calculateFromAndByValues(m_fromType, m_toType, fromString, byString);
+    ASSERT(m_animatedPropertyType == m_animator->type());
     return true;
 }
 
 void SVGAnimateElement::resetToBaseValue(const String& baseString)
 {
-    SVGElement* targetElement = this->targetElement();
-    ASSERT(targetElement);
-    m_animatedPropertyType = determineAnimatedPropertyType(targetElement);
-
     if (!m_animatedType)
         m_animatedType = ensureAnimator()->constructFromString(baseString);
     else
         m_animatedType->setValueAsString(attributeName(), baseString);
+    ASSERT(m_animatedPropertyType == m_animator->type());
 }
     
 void SVGAnimateElement::applyResultsToTarget()
@@ -239,15 +239,24 @@
     SVGElement* targetElement = this->targetElement();
     if (!targetElement)
         return -1;
-    m_animatedPropertyType = determineAnimatedPropertyType(targetElement);
-    
+
     return ensureAnimator()->calculateDistance(fromString, toString);
 }
 
+void SVGAnimateElement::targetElementDidChange(SVGElement* targetElement)
+{
+    m_animatedType.clear();
+    m_fromType.clear();
+    m_toType.clear();
+    m_animator.clear();
+    m_animatedPropertyType = targetElement ? determineAnimatedPropertyType(targetElement) : AnimatedString;
+}
+
 SVGAnimatedTypeAnimator* SVGAnimateElement::ensureAnimator()
 {
     if (!m_animator)
         m_animator = SVGAnimatorFactory::create(this, targetElement(), m_animatedPropertyType);
+    ASSERT(m_animatedPropertyType == m_animator->type());
     return m_animator.get();
 }
 

Modified: branches/chromium/963/Source/WebCore/svg/SVGAnimateElement.h (109357 => 109358)


--- branches/chromium/963/Source/WebCore/svg/SVGAnimateElement.h	2012-03-01 17:53:00 UTC (rev 109357)
+++ branches/chromium/963/Source/WebCore/svg/SVGAnimateElement.h	2012-03-01 18:05:41 UTC (rev 109358)
@@ -45,7 +45,7 @@
     static PassRefPtr<SVGAnimateElement> create(const QualifiedName&, Document*);
 
     virtual ~SVGAnimateElement();
-    
+
     static void adjustForCurrentColor(SVGElement* targetElement, Color&);
     void adjustForInheritance(SVGElement* targetElement, const QualifiedName&, String& value);
     
@@ -65,6 +65,8 @@
     virtual void applyResultsToTarget();
     virtual float calculateDistance(const String& fromString, const String& toString);
 
+    virtual void targetElementDidChange(SVGElement* targetElement) OVERRIDE;
+
 private:
     SVGAnimatedTypeAnimator* ensureAnimator();
     

Modified: branches/chromium/963/Source/WebCore/svg/SVGAnimatedTypeAnimator.h (109357 => 109358)


--- branches/chromium/963/Source/WebCore/svg/SVGAnimatedTypeAnimator.h	2012-03-01 17:53:00 UTC (rev 109357)
+++ branches/chromium/963/Source/WebCore/svg/SVGAnimatedTypeAnimator.h	2012-03-01 18:05:41 UTC (rev 109358)
@@ -41,7 +41,9 @@
     virtual float calculateDistance(const String& fromString, const String& toString) = 0;
 
     void setContextElement(SVGElement* contextElement) { m_contextElement = contextElement; }
-    
+
+    AnimatedPropertyType type() const { return m_type; }
+
 protected:
     SVGAnimatedTypeAnimator(AnimatedPropertyType type, SVGAnimationElement* animationElement, SVGElement* contextElement)
         : m_type(type)

Modified: branches/chromium/963/Source/WebCore/svg/animation/SVGSMILElement.cpp (109357 => 109358)


--- branches/chromium/963/Source/WebCore/svg/animation/SVGSMILElement.cpp	2012-03-01 17:53:00 UTC (rev 109357)
+++ branches/chromium/963/Source/WebCore/svg/animation/SVGSMILElement.cpp	2012-03-01 18:05:41 UTC (rev 109358)
@@ -498,17 +498,32 @@
     ContainerNode* target = href.isEmpty() ? parentNode() : SVGURIReference::targetElementFromIRIString(href, document());
     if (!target || !target->isSVGElement())
         return 0;
-    
+
     m_targetElement = static_cast<SVGElement*>(target);
     document()->accessSVGExtensions()->addAnimationElementToTarget(this, m_targetElement);
+
+    targetElementDidChange(m_targetElement);
+
     return m_targetElement;
 }
 
-SMILTime SVGSMILElement::elapsed() const 
+void SVGSMILElement::resetTargetElement()
 {
+    m_targetElement = 0;
+
+    // Force the animation to recompute values that are only calculated when an animation becomes active.
+    // Failing to do this means that a target reset and change during active animation may result in
+    // invalid state.
+    m_activeState = Inactive;
+
+    targetElementDidChange(0);
+}
+
+SMILTime SVGSMILElement::elapsed() const
+{
     return m_timeContainer ? m_timeContainer->elapsed() : 0;
-} 
-    
+}
+
 bool SVGSMILElement::isInactive() const
 {
      return m_activeState == Inactive;

Modified: branches/chromium/963/Source/WebCore/svg/animation/SVGSMILElement.h (109357 => 109358)


--- branches/chromium/963/Source/WebCore/svg/animation/SVGSMILElement.h	2012-03-01 17:53:00 UTC (rev 109357)
+++ branches/chromium/963/Source/WebCore/svg/animation/SVGSMILElement.h	2012-03-01 18:05:41 UTC (rev 109358)
@@ -54,7 +54,7 @@
     SMILTimeContainer* timeContainer() const { return m_timeContainer.get(); }
 
     SVGElement* targetElement();
-    void resetTargetElement() { m_targetElement = 0; }
+    void resetTargetElement();
     const QualifiedName& attributeName() const { return m_attributeName; }
 
     void beginByLinkActivation();
@@ -112,6 +112,9 @@
 
     void setInactive() { m_activeState = Inactive; }
 
+    // Sub-classes may need to take action when the target is changed.
+    virtual void targetElementDidChange(SVGElement*) { }
+
 private:
     virtual void startedActiveInterval() = 0;
     virtual void updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement) = 0;
@@ -228,4 +231,3 @@
 
 #endif // ENABLE(SVG)
 #endif // SVGSMILElement_h
-
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to