Bug 1441547: Make character data change notifications use a const reference for the info parameter. r?smaug draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 27 Feb 2018 15:30:27 +0100
changeset 760412 0862ada3a18b298497c58ee54bef7f233ac76c62
parent 760407 c75e8b8142ccd3bc96d416266ea3d70aed488d73
child 760422 edb5394ef1cc300797f9057d5729a039c0339167
child 760923 013a10e7b9ecd135de97259f1af7c6c7aae85c71
push id100631
push userbmo:emilio@crisal.io
push dateTue, 27 Feb 2018 15:03:18 +0000
reviewerssmaug
bugs1441547
milestone60.0a1
Bug 1441547: Make character data change notifications use a const reference for the info parameter. r?smaug It's not intended to be mutated. MozReview-Commit-ID: 5nkD1YkidlV
accessible/generic/DocAccessible.cpp
docshell/shistory/nsSHEntryShared.cpp
dom/base/nsDOMMutationObserver.cpp
dom/base/nsGenericDOMDataNode.cpp
dom/base/nsIMutationObserver.h
dom/base/nsNodeUtils.cpp
dom/base/nsNodeUtils.h
dom/base/nsRange.cpp
dom/events/IMEContentObserver.cpp
dom/html/HTMLOutputElement.cpp
dom/html/HTMLStyleElement.cpp
dom/html/HTMLTextAreaElement.cpp
dom/html/HTMLTitleElement.cpp
dom/script/ScriptElement.cpp
dom/svg/SVGStyleElement.cpp
dom/svg/SVGTitleElement.cpp
dom/svg/SVGUseElement.cpp
dom/xslt/xpath/XPathResult.cpp
dom/xslt/xslt/txMozillaXSLTProcessor.cpp
layout/base/PresShell.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSFrameConstructor.h
layout/forms/nsTextControlFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsFrame.h
layout/generic/nsIFrame.h
layout/generic/nsTextFrame.cpp
layout/generic/nsTextFrame.h
layout/svg/SVGTextFrame.cpp
layout/xul/nsLeafBoxFrame.cpp
layout/xul/nsLeafBoxFrame.h
parser/html/nsHtml5TreeOperation.cpp
toolkit/components/satchel/nsFormFillController.cpp
widget/cocoa/nsMenuGroupOwnerX.mm
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -1136,24 +1136,24 @@ void
 DocAccessible::DocumentStatesChanged(nsIDocument* aDocument,
                                      EventStates aStateMask)
 {
 }
 
 void
 DocAccessible::CharacterDataWillChange(nsIDocument* aDocument,
                                        nsIContent* aContent,
-                                       CharacterDataChangeInfo* aInfo)
+                                       const CharacterDataChangeInfo&)
 {
 }
 
 void
 DocAccessible::CharacterDataChanged(nsIDocument* aDocument,
                                     nsIContent* aContent,
-                                    CharacterDataChangeInfo* aInfo)
+                                    const CharacterDataChangeInfo&)
 {
 }
 
 void
 DocAccessible::ContentInserted(nsIDocument* aDocument, nsIContent* aContainer,
                                nsIContent* aChild)
 {
 }
