Back out changeset d49beb57db23 (bug 558516) for causing all Mac builds to crash in nsXULElement::GetAttrValue and for causing a single mochitest-1 failure.
authorL. David Baron <dbaron@dbaron.org>
Fri, 13 Jul 2012 18:01:25 -0700
changeset 104058 d4e43a290fa76140a8b9089af376fd1e5f689a38
parent 104057 31342850f91f2a0622b6402004ecd4191787c698
child 104059 9d29e87c3b6484d5bc309a0c6638f3fa8a6d7921
push id1316
push userakeybl@mozilla.com
push dateMon, 27 Aug 2012 22:37:00 +0000
treeherdermozilla-beta@db4b09302ee2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs558516
milestone16.0a1
backs outd49beb57db23b539ad5f36e1d45df926eeae0e78
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
Back out changeset d49beb57db23 (bug 558516) for causing all Mac builds to crash in nsXULElement::GetAttrValue and for causing a single mochitest-1 failure.
content/base/public/nsContentUtils.h
content/base/src/nsAttrAndChildArray.cpp
content/base/src/nsAttrAndChildArray.h
content/base/src/nsContentUtils.cpp
content/base/src/nsGenericElement.cpp
content/base/src/nsMappedAttributes.cpp
content/base/src/nsMappedAttributes.h
content/html/content/src/nsGenericHTMLElement.cpp
content/xul/content/src/nsXULElement.cpp
content/xul/content/src/nsXULElement.h
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1626,21 +1626,16 @@ public:
   /**
    * Convert ASCII a-z to A-Z.
    * @return NS_OK on success, or NS_ERROR_OUT_OF_MEMORY if making the string
    * writable needs to allocate memory and that allocation fails.
    */
   static nsresult ASCIIToUpper(nsAString& aStr);
   static nsresult ASCIIToUpper(const nsAString& aSource, nsAString& aDest);
 
-  /**
-   * Return whether aStr contains an ASCII uppercase character.
-   */
-  static bool StringContainsASCIIUpper(const nsAString& aStr);
-
   // Returns NS_OK for same origin, error (NS_ERROR_DOM_BAD_URI) if not.
   static nsresult CheckSameOrigin(nsIChannel *aOldChannel, nsIChannel *aNewChannel);
   static nsIInterfaceRequestor* GetSameOriginChecker();
 
   static nsIThreadJSContextStack* ThreadJSContextStack()
   {
     return sThreadJSContextStack;
   }
--- a/content/base/src/nsAttrAndChildArray.cpp
+++ b/content/base/src/nsAttrAndChildArray.cpp
@@ -315,49 +315,16 @@ nsAttrAndChildArray::GetAttr(nsIAtom* aL
       }
     }
   }
 
   return nsnull;
 }
 
 const nsAttrValue*
