Bug 1441547: Make character data change notifications use a const reference for the info parameter. r=smaug
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 27 Feb 2018 15:30:27 +0100
changeset 405602 8e1b5f09ce6dc5c939f5ef2f6ce4731829b6b088
parent 405601 d2192f653b256c97b249764632bbe38ed33d97da
child 405603 822867d9e17626eca8c4ddf1b60368bf63b3a4fb
push id33525
push usernerli@mozilla.com
push dateWed, 28 Feb 2018 10:11:03 +0000
treeherdermozilla-central@9b1228043619 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1441547
milestone60.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 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
@@ -8846,17 +8846,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)
 {