Bug 693145 - Simplify class animation processing. r=dholbert
authorRobert Longson <longsonr@gmail.com>
Tue, 18 Oct 2011 13:43:57 +0100
changeset 78881 d7295730c0ef1adb8be8d236e16c09ad978fe0a7
parent 78880 308f180eb3f45cf94c7e3ca42c66377fceba89c7
child 78882 6f03f6a821c0bb102e7fa9b9fa52df3570d14210
push id2740
push userlongsonr@gmail.com
push dateTue, 18 Oct 2011 12:43:25 +0000
treeherdermozilla-inbound@d7295730c0ef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs693145
milestone10.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 693145 - Simplify class animation processing. r=dholbert
content/svg/content/src/nsSVGClass.cpp
content/svg/content/src/nsSVGClass.h
content/svg/content/src/nsSVGElement.cpp
content/svg/content/src/nsSVGElement.h
content/svg/content/src/nsSVGString.h
content/svg/content/src/nsSVGStylableElement.cpp
content/svg/content/src/nsSVGStylableElement.h
--- a/content/svg/content/src/nsSVGClass.cpp
+++ b/content/svg/content/src/nsSVGClass.cpp
@@ -30,16 +30,17 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsSVGClass.h"
+#include "nsSVGStylableElement.h"
 #ifdef MOZ_SMIL
 #include "nsSMILValue.h"
 #include "SMILStringType.h"
 #endif // MOZ_SMIL
 
 using namespace mozilla;
 
 NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGClass::DOMAnimatedString, mSVGElement)
@@ -54,70 +55,86 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAnimatedString)
 NS_INTERFACE_MAP_END
 
 /* Implementation */
 
 void
 nsSVGClass::SetBaseValue(const nsAString& aValue,
-                         nsSVGElement *aSVGElement,
+                         nsSVGStylableElement *aSVGElement,
                          bool aDoSetAttr)
 {
   NS_ASSERTION(aSVGElement, "Null element passed to SetBaseValue");
 
   aSVGElement->SetFlags(NODE_MAY_HAVE_CLASS);
   if (aDoSetAttr) {
     aSVGElement->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, aValue, true);
   }
 #ifdef MOZ_SMIL
   if (mAnimVal) {
     aSVGElement->AnimationNeedsResample();
   }
 #endif
 }
 
 void
-nsSVGClass::GetAnimValue(nsAString& aResult, const nsSVGElement *aSVGElement) const
+nsSVGClass::GetBaseValue(nsAString& aValue, const nsSVGStylableElement *aSVGElement) const
+{
+  aSVGElement->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, aValue);
+}
+
+void
+nsSVGClass::GetAnimValue(nsAString& aResult, const nsSVGStylableElement *aSVGElement) const
 {
   if (mAnimVal) {
     aResult = *mAnimVal;
     return;
   }
 
   aSVGElement->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, aResult);
 }
 
 void
-nsSVGClass::SetAnimValue(const nsAString& aValue, nsSVGElement *aSVGElement)
+nsSVGClass::SetAnimValue(const nsAString& aValue, nsSVGStylableElement *aSVGElement)
 {
   if (!mAnimVal) {
     mAnimVal = new nsString();
   }
   *mAnimVal = aValue;
   aSVGElement->SetFlags(NODE_MAY_HAVE_CLASS);
   aSVGElement->DidAnimateClass();
 }
 
 nsresult
 nsSVGClass::ToDOMAnimatedString(nsIDOMSVGAnimatedString **aResult,
-                                nsSVGElement *aSVGElement)
+                                nsSVGStylableElement *aSVGElement)
 {
   *aResult = new DOMAnimatedString(this, aSVGElement);
   NS_ADDREF(*aResult);
   return NS_OK;
 }
 
 #ifdef MOZ_SMIL
 nsISMILAttr*
-nsSVGClass::ToSMILAttr(nsSVGElement *aSVGElement)
+nsSVGClass::ToSMILAttr(nsSVGStylableElement *aSVGElement)
 {
   return new SMILString(this, aSVGElement);
 }
 