-nsAttrAndChildArray::GetAttr(const nsAString& aName,
-                             nsCaseTreatment aCaseSensitive) const
-{
-  PRUint32 i, slotCount = AttrSlotCount();
-  for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) {
-    if (ATTRS(mImpl)[i].mName.QualifiedNameEquals(aName)) {
-      return &ATTRS(mImpl)[i].mValue;
-    }
-  }
-
-  if (mImpl && mImpl->mMappedAttrs) {
-    const nsAttrValue* val =
-      mImpl->mMappedAttrs->GetAttr(aName);
-    if (val) {
-      return val;
-    }
-  }
-
-  // Now check whether someone is being silly and passing
-  // non-lowercase attr names.
-  if (aCaseSensitive == eIgnoreCase &&
-      nsContentUtils::StringContainsASCIIUpper(aName)) {
-    // Try again, but make sure we can't reenter this block by passing
-    // eCaseSensitive for aCaseSensitive.
-    nsAutoString lowercase;
-    nsContentUtils::ASCIIToLower(aName, lowercase);
-    return GetAttr(lowercase, eCaseMatters);
-  }
-
-  return nsnull;
-}
-
-const nsAttrValue*
 nsAttrAndChildArray::AttrAt(PRUint32 aPos) const
 {
   NS_ASSERTION(aPos < AttrCount(),
                "out-of-bounds access in nsAttrAndChildArray");
 
   PRUint32 mapped = MappedAttrCount();
   if (aPos < mapped) {
     return mImpl->mMappedAttrs->AttrAt(aPos);
@@ -518,18 +485,18 @@ nsAttrAndChildArray::GetExistingAttrName
 
   return nsnull;
 }
 
 PRInt32
 nsAttrAndChildArray::IndexOfAttr(nsIAtom* aLocalName, PRInt32 aNamespaceID) const
 {
   PRInt32 idx;
-  if (mImpl && mImpl->mMappedAttrs && aNamespaceID == kNameSpaceID_None) {
-    idx = mImpl->mMappedAttrs->IndexOfAttr(aLocalName);
+  if (mImpl && mImpl->mMappedAttrs) {
+    idx = mImpl->mMappedAttrs->IndexOfAttr(aLocalName, aNamespaceID);
     if (idx >= 0) {
       return idx;
     }
   }
 
   PRUint32 i;
   PRUint32 mapped = MappedAttrCount();
   PRUint32 slotCount = AttrSlotCount();
--- a/content/base/src/nsAttrAndChildArray.h
+++ b/content/base/src/nsAttrAndChildArray.h
@@ -11,17 +11,16 @@
 #ifndef nsAttrAndChildArray_h___
 #define nsAttrAndChildArray_h___
 
 #include "mozilla/Attributes.h"
 
 #include "nscore.h"
 #include "nsAttrName.h"
 #include "nsAttrValue.h"
-#include "nsCaseTreatment.h"
 
 class nsINode;
 class nsIContent;
 class nsMappedAttributes;
 class nsHTMLStyleSheet;
 class nsRuleWalker;
 class nsMappedAttributeElement;
 
@@ -67,20 +66,16 @@ public:
   void RemoveChildAt(PRUint32 aPos);
   // Like RemoveChildAt but hands the reference to the child being
   // removed back to the caller instead of just releasing it.
   already_AddRefed<nsIContent> TakeChildAt(PRUint32 aPos);
   PRInt32 IndexOfChild(nsINode* aPossibleChild) const;
 
   PRUint32 AttrCount() const;
   const nsAttrValue* GetAttr(nsIAtom* aLocalName, PRInt32 aNamespaceID = kNameSpaceID_None) const;
-  // Get an nsAttrValue by qualified name.  Can optionally do
-  // ASCII-case-insensitive name matching.
-  const nsAttrValue* GetAttr(const nsAString& aName,
-                             nsCaseTreatment aCaseSensitive) const;
   const nsAttrValue* AttrAt(PRUint32 aPos) const;
   nsresult SetAndTakeAttr(nsIAtom* aLocalName, nsAttrValue& aValue);
   nsresult SetAndTakeAttr(nsINodeInfo* aName, nsAttrValue& aValue);
 
   // Remove the attr at position aPos.  The value of the attr is placed in
   // aValue; any value that was already in aValue is destroyed.
   nsresult RemoveAttrAt(PRUint32 aPos, nsAttrValue& aValue);
 
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -5631,33 +5631,16 @@ nsContentUtils::EqualsLiteralIgnoreASCII
       }
     }
   }
   
   return true;
 }
 
 /* static */
