Bug 1184842. Change nsAttrAndChildArray::SetAndTakeAttr to nsAttrAndChildArray::SetAndSwapAttr. r=peterv
authorRobert O'Callahan <robert@ocallahan.org>
Wed, 22 Jul 2015 14:09:41 +1200
changeset 287665 1818b9f17a2648257aaa247f0620c6217e39483e
parent 287664 4e87cabdf930af16ba0c1b79b258df220203b2e8
child 287666 dd8314c68fb66569d9a44400e698b078e81b23c5
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs1184842
milestone42.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 1184842. Change nsAttrAndChildArray::SetAndTakeAttr to nsAttrAndChildArray::SetAndSwapAttr. r=peterv
dom/base/Element.cpp
dom/base/Element.h
dom/base/nsAttrAndChildArray.cpp
dom/base/nsAttrAndChildArray.h
dom/base/nsStyledElement.cpp
dom/svg/nsSVGElement.cpp
dom/xul/nsXULElement.cpp
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -2252,17 +2252,17 @@ Element::SetAttrAndNotify(int32_t aNames
   nsresult rv;
 
   nsIDocument* document = GetComposedDoc();
   mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
 
   nsMutationGuard::DidMutate();
 
   // Copy aParsedValue for later use since it will be lost when we call
-  // SetAndTakeMappedAttr below
+  // SetAndSwapMappedAttr below
   nsAttrValue aValueForAfterSetAttr;
   if (aCallAfterSetAttr) {
     aValueForAfterSetAttr.SetTo(aParsedValue);
   }
 
   bool hadValidDir = false;
   bool hadDirAuto = false;
 
@@ -2271,26 +2271,26 @@ Element::SetAttrAndNotify(int32_t aNames
       hadValidDir = HasValidDir() || IsHTMLElement(nsGkAtoms::bdi);
       hadDirAuto = HasDirAuto(); // already takes bdi into account
     }
 
     // XXXbz Perhaps we should push up the attribute mapping function
     // stuff to Element?
     if (!IsAttributeMapped(aName) ||
         !SetMappedAttribute(document, aName, aParsedValue, &rv)) {
-      rv = mAttrsAndChildren.SetAndTakeAttr(aName, aParsedValue);
+      rv = mAttrsAndChildren.SetAndSwapAttr(aName, aParsedValue);
     }
   }
   else {
     nsRefPtr<mozilla::dom::NodeInfo> ni;
     ni = mNodeInfo->NodeInfoManager()->GetNodeInfo(aName, aPrefix,
                                                    aNamespaceID,
                                                    nsIDOMNode::ATTRIBUTE_NODE);
 
-    rv = mAttrsAndChildren.SetAndTakeAttr(ni, aParsedValue);
+    rv = mAttrsAndChildren.SetAndSwapAttr(ni, aParsedValue);
   }
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (document || HasFlag(NODE_FORCE_XBL_BINDINGS)) {
     nsRefPtr<nsXBLBinding> binding = GetXBLBinding();
     if (binding) {
       binding->AttributeChanged(aName, aNamespaceID, false, aNotify);
     }
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -1085,17 +1085,18 @@ protected:
    * code readability.
    *
    * @param aNamespaceID  namespace of attribute
    * @param aAttribute    local-name of attribute
    * @param aPrefix       aPrefix of attribute
    * @param aOldValue     previous value of attribute. Only needed if
    *                      aFireMutation is true or if the element is a
    *                      custom element (in web components).
-   * @param aParsedValue  parsed new value of attribute
+   * @param aParsedValue  parsed new value of attribute. Replaced by the
+   *                      old value of the attribute.
    * @param aModType      nsIDOMMutationEvent::MODIFICATION or ADDITION.  Only
    *                      needed if aFireMutation or aNotify is true.
    * @param aFireMutation should mutation-events be fired?
    * @param aNotify       should we notify document-observers?
    * @param aCallAfterSetAttr should we call AfterSetAttr?
    */
   nsresult SetAttrAndNotify(int32_t aNamespaceID,
                             nsIAtom* aName,
--- a/dom/base/nsAttrAndChildArray.cpp
+++ b/dom/base/nsAttrAndChildArray.cpp
@@ -382,24 +382,22 @@ nsAttrAndChildArray::AttrAt(uint32_t aPo
   if (aPos < mapped) {
     return mImpl->mMappedAttrs->AttrAt(aPos);
   }
 
   return &ATTRS(mImpl)[aPos - mapped].mValue;
 }
 
 nsresult
-nsAttrAndChildArray::SetAndTakeAttr(nsIAtom* aLocalName, nsAttrValue& aValue)
+nsAttrAndChildArray::SetAndSwapAttr(nsIAtom* aLocalName, nsAttrValue& aValue)
 {
   uint32_t i, slotCount = AttrSlotCount();
   for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) {
     if (ATTRS(mImpl)[i].mName.Equals(aLocalName)) {
-      ATTRS(mImpl)[i].mValue.Reset();
       ATTRS(mImpl)[i].mValue.SwapValueWith(aValue);
-
       return NS_OK;
     }
   }
 
   NS_ENSURE_TRUE(i < ATTRCHILD_ARRAY_MAX_ATTR_COUNT,
                  NS_ERROR_FAILURE);
 
   if (i == slotCount && !AddAttrSlot()) {
@@ -409,22 +407,22 @@ nsAttrAndChildArray::SetAndTakeAttr(nsIA
   new (&ATTRS(mImpl)[i].mName) nsAttrName(aLocalName);
   new (&ATTRS(mImpl)[i].mValue) nsAttrValue();
   ATTRS(mImpl)[i].mValue.SwapValueWith(aValue);
 
   return NS_OK;
 }
 
 nsresult
-nsAttrAndChildArray::SetAndTakeAttr(mozilla::dom::NodeInfo* aName, nsAttrValue& aValue)
+nsAttrAndChildArray::SetAndSwapAttr(mozilla::dom::NodeInfo* aName, nsAttrValue& aValue)
 {
   int32_t namespaceID = aName->NamespaceID();
   nsIAtom* localName = aName->NameAtom();
   if (namespaceID == kNameSpaceID_None) {
-    return SetAndTakeAttr(localName, aValue);
+    return SetAndSwapAttr(localName, aValue);
   }
 
   uint32_t i, slotCount = AttrSlotCount();
   for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) {
     if (ATTRS(mImpl)[i].mName.Equals(localName, namespaceID)) {
       ATTRS(mImpl)[i].mName.SetTo(aName);
       ATTRS(mImpl)[i].mValue.Reset();
       ATTRS(mImpl)[i].mValue.SwapValueWith(aValue);
--- a/dom/base/nsAttrAndChildArray.h
+++ b/dom/base/nsAttrAndChildArray.h
@@ -83,18 +83,18 @@ public:
   // As above but using a string attr name and always using
   // kNameSpaceID_None.  This is always case-sensitive.
   const nsAttrValue* GetAttr(const nsAString& aName) 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(uint32_t aPos) const;
-  nsresult SetAndTakeAttr(nsIAtom* aLocalName, nsAttrValue& aValue);
-  nsresult SetAndTakeAttr(mozilla::dom::NodeInfo* aName, nsAttrValue& aValue);
+  nsresult SetAndSwapAttr(nsIAtom* aLocalName, nsAttrValue& aValue);
+  nsresult SetAndSwapAttr(mozilla::dom::NodeInfo* 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(uint32_t aPos, nsAttrValue& aValue);
 
   // Returns attribute name at given position, *not* out-of-bounds safe
   const nsAttrName* AttrNameAt(uint32_t aPos) const;
 
--- a/dom/base/nsStyledElement.cpp
+++ b/dom/base/nsStyledElement.cpp
@@ -133,17 +133,17 @@ nsStyledElementNotElementCSSInlineStyle:
   
   if (oldVal && oldVal->Type() != nsAttrValue::eCSSStyleRule) {
     nsAttrValue attrValue;
     nsAutoString stringValue;
     oldVal->ToString(stringValue);
     ParseStyleAttribute(stringValue, attrValue, aForceInDataDoc);
     // Don't bother going through SetInlineStyleRule, we don't want to fire off
     // mutation events or document notifications anyway
-    nsresult rv = mAttrsAndChildren.SetAndTakeAttr(nsGkAtoms::style, attrValue);
+    nsresult rv = mAttrsAndChildren.SetAndSwapAttr(nsGkAtoms::style, attrValue);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   
   return NS_OK;
 }
 
 void
 nsStyledElementNotElementCSSInlineStyle::ParseStyleAttribute(const nsAString& aValue,
--- a/dom/svg/nsSVGElement.cpp
+++ b/dom/svg/nsSVGElement.cpp
@@ -268,17 +268,17 @@ nsSVGElement::BindToTree(nsIDocument* aD
     // ownerDocument on XBL anonymous content, this can all go away.
     nsAttrValue attrValue;
     nsAutoString stringValue;
     oldVal->ToString(stringValue);
     // Force in data doc, since we already have a style rule
     ParseStyleAttribute(stringValue, attrValue, true);
     // Don't bother going through SetInlineStyleRule, we don't want to fire off
     // mutation events or document notifications anyway
-    rv = mAttrsAndChildren.SetAndTakeAttr(nsGkAtoms::style, attrValue);
+    rv = mAttrsAndChildren.SetAndSwapAttr(nsGkAtoms::style, attrValue);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
 nsresult
 nsSVGElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
@@ -1449,16 +1449,18 @@ nsSVGElement::WillChangeValue(nsIAtom* a
  *
  * aEmptyOrOldValue will normally be the object returned from the corresponding
  * WillChangeXXX call. This is because:
  * a) WillChangeXXX will ensure the object is set when we have mutation
  *    listeners, and
  * b) WillChangeXXX will ensure the object represents a serialized version of
  *    the old attribute value so that the value doesn't change when the
  *    underlying SVG type is updated.
+ *
+ * aNewValue is replaced with the old value.
  */
 void
 nsSVGElement::DidChangeValue(nsIAtom* aName,
                              const nsAttrValue& aEmptyOrOldValue,
                              nsAttrValue& aNewValue)
 {
   bool hasListeners =
     nsContentUtils::HasMutationListeners(this,
@@ -1484,17 +1486,17 @@ nsSVGElement::MaybeSerializeAttrBeforeRe
 
   const nsAttrValue* attrValue = mAttrsAndChildren.GetAttr(aName);
   if (!attrValue)
     return;
 
   nsAutoString serializedValue;
   attrValue->ToString(serializedValue);
   nsAttrValue oldAttrValue(serializedValue);
-  mAttrsAndChildren.SetAndTakeAttr(aName, oldAttrValue);
+  mAttrsAndChildren.SetAndSwapAttr(aName, oldAttrValue);
 }
 
 /* static */
 nsIAtom* nsSVGElement::GetEventNameForAttr(nsIAtom* aAttr)
 {
   if (aAttr == nsGkAtoms::onload)
     return nsGkAtoms::onSVGLoad;
   if (aAttr == nsGkAtoms::onunload)
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -399,20 +399,20 @@ nsXULElement::Clone(mozilla::dom::NodeIn
 
             nsRefPtr<css::StyleRule> styleRule = do_QueryObject(ruleClone);
             attrValue.SetTo(styleRule, &stringValue);
         } else {
             attrValue.SetTo(*originalValue);
         }
 
         if (originalName->IsAtom()) {
-           rv = element->mAttrsAndChildren.SetAndTakeAttr(originalName->Atom(),
+           rv = element->mAttrsAndChildren.SetAndSwapAttr(originalName->Atom(),
                                                           attrValue);
         } else {
-            rv = element->mAttrsAndChildren.SetAndTakeAttr(originalName->NodeInfo(),
+            rv = element->mAttrsAndChildren.SetAndSwapAttr(originalName->NodeInfo(),
                                                            attrValue);
         }
         NS_ENSURE_SUCCESS(rv, rv);
         element->AddListenerFor(*originalName, true);
         if (originalName->Equals(nsGkAtoms::id) &&
             !originalValue->IsEmptyString()) {
             element->SetHasID();
         }
@@ -1891,20 +1891,20 @@ nsXULElement::MakeHeavyweight(nsXULProto
             attrValue.SetTo(styleRule, &stringValue);
         }
         else {
             attrValue.SetTo(protoattr->mValue);
         }
 
         // XXX we might wanna have a SetAndTakeAttr that takes an nsAttrName
         if (protoattr->mName.IsAtom()) {
-            rv = mAttrsAndChildren.SetAndTakeAttr(protoattr->mName.Atom(), attrValue);
+            rv = mAttrsAndChildren.SetAndSwapAttr(protoattr->mName.Atom(), attrValue);
         }
         else {
-            rv = mAttrsAndChildren.SetAndTakeAttr(protoattr->mName.NodeInfo(),
+            rv = mAttrsAndChildren.SetAndSwapAttr(protoattr->mName.NodeInfo(),
                                                   attrValue);
         }
         NS_ENSURE_SUCCESS(rv, rv);
     }
     return NS_OK;
 }
 
 nsresult