+NS_IMETHODIMP
+nsSVGClass::DOMAnimatedString::GetAnimVal(nsAString& aResult)
+{ 
+#ifdef MOZ_SMIL
+  mSVGElement->FlushAnimations();
+#endif
+  mVal->GetAnimValue(aResult, mSVGElement);
+  return NS_OK;
+}
+
 nsresult
 nsSVGClass::SMILString::ValueFromString(const nsAString& aStr,
                                         const nsISMILAnimationElement* /*aSrcElement*/,
                                         nsSMILValue& aValue,
                                         bool& aPreventCachingOfSandwich) const
 {
   nsSMILValue val(&SMILStringType::sSingleton);
 
--- a/content/svg/content/src/nsSVGClass.h
+++ b/content/svg/content/src/nsSVGClass.h
@@ -33,87 +33,84 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __NS_SVGCLASS_H__
 #define __NS_SVGCLASS_H__
 
 #include "nsIDOMSVGAnimatedString.h"
-#include "nsSVGElement.h"
+#include "nsAutoPtr.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsString.h"
+#include "nsISMILAttr.h"
 #include "nsDOMError.h"
 
+class nsSVGStylableElement;
+
 class nsSVGClass
 {
 
 public:
   void Init() {
     mAnimVal = nsnull;
   }
 
   void SetBaseValue(const nsAString& aValue,
-                    nsSVGElement *aSVGElement,
+                    nsSVGStylableElement *aSVGElement,
                     bool aDoSetAttr);
-  void GetBaseValue(nsAString& aValue, nsSVGElement *aSVGElement) const
-    { aSVGElement->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, aValue); }
+  void GetBaseValue(nsAString& aValue, const nsSVGStylableElement *aSVGElement) const;
 
-  void SetAnimValue(const nsAString& aValue, nsSVGElement *aSVGElement);
-  void GetAnimValue(nsAString& aValue, const nsSVGElement *aSVGElement) const;
+  void SetAnimValue(const nsAString& aValue, nsSVGStylableElement *aSVGElement);
+  void GetAnimValue(nsAString& aValue, const nsSVGStylableElement *aSVGElement) const;
   bool IsAnimated() const
     { return !!mAnimVal; }
 
   nsresult ToDOMAnimatedString(nsIDOMSVGAnimatedString **aResult,
-                               nsSVGElement *aSVGElement);
+                               nsSVGStylableElement *aSVGElement);
 #ifdef MOZ_SMIL
   // Returns a new nsISMILAttr object that the caller must delete