-bool
-nsContentUtils::StringContainsASCIIUpper(const nsAString& aStr)
-{
-  const PRUnichar* iter = aStr.BeginReading();
-  const PRUnichar* end = aStr.EndReading();
-  while (iter != end) {
-    PRUnichar c = *iter;
-    if (c >= 'A' && c <= 'Z') {
-      return true;
-    }
-    ++iter;
-  }
-
-  return false;
-}
-
-/* static */
 nsIInterfaceRequestor*
 nsContentUtils::GetSameOriginChecker()
 {
   if (!sSameOriginChecker) {
     sSameOriginChecker = new SameOriginChecker();
     NS_IF_ADDREF(sSameOriginChecker);
   }
   return sSameOriginChecker;
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -1531,40 +1531,32 @@ nsGenericElement::GetTagName(nsAString& 
   aTagName = NodeName();
   return NS_OK;
 }
 
 nsresult
 nsGenericElement::GetAttribute(const nsAString& aName,
                                nsAString& aReturn)
 {
-  // I hate XUL
-  if (IsXUL()) {
-    const nsAttrValue* val =
-      nsXULElement::FromContent(this)->GetAttrValue(aName);
-    if (val) {
-      val->ToString(aReturn);
-    }
-    else {
+  const nsAttrName* name = InternalGetExistingAttrNameFromQName(aName);
+
+  if (!name) {
+    if (mNodeInfo->NamespaceID() == kNameSpaceID_XUL) {
       // XXX should be SetDOMStringToNull(aReturn);
       // See bug 232598
       aReturn.Truncate();
     }
+    else {
+      SetDOMStringToNull(aReturn);
+    }
+
     return NS_OK;
   }
-  
-  const nsAttrValue* val =
-    mAttrsAndChildren.GetAttr(aName,
-                              IsHTML() && IsInHTMLDocument() ?
-                                eIgnoreCase : eCaseMatters);
-  if (val) {
-    val->ToString(aReturn);
-  } else {
-    SetDOMStringToNull(aReturn);
-  }
+
+  GetAttr(name->NamespaceID(), name->LocalName(), aReturn);
 
   return NS_OK;
 }
 
 nsresult
 nsGenericElement::SetAttribute(const nsAString& aName,
                                const nsAString& aValue)
 {
--- a/content/base/src/nsMappedAttributes.cpp
+++ b/content/base/src/nsMappedAttributes.cpp
@@ -108,32 +108,19 @@ nsMappedAttributes::SetAndTakeAttr(nsIAt
   return NS_OK;
 }
 
 const nsAttrValue*
 nsMappedAttributes::GetAttr(nsIAtom* aAttrName) const
 {
   NS_PRECONDITION(aAttrName, "null name");
 
-  for (PRUint32 i = 0; i < mAttrCount; ++i) {
-    if (Attrs()[i].mName.Equals(aAttrName)) {
-      return &Attrs()[i].mValue;
-    }
-  }
-
-  return nsnull;
-}
-
-const nsAttrValue*
-nsMappedAttributes::GetAttr(const nsAString& aAttrName) const
-{
-  for (PRUint32 i = 0; i < mAttrCount; ++i) {
-    if (Attrs()[i].mName.Atom()->Equals(aAttrName)) {
-      return &Attrs()[i].mValue;
-    }
+  PRInt32 i = IndexOfAttr(aAttrName, kNameSpaceID_None);
+  if (i >= 0) {
+    return &Attrs()[i].mValue;
   }
 
   return nsnull;
 }
 
 bool
 nsMappedAttributes::Equals(const nsMappedAttributes* aOther) const
 {
@@ -236,22 +223,32 @@ nsMappedAttributes::GetExistingAttrNameF
       }
     }
   }
 
   return nsnull;
 }
 
 PRInt32
-nsMappedAttributes::IndexOfAttr(nsIAtom* aLocalName) const
+nsMappedAttributes::IndexOfAttr(nsIAtom* aLocalName, PRInt32 aNamespaceID) const
 {
   PRUint32 i;
-  for (i = 0; i < mAttrCount; ++i) {
-    if (Attrs()[i].mName.Equals(aLocalName)) {
-      return i;
+  if (aNamespaceID == kNameSpaceID_None) {
+    // This should be the common case so lets make an optimized loop
+    for (i = 0; i < mAttrCount; ++i) {
+      if (Attrs()[i].mName.Equals(aLocalName)) {
+        return i;
+      }
+    }
+  }
+  else {
+    for (i = 0; i < mAttrCount; ++i) {
+      if (Attrs()[i].mName.Equals(aLocalName, aNamespaceID)) {
+        return i;
+      }
     }
   }
 
   return -1;
 }
 
 size_t
 nsMappedAttributes::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
--- a/content/base/src/nsMappedAttributes.h
+++ b/content/base/src/nsMappedAttributes.h
@@ -29,17 +29,16 @@ public:
   void* operator new(size_t size, PRUint32 aAttrCount = 1) CPP_THROW_NEW;
 
   nsMappedAttributes* Clone(bool aWillAddAttr);
 
   NS_DECL_ISUPPORTS
 
   nsresult SetAndTakeAttr(nsIAtom* aAttrName, nsAttrValue& aValue);
   const nsAttrValue* GetAttr(nsIAtom* aAttrName) const;
-  const nsAttrValue* GetAttr(const nsAString& aAttrName) const;
 
   PRUint32 Count() const
   {
     return mAttrCount;
   }
 
   bool Equals(const nsMappedAttributes* aAttributes) const;
   PRUint32 HashValue() const;
@@ -63,17 +62,17 @@ public:
   {
     NS_ASSERTION(aPos < mAttrCount, "out-of-bounds");
     return &Attrs()[aPos].mValue;
   }
   // Remove the attr at position aPos.  The value of the attr is placed in
   // aValue; any value that was already in aValue is destroyed.
   void RemoveAttrAt(PRUint32 aPos, nsAttrValue& aValue);
   const nsAttrName* GetExistingAttrNameFromQName(const nsAString& aName) const;
-  PRInt32 IndexOfAttr(nsIAtom* aLocalName) const;
+  PRInt32 IndexOfAttr(nsIAtom* aLocalName, PRInt32 aNamespaceID) const;
   
 
   // nsIStyleRule 
   virtual void MapRuleInfoInto(nsRuleData* aRuleData);
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
 #endif
 
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -2444,17 +2444,17 @@ void
 nsGenericHTMLElement::MapCommonAttributesInto(const nsMappedAttributes* aAttributes,
                                               nsRuleData* aData)
 {
   nsGenericHTMLElement::MapCommonAttributesExceptHiddenInto(aAttributes, aData);
 
   if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Display)) {
     nsCSSValue* display = aData->ValueForDisplay();
     if (display->GetUnit() == eCSSUnit_Null) {
-      if (aAttributes->IndexOfAttr(nsGkAtoms::hidden) >= 0) {
+      if (aAttributes->IndexOfAttr(nsGkAtoms::hidden, kNameSpaceID_None) >= 0) {
         display->SetIntValue(NS_STYLE_DISPLAY_NONE, eCSSUnit_Enumerated);
       }
     }
   }
 }
 
 
 /* static */ const nsGenericHTMLElement::MappedAttributeEntry
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -1155,39 +1155,16 @@ nsXULElement::InternalGetExistingAttrNam
                 return attrName;
             }
         }
     }
 
     return nsnull;
 }
 
