Bug 1480055 - part 4: Make AutoTransactionsConserveSelection take reference of Editor rather than pointer r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 01 Aug 2018 21:30:14 +0900
changeset 825749 07e32f07504be1dc311b114b460a970e756cf980
parent 825748 4849353b3dc0da9184401d5a45f18206459ab2bc
child 825807 82574607f52f7ca2e64d890a5f29c1ad155872c1
push id118159
push usermasayuki@d-toybox.com
push dateThu, 02 Aug 2018 07:24:41 +0000
reviewersm_kato
bugs1480055
milestone63.0a1
Bug 1480055 - part 4: Make AutoTransactionsConserveSelection take reference of Editor rather than pointer r?m_kato It's always created with non-nullptr. So, making it treat reference of EditorBase makes its implementation simpler. Note that this changes comment in EditorBase::InsertTextWithTransaction() to a MOZ_ASSERT() for detecting bugs. However, the comment is wrong. When the insertion is for updating composition string, callers don't need to create AutoTransactionsConserveSelection since it'll be ignored by CompositionTransaction. So, the new MOZ_ASSERT() checks whether it's in composition or prevented transaction changing Selection. MozReview-Commit-ID: 6jZ4LpksyoD
editor/libeditor/EditorBase.cpp
editor/libeditor/EditorUtils.h
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditor.cpp
editor/libeditor/HTMLEditorDataTransfer.cpp
editor/libeditor/HTMLStyleEditor.cpp
editor/libeditor/HTMLTableEditor.cpp
editor/libeditor/TextEditRules.cpp
editor/libeditor/TextEditor.cpp
editor/libeditor/TextEditorDataTransfer.cpp
editor/libeditor/WSRunObject.cpp
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -1719,17 +1719,17 @@ EditorBase::ReplaceContainerWithTransact
   }
 
   // Notify our internal selection state listener.
   // Note: An AutoSelectionRestorer object must be created before calling this
   // to initialize mRangeUpdater.
   AutoReplaceContainerSelNotify selStateNotify(mRangeUpdater, &aOldContainer,
                                                newContainer);
   {
-    AutoTransactionsConserveSelection conserveSelection(this);
+    AutoTransactionsConserveSelection conserveSelection(*this);
     // Move all children from the old container to the new container.
     while (aOldContainer.HasChildren()) {
       nsCOMPtr<nsIContent> child = aOldContainer.GetFirstChild();
       if (NS_WARN_IF(!child)) {
         return nullptr;
       }
       nsresult rv = DeleteNodeWithTransaction(*child);
       if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -1848,17 +1848,17 @@ EditorBase::InsertContainerWithTransacti
 
   // Put aNode in the new container, first.
   nsresult rv = DeleteNodeWithTransaction(aContent);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return nullptr;
   }
 
   {
-    AutoTransactionsConserveSelection conserveSelection(this);
+    AutoTransactionsConserveSelection conserveSelection(*this);
     rv = InsertNodeWithTransaction(aContent,
                                    EditorRawDOMPoint(newContainer, 0));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return nullptr;
     }
   }
 
   // Put the new container where aNode was.
