Bug 1184842. Pass aOldValue to all mutation observers. r=peterv
authorRobert O'Callahan <robert@ocallahan.org>
Sat, 25 Jul 2015 18:01:19 +1200
changeset 276069 68a898398e3dbbb592b7c0b975e900cde95745c8
parent 276068 3148cb83d613efb72814e5b0b10dc0f2bfbfbc7b
child 276070 727955f60cd89654b981ad1da8783e9b9f02b9f4
push id8304
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 19:25:01 +0000
treeherdermozilla-aurora@7308dd0a6c3b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs1184842
milestone42.0a1
Bug 1184842. Pass aOldValue to all mutation observers. r=peterv
accessible/generic/DocAccessible.cpp
docshell/shistory/nsSHEntryShared.cpp
dom/base/ShadowRoot.cpp
dom/base/nsContentList.cpp
dom/base/nsFrameLoader.cpp
dom/base/nsIMutationObserver.h
dom/base/nsNodeUtils.cpp
dom/base/nsScriptElement.cpp
dom/base/nsTextNode.cpp
dom/events/IMEContentObserver.cpp
dom/html/HTMLPropertiesCollection.cpp
dom/html/nsDOMStringMap.cpp
dom/svg/SVGMPathElement.cpp
dom/svg/SVGUseElement.cpp
dom/xml/nsXMLPrettyPrinter.cpp
dom/xslt/xpath/XPathResult.cpp
dom/xslt/xslt/txMozillaXSLTProcessor.cpp
dom/xul/XULDocument.cpp
dom/xul/templates/nsXULContentBuilder.cpp
dom/xul/templates/nsXULTemplateBuilder.cpp
layout/base/nsPresShell.cpp
layout/generic/nsImageMap.cpp
layout/inspector/inDOMView.cpp
layout/svg/SVGTextFrame.cpp
layout/svg/nsSVGEffects.cpp
layout/xul/tree/nsTreeContentView.cpp
toolkit/components/satchel/nsFormFillController.cpp
widget/cocoa/nsMenuGroupOwnerX.mm
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -728,17 +728,18 @@ DocAccessible::AttributeWillChange(nsIDo
       aAttribute == nsGkAtoms::disabled)
     mStateBitWasOn = accessible->Unavailable();
 }
 
 void
 DocAccessible::AttributeChanged(nsIDocument* aDocument,
                                 dom::Element* aElement,
                                 int32_t aNameSpaceID, nsIAtom* aAttribute,
-                                int32_t aModType)
+                                int32_t aModType,
+                                const nsAttrValue* aOldValue)
 {
   NS_ASSERTION(!IsDefunct(),
                "Attribute changed called on defunct document accessible!");
 
   // Proceed even if the element is not accessible because element may become
   // accessible if it gets certain attribute.
   if (UpdateAccessibleOnAttrChange(aElement, aAttribute))
     return;
--- a/docshell/shistory/nsSHEntryShared.cpp
+++ b/docshell/shistory/nsSHEntryShared.cpp
@@ -331,17 +331,18 @@ nsSHEntryShared::AttributeWillChange(nsI
 {
 }
 
 void
 nsSHEntryShared::AttributeChanged(nsIDocument* aDocument,
                                   dom::Element* aElement,
                                   int32_t aNameSpaceID,
                                   nsIAtom* aAttribute,
-                                  int32_t aModType)
+                                  int32_t aModType,
+                                  const nsAttrValue* aOldValue)
 {
   RemoveFromBFCacheAsync();
 }
 
 void
 nsSHEntryShared::ContentAppended(nsIDocument* aDocument,
                                  nsIContent* aContainer,
                                  nsIContent* aFirstNewContent,
--- a/dom/base/ShadowRoot.cpp
+++ b/dom/base/ShadowRoot.cpp
@@ -602,17 +602,18 @@ ShadowRoot::IsPooledNode(nsIContent* aCo
   return false;
 }
 
 void
 ShadowRoot::AttributeChanged(nsIDocument* aDocument,
                              Element* aElement,
                              int32_t aNameSpaceID,
                              nsIAtom* aAttribute,
-                             int32_t aModType)
+                             int32_t aModType,
+                             const nsAttrValue* aOldValue)
 {
   if (!IsPooledNode(aElement, aElement->GetParent(), mPoolHost)) {
     return;
   }
 
   // Attributes may change insertion point matching, find its new distribution.
   RemoveDistributedNode(aElement);
   DistributeSingleNode(aElement);
--- a/dom/base/nsContentList.cpp
+++ b/dom/base/nsContentList.cpp
@@ -654,17 +654,18 @@ nsIContent*
 nsContentList::Item(uint32_t aIndex)
 {
   return GetElementAt(aIndex);
 }
 
 void
 nsContentList::AttributeChanged(nsIDocument *aDocument, Element* aElement,
                                 int32_t aNameSpaceID, nsIAtom* aAttribute,
-                                int32_t aModType)
+                                int32_t aModType,
+                                const nsAttrValue* aOldValue)
 {
   NS_PRECONDITION(aElement, "Must have a content node to work with");
   
   if (!mFunc || !mFuncMayDependOnAttr || mState == LIST_DIRTY ||
       !MayContainRelevantNodes(aElement->GetParentNode()) ||
       !nsContentUtils::IsInSameAnonymousTree(mRootNode, aElement)) {
     // Either we're already dirty or this notification doesn't affect
     // whether we might match aElement.
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -2585,17 +2585,18 @@ nsFrameLoader::ApplySandboxFlags(uint32_
   }
 }
 
 /* virtual */ void
 nsFrameLoader::AttributeChanged(nsIDocument* aDocument,
                                 mozilla::dom::Element* aElement,
                                 int32_t      aNameSpaceID,
                                 nsIAtom*     aAttribute,
-                                int32_t      aModType)
+                                int32_t      aModType,
+                                const nsAttrValue* aOldValue)
 {
   MOZ_ASSERT(mObservingOwnerContent);
   // TODO: Implement ContentShellAdded for remote browsers (bug 658304)
   MOZ_ASSERT(!mRemoteBrowser);
 
   if (aNameSpaceID != kNameSpaceID_None || aAttribute != TypeAttrName()) {
     return;
   }
--- a/dom/base/nsIMutationObserver.h
+++ b/dom/base/nsIMutationObserver.h
@@ -4,31 +4,31 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsIMutationObserver_h
 #define nsIMutationObserver_h
 
 #include "nsISupports.h"
 
+class nsAttrValue;
 class nsIAtom;
 class nsIContent;
 class nsIDocument;
 class nsINode;
 
 namespace mozilla {
 namespace dom {
 class Element;
 } // namespace dom
 } // namespace mozilla
 
 #define NS_IMUTATION_OBSERVER_IID \
-{ 0x16fe5e3e, 0xeadc, 0x4312, \
-  { 0x9d, 0x44, 0xb6, 0xbe, 0xdd, 0x6b, 0x54, 0x74 } }
-
+{ 0x51a4cec3, 0xb720, 0x4893, \
+  { 0xb1, 0x11, 0x33, 0xca, 0xbe, 0xae, 0xbf, 0x57 } }
 /**
  * Information details about a characterdata change.  Basically, we
  * view all changes as replacements of a length of text at some offset
  * with some other text (of possibly some other length).
  */
 struct CharacterDataChangeInfo
 {
   /**
@@ -175,28 +175,31 @@ public:
    *
    * @param aDocument    The owner-document of aContent. Can be null.
    * @param aElement     The element whose attribute changed
    * @param aNameSpaceID The namespace id of the changed attribute
    * @param aAttribute   The name of the changed attribute
    * @param aModType     Whether or not the attribute was added, changed, or
    *                     removed. The constants are defined in
    *                     nsIDOMMutationEvent.h.
+   * @param aOldValue    The old value, if either the old value or the new
+   *                     value are StoresOwnData() (or absent); null otherwise.
    *
    * @note Callers of this method might not hold a strong reference to the
    *       observer.  The observer is responsible for making sure it stays
    *       alive for the duration of the call as needed.  The observer may
    *       assume that this call will happen when there are script blockers on
    *       the stack.
    */
   virtual void AttributeChanged(nsIDocument* aDocument,
                                 mozilla::dom::Element* aElement,
                                 int32_t      aNameSpaceID,
                                 nsIAtom*     aAttribute,
-                                int32_t      aModType) = 0;
+                                int32_t      aModType,
+                                const nsAttrValue* aOldValue) = 0;
 
   /**
    * Notification that an attribute of an element has been
    * set to the value it already had.
    *
    * @param aDocument    The owner-document of aContent.
    * @param aElement     The element whose attribute changed
    * @param aNameSpaceID The namespace id of the changed attribute
@@ -338,17 +341,18 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIMutatio
                                      nsIAtom* aAttribute,                    \
                                      int32_t aModType) override;
 
 #define NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED                         \
     virtual void AttributeChanged(nsIDocument* aDocument,                    \
                                   mozilla::dom::Element* aElement,           \
                                   int32_t aNameSpaceID,                      \
                                   nsIAtom* aAttribute,                       \
-                                  int32_t aModType) override;
+                                  int32_t aModType,                          \
+                                  const nsAttrValue* aOldValue) override;
 
 #define NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED                          \
     virtual void ContentAppended(nsIDocument* aDocument,                     \
                                  nsIContent* aContainer,                     \
                                  nsIContent* aFirstNewContent,               \
                                  int32_t aNewIndexInContainer) override;
 
 #define NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED                          \
@@ -408,17 +412,18 @@ void                                    
                             int32_t aModType)                             \
 {                                                                         \
 }                                                                         \
 void                                                                      \
 _class::AttributeChanged(nsIDocument* aDocument,                          \
                          mozilla::dom::Element* aElement,                 \
                          int32_t aNameSpaceID,                            \
                          nsIAtom* aAttribute,                             \
-                         int32_t aModType)                                \
+                         int32_t aModType,                                \
+                         const nsAttrValue* aOldValue)                    \
 {                                                                         \
 }                                                                         \
 void                                                                      \
 _class::ContentAppended(nsIDocument* aDocument,                           \
                         nsIContent* aContainer,                           \
                         nsIContent* aFirstNewContent,                     \
                         int32_t aNewIndexInContainer)                     \
 {                                                                         \
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -136,17 +136,17 @@ nsNodeUtils::AttributeChanged(Element* a
                               int32_t aNameSpaceID,
                               nsIAtom* aAttribute,
                               int32_t aModType,
                               const nsAttrValue* aOldValue)
 {
   nsIDocument* doc = aElement->OwnerDoc();
   IMPL_MUTATION_NOTIFICATION(AttributeChanged, aElement,
                              (doc, aElement, aNameSpaceID, aAttribute,
-                              aModType));
+                              aModType, aOldValue));
 }
 
 void
 nsNodeUtils::AttributeSetToCurrentValue(Element* aElement,
                                         int32_t aNameSpaceID,
                                         nsIAtom* aAttribute)
 {
   nsIDocument* doc = aElement->OwnerDoc();
--- a/dom/base/nsScriptElement.cpp
+++ b/dom/base/nsScriptElement.cpp
@@ -78,17 +78,18 @@ nsScriptElement::CharacterDataChanged(ns
   MaybeProcessScript();
 }
 
 void
 nsScriptElement::AttributeChanged(nsIDocument* aDocument,
                                   Element* aElement,
                                   int32_t aNameSpaceID,
                                   nsIAtom* aAttribute,
-                                  int32_t aModType)
+                                  int32_t aModType,
+                                  const nsAttrValue* aOldValue)
 {
   MaybeProcessScript();
 }
 
 void
 nsScriptElement::ContentAppended(nsIDocument* aDocument,
                                  nsIContent* aContainer,
                                  nsIContent* aFirstNewContent,
--- a/dom/base/nsTextNode.cpp
+++ b/dom/base/nsTextNode.cpp
@@ -263,17 +263,18 @@ nsAttributeTextNode::UnbindFromTree(bool
   nsTextNode::UnbindFromTree(aDeep, aNullParent);
 }
 
 void
 nsAttributeTextNode::AttributeChanged(nsIDocument* aDocument,
                                       Element* aElement,
                                       int32_t aNameSpaceID,
                                       nsIAtom* aAttribute,
-                                      int32_t aModType)
+                                      int32_t aModType,
+                                      const nsAttrValue* aOldValue)
 {
   if (aNameSpaceID == mNameSpaceID && aAttribute == mAttrName &&
       aElement == mGrandparent) {
     // Since UpdateText notifies, do it when it's safe to run script.  Note
     // that if we get unbound while the event is up that's ok -- we'll just
     // have no grandparent when it fires, and will do nothing.
     void (nsAttributeTextNode::*update)() = &nsAttributeTextNode::UpdateText;
     nsCOMPtr<nsIRunnable> ev = NS_NewRunnableMethod(this, update);
--- a/dom/events/IMEContentObserver.cpp
+++ b/dom/events/IMEContentObserver.cpp
@@ -751,17 +751,18 @@ IMEContentObserver::AttributeWillChange(
     ContentEventHandler::GetNativeTextLength(content) : 0;
 }
 
 void
 IMEContentObserver::AttributeChanged(nsIDocument* aDocument,
                                      dom::Element* aElement,
                                      int32_t aNameSpaceID,
                                      nsIAtom* aAttribute,
-                                     int32_t aModType)
+                                     int32_t aModType,
+                                     const nsAttrValue* aOldValue)
 {
   mEndOfAddedTextCache.Clear();
   mStartOfRemovingTextRangeCache.Clear();
 
   bool causedByComposition = IsEditorHandlingEventForComposition();
   if (!mTextChangeData.IsValid() && causedByComposition &&
       !mUpdatePreference.WantChangesCausedByComposition()) {
     return;
--- a/dom/html/HTMLPropertiesCollection.cpp
+++ b/dom/html/HTMLPropertiesCollection.cpp
@@ -148,17 +148,18 @@ HTMLPropertiesCollection::NamedItem(cons
     propertyList = newPropertyList;
   }
   return propertyList;
 }
 
 void
 HTMLPropertiesCollection::AttributeChanged(nsIDocument *aDocument, Element* aElement,
                                            int32_t aNameSpaceID, nsIAtom* aAttribute,
-                                           int32_t aModType)
+                                           int32_t aModType,
+                                           const nsAttrValue* aOldValue)
 {
   mIsDirty = true;
 }
 
 void
 HTMLPropertiesCollection::ContentAppended(nsIDocument* aDocument, nsIContent* aContainer,
                                           nsIContent* aFirstNewContent,
                                           int32_t aNewIndexInContainer)
@@ -422,17 +423,18 @@ PropertyNodeList::GetValues(JSContext* a
     }
     aResult.AppendElement(v);
   }
 }
 
 void
 PropertyNodeList::AttributeChanged(nsIDocument* aDocument, Element* aElement,
                                    int32_t aNameSpaceID, nsIAtom* aAttribute,
-                                   int32_t aModType)
+                                   int32_t aModType,
+                                   const nsAttrValue* aOldValue)
 {
   mIsDirty = true;
 }
 
 void
 PropertyNodeList::ContentAppended(nsIDocument* aDocument, nsIContent* aContainer,
                                   nsIContent* aFirstNewContent,
                                   int32_t aNewIndexInContainer)
--- a/dom/html/nsDOMStringMap.cpp
+++ b/dom/html/nsDOMStringMap.cpp
@@ -254,17 +254,18 @@ bool nsDOMStringMap::AttrToDataProp(cons
   }
 
   return true;
 }
 
 void
 nsDOMStringMap::AttributeChanged(nsIDocument *aDocument, Element* aElement,
                                  int32_t aNameSpaceID, nsIAtom* aAttribute,
-                                 int32_t aModType)
+                                 int32_t aModType,
+                                 const nsAttrValue* aOldValue)
 {
   if ((aModType == nsIDOMMutationEvent::ADDITION ||
        aModType == nsIDOMMutationEvent::REMOVAL) &&
       aNameSpaceID == kNameSpaceID_None &&
       StringBeginsWith(nsDependentAtomString(aAttribute),
                        NS_LITERAL_STRING("data-"))) {
     ++mExpandoAndGeneration.generation;
   }
--- a/dom/svg/SVGMPathElement.cpp
+++ b/dom/svg/SVGMPathElement.cpp
@@ -160,17 +160,18 @@ SVGMPathElement::GetStringInfo()
 //----------------------------------------------------------------------
 // nsIMutationObserver methods
 
 void
 SVGMPathElement::AttributeChanged(nsIDocument* aDocument,
                                   Element* aElement,
                                   int32_t aNameSpaceID,
                                   nsIAtom* aAttribute,
-                                  int32_t aModType)
+                                  int32_t aModType,
+                                  const nsAttrValue* aOldValue)
 {
   if (aNameSpaceID == kNameSpaceID_None) {
     if (aAttribute == nsGkAtoms::d) {
       NotifyParentOfMpathChange(GetParent());
     }
   }
 }
 
--- a/dom/svg/SVGUseElement.cpp
+++ b/dom/svg/SVGUseElement.cpp
@@ -151,17 +151,18 @@ SVGUseElement::CharacterDataChanged(nsID
   }
 }
 
 void
 SVGUseElement::AttributeChanged(nsIDocument* aDocument,
                                 Element* aElement,
                                 int32_t aNameSpaceID,
                                 nsIAtom* aAttribute,
-                                int32_t aModType)
+                                int32_t aModType,
+                                const nsAttrValue* aOldValue)
 {
   if (nsContentUtils::IsInSameAnonymousTree(this, aElement)) {
     TriggerReclone();
   }
 }
 
 void
 SVGUseElement::ContentAppended(nsIDocument *aDocument,
--- a/dom/xml/nsXMLPrettyPrinter.cpp
+++ b/dom/xml/nsXMLPrettyPrinter.cpp
@@ -213,17 +213,18 @@ nsXMLPrettyPrinter::Unhook()
     NS_RELEASE_THIS();
 }
 
 void
 nsXMLPrettyPrinter::AttributeChanged(nsIDocument* aDocument,
                                      Element* aElement,
                                      int32_t aNameSpaceID,
                                      nsIAtom* aAttribute,
-                                     int32_t aModType)
+                                     int32_t aModType,
+                                     const nsAttrValue* aOldValue)
 {
     MaybeUnhook(aElement);
 }
 
 void
 nsXMLPrettyPrinter::ContentAppended(nsIDocument* aDocument,
                                     nsIContent* aContainer,
                                     nsIContent* aFirstNewContent,
--- a/dom/xslt/xpath/XPathResult.cpp
+++ b/dom/xslt/xpath/XPathResult.cpp
@@ -131,17 +131,18 @@ XPathResult::CharacterDataChanged(nsIDoc
     Invalidate(aContent);
 }
 
 void
 XPathResult::AttributeChanged(nsIDocument* aDocument,
                               Element* aElement,
                               int32_t aNameSpaceID,
                               nsIAtom* aAttribute,
-                              int32_t aModType)
+                              int32_t aModType,
+                              const nsAttrValue* aOldValue)
 {
     Invalidate(aElement);
 }
 
 void
 XPathResult::ContentAppended(nsIDocument* aDocument,
                              nsIContent* aContainer,
                              nsIContent* aFirstNewContent,
--- a/dom/xslt/xslt/txMozillaXSLTProcessor.cpp
+++ b/dom/xslt/xslt/txMozillaXSLTProcessor.cpp
@@ -1239,17 +1239,18 @@ txMozillaXSLTProcessor::CharacterDataCha
     mStylesheet = nullptr;
 }
 
 void
 txMozillaXSLTProcessor::AttributeChanged(nsIDocument* aDocument,
                                          Element* aElement,
                                          int32_t aNameSpaceID,
                                          nsIAtom* aAttribute,
-                                         int32_t aModType)
+                                         int32_t aModType,
+                                         const nsAttrValue* aOldValue)
 {
     mStylesheet = nullptr;
 }
 
 void
 txMozillaXSLTProcessor::ContentAppended(nsIDocument* aDocument,
                                         nsIContent* aContainer,
                                         nsIContent* aFirstNewContent,
--- a/dom/xul/XULDocument.cpp
+++ b/dom/xul/XULDocument.cpp
@@ -926,17 +926,18 @@ XULDocument::AttributeWillChange(nsIDocu
         nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
         RemoveElementFromRefMap(aElement);
     }
 }
 
 void
 XULDocument::AttributeChanged(nsIDocument* aDocument,
                               Element* aElement, int32_t aNameSpaceID,
-                              nsIAtom* aAttribute, int32_t aModType)
+                              nsIAtom* aAttribute, int32_t aModType,
+                              const nsAttrValue* aOldValue)
 {
     NS_ASSERTION(aDocument == this, "unexpected doc");
 
     // Might not need this, but be safe for now.
     nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
 
     // XXXbz check aNameSpaceID, dammit!
     // See if we need to update our ref map.
--- a/dom/xul/templates/nsXULContentBuilder.cpp
+++ b/dom/xul/templates/nsXULContentBuilder.cpp
@@ -1505,17 +1505,18 @@ nsXULContentBuilder::GetResultForContent
 // nsIDocumentObserver methods
 //
 
 void
 nsXULContentBuilder::AttributeChanged(nsIDocument* aDocument,
                                       Element*     aElement,
                                       int32_t      aNameSpaceID,
                                       nsIAtom*     aAttribute,
-                                      int32_t      aModType)
+                                      int32_t      aModType,
+                                      const nsAttrValue* aOldValue)
 {
     nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
 
     // Handle "open" and "close" cases. We do this handling before
     // we've notified the observer, so that content is already created
     // for the frame system to walk.
     if (aElement->GetNameSpaceID() == kNameSpaceID_XUL &&
         aAttribute == nsGkAtoms::open) {
@@ -1531,17 +1532,17 @@ nsXULContentBuilder::AttributeChanged(ns
         ((aAttribute == nsGkAtoms::sort) ||
          (aAttribute == nsGkAtoms::sortDirection) ||
          (aAttribute == nsGkAtoms::sortResource) ||
          (aAttribute == nsGkAtoms::sortResource2)))
         mSortState.initialized = false;
 
     // Pass along to the generic template builder.
     nsXULTemplateBuilder::AttributeChanged(aDocument, aElement, aNameSpaceID,
-                                           aAttribute, aModType);
+                                           aAttribute, aModType, aOldValue);
 }
 
 void
 nsXULContentBuilder::NodeWillBeDestroyed(const nsINode* aNode)
 {
     nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
     // Break circular references
     mContentSupportMap.Clear();
--- a/dom/xul/templates/nsXULTemplateBuilder.cpp
+++ b/dom/xul/templates/nsXULTemplateBuilder.cpp
@@ -1088,17 +1088,18 @@ nsXULTemplateBuilder::Observe(nsISupport
 // nsIDocumentOberver interface
 //
 
 void
 nsXULTemplateBuilder::AttributeChanged(nsIDocument* aDocument,
                                        Element*     aElement,
                                        int32_t      aNameSpaceID,
                                        nsIAtom*     aAttribute,
-                                       int32_t      aModType)
+                                       int32_t      aModType,
+                                       const nsAttrValue* aOldValue)
 {
     if (aElement == mRoot && aNameSpaceID == kNameSpaceID_None) {
         // Check for a change to the 'ref' attribute on an atom, in which
         // case we may need to nuke and rebuild the entire content model
         // beneath the element.
         if (aAttribute == nsGkAtoms::ref)
             nsContentUtils::AddScriptRunner(
                 NS_NewRunnableMethod(this, &nsXULTemplateBuilder::RunnableRebuild));
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -4252,17 +4252,18 @@ PresShell::AttributeWillChange(nsIDocume
   }
 }
 
 void
 PresShell::AttributeChanged(nsIDocument* aDocument,
                             Element*     aElement,
                             int32_t      aNameSpaceID,
                             nsIAtom*     aAttribute,
-                            int32_t      aModType)
+                            int32_t      aModType,
+                            const nsAttrValue* aOldValue)
 {
   NS_PRECONDITION(!mIsDocumentGone, "Unexpected AttributeChanged");
   NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument");
 
   // XXXwaterson it might be more elegant to wait until after the
   // initial reflow to begin observing the document. That would
   // squelch any other inappropriate notifications as well.
   if (mDidInitialize) {
--- a/layout/generic/nsImageMap.cpp
+++ b/layout/generic/nsImageMap.cpp
@@ -914,17 +914,18 @@ nsImageMap::MaybeUpdateAreas(nsIContent 
   }
 }
 
 void
 nsImageMap::AttributeChanged(nsIDocument*  aDocument,
                              dom::Element* aElement,
                              int32_t       aNameSpaceID,
                              nsIAtom*      aAttribute,
-                             int32_t       aModType)
+                             int32_t       aModType,
+                             const nsAttrValue* aOldValue)
 {
   // If the parent of the changing content node is our map then update
   // the map.  But only do this if the node is an HTML <area> or <a>
   // and the attribute that's changing is "shape" or "coords" -- those
   // are the only cases we care about.
   if ((aElement->NodeInfo()->Equals(nsGkAtoms::area) ||
        aElement->NodeInfo()->Equals(nsGkAtoms::a)) &&
       aElement->IsHTMLElement() &&
--- a/layout/inspector/inDOMView.cpp
+++ b/layout/inspector/inDOMView.cpp
@@ -627,17 +627,18 @@ void
 inDOMView::NodeWillBeDestroyed(const nsINode* aNode)
 {
   NS_NOTREACHED("Document destroyed while we're holding a strong ref to it");
 }
 
 void
 inDOMView::AttributeChanged(nsIDocument* aDocument, dom::Element* aElement,
                             int32_t aNameSpaceID, nsIAtom* aAttribute,
-                            int32_t aModType)
+                            int32_t aModType,
+                            const nsAttrValue* aOldValue)
 {
   if (!mTree) {
     return;
   }
 
   if (!(mWhatToShow & nsIDOMNodeFilter::SHOW_ATTRIBUTE)) {
     return;
   }
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -3462,17 +3462,18 @@ SVGTextFrame::MutationObserver::Characte
 }
 
 void
 SVGTextFrame::MutationObserver::AttributeChanged(
                                                 nsIDocument* aDocument,
                                                 mozilla::dom::Element* aElement,
                                                 int32_t aNameSpaceID,
                                                 nsIAtom* aAttribute,
-                                                int32_t aModType)
+                                                int32_t aModType,
+                                                const nsAttrValue* aOldValue)
 {
   if (!aElement->IsSVGElement()) {
     return;
   }
 
   // Attribute changes on this element will be handled by
   // SVGTextFrame::AttributeChanged.
   if (aElement == mFrame->GetContent()) {
--- a/layout/svg/nsSVGEffects.cpp
+++ b/layout/svg/nsSVGEffects.cpp
@@ -107,17 +107,18 @@ nsSVGRenderingObserver::NotifyEvictedFro
   StopListening();            // Remove ourselves from mutation-obs. list.
 }
 
 void
 nsSVGRenderingObserver::AttributeChanged(nsIDocument* aDocument,
                                          dom::Element* aElement,
                                          int32_t aNameSpaceID,
                                          nsIAtom* aAttribute,
-                                         int32_t aModType)
+                                         int32_t aModType,
+                                         const nsAttrValue* aOldValue)
 {
   // An attribute belonging to the element that we are observing *or one of its
   // descendants* has changed.
   //
   // In the case of observing a gradient element, say, we want to know if any
   // of its 'stop' element children change, but we don't actually want to do
   // anything for changes to SMIL element children, for example. Maybe it's not
   // worth having logic to optimize for that, but in most cases it could be a
--- a/layout/xul/tree/nsTreeContentView.cpp
+++ b/layout/xul/tree/nsTreeContentView.cpp
@@ -710,17 +710,18 @@ nsTreeContentView::GetIndexOfItem(nsIDOM
   return NS_OK;
 }
 
 void
 nsTreeContentView::AttributeChanged(nsIDocument*  aDocument,
                                     dom::Element* aElement,
                                     int32_t       aNameSpaceID,
                                     nsIAtom*      aAttribute,
-                                    int32_t       aModType)
+                                    int32_t       aModType,
+                                    const nsAttrValue* aOldValue)
 {
   // Lots of codepaths under here that do all sorts of stuff, so be safe.
   nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
 
   // Make sure this notification concerns us.
   // First check the tag to see if it's one that we care about.
 
   if (mBoxObject && (aElement == mRoot || aElement == mBody)) {
--- a/toolkit/components/satchel/nsFormFillController.cpp
+++ b/toolkit/components/satchel/nsFormFillController.cpp
@@ -109,17 +109,18 @@ nsFormFillController::~nsFormFillControl
 ////////////////////////////////////////////////////////////////////////
 //// nsIMutationObserver
 //
 
 void
 nsFormFillController::AttributeChanged(nsIDocument* aDocument,
                                        mozilla::dom::Element* aElement,
                                        int32_t aNameSpaceID,
-                                       nsIAtom* aAttribute, int32_t aModType)
+                                       nsIAtom* aAttribute, int32_t aModType,
+                                       const nsAttrValue* aOldValue)
 {
   if ((aAttribute == nsGkAtoms::type || aAttribute == nsGkAtoms::readonly ||
        aAttribute == nsGkAtoms::autocomplete) &&
       aNameSpaceID == kNameSpaceID_None) {
     nsCOMPtr<nsIDOMHTMLInputElement> focusedInput(mFocusedInput);
     // Reset the current state of the controller, unconditionally.
     StopControllingInput();
     // Then restart based on the new values.  We have to delay this
--- a/widget/cocoa/nsMenuGroupOwnerX.mm
+++ b/widget/cocoa/nsMenuGroupOwnerX.mm
@@ -95,17 +95,18 @@ void nsMenuGroupOwnerX::AttributeWillCha
 {
 }
 
 
 void nsMenuGroupOwnerX::AttributeChanged(nsIDocument* aDocument,
                                          dom::Element* aElement,
                                          int32_t aNameSpaceID,
                                          nsIAtom* aAttribute,
-                                         int32_t aModType)
+                                         int32_t aModType,
+                                         const nsAttrValue* aOldValue)
 {
   nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
   nsChangeObserver* obs = LookupContentChangeObserver(aElement);
   if (obs)
     obs->ObserveAttributeChanged(aDocument, aElement, aAttribute);
 }