Bug 834877 part 4. Add overloads of GetAttr() and GetId() that take a DOMString. r=peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 29 Jan 2013 09:42:14 -0500
changeset 120223 4f59efe7733355f97fb2a9fedf219a44bb306720
parent 120222 9ed387b675bb030f4521074fc7b46410c1a06271
child 120224 27e211d02a7ab9f13d1252cba8c4d4e538df0788
push id24243
push userryanvm@gmail.com
push dateWed, 30 Jan 2013 00:49:21 +0000
treeherdermozilla-central@5c248ef0fe62 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs834877
milestone21.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 834877 part 4. Add overloads of GetAttr() and GetId() that take a DOMString. r=peterv
content/base/public/Element.h
content/base/src/Element.cpp
content/base/src/nsAttrValue.h
xpcom/ds/nsIAtom.idl
--- a/content/base/public/Element.h
+++ b/content/base/public/Element.h
@@ -40,16 +40,18 @@
 #include "nsContentUtils.h"
 #include "nsINodeList.h"
 #include "mozilla/ErrorResult.h"
 #include "nsIScrollableFrame.h"
 #include "nsIDOMAttr.h"
 #include "nsISMILAttr.h"
 #include "nsClientRect.h"
 #include "nsEvent.h"
+#include "nsAttrValue.h"
+#include "mozilla/dom/BindingDeclarations.h"
 
 class nsIDOMEventListener;
 class nsIFrame;
 class nsIDOMNamedNodeMap;
 class nsIDOMCSSStyleDeclaration;
 class nsIURI;
 class nsINodeInfo;
 class nsIControllers;
@@ -456,17 +458,17 @@ public:
     return false;
   }
 
   virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
                            const nsAString& aValue, bool aNotify);
   nsresult SetParsedAttr(int32_t aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
                          nsAttrValue& aParsedValue, bool aNotify);
   virtual bool GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
-                         nsAString& aResult) const;
+                       nsAString& aResult) const;
   virtual bool HasAttr(int32_t aNameSpaceID, nsIAtom* aName) const;
   // aCaseSensitive == eIgnoreCaase means ASCII case-insensitive matching.
   virtual bool AttrValueIs(int32_t aNameSpaceID, nsIAtom* aName,
                              const nsAString& aValue,
                              nsCaseTreatment aCaseSensitive) const;
   virtual bool AttrValueIs(int32_t aNameSpaceID, nsIAtom* aName,
                              nsIAtom* aValue,
                              nsCaseTreatment aCaseSensitive) const;
@@ -512,25 +514,46 @@ public:
   }
 
 private:
   static bool
   FindAttributeDependence(const nsIAtom* aAttribute,
                           const MappedAttributeEntry* const aMaps[],
                           uint32_t aMapCount);
 
+protected:
+  inline bool GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
+                      mozilla::dom::DOMString& aResult) const
+  {
+    NS_ASSERTION(nullptr != aName, "must have attribute name");
+    NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown,
+                 "must have a real namespace ID!");
+    MOZ_ASSERT(aResult.HasStringBuffer() && aResult.StringBufferLength() == 0,
+               "Should have empty string coming in");
+    const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
+    if (val) {
+      val->ToString(aResult);
+    }
+    // else DOMString comes pre-emptied.
+    return val != nullptr;
+  }
+
 public:
   void GetTagName(nsAString& aTagName) const
   {
     aTagName = NodeName();
   }
   void GetId(nsAString& aId) const
   {
     GetAttr(kNameSpaceID_None, nsGkAtoms::id, aId);
   }
+  void GetId(mozilla::dom::DOMString& aId) const
+  {
+    GetAttr(kNameSpaceID_None, nsGkAtoms::id, aId);
+  }
   void SetId(const nsAString& aId)
   {
     SetAttr(kNameSpaceID_None, nsGkAtoms::id, aId, true);
   }
 
   nsDOMTokenList* GetClassList();
   nsDOMAttributeMap* GetAttributes()
   {
--- a/content/base/src/Element.cpp
+++ b/content/base/src/Element.cpp
@@ -1956,33 +1956,20 @@ Element::GetAttrInfo(int32_t aNamespaceI
   return nsAttrInfo(nullptr, nullptr);
 }
   
 
 bool
 Element::GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                  nsAString& aResult) const
 {
-  NS_ASSERTION(nullptr != aName, "must have attribute name");
-  NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown,
-               "must have a real namespace ID!");
-
-  const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
-  if (!val) {
-    // Since we are returning a success code we'd better do
-    // something about the out parameters (someone may have
-    // given us a non-empty string).
-    aResult.Truncate();
-    
-    return false;
-  }
-
-  val->ToString(aResult);
-
-  return true;
+  DOMString str;
+  bool haveAttr = GetAttr(aNameSpaceID, aName, str);
+  str.ToString(aResult);
+  return haveAttr;
 }
 
 bool
 Element::HasAttr(int32_t aNameSpaceID, nsIAtom* aName) const
 {
   NS_ASSERTION(nullptr != aName, "must have attribute name");
   NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown,
                "must have a real namespace ID!");