@@ -2648,19 +2648,20 @@ EditorBase::FindBetterInsertionPoint(con
 
 nsresult
 EditorBase::InsertTextWithTransaction(
               nsIDocument& aDocument,
               const nsAString& aStringToInsert,
               const EditorRawDOMPoint& aPointToInsert,
               EditorRawDOMPoint* aPointAfterInsertedString)
 {
-  // NOTE: caller *must* have already used AutoTransactionsConserveSelection
-  // stack-based class to turn off txn selection updating.  Caller also turned
-  // on rules sniffing if desired.
+  MOZ_ASSERT(ShouldHandleIMEComposition() ||
+             !AllowsTransactionsToChangeSelection(),
+             "caller must have already used AutoTransactionsConserveSelection "
+             "if this is not for updating composition string");
 
   if (NS_WARN_IF(!aPointToInsert.IsSet())) {
     return NS_ERROR_INVALID_ARG;
   }
 
   MOZ_ASSERT(aPointToInsert.IsSetAndValid());
 
   if (!ShouldHandleIMEComposition() && aStringToInsert.IsEmpty()) {
--- a/editor/libeditor/EditorUtils.h
+++ b/editor/libeditor/EditorUtils.h
@@ -567,39 +567,34 @@ protected:
 
 /***************************************************************************
  * stack based helper class for turning off active selection adjustment
  * by low level transactions
  */
 class MOZ_RAII AutoTransactionsConserveSelection final
 {
 public:
-  explicit AutoTransactionsConserveSelection(EditorBase* aEditorBase
+  explicit AutoTransactionsConserveSelection(EditorBase& aEditorBase
                                              MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     : mEditorBase(aEditorBase)
-    , mAllowedTransactionsToChangeSelection(true)
+    , mAllowedTransactionsToChangeSelection(
+        aEditorBase.AllowsTransactionsToChangeSelection())
   {
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-    if (mEditorBase) {
-      mAllowedTransactionsToChangeSelection =
-        mEditorBase->AllowsTransactionsToChangeSelection();
-      mEditorBase->MakeThisAllowTransactionsToChangeSelection(false);
-    }
+    mEditorBase.MakeThisAllowTransactionsToChangeSelection(false);
   }
 
   ~AutoTransactionsConserveSelection()
   {
-    if (mEditorBase) {
-      mEditorBase->MakeThisAllowTransactionsToChangeSelection(
-                     mAllowedTransactionsToChangeSelection);
-    }
+    mEditorBase.MakeThisAllowTransactionsToChangeSelection(
+                  mAllowedTransactionsToChangeSelection);
   }
 
 protected:
-  EditorBase* mEditorBase;
+  EditorBase& mEditorBase;
   bool mAllowedTransactionsToChangeSelection;
   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 /***************************************************************************
  * stack based helper class for batching reflow and paint requests.
  */
 class MOZ_RAII AutoUpdateViewBatch final
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -486,17 +486,17 @@ HTMLEditRules::AfterEditInner(EditSubAct
       bDamagedRange = true;
     }
   }
 
   if (bDamagedRange && !((aEditSubAction == EditSubAction::eUndo) ||
                          (aEditSubAction == EditSubAction::eRedo))) {
     // don't let any txns in here move the selection around behind our back.
     // Note that this won't prevent explicit selection setting from working.
-    AutoTransactionsConserveSelection dontChangeMySelection(&HTMLEditorRef());
+    AutoTransactionsConserveSelection dontChangeMySelection(HTMLEditorRef());
 
     // expand the "changed doc range" as needed
     PromoteRange(*mDocChangeRange, aEditSubAction);
 
     // if we did a ranged deletion or handling backspace key, make sure we have
     // a place to put caret.
     // Note we only want to do this if the overall operation was deletion,
     // not if deletion was done along the way for
@@ -1444,17 +1444,17 @@ HTMLEditRules::WillInsertText(EditSubAct
 
   // turn off the edit listener: we know how to
   // build the "doc changed range" ourselves, and it's
   // must faster to do it once here than to track all
   // the changes one at a time.
   AutoLockListener lockit(&mListenerEnabled);
 
   // don't change my selection in subtransactions
-  AutoTransactionsConserveSelection dontChangeMySelection(&HTMLEditorRef());
+  AutoTransactionsConserveSelection dontChangeMySelection(HTMLEditorRef());
   nsAutoString tString(*inString);
   const char16_t *unicodeBuf = tString.get();
   int32_t pos = 0;
   NS_NAMED_LITERAL_STRING(newlineStr, LFSTR);
 
   {
     AutoTrackDOMPoint tracker(HTMLEditorRef().mRangeUpdater, &pointToInsert);
 
@@ -2962,17 +2962,17 @@ HTMLEditRules::WillDeleteSelection(nsIEd
   if (NS_WARN_IF(!endNode)) {
     return NS_ERROR_FAILURE;
   }
   int32_t endOffset = firstRange->EndOffset();
 
   // Figure out if the endpoints are in nodes that can be merged.  Adjust
   // surrounding whitespace in preparation to delete selection.
   if (!IsPlaintextEditor()) {
-    AutoTransactionsConserveSelection dontChangeMySelection(&HTMLEditorRef());
+    AutoTransactionsConserveSelection dontChangeMySelection(HTMLEditorRef());
     rv = WSRunObject::PrepareToDeleteRange(&HTMLEditorRef(),
                                            address_of(startNode), &startOffset,
                                            address_of(endNode), &endOffset);
     if (NS_WARN_IF(!CanHandleEditAction())) {
       return NS_ERROR_EDITOR_DESTROYED;
     }
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
@@ -3378,17 +3378,17 @@ HTMLEditRules::TryToJoinBlocksWithTransa
       MOZ_DIAGNOSTIC_ASSERT(!atChildInBlock.IsSet());
       leftBlock = leftList;
       rightBlock = rightList;
       mergeLists = true;
       existingList = leftList->NodeInfo()->NameAtom();
     }
   }
 
-  AutoTransactionsConserveSelection dontChangeMySelection(&HTMLEditorRef());
+  AutoTransactionsConserveSelection dontChangeMySelection(HTMLEditorRef());
 
   // offset below is where you find yourself in rightBlock when you traverse
   // upwards from leftBlock
   EditorDOMPoint atRightBlockChild;
   if (EditorUtils::IsDescendantOf(*leftBlock, *rightBlock,
                                   &atRightBlockChild)) {
     // Tricky case.  Left block is inside right block.  Do ws adjustment.  This
     // just destroys non-visible ws at boundaries we will be joining.
@@ -4501,17 +4501,17 @@ HTMLEditRules::MakeBasicBlock(nsAtom& bl
   MOZ_ASSERT(IsEditorDataAvailable());
 
   nsresult rv = NormalizeSelection();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   AutoSelectionRestorer selectionRestorer(&SelectionRef(), &HTMLEditorRef());
-  AutoTransactionsConserveSelection dontChangeMySelection(&HTMLEditorRef());
+  AutoTransactionsConserveSelection dontChangeMySelection(HTMLEditorRef());
 
   // Contruct a list of nodes to act on.
   nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
   rv = GetNodesFromSelection(EditSubAction::eCreateOrRemoveBlock, arrayOfNodes,
                              TouchContent::yes);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
@@ -5916,17 +5916,17 @@ HTMLEditRules::CreateStyleForInsertText(
     return NS_ERROR_FAILURE;
   }
 
   // process clearing any styles first
   UniquePtr<PropItem> item = HTMLEditorRef().mTypeInState->TakeClearProperty();
 
   {
     // Transactions may set selection, but we will set selection if necessary.
-    AutoTransactionsConserveSelection dontChangeMySelection(&HTMLEditorRef());
+    AutoTransactionsConserveSelection dontChangeMySelection(HTMLEditorRef());
 
     while (item && node != rootElement) {
       // XXX If we redesign ClearStyle(), we can use EditorDOMPoint in this
       //     method.
       nsresult rv =
         HTMLEditorRef().ClearStyle(address_of(node), &offset,
                                    item->tag, item->attr);
       if (NS_WARN_IF(!CanHandleEditAction())) {
@@ -7543,17 +7543,17 @@ HTMLEditRules::GetListActionNodes(
     // the selection spans multiple lists but with no common list parent.
     if (!aOutArrayOfNodes.IsEmpty()) {
       return NS_OK;
     }
   }
 
   {
     // We don't like other people messing with our selection!
-    AutoTransactionsConserveSelection dontChangeMySelection(&HTMLEditorRef());
+    AutoTransactionsConserveSelection dontChangeMySelection(HTMLEditorRef());
 
     // contruct a list of nodes to act on.
     nsresult rv = GetNodesFromSelection(EditSubAction::eCreateOrChangeList,
                                         aOutArrayOfNodes, aTouchContent);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -3607,17 +3607,17 @@ HTMLEditor::GetEnclosingTable(nsINode* a
  * "adjacent" means literally adjacent siblings of the same parent.
  * Uses EditorBase::JoinNodesWithTransaction() so action is undoable.
  * Should be called within the context of a batch transaction.
  */
 nsresult
 HTMLEditor::CollapseAdjacentTextNodes(nsRange* aInRange)
 {
   NS_ENSURE_TRUE(aInRange, NS_ERROR_NULL_POINTER);
-  AutoTransactionsConserveSelection dontChangeMySelection(this);
+  AutoTransactionsConserveSelection dontChangeMySelection(*this);
   nsTArray<nsCOMPtr<nsINode>> textNodes;
   // we can't actually do anything during iteration, so store the text nodes in an array
   // don't bother ref counting them because we know we can hold them for the
   // lifetime of this method
 
 
   // build a list of editable text nodes
   nsresult rv = NS_ERROR_UNEXPECTED;
@@ -4271,17 +4271,17 @@ HTMLEditor::SetCSSBackgroundColorWithTra
 
   bool isCollapsed = selection->IsCollapsed();
 
   AutoPlaceholderBatch batchIt(this);
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this, EditSubAction::eInsertElement,
                                       nsIEditor::eNext);
   AutoSelectionRestorer selectionRestorer(selection, this);
-  AutoTransactionsConserveSelection dontChangeMySelection(this);
+  AutoTransactionsConserveSelection dontChangeMySelection(*this);
 
   // XXX Although, this method may set background color of ancestor block
   //     element, using EditSubAction::eSetTextProperty.
   bool cancel, handled;
   EditSubActionInfo subActionInfo(EditSubAction::eSetTextProperty);
   nsresult rv =
     rules->WillDoAction(selection, subActionInfo, &cancel, &handled);
   if (NS_WARN_IF(NS_FAILED(rv))) {
--- a/editor/libeditor/HTMLEditorDataTransfer.cpp
+++ b/editor/libeditor/HTMLEditorDataTransfer.cpp
@@ -1106,17 +1106,17 @@ HTMLEditor::InsertFromTransferable(nsITr
   nsresult rv = NS_OK;
   nsAutoCString bestFlavor;
   nsCOMPtr<nsISupports> genericDataObj;
   uint32_t len = 0;
   if (NS_SUCCEEDED(
         transferable->GetAnyTransferData(bestFlavor,
                                          getter_AddRefs(genericDataObj),
                                          &len))) {
-    AutoTransactionsConserveSelection dontChangeMySelection(this);
+    AutoTransactionsConserveSelection dontChangeMySelection(*this);
     nsAutoString flavor;
     CopyASCIItoUTF16(bestFlavor, flavor);
     nsAutoString stuffToPaste;
     bool isSafe = IsSafeToInsertData(aSourceDoc);
 
     if (bestFlavor.EqualsLiteral(kFileMime) ||
         bestFlavor.EqualsLiteral(kJPEGImageMime) ||
         bestFlavor.EqualsLiteral(kJPGImageMime) ||
--- a/editor/libeditor/HTMLStyleEditor.cpp
+++ b/editor/libeditor/HTMLStyleEditor.cpp
@@ -84,17 +84,17 @@ HTMLEditor::SetInlineProperty(nsAtom* aP
     return NS_OK;
   }
 
   AutoPlaceholderBatch batchIt(this);
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this, EditSubAction::eInsertElement,
                                       nsIEditor::eNext);
   AutoSelectionRestorer selectionRestorer(selection, this);
-  AutoTransactionsConserveSelection dontChangeMySelection(this);
+  AutoTransactionsConserveSelection dontChangeMySelection(*this);
 
   bool cancel, handled;
   EditSubActionInfo subActionInfo(EditSubAction::eSetTextProperty);
   // Protect the edit rules object from dying
   nsresult rv =
     rules->WillDoAction(selection, subActionInfo, &cancel, &handled);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -1239,17 +1239,17 @@ HTMLEditor::RemoveInlineProperty(nsAtom*
     return NS_OK;
   }
 
   AutoPlaceholderBatch batchIt(this);
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this, EditSubAction::eRemoveTextProperty,
                                       nsIEditor::eNext);
   AutoSelectionRestorer selectionRestorer(selection, this);
-  AutoTransactionsConserveSelection dontChangeMySelection(this);
+  AutoTransactionsConserveSelection dontChangeMySelection(*this);
 
   bool cancel, handled;
   EditSubActionInfo subActionInfo(EditSubAction::eRemoveTextProperty);
   // Protect the edit rules object from dying
   RefPtr<TextEditRules> rules(mRules);
   nsresult rv =
     rules->WillDoAction(selection, subActionInfo, &cancel, &handled);
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -1400,17 +1400,17 @@ HTMLEditor::RelativeFontChange(FontSize 
   }
 
   // Wrap with txn batching, rules sniffing, and selection preservation code
   AutoPlaceholderBatch batchIt(this);
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this, EditSubAction::eSetTextProperty,
                                       nsIEditor::eNext);
   AutoSelectionRestorer selectionRestorer(selection, this);
-  AutoTransactionsConserveSelection dontChangeMySelection(this);
+  AutoTransactionsConserveSelection dontChangeMySelection(*this);
 
   // Loop through the ranges in the selection
   AutoRangeArray arrayOfRanges(selection);
   for (auto& range : arrayOfRanges.mRanges) {
     // Adjust range to include any ancestors with entirely selected children
     nsresult rv = PromoteInlineRange(*range);
     NS_ENSURE_SUCCESS(rv, rv);
 
--- a/editor/libeditor/HTMLTableEditor.cpp
+++ b/editor/libeditor/HTMLTableEditor.cpp
@@ -134,17 +134,17 @@ HTMLEditor::InsertCell(Element* aCell,
   }
   if (aAfter) {
     DebugOnly<bool> advanced = pointToInsert.AdvanceOffset();
     NS_WARNING_ASSERTION(advanced,
       "Failed to advance offset to after the old cell");
   }
 
   // Don't let Rules System change the selection.
-  AutoTransactionsConserveSelection dontChangeSelection(this);
+  AutoTransactionsConserveSelection dontChangeSelection(*this);
   return InsertNodeWithTransaction(*newCell, pointToInsert);
 }
 
 nsresult
 HTMLEditor::SetColSpan(Element* aCell,
                        int32_t aColSpan)
 {
   if (NS_WARN_IF(!aCell)) {
@@ -194,17 +194,17 @@ HTMLEditor::InsertTableCell(int32_t aNum
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(curCell, NS_ERROR_FAILURE);
   int32_t newCellIndex = aAfter ? (startColIndex+colSpan) : startColIndex;
   //We control selection resetting after the insert...
   AutoSelectionSetterAfterTableEdit setCaret(*this, table, startRowIndex,
                                              newCellIndex, ePreviousColumn,
                                              false);
   //...so suppress Rules System selection munging
-  AutoTransactionsConserveSelection dontChangeSelection(this);
+  AutoTransactionsConserveSelection dontChangeSelection(*this);
 
   for (int32_t i = 0; i < aNumber; i++) {
     RefPtr<Element> newCell;
     rv = CreateElementWithDefaults(NS_LITERAL_STRING("td"),
                                    getter_AddRefs(newCell));
     if (NS_SUCCEEDED(rv) && newCell) {
       if (aAfter) {
         cellOffset++;
@@ -395,17 +395,17 @@ HTMLEditor::InsertTableColumn(int32_t aN
   rv = GetTableSize(table, &rowCount, &colCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   //We reset caret in destructor...
   AutoSelectionSetterAfterTableEdit setCaret(*this, table, startRowIndex,
                                              startColIndex, ePreviousRow,
                                              false);
   //.. so suppress Rules System selection munging
-  AutoTransactionsConserveSelection dontChangeSelection(this);
+  AutoTransactionsConserveSelection dontChangeSelection(*this);
 
   // If we are inserting after all existing columns
   // Make sure table is "well formed"
   //  before appending new column
   if (startColIndex >= colCount) {
     NormalizeTable(table);
   }
 
@@ -527,17 +527,17 @@ HTMLEditor::InsertTableRow(int32_t aNumb
     }
   }
 
   //We control selection resetting after the insert...
   AutoSelectionSetterAfterTableEdit setCaret(*this, table, startRowIndex,
                                              startColIndex, ePreviousColumn,
                                              false);
   //...so suppress Rules System selection munging
-  AutoTransactionsConserveSelection dontChangeSelection(this);
+  AutoTransactionsConserveSelection dontChangeSelection(*this);
 
   RefPtr<Element> cellForRowParent;
   int32_t cellsInRow = 0;
   if (startRowIndex < rowCount) {
     // We are inserting above an existing row
     // Get each cell in the insert row to adjust for COLSPAN effects while we
     //   count how many cells are needed
     int32_t colIndex = 0;
@@ -744,17 +744,17 @@ HTMLEditor::DeleteTableCell(int32_t aNum
     rv = GetCellIndexes(cell, &startRowIndex, &startColIndex);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // The setCaret object will call AutoSelectionSetterAfterTableEdit in its
     // destructor
     AutoSelectionSetterAfterTableEdit setCaret(*this, table, startRowIndex,
                                                startColIndex, ePreviousColumn,
                                                false);
-    AutoTransactionsConserveSelection dontChangeSelection(this);
+    AutoTransactionsConserveSelection dontChangeSelection(*this);
 
     bool    checkToDeleteRow = true;
     bool    checkToDeleteColumn = true;
     while (cell) {
       bool deleteRow = false;
       bool deleteCol = false;
 
       if (checkToDeleteRow) {
@@ -873,17 +873,17 @@ HTMLEditor::DeleteTableCell(int32_t aNum
       } else {
         // More than 1 cell in the row
 
         // The setCaret object will call AutoSelectionSetterAfterTableEdit in its
         // destructor
         AutoSelectionSetterAfterTableEdit setCaret(*this, table, startRowIndex,
                                                    startColIndex, ePreviousColumn,
                                                    false);
-        AutoTransactionsConserveSelection dontChangeSelection(this);
+        AutoTransactionsConserveSelection dontChangeSelection(*this);
         rv = DeleteNodeWithTransaction(*cell);
         // If we fail, don't try to delete any more cells???
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
       }
     }
   }
@@ -908,17 +908,17 @@ HTMLEditor::DeleteTableCellContents()
 
 
   AutoPlaceholderBatch beginBatching(this);
   // Prevent rules testing until we're done
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this, EditSubAction::eDeleteNode,
                                       nsIEditor::eNext);
   //Don't let Rules System change the selection
-  AutoTransactionsConserveSelection dontChangeSelection(this);
+  AutoTransactionsConserveSelection dontChangeSelection(*this);
 
 
   RefPtr<Element> firstCell;
   rv = GetFirstSelectedCell(nullptr, getter_AddRefs(firstCell));
   NS_ENSURE_SUCCESS(rv, rv);
 
 
   if (firstCell) {
@@ -1172,17 +1172,17 @@ HTMLEditor::DeleteTableRow(int32_t aNumb
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   //We control selection resetting after the insert...
   AutoSelectionSetterAfterTableEdit setCaret(*this, table, startRowIndex,
                                              startColIndex, ePreviousRow,
                                              false);
   // Don't change selection during deletions
-  AutoTransactionsConserveSelection dontChangeSelection(this);
+  AutoTransactionsConserveSelection dontChangeSelection(*this);
 
   if (firstCell && rangeCount > 1) {
     // Use selected cells to determine what rows to delete
     cell = firstCell;
 
     while (cell) {
       if (cell != firstCell) {
         rv = GetCellIndexes(cell, &startRowIndex, &startColIndex);
@@ -1683,17 +1683,17 @@ HTMLEditor::SplitTableCell()
                                       *this, EditSubAction::eInsertNode,
                                       nsIEditor::eNext);
 
   // We reset selection
   AutoSelectionSetterAfterTableEdit setCaret(*this, table, startRowIndex,
                                              startColIndex, ePreviousColumn,
                                              false);
   //...so suppress Rules System selection munging
-  AutoTransactionsConserveSelection dontChangeSelection(this);
+  AutoTransactionsConserveSelection dontChangeSelection(*this);
 
   RefPtr<Element> newCell;
   int32_t rowIndex = startRowIndex;
   int32_t rowSpanBelow, colSpanAfter;
 
   // Split up cell row-wise first into rowspan=1 above, and the rest below,
   //  whittling away at the cell below until no more extra span
   for (rowSpanBelow = actualRowSpan-1; rowSpanBelow >= 0; rowSpanBelow--) {
@@ -1968,17 +1968,17 @@ HTMLEditor::JoinTableCells(bool aMergeNo
                                &startRowIndex, &startColIndex);
   NS_ENSURE_SUCCESS(rv, rv);
   if (!table || !targetCell) {
     return NS_SUCCESS_EDITOR_ELEMENT_NOT_FOUND;
   }
 
   AutoPlaceholderBatch beginBatching(this);
   //Don't let Rules System change the selection
-  AutoTransactionsConserveSelection dontChangeSelection(this);
+  AutoTransactionsConserveSelection dontChangeSelection(*this);
 
   // Note: We dont' use AutoSelectionSetterAfterTableEdit here so the selection
   //  is retained after joining. This leaves the target cell selected
   //  as well as the "non-contiguous" cells, so user can see what happened.
 
   RefPtr<Element> firstCell;
   int32_t firstRowIndex, firstColIndex;
   rv = GetFirstSelectedCellInTable(&firstRowIndex, &firstColIndex,
--- a/editor/libeditor/TextEditRules.cpp
+++ b/editor/libeditor/TextEditRules.cpp
@@ -373,17 +373,17 @@ TextEditRules::DidDoAction(Selection* aS
   if (NS_WARN_IF(!CanHandleEditAction())) {
     return NS_ERROR_EDITOR_DESTROYED;
   }
 
   AutoSafeEditorData setData(*this, *mTextEditor, *aSelection);
 
   // don't let any txns in here move the selection around behind our back.
   // Note that this won't prevent explicit selection setting from working.
-  AutoTransactionsConserveSelection dontChangeMySelection(&TextEditorRef());
+  AutoTransactionsConserveSelection dontChangeMySelection(TextEditorRef());
 
   switch (aInfo.mEditSubAction) {
     case EditSubAction::eDeleteSelectedContent:
       return DidDeleteSelection();
     case EditSubAction::eUndo:
       return DidUndo(aResult);
     case EditSubAction::eRedo:
       return DidRedo(aResult);
@@ -844,17 +844,17 @@ TextEditRules::WillInsertText(EditSubAct
     }
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   } else {
     // aEditSubAction == EditSubAction::eInsertText
 
     // don't change my selection in subtransactions
-    AutoTransactionsConserveSelection dontChangeMySelection(&TextEditorRef());
+    AutoTransactionsConserveSelection dontChangeMySelection(TextEditorRef());
 
     EditorRawDOMPoint pointAfterStringInserted;
     rv = TextEditorRef().InsertTextWithTransaction(*doc, *outString,
                                                    atStartOfSelection,
                                                    &pointAfterStringInserted);
     if (NS_WARN_IF(!CanHandleEditAction())) {
       return NS_ERROR_EDITOR_DESTROYED;
     }
@@ -1472,17 +1472,17 @@ TextEditRules::CreateTrailingBRIfNeeded(
 
   nsCOMPtr<nsIContent> lastChild = rootElement->GetLastChild();
   // assuming CreateBogusNodeIfNeeded() has been called first
   if (NS_WARN_IF(!lastChild)) {
     return NS_ERROR_FAILURE;
   }
 
   if (!lastChild->IsHTMLElement(nsGkAtoms::br)) {
-    AutoTransactionsConserveSelection dontChangeMySelection(&TextEditorRef());
+    AutoTransactionsConserveSelection dontChangeMySelection(TextEditorRef());
     EditorRawDOMPoint endOfRoot;
     endOfRoot.SetToEndOf(rootElement);
     CreateElementResult createMozBrResult = CreateMozBR(endOfRoot);
     if (NS_WARN_IF(createMozBrResult.Failed())) {
       return createMozBrResult.Rv();
     }
     return NS_OK;
   }
--- a/editor/libeditor/TextEditor.cpp
+++ b/editor/libeditor/TextEditor.cpp
@@ -1090,17 +1090,17 @@ TextEditor::InsertParagraphSeparatorAsAc
 
     // we need to get the doc
     nsCOMPtr<nsIDocument> doc = GetDocument();
     if (NS_WARN_IF(!doc)) {
       return NS_ERROR_NOT_INITIALIZED;
     }
 
     // don't change my selection in subtransactions
-    AutoTransactionsConserveSelection dontChangeMySelection(this);
+    AutoTransactionsConserveSelection dontChangeMySelection(*this);
 
     // insert a linefeed character
     EditorRawDOMPoint pointAfterInsertedLineBreak;
     rv = InsertTextWithTransaction(*doc, NS_LITERAL_STRING("\n"), pointToInsert,
                                    &pointAfterInsertedLineBreak);
     if (NS_WARN_IF(!pointAfterInsertedLineBreak.IsSet())) {
       rv = NS_ERROR_NULL_POINTER; // don't return here, so DidDoAction is called
     }
--- a/editor/libeditor/TextEditorDataTransfer.cpp
+++ b/editor/libeditor/TextEditorDataTransfer.cpp
@@ -110,17 +110,17 @@ TextEditor::InsertTextFromTransferable(n
   nsCOMPtr<nsISupports> genericDataObj;
   uint32_t len = 0;
   if (NS_SUCCEEDED(
         aTransferable->GetAnyTransferData(bestFlavor,
                                           getter_AddRefs(genericDataObj),
                                           &len)) &&
       (bestFlavor.EqualsLiteral(kUnicodeMime) ||
        bestFlavor.EqualsLiteral(kMozTextInternal))) {
-    AutoTransactionsConserveSelection dontChangeMySelection(this);
+    AutoTransactionsConserveSelection dontChangeMySelection(*this);
     nsCOMPtr<nsISupportsString> textDataObj ( do_QueryInterface(genericDataObj) );
     if (textDataObj && len > 0) {
       nsAutoString stuffToPaste;
       textDataObj->GetData(stuffToPaste);
       NS_ASSERTION(stuffToPaste.Length() <= (len/2), "Invalid length!");
 
       // Sanitize possible carriage returns in the string to be inserted
       nsContentUtils::PlatformToDOMLineBreaks(stuffToPaste);
--- a/editor/libeditor/WSRunObject.cpp
+++ b/editor/libeditor/WSRunObject.cpp
@@ -1542,22 +1542,27 @@ nsresult
 WSRunObject::InsertNBSPAndRemoveFollowingASCIIWhitespaces(WSPoint aPoint)
 {
   // MOOSE: this routine needs to be modified to preserve the integrity of the
   // wsFragment info.
   if (NS_WARN_IF(!aPoint.mTextNode)) {
     return NS_ERROR_NULL_POINTER;
   }
 
- // First, insert an NBSP.
-  AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor);
+  if (NS_WARN_IF(!mHTMLEditor)) {
+    return NS_ERROR_NOT_INITIALIZED;
+  }
+  RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
+
+  // First, insert an NBSP.
+  AutoTransactionsConserveSelection dontChangeMySelection(*htmlEditor);
   nsresult rv =
-    mHTMLEditor->InsertTextIntoTextNodeWithTransaction(
-                   nsDependentSubstring(&kNBSP, 1),
-                   *aPoint.mTextNode, aPoint.mOffset, true);
+    htmlEditor->InsertTextIntoTextNodeWithTransaction(
+                  nsDependentSubstring(&kNBSP, 1),
+                  *aPoint.mTextNode, aPoint.mOffset, true);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   // Now, the text node may have been modified by mutation observer.
   // So, the NBSP may have gone.
   if (aPoint.mTextNode->TextDataLength() <= aPoint.mOffset ||
       aPoint.mTextNode->GetText()->CharAt(aPoint.mOffset) != kNBSP) {
@@ -1886,24 +1891,26 @@ WSRunObject::CheckTrailingNBSPOfRun(WSFr
         // Refresh thePoint, prevPoint
         thePoint = GetPreviousCharPoint(aRun->EndPoint());
         prevPoint = GetPreviousCharPoint(thePoint);
         rightCheck = true;
       }
     }
     if (leftCheck && rightCheck) {
       // Now replace nbsp with space.  First, insert a space
-      AutoTransactionsConserveSelection dontChangeMySelection(htmlEditor);
+      AutoTransactionsConserveSelection dontChangeMySelection(*htmlEditor);
       nsAutoString spaceStr(char16_t(32));
       nsresult rv =
         htmlEditor->InsertTextIntoTextNodeWithTransaction(spaceStr,
                                                           *thePoint.mTextNode,
                                                           thePoint.mOffset,
                                                           true);
-      NS_ENSURE_SUCCESS(rv, rv);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return rv;
+      }
 
       // Finally, delete that nbsp
       rv = DeleteRange(EditorRawDOMPoint(thePoint.mTextNode,
                                          thePoint.mOffset + 1),
                        EditorRawDOMPoint(thePoint.mTextNode,
                                          thePoint.mOffset + 2));
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
@@ -1928,22 +1935,24 @@ WSRunObject::CheckTrailingNBSPOfRun(WSFr
                                                   thePoint.mOffset),
                                 EditorRawDOMPoint(thePoint.mTextNode,
                                                   thePoint.mOffset + 1));
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
 
       // Finally, insert that nbsp before the ASCII ws run
-      AutoTransactionsConserveSelection dontChangeMySelection(htmlEditor);
+      AutoTransactionsConserveSelection dontChangeMySelection(*htmlEditor);
       rv =
         htmlEditor->InsertTextIntoTextNodeWithTransaction(
                       nsDependentSubstring(&kNBSP, 1),
                       *startNode, startOffset, true);
-      NS_ENSURE_SUCCESS(rv, rv);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return rv;
+      }
     }
   }
   return NS_OK;
 }
 
 template<typename PT, typename CT>
 nsresult
 WSRunObject::ReplacePreviousNBSPIfUnncessary(
@@ -1980,23 +1989,28 @@ WSRunObject::ReplacePreviousNBSPIfUnnces
       canConvert = true;
     }
   }
 
   if (!canConvert) {
     return NS_OK;
   }
 
+  if (NS_WARN_IF(!mHTMLEditor)) {
+    return NS_ERROR_NOT_INITIALIZED;
+  }
+  RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
+
   // First, insert a space before the previous NBSP.
-  AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor);
+  AutoTransactionsConserveSelection dontChangeMySelection(*htmlEditor);
   nsAutoString spaceStr(char16_t(32));
   nsresult rv =
-    mHTMLEditor->InsertTextIntoTextNodeWithTransaction(spaceStr,
-                                                       *thePoint.mTextNode,
-                                                       thePoint.mOffset, true);
+    htmlEditor->InsertTextIntoTextNodeWithTransaction(spaceStr,
+                                                      *thePoint.mTextNode,
+                                                      thePoint.mOffset, true);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   // Finally, delete the previous NBSP.
   rv = DeleteRange(EditorRawDOMPoint(thePoint.mTextNode,
                                      thePoint.mOffset + 1),
                    EditorRawDOMPoint(thePoint.mTextNode,
@@ -2029,25 +2043,32 @@ WSRunObject::CheckLeadingNBSP(WSFragment
       }
     } else if (aRun->mRightType == WSType::text ||
                aRun->mRightType == WSType::special ||
                aRun->mRightType == WSType::br) {
       canConvert = true;
     }
   }
   if (canConvert) {
+    if (NS_WARN_IF(!mHTMLEditor)) {
+      return NS_ERROR_NOT_INITIALIZED;
+    }
+    RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
+
     // First, insert a space
-    AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor);
+    AutoTransactionsConserveSelection dontChangeMySelection(*htmlEditor);
     nsAutoString spaceStr(char16_t(32));
     nsresult rv =
-      mHTMLEditor->InsertTextIntoTextNodeWithTransaction(spaceStr,
-                                                         *thePoint.mTextNode,
-                                                         thePoint.mOffset,
-                                                         true);
-    NS_ENSURE_SUCCESS(rv, rv);
+      htmlEditor->InsertTextIntoTextNodeWithTransaction(spaceStr,
+                                                        *thePoint.mTextNode,
+                                                        thePoint.mOffset,
+                                                        true);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
 
     // Finally, delete that nbsp
     rv = DeleteRange(EditorRawDOMPoint(thePoint.mTextNode,
                                        thePoint.mOffset + 1),
                      EditorRawDOMPoint(thePoint.mTextNode,
                                        thePoint.mOffset + 2));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;