-const nsAttrValue*
-nsXULElement::GetAttrValue(const nsAString& aName)
-{
-  MOZ_ASSERT(!IsXUL(), "XUL does its own thing here");
-  const nsAttrValue* val =
-      mAttrsAndChildren.GetAttr(aName, eCaseMatters);
-  if (val) {
-      return val;
-  }
-
-  if (mPrototype) {
-      PRUint32 i, count = mPrototype->mNumAttributes;
-      for (i = 0; i < count; ++i) {
-          nsXULPrototypeAttribute *protoAttr = &mPrototype->mAttributes[i];
-          if (protoAttr->mName.QualifiedNameEquals(aName)) {
-              return &protoAttr->mValue;
-          }
-      }
-  }
-
-  return nsnull;
-}
-
 bool
 nsXULElement::GetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
                       nsAString& aResult) const
 {
     NS_ASSERTION(nsnull != aName, "must have attribute name");
     NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown,
                  "must have a real namespace ID!");
 
--- a/content/xul/content/src/nsXULElement.h
+++ b/content/xul/content/src/nsXULElement.h
@@ -483,18 +483,16 @@ public:
     // This function should ONLY be used by BindToTree implementations.
     // The function exists solely because XUL elements store the binding
     // parent as a member instead of in the slots, as nsGenericElement does.
     void SetXULBindingParent(nsIContent* aBindingParent)
     {
       mBindingParent = aBindingParent;
     }
 
-    const nsAttrValue* GetAttrValue(const nsAString& aName);
-
     /**
      * Get the attr info for the given namespace ID and attribute name.
      * The namespace ID must not be kNameSpaceID_Unknown and the name
      * must not be null.
      */
     virtual nsAttrInfo GetAttrInfo(PRInt32 aNamespaceID, nsIAtom* aName) const;
 
     virtual nsXPCClassInfo* GetClassInfo();