--- a/content/base/src/nsAttrValue.h
+++ b/content/base/src/nsAttrValue.h
@@ -15,19 +15,20 @@
 #include "nsStringGlue.h"
 #include "nsStringBuffer.h"
 #include "nsColor.h"
 #include "nsCaseTreatment.h"
 #include "nsMargin.h"
 #include "nsCOMPtr.h"
 #include "SVGAttrValueWrapper.h"
 #include "nsTArrayForwardDeclare.h"
+#include "nsIAtom.h"
+#include "mozilla/dom/BindingDeclarations.h"
 
 class nsAString;
-class nsIAtom;
 class nsIDocument;
 class nsStyledElementNotElementCSSInlineStyle;
 struct MiscContainer;
 
 namespace mozilla {
 namespace css {
 class StyleRule;
 struct URLValue;
@@ -154,16 +155,18 @@ public:
    * type of aValue is eAtom, in which case this object will also have type
    * eAtom.
    */
   void SetToSerialized(const nsAttrValue& aValue);
 
   void SwapValueWith(nsAttrValue& aOther);
 
   void ToString(nsAString& aResult) const;
+  inline void ToString(mozilla::dom::DOMString& aResult) const;
+
   /**
    * Returns the value of this object as an atom. If necessary, the value will
    * first be serialised using ToString before converting to an atom.
    */
   already_AddRefed<nsIAtom> GetAsAtom() const;
 
   // Methods to get value. These methods do not convert so only use them
   // to retrieve the datatype that this nsAttrValue has.
@@ -459,9 +462,35 @@ nsAttrValue::GetPtr() const
 }
 
 inline bool
 nsAttrValue::IsEmptyString() const
 {
   return !mBits;
 }
 
+inline void
+nsAttrValue::ToString(mozilla::dom::DOMString& aResult) const
+{
+  switch (Type()) {
+    case eString:
+    {
+      nsStringBuffer* str = static_cast<nsStringBuffer*>(GetPtr());
+      if (str) {
+        aResult.SetStringBuffer(str, str->StorageSize()/sizeof(PRUnichar) - 1);
+      }
+      // else aResult is already empty
+      return;
+    }
+    case eAtom:
+    {
+      nsIAtom *atom = static_cast<nsIAtom*>(GetPtr());
+      aResult.SetStringBuffer(atom->GetStringBuffer(), atom->GetLength());
+      break;
+    }
+    default:
+    {
+      ToString(aResult.AsAString());
+    }
+  }
+}
+
 #endif
--- a/xpcom/ds/nsIAtom.idl
+++ b/xpcom/ds/nsIAtom.idl
@@ -35,32 +35,36 @@ interface nsIAtom : nsISupports
 
   /**
    * Returns true if the atom is static and false otherwise.
    */
   [noscript, notxpcom] boolean isStaticAtom();
 
 %{C++
   // note this is NOT virtual so this won't muck with the vtable!
-  inline bool Equals(const nsAString& aString) {
+  inline bool Equals(const nsAString& aString) const {
     return aString.Equals(nsDependentString(mString, mLength));
   }
 
-  inline const PRUnichar* GetUTF16String() {
+  inline const PRUnichar* GetUTF16String() const {
     return mString;
   }
 
-  inline const uint32_t GetLength() {
+  inline const uint32_t GetLength() const {
     return mLength;
   }
 
   inline void ToString(nsAString& aBuf) {
     nsStringBuffer::FromData(mString)->ToString(mLength, aBuf);
   }
 
+  inline nsStringBuffer* GetStringBuffer() const {
+    return nsStringBuffer::FromData(mString);
+  }
+
   /**
    * A hashcode that is better distributed than the actual atom
    * pointer, for use in situations that need a well-distributed
    * hashcode.
    */
   inline uint32_t hash() const {
     return mHash;
   }