--- a/docshell/shistory/nsSHEntryShared.cpp
+++ b/docshell/shistory/nsSHEntryShared.cpp
@@ -250,24 +250,24 @@ void
 nsSHEntryShared::NodeWillBeDestroyed(const nsINode* aNode)
 {
   NS_NOTREACHED("Document destroyed while we're holding a strong ref to it");
 }
 
 void
 nsSHEntryShared::CharacterDataWillChange(nsIDocument* aDocument,
                                          nsIContent* aContent,
-                                         CharacterDataChangeInfo* aInfo)
+                                         const CharacterDataChangeInfo&)
 {
 }
 
 void
 nsSHEntryShared::CharacterDataChanged(nsIDocument* aDocument,
                                       nsIContent* aContent,
-                                      CharacterDataChangeInfo* aInfo)
+                                      const CharacterDataChangeInfo&)
 {
   RemoveFromBFCacheAsync();
 }
 
 void
 nsSHEntryShared::AttributeWillChange(nsIDocument* aDocument,
                                      dom::Element* aContent,
                                      int32_t aNameSpaceID,
--- a/dom/base/nsDOMMutationObserver.cpp
+++ b/dom/base/nsDOMMutationObserver.cpp
@@ -185,19 +185,19 @@ nsMutationReceiver::AttributeWillChange(
   if (AttributeOldValue() && m->mPrevValue.IsVoid()) {
     if (!aElement->GetAttr(aNameSpaceID, aAttribute, m->mPrevValue)) {
       m->mPrevValue.SetIsVoid(true);
     }
   }
 }
 
 void
-nsMutationReceiver::CharacterDataWillChange(nsIDocument *aDocument,
+nsMutationReceiver::CharacterDataWillChange(nsIDocument* aDocument,
                                             nsIContent* aContent,
-                                            CharacterDataChangeInfo* aInfo)
+                                            const CharacterDataChangeInfo&)
 {
   if (nsAutoMutationBatch::IsBatching() ||
       !CharacterData() ||
       (!Subtree() && aContent != Target()) ||
       (Subtree() && RegisterTarget()->SubtreeRoot() != aContent->SubtreeRoot()) ||
       !IsObservable(aContent)) {
     return;
   }
--- a/dom/base/nsGenericDOMDataNode.cpp
+++ b/dom/base/nsGenericDOMDataNode.cpp
@@ -301,17 +301,17 @@ nsGenericDOMDataNode::SetTextInternal(ui
   if (aNotify) {
     CharacterDataChangeInfo info = {
       aOffset == textLength,
       aOffset,
       endOffset,
       aLength,
       aDetails
     };
-    nsNodeUtils::CharacterDataWillChange(this, &info);
+    nsNodeUtils::CharacterDataWillChange(this, info);
   }
 
   Directionality oldDir = eDir_NotSet;
   bool dirAffectsAncestor = (NodeType() == TEXT_NODE &&
                              TextNodeWillChangeDirection(this, &oldDir, aOffset));
 
   if (aOffset == 0 && endOffset == textLength) {
     // Replacing whole text or old text was empty.  Don't bother to check for
@@ -385,17 +385,17 @@ nsGenericDOMDataNode::SetTextInternal(ui
   if (aNotify) {
     CharacterDataChangeInfo info = {
       aOffset == textLength,
       aOffset,
       endOffset,
       aLength,
       aDetails
     };
-    nsNodeUtils::CharacterDataChanged(this, &info);
+    nsNodeUtils::CharacterDataChanged(this, info);
 
     if (haveMutationListeners) {
       InternalMutationEvent mutation(true, eLegacyCharacterDataModified);
 
       mutation.mPrevAttrValue = oldValue;
       if (aLength > 0) {
         nsAutoString val;
         mText.AppendTo(val);
--- a/dom/base/nsIMutationObserver.h
+++ b/dom/base/nsIMutationObserver.h
@@ -113,19 +113,19 @@ public:
    * @param aInfo     The structure with information details about the change.
    *
    * @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 CharacterDataWillChange(nsIDocument *aDocument,
+  virtual void CharacterDataWillChange(nsIDocument* aDocument,
                                        nsIContent* aContent,
-                                       CharacterDataChangeInfo* aInfo) = 0;
+                                       const CharacterDataChangeInfo&) = 0;
 
   /**
    * Notification that the node value of a data node (text, cdata, pi, comment)
    * has changed.
    *
    * This notification is not sent when a piece of content is
    * added/removed from the document (the other notifications are used
    * for that).
@@ -135,19 +135,19 @@ public:
    * @param aInfo     The structure with information details about the change.
    *
    * @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 CharacterDataChanged(nsIDocument *aDocument,
+  virtual void CharacterDataChanged(nsIDocument* aDocument,
                                     nsIContent* aContent,
-                                    CharacterDataChangeInfo* aInfo) = 0;
+                                    const CharacterDataChangeInfo&) = 0;
 
   /**
    * Notification that an attribute of an element will change.  This
    * can happen before the BeginUpdate for the change and may not
    * always be followed by an AttributeChanged (in particular, if the
    * attribute doesn't actually change there will be no corresponding
    * AttributeChanged).
    *
@@ -236,17 +236,17 @@ public:
    * @param aFirstNewContent the node at aIndexInContainer in aContainer.
    *
    * @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 ContentAppended(nsIDocument *aDocument,
+  virtual void ContentAppended(nsIDocument* aDocument,
                                nsIContent* aContainer,
                                nsIContent* aFirstNewContent) = 0;
 
   /**
    * Notification that a content node has been inserted as child to another
    * node in the tree.
    *
    * @param aDocument  The owner-document of aContent, or, when aContainer
@@ -259,17 +259,17 @@ public:
    * @param aIndexInContainer The index in the container of the new child.
    *
    * @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 ContentInserted(nsIDocument *aDocument,
+  virtual void ContentInserted(nsIDocument* aDocument,
                                nsIContent* aContainer,
                                nsIContent* aChild) = 0;
 
   /**
    * Notification that a content node has been removed from the child list of
    * another node in the tree.
    *
    * @param aDocument  The owner-document of aContent, or, when aContainer
@@ -285,17 +285,17 @@ public:
    *                         Can be null if there was no previous sibling.
    *
    * @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 ContentRemoved(nsIDocument *aDocument,
+  virtual void ContentRemoved(nsIDocument* aDocument,
                               nsIContent* aContainer,
                               nsIContent* aChild,
                               nsIContent* aPreviousSibling) = 0;
 
  /**
    * The node is in the process of being destroyed. Calling QI on the node is
    * not supported, however it is possible to get children and flags through
    * nsINode as well as calling IsContent and casting to nsIContent to get
@@ -333,22 +333,22 @@ public:
   virtual void ParentChainChanged(nsIContent *aContent) = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIMutationObserver, NS_IMUTATION_OBSERVER_IID)
 
 #define NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATAWILLCHANGE                  \
     virtual void CharacterDataWillChange(nsIDocument* aDocument,             \
                                          nsIContent* aContent,               \
-                                         CharacterDataChangeInfo* aInfo) override;
+                                         const CharacterDataChangeInfo& aInfo) override;
 
 #define NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED                     \
     virtual void CharacterDataChanged(nsIDocument* aDocument,                \
                                       nsIContent* aContent,                  \
-                                      CharacterDataChangeInfo* aInfo) override;
+                                      const CharacterDataChangeInfo& aInfo) override;
 
 #define NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE                      \
     virtual void AttributeWillChange(nsIDocument* aDocument,                 \
                                      mozilla::dom::Element* aElement,        \
                                      int32_t aNameSpaceID,                   \
                                      nsAtom* aAttribute,                    \
                                      int32_t aModType,                       \
                                      const nsAttrValue* aNewValue) override;
@@ -405,23 +405,23 @@ void                                    
 _class::NodeWillBeDestroyed(const nsINode* aNode)                               \
 {                                                                         \
 }
 
 #define NS_IMPL_NSIMUTATIONOBSERVER_CONTENT(_class)                       \
 void                                                                      \
 _class::CharacterDataWillChange(nsIDocument* aDocument,                   \
                                 nsIContent* aContent,                     \
-                                CharacterDataChangeInfo* aInfo)           \
+                                const CharacterDataChangeInfo& aInfo)     \
 {                                                                         \
 }                                                                         \
 void                                                                      \
 _class::CharacterDataChanged(nsIDocument* aDocument,                      \
                              nsIContent* aContent,                        \
-                             CharacterDataChangeInfo* aInfo)              \
+                             const CharacterDataChangeInfo& aInfo)        \
 {                                                                         \
 }                                                                         \
 void                                                                      \
 _class::AttributeWillChange(nsIDocument* aDocument,                       \
                             mozilla::dom::Element* aElement,              \
                             int32_t aNameSpaceID,                         \
                             nsAtom* aAttribute,                          \
                             int32_t aModType,                             \
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -125,26 +125,26 @@ enum class IsRemoveNotification
   } while (node);                                                 \
   if (needsEnterLeave) {                                          \
     nsDOMMutationObserver::LeaveMutationHandling();               \
   }                                                               \
   PR_END_MACRO
 
 void
 nsNodeUtils::CharacterDataWillChange(nsIContent* aContent,
-                                     CharacterDataChangeInfo* aInfo)
+                                     const CharacterDataChangeInfo& aInfo)
 {
   nsIDocument* doc = aContent->OwnerDoc();
   IMPL_MUTATION_NOTIFICATION(CharacterDataWillChange, aContent,
                              (doc, aContent, aInfo), IsRemoveNotification::No);
 }
 
 void
 nsNodeUtils::CharacterDataChanged(nsIContent* aContent,
-                                  CharacterDataChangeInfo* aInfo)
+                                  const CharacterDataChangeInfo& aInfo)
 {
   nsIDocument* doc = aContent->OwnerDoc();
   IMPL_MUTATION_NOTIFICATION(CharacterDataChanged, aContent,
                              (doc, aContent, aInfo), IsRemoveNotification::No);
 }
 
 void
 nsNodeUtils::AttributeWillChange(Element* aElement,
--- a/dom/base/nsNodeUtils.h
+++ b/dom/base/nsNodeUtils.h
@@ -29,26 +29,26 @@ class nsNodeUtils
 public:
   /**
    * Send CharacterDataWillChange notifications to nsIMutationObservers.
    * @param aContent  Node whose data changed
    * @param aInfo     Struct with information details about the change
    * @see nsIMutationObserver::CharacterDataWillChange
    */
   static void CharacterDataWillChange(nsIContent* aContent,
-                                      CharacterDataChangeInfo* aInfo);
+                                      const CharacterDataChangeInfo&);
 
   /**
    * Send CharacterDataChanged notifications to nsIMutationObservers.
    * @param aContent  Node whose data changed
    * @param aInfo     Struct with information details about the change
    * @see nsIMutationObserver::CharacterDataChanged
    */
   static void CharacterDataChanged(nsIContent* aContent,
-                                   CharacterDataChangeInfo* aInfo);
+                                   const CharacterDataChangeInfo&);
 
   /**
    * 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
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -514,153 +514,153 @@ nsRange::UnregisterCommonAncestor(nsINod
 }
 
 /******************************************************
  * nsIMutationObserver implementation
  ******************************************************/
 void
 nsRange::CharacterDataChanged(nsIDocument* aDocument,
                               nsIContent* aContent,
-                              CharacterDataChangeInfo* aInfo)
+                              const CharacterDataChangeInfo& aInfo)
 {
   MOZ_ASSERT(!mNextEndRef);
   MOZ_ASSERT(!mNextStartRef);
   MOZ_ASSERT(mIsPositioned, "shouldn't be notified if not positioned");
 
   nsINode* newRoot = nullptr;
   RawRangeBoundary newStart;
   RawRangeBoundary newEnd;
 
-  if (aInfo->mDetails &&
-      aInfo->mDetails->mType == CharacterDataChangeInfo::Details::eSplit) {
+  if (aInfo.mDetails &&
+      aInfo.mDetails->mType == CharacterDataChangeInfo::Details::eSplit) {
     // If the splitted text node is immediately before a range boundary point
     // that refers to a child index (i.e. its parent is the boundary container)
     // then we need to adjust the corresponding boundary to account for the new
     // text node that will be inserted. However, because the new sibling hasn't
     // been inserted yet, that would result in an invalid boundary. Therefore,
     // we store the new child in mNext*Ref to make sure we adjust the boundary
     // in the next ContentInserted or ContentAppended call.
     nsINode* parentNode = aContent->GetParentNode();
     if (parentNode == mEnd.Container()) {
       if (aContent == mEnd.Ref()) {
-        MOZ_ASSERT(aInfo->mDetails->mNextSibling);
-        mNextEndRef = aInfo->mDetails->mNextSibling;
+        MOZ_ASSERT(aInfo.mDetails->mNextSibling);
+        mNextEndRef = aInfo.mDetails->mNextSibling;
       }
     }
 
     if (parentNode == mStart.Container()) {
       if (aContent == mStart.Ref()) {
-        MOZ_ASSERT(aInfo->mDetails->mNextSibling);
-        mNextStartRef = aInfo->mDetails->mNextSibling;
+        MOZ_ASSERT(aInfo.mDetails->mNextSibling);
+        mNextStartRef = aInfo.mDetails->mNextSibling;
       }
     }
   }
 
   // If the changed node contains our start boundary and the change starts
   // before the boundary we'll need to adjust the offset.
-  if (aContent == mStart.Container() && aInfo->mChangeStart < mStart.Offset()) {
-    if (aInfo->mDetails) {
+  if (aContent == mStart.Container() && aInfo.mChangeStart < mStart.Offset()) {
+    if (aInfo.mDetails) {
       // splitText(), aInfo->mDetails->mNextSibling is the new text node
-      NS_ASSERTION(aInfo->mDetails->mType ==
+      NS_ASSERTION(aInfo.mDetails->mType ==
                    CharacterDataChangeInfo::Details::eSplit,
                    "only a split can start before the end");
-      NS_ASSERTION(mStart.Offset() <= aInfo->mChangeEnd + 1,
+      NS_ASSERTION(mStart.Offset() <= aInfo.mChangeEnd + 1,
                    "mStart.Offset() is beyond the end of this node");
-      int32_t newStartOffset = mStart.Offset() - aInfo->mChangeStart;
-      newStart.Set(aInfo->mDetails->mNextSibling, newStartOffset);
+      int32_t newStartOffset = mStart.Offset() - aInfo.mChangeStart;
+      newStart.Set(aInfo.mDetails->mNextSibling, newStartOffset);
       if (MOZ_UNLIKELY(aContent == mRoot)) {
         newRoot = IsValidBoundary(newStart.Container());
       }
 
       bool isCommonAncestor =
         IsInSelection() && mStart.Container() == mEnd.Container();
       if (isCommonAncestor) {
         UnregisterCommonAncestor(mStart.Container(), false);
         RegisterCommonAncestor(newStart.Container());
       }
       if (mStart.Container()->IsDescendantOfCommonAncestorForRangeInSelection()) {
         newStart.Container()->SetDescendantOfCommonAncestorForRangeInSelection();
       }
     } else {
       // If boundary is inside changed text, position it before change
       // else adjust start offset for the change in length.
-      int32_t newStartOffset = mStart.Offset() <= aInfo->mChangeEnd ?
-        aInfo->mChangeStart :
-        mStart.Offset() + aInfo->mChangeStart - aInfo->mChangeEnd +
-          aInfo->mReplaceLength;
+      int32_t newStartOffset = mStart.Offset() <= aInfo.mChangeEnd ?
+        aInfo.mChangeStart :
+        mStart.Offset() + aInfo.mChangeStart - aInfo.mChangeEnd +
+          aInfo.mReplaceLength;
       newStart.Set(mStart.Container(), newStartOffset);
     }
   }
 
   // Do the same thing for the end boundary, except for splitText of a node
   // with no parent then only switch to the new node if the start boundary
   // did so too (otherwise the range would end up with disconnected nodes).
-  if (aContent == mEnd.Container() && aInfo->mChangeStart < mEnd.Offset()) {
-    if (aInfo->mDetails && (aContent->GetParentNode() || newStart.Container())) {
-      // splitText(), aInfo->mDetails->mNextSibling is the new text node
-      NS_ASSERTION(aInfo->mDetails->mType ==
+  if (aContent == mEnd.Container() && aInfo.mChangeStart < mEnd.Offset()) {
+    if (aInfo.mDetails && (aContent->GetParentNode() || newStart.Container())) {
+      // splitText(), aInfo.mDetails->mNextSibling is the new text node
+      NS_ASSERTION(aInfo.mDetails->mType ==
                    CharacterDataChangeInfo::Details::eSplit,
                    "only a split can start before the end");
-      NS_ASSERTION(mEnd.Offset() <= aInfo->mChangeEnd + 1,
+      NS_ASSERTION(mEnd.Offset() <= aInfo.mChangeEnd + 1,
                    "mEnd.Offset() is beyond the end of this node");
-      newEnd.Set(aInfo->mDetails->mNextSibling, mEnd.Offset() - aInfo->mChangeStart);
+      newEnd.Set(aInfo.mDetails->mNextSibling, mEnd.Offset() - aInfo.mChangeStart);
 
       bool isCommonAncestor =
         IsInSelection() && mStart.Container() == mEnd.Container();
       if (isCommonAncestor && !newStart.Container()) {
         // The split occurs inside the range.
         UnregisterCommonAncestor(mStart.Container(), false);
         RegisterCommonAncestor(mStart.Container()->GetParentNode());
         newEnd.Container()->SetDescendantOfCommonAncestorForRangeInSelection();
       } else if (mEnd.Container()->
                    IsDescendantOfCommonAncestorForRangeInSelection()) {
         newEnd.Container()->SetDescendantOfCommonAncestorForRangeInSelection();
       }
     } else {
-      int32_t newEndOffset = mEnd.Offset() <= aInfo->mChangeEnd ?
-        aInfo->mChangeStart :
-        mEnd.Offset() + aInfo->mChangeStart - aInfo->mChangeEnd +
-          aInfo->mReplaceLength;
+      int32_t newEndOffset = mEnd.Offset() <= aInfo.mChangeEnd ?
+        aInfo.mChangeStart :
+        mEnd.Offset() + aInfo.mChangeStart - aInfo.mChangeEnd +
+          aInfo.mReplaceLength;
       newEnd.Set(mEnd.Container(), newEndOffset);
     }
   }
 
-  if (aInfo->mDetails &&
-      aInfo->mDetails->mType == CharacterDataChangeInfo::Details::eMerge) {
-    // normalize(), aInfo->mDetails->mNextSibling is the merged text node
+  if (aInfo.mDetails &&
+      aInfo.mDetails->mType == CharacterDataChangeInfo::Details::eMerge) {
+    // normalize(), aInfo.mDetails->mNextSibling is the merged text node
     // that will be removed
-    nsIContent* removed = aInfo->mDetails->mNextSibling;
+    nsIContent* removed = aInfo.mDetails->mNextSibling;
     if (removed == mStart.Container()) {
-      newStart.Set(aContent, mStart.Offset() + aInfo->mChangeStart);
+      newStart.Set(aContent, mStart.Offset() + aInfo.mChangeStart);
       if (MOZ_UNLIKELY(removed == mRoot)) {
         newRoot = IsValidBoundary(newStart.Container());
       }
     }
     if (removed == mEnd.Container()) {
-      newEnd.Set(aContent, mEnd.Offset() + aInfo->mChangeStart);
+      newEnd.Set(aContent, mEnd.Offset() + aInfo.mChangeStart);
       if (MOZ_UNLIKELY(removed == mRoot)) {
         newRoot = IsValidBoundary(newEnd.Container());
       }
     }
     // When the removed text node's parent is one of our boundary nodes we may
     // need to adjust the offset to account for the removed node. However,
     // there will also be a ContentRemoved notification later so the only cases
     // we need to handle here is when the removed node is the text node after
     // the boundary.  (The m*Offset > 0 check is an optimization - a boundary
     // point before the first child is never affected by normalize().)
     nsINode* parentNode = aContent->GetParentNode();
     if (parentNode == mStart.Container() && mStart.Offset() > 0 &&
         mStart.Offset() < parentNode->GetChildCount() &&
         removed == mStart.GetChildAtOffset()) {
-      newStart.Set(aContent, aInfo->mChangeStart);
+      newStart.Set(aContent, aInfo.mChangeStart);
     }
     if (parentNode == mEnd.Container() && mEnd.Offset() > 0 &&
         mEnd.Offset() < parentNode->GetChildCount() &&
         removed == mEnd.GetChildAtOffset()) {
-      newEnd.Set(aContent, aInfo->mChangeEnd);
+      newEnd.Set(aContent, aInfo.mChangeEnd);
     }
   }
 
   if (newStart.IsSet() || newEnd.IsSet()) {
     if (!newStart.IsSet()) {
       newStart = mStart;
     }
     if (!newEnd.IsSet()) {
--- a/dom/events/IMEContentObserver.cpp
+++ b/dom/events/IMEContentObserver.cpp
@@ -922,17 +922,17 @@ IMEContentObserver::OnMouseButtonEvent(n
     aMouseEvent->PreventDefault();
   }
   return consumed;
 }
 
 void
 IMEContentObserver::CharacterDataWillChange(nsIDocument* aDocument,
                                             nsIContent* aContent,
-                                            CharacterDataChangeInfo* aInfo)
+                                            const CharacterDataChangeInfo& aInfo)
 {
   NS_ASSERTION(aContent->IsNodeOfType(nsINode::eTEXT),
                "character data changed for non-text node");
   MOZ_ASSERT(mPreCharacterDataChangeLength < 0,
              "CharacterDataChanged() should've reset "
              "mPreCharacterDataChangeLength");
 
   if (!NeedsTextChangeNotification() ||
@@ -945,27 +945,27 @@ IMEContentObserver::CharacterDataWillCha
 
   // Although we don't assume this change occurs while this is storing
   // the range of added consecutive nodes, if it actually happens, we need to
   // flush them since this change may occur before or in the range.  So, it's
   // safe to flush pending computation of mTextChangeData before handling this.
   MaybeNotifyIMEOfAddedTextDuringDocumentChange();
 
   mPreCharacterDataChangeLength =
-    ContentEventHandler::GetNativeTextLength(aContent, aInfo->mChangeStart,
-                                             aInfo->mChangeEnd);
+    ContentEventHandler::GetNativeTextLength(aContent, aInfo.mChangeStart,
+                                             aInfo.mChangeEnd);
   MOZ_ASSERT(mPreCharacterDataChangeLength >=
-               aInfo->mChangeEnd - aInfo->mChangeStart,
+               aInfo.mChangeEnd - aInfo.mChangeStart,
              "The computed length must be same as or larger than XP length");
 }
 
 void
 IMEContentObserver::CharacterDataChanged(nsIDocument* aDocument,
                                          nsIContent* aContent,
-                                         CharacterDataChangeInfo* aInfo)
+                                         const CharacterDataChangeInfo& aInfo)
 {
   NS_ASSERTION(aContent->IsNodeOfType(nsINode::eTEXT),
                "character data changed for non-text node");
 
   if (!NeedsTextChangeNotification() ||
       !nsContentUtils::IsInSameAnonymousTree(mRootContent, aContent)) {
     return;
   }
@@ -982,26 +982,26 @@ IMEContentObserver::CharacterDataChanged
              "mPreCharacterDataChangeLength should've been set by "
              "CharacterDataWillChange()");
 
   uint32_t offset = 0;
   // get offsets of change and fire notification
   nsresult rv =
     ContentEventHandler::GetFlatTextLengthInRange(
                            NodePosition(mRootContent, 0),
-                           NodePosition(aContent, aInfo->mChangeStart),
+                           NodePosition(aContent, aInfo.mChangeStart),
                            mRootContent, &offset, LINE_BREAK_TYPE_NATIVE);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return;
   }
 
   uint32_t newLength =
-    ContentEventHandler::GetNativeTextLength(aContent, aInfo->mChangeStart,
-                                             aInfo->mChangeStart +
-                                               aInfo->mReplaceLength);
+    ContentEventHandler::GetNativeTextLength(aContent, aInfo.mChangeStart,
+                                             aInfo.mChangeStart +
+                                               aInfo.mReplaceLength);
 
   uint32_t oldEnd = offset + static_cast<uint32_t>(removedLength);
   uint32_t newEnd = offset + newLength;
 
   TextChangeData data(offset, oldEnd, newEnd,
                       IsEditorHandlingEventForComposition(),
                       IsEditorComposing());
   MaybeNotifyIMEOfTextChange(data);
--- a/dom/html/HTMLOutputElement.cpp
+++ b/dom/html/HTMLOutputElement.cpp
@@ -176,17 +176,17 @@ void HTMLOutputElement::DescendantsChang
     nsContentUtils::GetNodeTextContent(this, true, mDefaultValue);
   }
 }
 
 // nsIMutationObserver
 
 void HTMLOutputElement::CharacterDataChanged(nsIDocument* aDocument,
                                              nsIContent* aContent,
-                                             CharacterDataChangeInfo* aInfo)
+                                             const CharacterDataChangeInfo&)
 {
   DescendantsChanged();
 }
 
 void HTMLOutputElement::ContentAppended(nsIDocument* aDocument,
                                         nsIContent* aContainer,
                                         nsIContent* aFirstNewContent)
 {
--- a/dom/html/HTMLStyleElement.cpp
+++ b/dom/html/HTMLStyleElement.cpp
@@ -61,17 +61,17 @@ HTMLStyleElement::SetDisabled(bool aDisa
   if (StyleSheet* ss = GetSheet()) {
     ss->SetDisabled(aDisabled);
   }
 }
 
 void
 HTMLStyleElement::CharacterDataChanged(nsIDocument* aDocument,
                                        nsIContent* aContent,
-                                       CharacterDataChangeInfo* aInfo)
+                                       const CharacterDataChangeInfo&)
 {
   ContentChanged(aContent);
 }
 
 void
 HTMLStyleElement::ContentAppended(nsIDocument* aDocument,
                                   nsIContent* aContainer,
                                   nsIContent* aFirstNewContent)
--- a/dom/html/HTMLTextAreaElement.cpp
+++ b/dom/html/HTMLTextAreaElement.cpp
@@ -985,17 +985,17 @@ HTMLTextAreaElement::BeforeSetAttr(int32
 
   return nsGenericHTMLFormElementWithState::BeforeSetAttr(aNameSpaceID, aName,
                                                  aValue, aNotify);
 }
 
 void
 HTMLTextAreaElement::CharacterDataChanged(nsIDocument* aDocument,
                                           nsIContent* aContent,
-                                          CharacterDataChangeInfo* aInfo)
+                                          const CharacterDataChangeInfo&)
 {
   ContentChanged(aContent);
 }
 
 void
 HTMLTextAreaElement::ContentAppended(nsIDocument* aDocument,
                                      nsIContent* aContainer,
                                      nsIContent* aFirstNewContent)
--- a/dom/html/HTMLTitleElement.cpp
+++ b/dom/html/HTMLTitleElement.cpp
@@ -51,17 +51,17 @@ void
 HTMLTitleElement::SetText(const nsAString& aText, ErrorResult& aError)
 {
   aError = nsContentUtils::SetNodeTextContent(this, aText, true);
 }
 
 void
 HTMLTitleElement::CharacterDataChanged(nsIDocument *aDocument,
                                        nsIContent *aContent,
-                                       CharacterDataChangeInfo *aInfo)
+                                       const CharacterDataChangeInfo&)
 {
   SendTitleChangeEvent(false);
 }
 
 void
 HTMLTitleElement::ContentAppended(nsIDocument *aDocument,
                                   nsIContent *aContainer,
                                   nsIContent *aFirstNewContent)
--- a/dom/script/ScriptElement.cpp
+++ b/dom/script/ScriptElement.cpp
@@ -75,17 +75,17 @@ ScriptElement::ScriptEvaluated(nsresult 
   }
 
   return rv;
 }
 
 void
 ScriptElement::CharacterDataChanged(nsIDocument* aDocument,
                                     nsIContent* aContent,
-                                    CharacterDataChangeInfo* aInfo)
+                                    const CharacterDataChangeInfo&)
 {
   MaybeProcessScript();
 }
 
 void
 ScriptElement::AttributeChanged(nsIDocument* aDocument,
                                 Element* aElement,
                                 int32_t aNameSpaceID,
--- a/dom/svg/SVGStyleElement.cpp
+++ b/dom/svg/SVGStyleElement.cpp
@@ -130,17 +130,17 @@ SVGStyleElement::ParseAttribute(int32_t 
 }
 
 //----------------------------------------------------------------------
 // nsIMutationObserver methods
 
 void
 SVGStyleElement::CharacterDataChanged(nsIDocument* aDocument,
                                       nsIContent* aContent,
-                                      CharacterDataChangeInfo* aInfo)
+                                      const CharacterDataChangeInfo&)
 {
   ContentChanged(aContent);
 }
 
 void
 SVGStyleElement::ContentAppended(nsIDocument* aDocument,
                                  nsIContent* aContainer,
                                  nsIContent* aFirstNewContent)
--- a/dom/svg/SVGTitleElement.cpp
+++ b/dom/svg/SVGTitleElement.cpp
@@ -34,19 +34,19 @@ SVGTitleElement::SVGTitleElement(already
   AddMutationObserver(this);
 }
 
 SVGTitleElement::~SVGTitleElement()
 {
 }
 
 void
-SVGTitleElement::CharacterDataChanged(nsIDocument *aDocument,
-                                      nsIContent *aContent,
-                                      CharacterDataChangeInfo *aInfo)
+SVGTitleElement::CharacterDataChanged(nsIDocument* aDocument,
+                                      nsIContent* aContent,
+                                      const CharacterDataChangeInfo&)
 {
   SendTitleChangeEvent(false);
 }
 
 void
 SVGTitleElement::ContentAppended(nsIDocument *aDocument,
                                  nsIContent *aContainer,
                                  nsIContent *aFirstNewContent)
--- a/dom/svg/SVGUseElement.cpp
+++ b/dom/svg/SVGUseElement.cpp
@@ -142,19 +142,19 @@ SVGUseElement::Height()
 {
   return mLengthAttributes[ATTR_HEIGHT].ToDOMAnimatedLength(this);
 }
 
 //----------------------------------------------------------------------
 // nsIMutationObserver methods
 
 void
-SVGUseElement::CharacterDataChanged(nsIDocument *aDocument,
-                                    nsIContent *aContent,
-                                    CharacterDataChangeInfo* aInfo)
+SVGUseElement::CharacterDataChanged(nsIDocument* aDocument,
+                                    nsIContent* aContent,
+                                    const CharacterDataChangeInfo&)
 {
   if (nsContentUtils::IsInSameAnonymousTree(this, aContent)) {
     TriggerReclone();
   }
 }
 
 void
 SVGUseElement::AttributeChanged(nsIDocument* aDocument,
--- a/dom/xslt/xpath/XPathResult.cpp
+++ b/dom/xslt/xpath/XPathResult.cpp
@@ -118,18 +118,18 @@ XPathResult::NodeWillBeDestroyed(const n
     nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
     // Set to null to avoid unregistring unnecessarily
     mDocument = nullptr;
     Invalidate(aNode->IsContent() ? aNode->AsContent() : nullptr);
 }
 
 void
 XPathResult::CharacterDataChanged(nsIDocument* aDocument,
-                                  nsIContent *aContent,
-                                  CharacterDataChangeInfo* aInfo)
+                                  nsIContent* aContent,
+                                  const CharacterDataChangeInfo&)
 {
     Invalidate(aContent);
 }
 
 void
 XPathResult::AttributeChanged(nsIDocument* aDocument,
                               Element* aElement,
                               int32_t aNameSpaceID,
--- a/dom/xslt/xslt/txMozillaXSLTProcessor.cpp
+++ b/dom/xslt/xslt/txMozillaXSLTProcessor.cpp
@@ -1231,18 +1231,18 @@ txMozillaXSLTProcessor::NodeWillBeDestro
 
     mCompileResult = ensureStylesheet();
     mStylesheetDocument = nullptr;
     mEmbeddedStylesheetRoot = nullptr;
 }
 
 void
 txMozillaXSLTProcessor::CharacterDataChanged(nsIDocument* aDocument,
-                                             nsIContent *aContent,
-                                             CharacterDataChangeInfo* aInfo)
+                                             nsIContent* aContent,
+                                             const CharacterDataChangeInfo&)
 {
     mStylesheet = nullptr;
 }
 
 void
 txMozillaXSLTProcessor::AttributeChanged(nsIDocument* aDocument,
                                          Element* aElement,
                                          int32_t aNameSpaceID,
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -4284,34 +4284,34 @@ PresShell::DoFlushPendingNotifications(m
     // We suppressed this flush either due to it not being safe to flush,
     // or due to SuppressInterruptibleReflows().  Either way, the
     // mNeedLayoutFlush flag needs to be re-set.
     SetNeedLayoutFlush();
   }
 }
 
 void
-PresShell::CharacterDataChanged(nsIDocument *aDocument,
-                                nsIContent*  aContent,
-                                CharacterDataChangeInfo* aInfo)
+PresShell::CharacterDataChanged(nsIDocument* aDocument,
+                                nsIContent* aContent,
+                                const CharacterDataChangeInfo& aInfo)
 {
   NS_PRECONDITION(!mIsDocumentGone, "Unexpected CharacterDataChanged");
   NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument");
 
   nsAutoCauseReflowNotifier crNotifier(this);
 
   // Call this here so it only happens for real content mutations and
   // not cases when the frame constructor calls its own methods to force
   // frame reconstruction.
   nsIContent *container = aContent->GetParent();
   uint32_t selectorFlags =
     container ? (container->GetFlags() & NODE_ALL_SELECTOR_FLAGS) : 0;
   if (selectorFlags != 0 && !aContent->IsRootOfAnonymousSubtree()) {
     Element* element = container->AsElement();
-    if (aInfo->mAppend && !aContent->GetNextSibling())
+    if (aInfo.mAppend && !aContent->GetNextSibling())
       mPresContext->RestyleManager()->RestyleForAppend(element, aContent);
     else
       mPresContext->RestyleManager()->RestyleForInsertOrChange(element, aContent);
   }
 
   mFrameConstructor->CharacterDataChanged(aContent, aInfo);
   VERIFY_STYLE_TREE;
 }
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -8859,17 +8859,17 @@ nsCSSFrameConstructor::EnsureFrameForTex
 
   RestyleManager()->PostRestyleEvent(
     root, nsRestyleHint(0), nsChangeHint_ReconstructFrame);
   return true;
 }
 
 void
 nsCSSFrameConstructor::CharacterDataChanged(nsIContent* aContent,
-                                            CharacterDataChangeInfo* aInfo)
+                                            const CharacterDataChangeInfo& aInfo)
 {
   AUTO_LAYOUT_PHASE_ENTRY_POINT(mPresShell->GetPresContext(), FrameC);
 
   if ((aContent->HasFlag(NS_CREATE_FRAME_IF_NON_WHITESPACE) &&
        !aContent->TextIsOnlyWhitespace()) ||
       (aContent->HasFlag(NS_REFRAME_IF_WHITESPACE) &&
        aContent->TextIsOnlyWhitespace())) {
 #ifdef DEBUG
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -315,17 +315,17 @@ public:
    * async.
    */
   bool ContentRemoved(nsIContent* aContainer,
                       nsIContent* aChild,
                       nsIContent* aOldNextSibling,
                       RemoveFlags aFlags);
 
   void CharacterDataChanged(nsIContent* aContent,
-                            CharacterDataChangeInfo* aInfo);
+                            const CharacterDataChangeInfo& aInfo);
 
   // If aContent is a text node that has been optimized away due to being
   // whitespace next to a block boundary (or for some other reason), ensure that
   // a frame for it is created the next time frames are flushed, if it can
   // possibly have a frame at all.
   //
   // Returns whether there are chances for the frame to be unsuppressed.
   bool EnsureFrameForTextNodeIsCreatedAfterFlush(nsGenericDOMDataNode* aContent);
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -1463,17 +1463,17 @@ nsTextControlFrame::EditorInitializer::R
 }
 
 NS_IMPL_ISUPPORTS(nsTextControlFrame::nsAnonDivObserver, nsIMutationObserver)
 
 void
 nsTextControlFrame::nsAnonDivObserver::CharacterDataChanged(
   nsIDocument* aDocument,
   nsIContent* aContent,
-  CharacterDataChangeInfo* aInfo)
+  const CharacterDataChangeInfo&)
 {
   mFrame.ClearCachedValue();
 }
 
 void
 nsTextControlFrame::nsAnonDivObserver::ContentAppended(
   nsIDocument* aDocument,
   nsIContent* aContainer,
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -6559,17 +6559,17 @@ nsIFrame::IsContentDisabled() const
     return true;
   }
 
   auto* element = nsGenericHTMLElement::FromContentOrNull(GetContent());
   return element && element->IsDisabled();
 }
 
 nsresult
-nsFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo)
+nsFrame::CharacterDataChanged(const CharacterDataChangeInfo&)
 {
   NS_NOTREACHED("should only be called for text frames");
   return NS_OK;
 }
 
 nsresult
 nsFrame::AttributeChanged(int32_t         aNameSpaceID,
                           nsAtom*        aAttribute,
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -188,17 +188,17 @@ public:
                                          nsIFrame** outChildFrame) override;
 
   static nsresult GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
                                                  nsPeekOffsetStruct *aPos,
                                                  nsIFrame *aBlockFrame,
                                                  int32_t aLineStart,
                                                  int8_t aOutSideLimit);
 
-  nsresult CharacterDataChanged(CharacterDataChangeInfo* aInfo) override;
+  nsresult CharacterDataChanged(const CharacterDataChangeInfo& aInfo) override;
   nsresult AttributeChanged(int32_t  aNameSpaceID,
                             nsAtom* aAttribute,
                             int32_t aModType) override;
   nsSplittableType GetSplittableType() const override;
   nsIFrame* GetPrevContinuation() const override;
   void SetPrevContinuation(nsIFrame*) override;
   nsIFrame* GetNextContinuation() const override;
   void SetNextContinuation(nsIFrame*) override;
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -2054,17 +2054,17 @@ public:
   bool IsPrimaryFrame() const { return mIsPrimaryFrame; }
 
   void SetIsPrimaryFrame(bool aIsPrimary) { mIsPrimaryFrame = aIsPrimary; }
 
   /**
    * This call is invoked on the primary frame for a character data content
    * node, when it is changed in the content tree.
    */
-  virtual nsresult  CharacterDataChanged(CharacterDataChangeInfo* aInfo) = 0;
+  virtual nsresult  CharacterDataChanged(const CharacterDataChangeInfo&) = 0;
 
   /**
    * This call is invoked when the value of a content objects's attribute
    * is changed.
    * The first frame that maps that content is asked to deal
    * with the change by doing whatever is appropriate.
    *
    * @param aNameSpaceID the namespace of the attribute
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -4818,39 +4818,39 @@ nsTextFrame::DisconnectTextRuns()
              "Textrun mentions this frame in its user data so we can't just disconnect");
   mTextRun = nullptr;
   if ((GetStateBits() & TEXT_HAS_FONT_INFLATION)) {
     DeleteProperty(UninflatedTextRunProperty());
   }
 }
 
 nsresult
-nsTextFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo)
+nsTextFrame::CharacterDataChanged(const CharacterDataChangeInfo& aInfo)
 {
   if (mContent->HasFlag(NS_HAS_NEWLINE_PROPERTY)) {
     mContent->DeleteProperty(nsGkAtoms::newline);
     mContent->UnsetFlags(NS_HAS_NEWLINE_PROPERTY);
   }
   if (mContent->HasFlag(NS_HAS_FLOWLENGTH_PROPERTY)) {
     mContent->DeleteProperty(nsGkAtoms::flowlength);
     mContent->UnsetFlags(NS_HAS_FLOWLENGTH_PROPERTY);
   }
 
   // Find the first frame whose text has changed. Frames that are entirely
   // before the text change are completely unaffected.
   nsTextFrame* next;
   nsTextFrame* textFrame = this;
   while (true) {
     next = textFrame->GetNextContinuation();
-    if (!next || next->GetContentOffset() > int32_t(aInfo->mChangeStart))
+    if (!next || next->GetContentOffset() > int32_t(aInfo.mChangeStart))
       break;
     textFrame = next;
   }
 
-  int32_t endOfChangedText = aInfo->mChangeStart + aInfo->mReplaceLength;
+  int32_t endOfChangedText = aInfo.mChangeStart + aInfo.mReplaceLength;
 
   // Parent of the last frame that we passed to FrameNeedsReflow (or noticed
   // had already received an earlier FrameNeedsReflow call).
   // (For subsequent frames with this same parent, we can just set their
   // dirty bit without bothering to call FrameNeedsReflow again.)
   nsIFrame* lastDirtiedFrameParent = nullptr;
 
   nsIPresShell* shell = PresContext()->GetPresShell();
@@ -4902,22 +4902,22 @@ nsTextFrame::CharacterDataChanged(Charac
     // along the continuation chain. So we need to ensure that frames that
     // started in the deleted text are all still starting before the
     // unchanged text.
     if (textFrame->mContentOffset > endOfChangedText) {
       textFrame->mContentOffset = endOfChangedText;
     }
 
     textFrame = textFrame->GetNextContinuation();
-  } while (textFrame && textFrame->GetContentOffset() < int32_t(aInfo->mChangeEnd));
+  } while (textFrame && textFrame->GetContentOffset() < int32_t(aInfo.mChangeEnd));
 
   // This is how much the length of the string changed by --- i.e.,
   // how much the trailing unchanged text moved.
   int32_t sizeChange =
-    aInfo->mChangeStart + aInfo->mReplaceLength - aInfo->mChangeEnd;
+    aInfo.mChangeStart + aInfo.mReplaceLength - aInfo.mChangeEnd;
 
   if (sizeChange) {
     // Fix the offsets of the text frames that start in the trailing
     // unchanged text.
     while (textFrame) {
       textFrame->mContentOffset += sizeChange;
       // XXX we could rescue some text runs by adjusting their user data
       // to reflect the change in DOM offsets
--- a/layout/generic/nsTextFrame.h
+++ b/layout/generic/nsTextFrame.h
@@ -76,17 +76,17 @@ public:
   void Init(nsIContent* aContent,
             nsContainerFrame* aParent,
             nsIFrame* aPrevInFlow) override;
 
   void DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData) override;
 
   nsresult GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor) override;
 
-  nsresult CharacterDataChanged(CharacterDataChangeInfo* aInfo) final;
+  nsresult CharacterDataChanged(const CharacterDataChangeInfo&) final;
 
   nsTextFrame* GetPrevContinuation() const override { return nullptr; }
   nsTextFrame* GetNextContinuation() const final { return mNextContinuation; }
   void SetNextContinuation(nsIFrame* aNextContinuation) final
   {
     NS_ASSERTION(!aNextContinuation || Type() == aNextContinuation->Type(),
                  "setting a next continuation with incorrect type!");
     NS_ASSERTION(
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -3363,17 +3363,17 @@ SVGTextFrame::MutationObserver::ContentR
 {
   mFrame->NotifyGlyphMetricsChange();
 }
 
 void
 SVGTextFrame::MutationObserver::CharacterDataChanged(
                                                  nsIDocument* aDocument,
                                                  nsIContent* aContent,
-                                                 CharacterDataChangeInfo* aInfo)
+                                                 const CharacterDataChangeInfo&)
 {
   mFrame->NotifyGlyphMetricsChange();
 }
 
 void
 SVGTextFrame::MutationObserver::AttributeChanged(
                                                 nsIDocument* aDocument,
                                                 mozilla::dom::Element* aElement,
--- a/layout/xul/nsLeafBoxFrame.cpp
+++ b/layout/xul/nsLeafBoxFrame.cpp
@@ -321,17 +321,17 @@ nsLeafBoxFrame::Reflow(nsPresContext*   
 nsresult
 nsLeafBoxFrame::GetFrameName(nsAString& aResult) const
 {
   return MakeFrameName(NS_LITERAL_STRING("LeafBox"), aResult);
 }
 #endif
 
 nsresult
-nsLeafBoxFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo)
+nsLeafBoxFrame::CharacterDataChanged(const CharacterDataChangeInfo& aInfo)
 {
   MarkIntrinsicISizesDirty();
   return nsLeafFrame::CharacterDataChanged(aInfo);
 }
 
 /* virtual */ nsSize
 nsLeafBoxFrame::GetXULPrefSize(nsBoxLayoutState& aState)
 {
--- a/layout/xul/nsLeafBoxFrame.h
+++ b/layout/xul/nsLeafBoxFrame.h
@@ -52,17 +52,17 @@ public:
                   const mozilla::LogicalSize& aPadding,
                   ComputeSizeFlags            aFlags) override;
 
   virtual void Reflow(nsPresContext*           aPresContext,
                       ReflowOutput&     aDesiredSize,
                       const ReflowInput& aReflowInput,
                       nsReflowStatus&          aStatus) override;
 
-  virtual nsresult CharacterDataChanged(CharacterDataChangeInfo* aInfo) override;
+  virtual nsresult CharacterDataChanged(const CharacterDataChangeInfo&) override;
 
   virtual void Init(nsIContent*       aContent,
                     nsContainerFrame* aParent,
                     nsIFrame*         asPrevInFlow) override;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsDisplayListSet& aLists) override;
 
