Bug 548899: Don't issue attribute-changed notification when transform attribute is animated. r=jwatt sr=roc
authorDaniel Holbert <dholbert@cs.stanford.edu>
Tue, 02 Mar 2010 07:36:31 -0800
changeset 38843 6776f09c1bc68bd233352f3f436839b5457d6157
parent 38842 ea63501d0e62f191cddabe3e5914b351c3959bc8
child 38844 e9ab6e4d121d97c2f8be97229e05ac3c53d43091
push id11893
push userdholbert@mozilla.com
push dateTue, 02 Mar 2010 15:38:08 +0000
treeherdermozilla-central@e9ab6e4d121d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt, roc
bugs548899
milestone1.9.3a3pre
Bug 548899: Don't issue attribute-changed notification when transform attribute is animated. r=jwatt sr=roc
content/smil/crashtests/548899-1.svg
content/smil/crashtests/crashtests.list
content/svg/content/src/nsSVGElement.cpp
content/svg/content/src/nsSVGElement.h
content/svg/content/src/nsSVGTransformSMILAttr.cpp
content/svg/content/src/nsSVGTransformSMILAttr.h
new file mode 100644
--- /dev/null
+++ b/content/smil/crashtests/548899-1.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink">
+  <defs>
+    <circle id="circleID" cx="20" cy="100" r="10" fill="orange" stroke="black">
+      <animateTransform attributeName="transform" type="scale"
+                        from="1" to="2" begin="0" dur="3"/>
+    </circle>
+    <rect id="rectID" fill="green" stroke="black" height="100" width="100">
+      <animate attributeName="fill" from="white" to="blue" begin="0" dur="3"/>
+    </rect>
+  </defs>
+  <use xlink:href="#circleID"/>
+</svg>
--- a/content/smil/crashtests/crashtests.list
+++ b/content/smil/crashtests/crashtests.list
@@ -1,8 +1,9 @@
 load 523188-1.svg
 load 525099-1.svg
 load 526536-1.svg
 load 526875-1.svg
 load 526875-2.svg
 load 529387-1.xhtml
 load 537157-1.svg
 load 547333-1.svg
+load 548899-1.svg
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -1603,16 +1603,28 @@ nsSVGElement::DidAnimatePreserveAspectRa
   
   if (frame) {
     frame->AttributeChanged(kNameSpaceID_None,
                             nsGkAtoms::preserveAspectRatio,
                             nsIDOMMutationEvent::MODIFICATION);
   }
 }
 