-  nsISMILAttr* ToSMILAttr(nsSVGElement *aSVGElement);
+  nsISMILAttr* ToSMILAttr(nsSVGStylableElement *aSVGElement);
 #endif // MOZ_SMIL
 
 private:
 
   nsAutoPtr<nsString> mAnimVal;
 
 public:
   struct DOMAnimatedString : public nsIDOMSVGAnimatedString
   {
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     NS_DECL_CYCLE_COLLECTION_CLASS(DOMAnimatedString)
 
-    DOMAnimatedString(nsSVGClass *aVal, nsSVGElement *aSVGElement)
+    DOMAnimatedString(nsSVGClass *aVal, nsSVGStylableElement *aSVGElement)
       : mVal(aVal), mSVGElement(aSVGElement) {}
 
     nsSVGClass* mVal; // kept alive because it belongs to content
-    nsRefPtr<nsSVGElement> mSVGElement;
+    nsRefPtr<nsSVGStylableElement> mSVGElement;
 
     NS_IMETHOD GetBaseVal(nsAString& aResult)
       { mVal->GetBaseValue(aResult, mSVGElement); return NS_OK; }
     NS_IMETHOD SetBaseVal(const nsAString& aValue)
       { mVal->SetBaseValue(aValue, mSVGElement, true); return NS_OK; }
 
-    NS_IMETHOD GetAnimVal(nsAString& aResult)
-    { 
-#ifdef MOZ_SMIL
-      mSVGElement->FlushAnimations();
-#endif
-      mVal->GetAnimValue(aResult, mSVGElement); return NS_OK;
-    }
-
+    NS_IMETHOD GetAnimVal(nsAString& aResult);
   };
 #ifdef MOZ_SMIL
   struct SMILString : public nsISMILAttr
   {
   public:
-    SMILString(nsSVGClass *aVal, nsSVGElement *aSVGElement)
+    SMILString(nsSVGClass *aVal, nsSVGStylableElement *aSVGElement)
       : mVal(aVal), mSVGElement(aSVGElement) {}
 
     // These will stay alive because a nsISMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
     nsSVGClass* mVal;
-    nsSVGElement* mSVGElement;
+    nsSVGStylableElement* mSVGElement;
 
     // nsISMILAttr methods
     virtual nsresult ValueFromString(const nsAString& aStr,
                                      const nsISMILAnimationElement *aSrcElement,
                                      nsSMILValue& aValue,
                                      bool& aPreventCachingOfSandwich) const;
     virtual nsSMILValue GetBaseValue() const;
     virtual void ClearAnimValue();
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -71,17 +71,16 @@
 #include "nsSVGNumberPair.h"
 #include "nsSVGInteger.h"
 #include "nsSVGIntegerPair.h"
 #include "nsSVGAngle.h"
 #include "nsSVGBoolean.h"
 #include "nsSVGEnum.h"
 #include "nsSVGViewBox.h"
 #include "nsSVGString.h"
-#include "nsSVGClass.h"
 #include "SVGAnimatedNumberList.h"
 #include "SVGAnimatedLengthList.h"
 #include "SVGAnimatedPointList.h"
 #include "SVGAnimatedPathSegList.h"
 #include "SVGAnimatedTransformList.h"
 #include "nsIDOMSVGUnitTypes.h"
 #include "nsSVGRect.h"
 #include "nsIFrame.h"
@@ -511,24 +510,16 @@ nsSVGElement::ParseAttribute(PRInt32 aNa
         SVGAnimatedTransformList *transformList = GetAnimatedTransformList();
         if (transformList) {
           rv = transformList->SetBaseValueString(aValue);
           if (NS_FAILED(rv)) {
             transformList->ClearBaseValue();
           }
           foundMatch = true;
         }
-      // Check for class attribute
-      } else if (aAttribute == nsGkAtoms::_class) {
-        nsSVGClass *svgClass = GetClass();
-        if (svgClass) {
-          svgClass->SetBaseValue(aValue, this, false);
-          aResult.ParseAtomArray(aValue);
-          return true;
-        }
       }
     }
   }
 
   if (!foundMatch) {
     // Check for nsSVGString attribute
     StringAttributesInfo stringInfo = GetStringInfo();
     for (PRUint32 i = 0; i < stringInfo.mStringCount; i++) {
@@ -730,26 +721,16 @@ nsSVGElement::UnsetAttrInternal(PRInt32 
     if (GetTransformListAttrName() == aName) {
       SVGAnimatedTransformList *transformList = GetAnimatedTransformList();
       if (transformList) {
         transformList->ClearBaseValue();
         DidChangeTransformList(false);
         return;
       }
     }
-
-    // Check if this is a class attribute going away
-    if (aName == nsGkAtoms::_class) {
-      nsSVGClass *svgClass = GetClass();
-
-      if (svgClass) {
-        svgClass->Init();
-        return;
-      }
-    }
   }
 
   // Check if this is a string attribute going away
   StringAttributesInfo stringInfo = GetStringInfo();
 
   for (PRUint32 i = 0; i < stringInfo.mStringCount; i++) {
     if (aNamespaceID == stringInfo.mStringInfo[i].mNamespaceID &&
         aName == *stringInfo.mStringInfo[i].mName) {
@@ -2116,33 +2097,16 @@ nsSVGElement::DidAnimateString(PRUint8 a
   if (frame) {
     StringAttributesInfo info = GetStringInfo();
     frame->AttributeChanged(info.mStringInfo[aAttrEnum].mNamespaceID,
                             *info.mStringInfo[aAttrEnum].mName,
                             nsIDOMMutationEvent::MODIFICATION);
   }
 }
 
-nsSVGClass *
-nsSVGElement::GetClass()
-{
-  return nsnull;
-}
-
-void
-nsSVGElement::DidAnimateClass()
-{
-  nsIFrame* frame = GetPrimaryFrame();
-
-  if (frame) {
-    frame->AttributeChanged(kNameSpaceID_None, nsGkAtoms::_class,
-                            nsIDOMMutationEvent::MODIFICATION);
-  }
-}
-
 nsresult
 nsSVGElement::ReportAttributeParseFailure(nsIDocument* aDocument,
                                           nsIAtom* aAttribute,
                                           const nsAString& aValue)
 {
   const nsAFlatString& attributeValue = PromiseFlatString(aValue);
   const PRUnichar *strings[] = { aAttribute->GetUTF16String(),
                                  attributeValue.get() };
@@ -2277,21 +2241,16 @@ nsSVGElement::GetAnimatedAttr(PRInt32 aN
     // preserveAspectRatio:
     if (aName == nsGkAtoms::preserveAspectRatio) {
       SVGAnimatedPreserveAspectRatio *preserveAspectRatio =
         GetPreserveAspectRatio();
       return preserveAspectRatio ?
         preserveAspectRatio->ToSMILAttr(this) : nsnull;
     }
 
-    if (aName == nsGkAtoms::_class) {
-      nsSVGClass *svgClass = GetClass();
-      return svgClass ? svgClass->ToSMILAttr(this) : nsnull;
-    }
-
     // NumberLists:
     {
       NumberListAttributesInfo info = GetNumberListInfo();
       for (PRUint32 i = 0; i < info.mNumberListCount; i++) {
         if (aName == *info.mNumberListInfo[i].mName) {
           NS_ABORT_IF_FALSE(i <= UCHAR_MAX, "Too many attributes");
           return info.mNumberLists[i].ToSMILAttr(this, PRUint8(i));
         }
--- a/content/svg/content/src/nsSVGElement.h
+++ b/content/svg/content/src/nsSVGElement.h
@@ -63,17 +63,16 @@ class nsSVGNumberPair;
 class nsSVGInteger;
 class nsSVGIntegerPair;
 class nsSVGAngle;
 class nsSVGBoolean;
 class nsSVGEnum;
 struct nsSVGEnumMapping;
 class nsSVGViewBox;
 class nsSVGString;
-class nsSVGClass;
 struct gfxMatrix;
 namespace mozilla {
 class SVGAnimatedNumberList;
 class SVGNumberList;
 class SVGAnimatedLengthList;
 class SVGUserUnitList;
 class SVGAnimatedPointList;
 class SVGAnimatedPathSegList;
@@ -192,17 +191,16 @@ public:
   virtual void DidAnimateViewBox();
   virtual void DidAnimatePreserveAspectRatio();
   virtual void DidAnimateNumberList(PRUint8 aAttrEnum);
   virtual void DidAnimateLengthList(PRUint8 aAttrEnum);
   virtual void DidAnimatePointList();
   virtual void DidAnimatePathSegList();
   virtual void DidAnimateTransformList();
   virtual void DidAnimateString(PRUint8 aAttrEnum);
-  virtual void DidAnimateClass();
 
   void GetAnimatedLengthValues(float *aFirst, ...);
   void GetAnimatedNumberValues(float *aFirst, ...);
   void GetAnimatedIntegerValues(PRInt32 *aFirst, ...);
   SVGAnimatedNumberList* GetAnimatedNumberList(PRUint8 aAttrEnum);
   SVGAnimatedNumberList* GetAnimatedNumberList(nsIAtom *aAttrName);
   void GetAnimatedLengthListValues(SVGUserUnitList *aFirst, ...);
   SVGAnimatedLengthList* GetAnimatedLengthList(PRUint8 aAttrEnum);
@@ -509,17 +507,16 @@ protected:
   virtual EnumAttributesInfo GetEnumInfo();
   // We assume all viewboxes and preserveAspectRatios are alike
   // so we don't need to wrap the class
   virtual nsSVGViewBox *GetViewBox();
   virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio();
   virtual NumberListAttributesInfo GetNumberListInfo();
   virtual LengthListAttributesInfo GetLengthListInfo();
   virtual StringAttributesInfo GetStringInfo();
-  virtual nsSVGClass *GetClass();
 
   static nsSVGEnumMapping sSVGUnitTypesMap[];
 
 private:
   void UnsetAttrInternal(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
                          bool aNotify);
 
   nsRefPtr<mozilla::css::StyleRule> mContentStyleRule;
--- a/content/svg/content/src/nsSVGString.h
+++ b/content/svg/content/src/nsSVGString.h
@@ -49,17 +49,17 @@ public:
     mAnimVal = nsnull;
     mAttrEnum = aAttrEnum;
     mIsBaseSet = false;
   }
 
   void SetBaseValue(const nsAString& aValue,
                     nsSVGElement *aSVGElement,
                     bool aDoSetAttr);
-  void GetBaseValue(nsAString& aValue, nsSVGElement *aSVGElement) const
+  void GetBaseValue(nsAString& aValue, const nsSVGElement *aSVGElement) const
     { aSVGElement->GetStringBaseValue(mAttrEnum, aValue); }
 
   void SetAnimValue(const nsAString& aValue, nsSVGElement *aSVGElement);
   void GetAnimValue(nsAString& aValue, const nsSVGElement *aSVGElement) const;
 
   // Returns true if the animated value of this string has been explicitly
   // set (either by animation, or by taking on the base value which has been
   // explicitly set by markup or a DOM call), false otherwise.
--- a/content/svg/content/src/nsSVGStylableElement.cpp
+++ b/content/svg/content/src/nsSVGStylableElement.cpp
@@ -65,16 +65,41 @@ const nsAttrValue*
 nsSVGStylableElement::DoGetClasses() const
 {
   if (mClassAttribute.IsAnimated()) {
     return mClassAnimAttr;
   }
   return nsSVGStylableElementBase::DoGetClasses();
 }
 
+bool
+nsSVGStylableElement::ParseAttribute(PRInt32 aNamespaceID,
+                                     nsIAtom* aAttribute,
+                                     const nsAString& aValue,
+                                     nsAttrValue& aResult)
+{
+  if (aNamespaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::_class) {
+    mClassAttribute.SetBaseValue(aValue, this, false);
+    aResult.ParseAtomArray(aValue);
+    return true;
+  }
+  return nsSVGStylableElementBase::ParseAttribute(aNamespaceID, aAttribute, aValue,
+                                                  aResult);
+}
+
+nsresult
+nsSVGStylableElement::UnsetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
+                                bool aNotify)
+{
+  if (aNamespaceID == kNameSpaceID_None && aName == nsGkAtoms::_class) {
+    mClassAttribute.Init();
+  }
+  return nsSVGStylableElementBase::UnsetAttr(aNamespaceID, aName, aNotify);
+}
+
 //----------------------------------------------------------------------
 // nsIDOMSVGStylable methods
 
 /* readonly attribute nsIDOMSVGAnimatedString className; */
 NS_IMETHODIMP
 nsSVGStylableElement::GetClassName(nsIDOMSVGAnimatedString** aClassName)
 {
   return mClassAttribute.ToDOMAnimatedString(aClassName, this);
@@ -121,11 +146,19 @@ nsSVGStylableElement::DidAnimateClass()
   nsIDocument* doc = GetOwnerDoc();
   NS_ASSERTION(doc, "If we're animating we should have an owner");
   if (doc) {
     nsIPresShell* shell = doc->GetShell();
     if (shell) {
       shell->RestyleForAnimation(this, eRestyle_Self);
     }
   }
+}
 
-  nsSVGStylableElementBase::DidAnimateClass();
+nsISMILAttr*
+nsSVGStylableElement::GetAnimatedAttr(PRInt32 aNamespaceID, nsIAtom* aName)
+{
+  if (aNamespaceID == kNameSpaceID_None && 
+      aName == nsGkAtoms::_class) {
+    return mClassAttribute.ToSMILAttr(this);
+  }
+  return nsSVGStylableElementBase::GetAnimatedAttr(aNamespaceID, aName);
 }
--- a/content/svg/content/src/nsSVGStylableElement.h
+++ b/content/svg/content/src/nsSVGStylableElement.h
@@ -59,22 +59,26 @@ public:
 
   // nsIContent
   virtual const nsAttrValue* DoGetClasses() const;
 
   nsIDOMCSSStyleDeclaration* GetStyle(nsresult* retval)
   {
     return nsSVGStylableElementBase::GetStyle(retval);
   }
+  virtual bool ParseAttribute(PRInt32 aNamespaceID, nsIAtom* aAttribute,
+                              const nsAString& aValue, nsAttrValue& aResult);
+  virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
+                             bool aNotify);
+
+#ifdef MOZ_SMIL
+  virtual nsISMILAttr* GetAnimatedAttr(PRInt32 aNamespaceID, nsIAtom* aName);
+#endif
+
+  void DidAnimateClass();
 
 protected:
-  virtual nsSVGClass *GetClass()
-  {
-    return &mClassAttribute;
-  }
-  virtual void DidAnimateClass();
-
   nsSVGClass mClassAttribute;
   nsAutoPtr<nsAttrValue> mClassAnimAttr;
 };
 
 
 #endif // __NS_SVGSTYLABLEELEMENT_H__