--- a/parser/html/nsHtml5TreeOperation.cpp
+++ b/parser/html/nsHtml5TreeOperation.cpp
@@ -129,22 +129,22 @@ nsHtml5TreeOperation::AppendTextToTextNo
   MOZ_ASSERT(aBuilder->IsInDocUpdate());
   uint32_t oldLength = aTextNode->TextLength();
   CharacterDataChangeInfo info = {
     true,
     oldLength,
     oldLength,
     aLength
   };
-  nsNodeUtils::CharacterDataWillChange(aTextNode, &info);
+  nsNodeUtils::CharacterDataWillChange(aTextNode, info);
 
   nsresult rv = aTextNode->AppendText(aBuffer, aLength, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsNodeUtils::CharacterDataChanged(aTextNode, &info);
+  nsNodeUtils::CharacterDataChanged(aTextNode, info);
   return rv;
 }
 
 
 nsresult
 nsHtml5TreeOperation::AppendText(const char16_t* aBuffer,
                                  uint32_t aLength,
                                  nsIContent* aParent,
--- a/toolkit/components/satchel/nsFormFillController.cpp
+++ b/toolkit/components/satchel/nsFormFillController.cpp
@@ -196,24 +196,24 @@ nsFormFillController::ContentRemoved(nsI
   if (mListNode && mListNode->Contains(aContainer)) {
     RevalidateDataList();
   }
 }
 
 void
 nsFormFillController::CharacterDataWillChange(nsIDocument* aDocument,
                                               nsIContent* aContent,
-                                              CharacterDataChangeInfo* aInfo)
+                                              const CharacterDataChangeInfo&)
 {
 }
 
 void
 nsFormFillController::CharacterDataChanged(nsIDocument* aDocument,
                                            nsIContent* aContent,
-                                           CharacterDataChangeInfo* aInfo)
+                                           const CharacterDataChangeInfo&)
 {
 }
 
 void
 nsFormFillController::AttributeWillChange(nsIDocument* aDocument,
                                           mozilla::dom::Element* aElement,
                                           int32_t aNameSpaceID,
                                           nsAtom* aAttribute, int32_t aModType,
--- a/widget/cocoa/nsMenuGroupOwnerX.mm
+++ b/widget/cocoa/nsMenuGroupOwnerX.mm
@@ -64,24 +64,24 @@ nsresult nsMenuGroupOwnerX::Create(mozil
 
 //
 // nsIMutationObserver
 //
 
 
 void nsMenuGroupOwnerX::CharacterDataWillChange(nsIDocument* aDocument,
                                                 nsIContent* aContent,
-                                                CharacterDataChangeInfo* aInfo)
+                                                const CharacterDataChangeInfo&)
 {
 }
 
 
 void nsMenuGroupOwnerX::CharacterDataChanged(nsIDocument* aDocument,
                                              nsIContent* aContent,
-                                             CharacterDataChangeInfo* aInfo)
+                                             const CharacterDataChangeInfo&)
 {
 }
 
 
 void nsMenuGroupOwnerX::ContentAppended(nsIDocument* aDocument,
                                         nsIContent* aContainer,
                                         nsIContent* aFirstNewContent)
 {