+void
+nsSVGElement::DidAnimateTransform()
+{
+  nsIFrame* frame = GetPrimaryFrame();
+  
+  if (frame) {
+    frame->AttributeChanged(kNameSpaceID_None,
+                            nsGkAtoms::transform,
+                            nsIDOMMutationEvent::MODIFICATION);
+  }
+}
+
 nsSVGElement::StringAttributesInfo
 nsSVGElement::GetStringInfo()
 {
   return StringAttributesInfo(nsnull, nsnull, 0);
 }
 
 void nsSVGElement::StringAttributesInfo::Reset(PRUint8 aAttrEnum)
 {
@@ -1777,17 +1789,17 @@ nsSVGElement::GetAnimatedAttr(const nsIA
       return nsnull;
     nsCOMPtr<nsIDOMSVGAnimatedTransformList> transformList;
     nsresult rv = transformable->GetTransform(getter_AddRefs(transformList));
     NS_ENSURE_SUCCESS(rv, nsnull);
     nsSVGAnimatedTransformList* list
       = static_cast<nsSVGAnimatedTransformList*>(transformList.get());
     NS_ENSURE_TRUE(list, nsnull);
 
-    return new nsSVGTransformSMILAttr(list);
+    return new nsSVGTransformSMILAttr(list, this);
   }
 
   // Lengths:
   LengthAttributesInfo info = GetLengthInfo();
   for (PRUint32 i = 0; i < info.mLengthCount; i++) {
     if (aName == *info.mLengthInfo[i].mName) {
       return info.mLengths[i].ToSMILAttr(this);
     }
--- a/content/svg/content/src/nsSVGElement.h
+++ b/content/svg/content/src/nsSVGElement.h
@@ -158,16 +158,17 @@ public:
   virtual void DidAnimateLength(PRUint8 aAttrEnum);
   virtual void DidAnimateNumber(PRUint8 aAttrEnum);
   virtual void DidAnimateInteger(PRUint8 aAttrEnum);
   virtual void DidAnimateAngle(PRUint8 aAttrEnum);
   virtual void DidAnimateBoolean(PRUint8 aAttrEnum);
   virtual void DidAnimateEnum(PRUint8 aAttrEnum);
   virtual void DidAnimateViewBox();
   virtual void DidAnimatePreserveAspectRatio();
+  virtual void DidAnimateTransform();
 
   void GetAnimatedLengthValues(float *aFirst, ...);
   void GetAnimatedNumberValues(float *aFirst, ...);
   void GetAnimatedIntegerValues(PRInt32 *aFirst, ...);
 
 #ifdef MOZ_SMIL
   virtual nsISMILAttr* GetAnimatedAttr(const nsIAtom* aName);
   void AnimationNeedsResample();
--- a/content/svg/content/src/nsSVGTransformSMILAttr.cpp
+++ b/content/svg/content/src/nsSVGTransformSMILAttr.cpp
@@ -108,32 +108,31 @@ nsSVGTransformSMILAttr::SetAnimValue(con
   if (aValue.mType != &nsSVGTransformSMILType::sSingleton) {
     NS_WARNING("Unexpected SMIL Type");
     return NS_ERROR_FAILURE;
   }
 
   nsresult rv = NS_OK;
 
   // Create the anim value if necessary
-  mVal->WillModify(nsISVGValue::mod_other);
   if (!mVal->mAnimVal) {
     rv = nsSVGTransformList::Create(getter_AddRefs(mVal->mAnimVal));
     NS_ENSURE_SUCCESS(rv,rv);
   }
 
   // Do a minimal update on the anim value and if anything fails, set the anim
   // value to null so that calls to nsSVGAnimatedTransformList::GetAnimVal will
   // return the base value instead.
   rv = UpdateFromSMILValue(mVal->mAnimVal, aValue);
   if (NS_FAILED(rv)) {
     mVal->mAnimVal = nsnull;
   }
   NS_ENSURE_SUCCESS(rv,rv);
 
-  mVal->DidModify(nsISVGValue::mod_other);
+  mSVGElement->DidAnimateTransform();
   return NS_OK;
 }
 
 //----------------------------------------------------------------------
 // Implementation helpers
 
 void
 nsSVGTransformSMILAttr::ParseValue(const nsAString& aSpec,
--- a/content/svg/content/src/nsSVGTransformSMILAttr.h
+++ b/content/svg/content/src/nsSVGTransformSMILAttr.h
@@ -47,18 +47,19 @@ class nsSVGAnimatedTransformList;
 class nsISMILType;
 class nsIDOMSVGTransform;
 class nsIDOMSVGTransformList;
 class nsSVGSMILTransform;
 
 class nsSVGTransformSMILAttr : public nsISMILAttr
 {
 public:
-  nsSVGTransformSMILAttr(nsSVGAnimatedTransformList* aTransform)
-    : mVal(aTransform) {}
+  nsSVGTransformSMILAttr(nsSVGAnimatedTransformList* aTransform,
+                         nsSVGElement* aSVGElement)
+    : mVal(aTransform), mSVGElement(aSVGElement) {}
 
   // nsISMILAttr methods
   virtual nsresult ValueFromString(const nsAString& aStr,
                                    const nsISMILAnimationElement* aSrcElement,
                                    nsSMILValue& aValue,
                                    PRBool& aCanCache) const;
   virtual nsSMILValue  GetBaseValue() const;
   virtual void         ClearAnimValue();
@@ -78,11 +79,12 @@ protected:
                     const nsSVGSMILTransform& aSMILTransform,
                     nsIDOMSVGTransform* aSVGTransform);
 
 private:
   // Raw pointers are OK here because this nsSVGTransformSMILAttr is both
   // created & destroyed during a SMIL sample-step, during which time the DOM
   // isn't modified.
   nsSVGAnimatedTransformList* mVal;
+  nsSVGElement* mSVGElement;
 };
 
 #endif // NS_SVGTRANSFORMSMILATTR_H_