Bug 1184842. Pass preparsed attribute values to nsNodeUtils::AttributeWillChange. r=peterv
authorRobert O'Callahan <robert@ocallahan.org>
Wed, 22 Jul 2015 15:53:35 +1200
changeset 287670 728a2b8ad48db210e76df3f2bb8d1975173142d7
parent 287669 727955f60cd89654b981ad1da8783e9b9f02b9f4
child 287671 feb5a318bf0a60f7b9bf8cd1750268374deaf478
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. Pass preparsed attribute values to nsNodeUtils::AttributeWillChange. r=peterv
dom/base/Element.cpp
dom/base/nsNodeUtils.cpp
dom/base/nsNodeUtils.h
layout/style/nsDOMCSSAttrDeclaration.cpp
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -2176,27 +2176,28 @@ Element::SetAttr(int32_t aNamespaceID, n
 
   if (OnlyNotifySameValueSet(aNamespaceID, aName, aPrefix, value, aNotify,
                              oldValue, &modType, &hasListeners)) {
     return NS_OK;
   }
 
   nsresult rv = BeforeSetAttr(aNamespaceID, aName, &value, aNotify);
   NS_ENSURE_SUCCESS(rv, rv);
+  nsAttrValue* preparsedAttrValue = value.GetStoredAttrValue();
 
   if (aNotify) {
-    nsNodeUtils::AttributeWillChange(this, aNamespaceID, aName, modType);
+    nsNodeUtils::AttributeWillChange(this, aNamespaceID, aName, modType,
+                                     preparsedAttrValue);
   }
 
   // Hold a script blocker while calling ParseAttribute since that can call
   // out to id-observers
   nsAutoScriptBlocker scriptBlocker;
 
   nsAttrValue attrValue;
-  nsAttrValue* preparsedAttrValue = value.GetStoredAttrValue();
   if (preparsedAttrValue) {
     attrValue.SwapValueWith(*preparsedAttrValue);
   }
   // Even the value was pre-parsed in BeforeSetAttr, we still need to call
   // ParseAttribute because it can have side effects.
   if (!ParseAttribute(aNamespaceID, aName, aValue, attrValue)) {
     attrValue.SetTo(aValue);
   }
@@ -2231,17 +2232,18 @@ Element::SetParsedAttr(int32_t aNamespac
                              oldValue, &modType, &hasListeners)) {
     return NS_OK;
   }
 
   nsresult rv = BeforeSetAttr(aNamespaceID, aName, &value, aNotify);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aNotify) {
-    nsNodeUtils::AttributeWillChange(this, aNamespaceID, aName, modType);
+    nsNodeUtils::AttributeWillChange(this, aNamespaceID, aName, modType,
+                                     &aParsedValue);
   }
 
   return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue,
                           aParsedValue, modType, hasListeners, aNotify,
                           kCallAfterSetAttr);
 }
 
 nsresult
@@ -2479,17 +2481,18 @@ Element::UnsetAttr(int32_t aNameSpaceID,
   nsresult rv = BeforeSetAttr(aNameSpaceID, aName, nullptr, aNotify);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsIDocument *document = GetComposedDoc();
   mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
 
   if (aNotify) {
     nsNodeUtils::AttributeWillChange(this, aNameSpaceID, aName,
-                                     nsIDOMMutationEvent::REMOVAL);
+                                     nsIDOMMutationEvent::REMOVAL,
+                                     nullptr);
   }
 
   bool hasMutationListeners = aNotify &&
     nsContentUtils::HasMutationListeners(this,
                                          NS_EVENT_BITS_MUTATION_ATTRMODIFIED,
                                          this);
 
   // Grab the attr node if needed before we remove it from the attr map
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -118,17 +118,18 @@ nsNodeUtils::CharacterDataChanged(nsICon
   IMPL_MUTATION_NOTIFICATION(CharacterDataChanged, aContent,
                              (doc, aContent, aInfo));
 }
 
 void
 nsNodeUtils::AttributeWillChange(Element* aElement,
                                  int32_t aNameSpaceID,
                                  nsIAtom* aAttribute,
-                                 int32_t aModType)
+                                 int32_t aModType,
+                                 const nsAttrValue* aNewValue)
 {
   nsIDocument* doc = aElement->OwnerDoc();
   IMPL_MUTATION_NOTIFICATION(AttributeWillChange, aElement,
                              (doc, aElement, aNameSpaceID, aAttribute,
                               aModType));
 }
 
 void
--- a/dom/base/nsNodeUtils.h
+++ b/dom/base/nsNodeUtils.h
@@ -43,22 +43,25 @@ public:
                                    CharacterDataChangeInfo* aInfo);
 
   /**
    * Send AttributeWillChange notifications to nsIMutationObservers.
    * @param aElement      Element whose data will change
    * @param aNameSpaceID  Namespace of changing attribute
    * @param aAttribute    Local-name of changing attribute
    * @param aModType      Type of change (add/change/removal)
+   * @param aNewValue     The parsed new value, but only if BeforeSetAttr
+   *                      preparsed it!!!
    * @see nsIMutationObserver::AttributeWillChange
    */
   static void AttributeWillChange(mozilla::dom::Element* aElement,
                                   int32_t aNameSpaceID,
                                   nsIAtom* aAttribute,
-                                  int32_t aModType);
+                                  int32_t aModType,
+                                  const nsAttrValue* aNewValue);
 
   /**
    * Send AttributeChanged notifications to nsIMutationObservers.
    * @param aElement      Element whose data changed
    * @param aNameSpaceID  Namespace of changed attribute
    * @param aAttribute    Local-name of changed attribute
    * @param aModType      Type of change (add/change/removal)
    * @param aOldValue     If the old value was StoresOwnData() (or absent),
--- a/layout/style/nsDOMCSSAttrDeclaration.cpp
+++ b/layout/style/nsDOMCSSAttrDeclaration.cpp
@@ -120,17 +120,18 @@ nsDOMCSSAttributeDeclaration::GetCSSDecl
   // BeginUpdate(), but this is a good chokepoint where we know we
   // plan to modify the CSSDeclaration, so need to notify
   // AttributeWillChange if this is inline style.
   if (!mIsSMILOverride &&
       ((aOperation == eOperation_Modify) ||
        (aOperation == eOperation_RemoveProperty && cssRule))) {
     nsNodeUtils::AttributeWillChange(mElement, kNameSpaceID_None,
                                      nsGkAtoms::style,
-                                     nsIDOMMutationEvent::MODIFICATION);
+                                     nsIDOMMutationEvent::MODIFICATION,
+                                     nullptr);
   }
 
   if (cssRule) {
     return cssRule->GetDeclaration();
   }
 
   if (aOperation != eOperation_Modify) {
     return nullptr;