Bug 1451672 - part 1: Rename EditorBase::CreateNode() to EditorBase::CreateNodeWithTransaction() r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 10 Apr 2018 01:17:26 +0900
changeset 786084 1ee3c3162756c0b4241e39031e597a69c0ec6326
parent 786083 d732707f0c2c25350654482efed2815ce797b22a
child 786085 9a90e0b804f29c52134daeffe56760ad862100a5
push id107393
push usermasayuki@d-toybox.com
push dateSat, 21 Apr 2018 04:40:12 +0000
reviewersm_kato
bugs1451672
milestone61.0a1
Bug 1451672 - part 1: Rename EditorBase::CreateNode() to EditorBase::CreateNodeWithTransaction() r?m_kato EditorBase::CreateNode() creates an element node with transaction. I.e., it's undoable. So, if somebody would use this method as a helper method for changing the DOM tree, that would cause unexpected undoable transaction. So, we should make the method name clearer to avoid such bug. MozReview-Commit-ID: GZsOGBfqog
editor/libeditor/EditorBase.cpp
editor/libeditor/EditorBase.h
editor/libeditor/EditorUtils.h
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditor.cpp
editor/libeditor/TextEditor.cpp
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -117,19 +117,21 @@ namespace mozilla {
 using namespace dom;
 using namespace widget;
 
 /*****************************************************************************
  * mozilla::EditorBase
  *****************************************************************************/
 
 template already_AddRefed<Element>
-EditorBase::CreateNode(nsAtom* aTag, const EditorDOMPoint& aPointToInsert);
+EditorBase::CreateNodeWithTransaction(nsAtom& aTag,
+                                      const EditorDOMPoint& aPointToInsert);
 template already_AddRefed<Element>
-EditorBase::CreateNode(nsAtom* aTag, const EditorRawDOMPoint& aPointToInsert);
+EditorBase::CreateNodeWithTransaction(nsAtom& aTag,
+                                      const EditorRawDOMPoint& aPointToInsert);
 template nsresult
 EditorBase::InsertNode(nsIContent& aContentToInsert,
                        const EditorDOMPoint& aPointToInsert);
 template nsresult
 EditorBase::InsertNode(nsIContent& aContentToInsert,
                        const EditorRawDOMPoint& aPointToInsert);
 template already_AddRefed<nsIContent>
 EditorBase::SplitNode(const EditorDOMPoint& aStartOfRightNode,
@@ -1341,33 +1343,33 @@ EditorBase::SetSpellcheckUserOverride(bo
 {
   mSpellcheckCheckboxState = enable ? eTriTrue : eTriFalse;
 
   return SyncRealTimeSpell();
 }
 
 template<typename PT, typename CT>
 already_AddRefed<Element>
-EditorBase::CreateNode(nsAtom* aTag,
-                       const EditorDOMPointBase<PT, CT>& aPointToInsert)
-{
-  MOZ_ASSERT(aTag);
+EditorBase::CreateNodeWithTransaction(
+              nsAtom& aTagName,
+              const EditorDOMPointBase<PT, CT>& aPointToInsert)
+{
   MOZ_ASSERT(aPointToInsert.IsSetAndValid());
 
   // XXX We need offset at new node for mRangeUpdater.  Therefore, we need
   //     to compute the offset now but this is expensive.  So, if it's possible,
   //     we need to redesign mRangeUpdater as avoiding using indices.
   Unused << aPointToInsert.Offset();
 
   AutoRules beginRulesSniffing(this, EditAction::createNode, nsIEditor::eNext);
 
   RefPtr<Element> newElement;
 
   RefPtr<CreateElementTransaction> transaction =
-    CreateElementTransaction::Create(*this, *aTag, aPointToInsert);
+    CreateElementTransaction::Create(*this, aTagName, aPointToInsert);
   nsresult rv = DoTransaction(transaction);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     // XXX Why do we do this even when DoTransaction() returned error?
     mRangeUpdater.SelAdjCreateNode(aPointToInsert);
   } else {
     newElement = transaction->GetNewNode();
     MOZ_ASSERT(newElement);
 
@@ -1385,17 +1387,17 @@ EditorBase::CreateNode(nsAtom* aTag,
   if (mRules && mRules->AsHTMLEditRules()) {
     RefPtr<HTMLEditRules> htmlEditRules = mRules->AsHTMLEditRules();
     htmlEditRules->DidCreateNode(newElement);
   }
 
   if (!mActionListeners.IsEmpty()) {
     AutoActionListenerArray listeners(mActionListeners);
     for (auto& listener : listeners) {
-      listener->DidCreateNode(nsDependentAtomString(aTag),
+      listener->DidCreateNode(nsDependentAtomString(&aTagName),
                               GetAsDOMNode(newElement), rv);
     }
   }
 
   return newElement.forget();
 }
 
 NS_IMETHODIMP
@@ -4338,17 +4340,17 @@ EditorBase::DeleteSelectionAndCreateElem
 
   RefPtr<Selection> selection = GetSelection();
   NS_ENSURE_TRUE(selection, nullptr);
 
   EditorRawDOMPoint pointToInsert(selection->AnchorRef());
   if (!pointToInsert.IsSet()) {
     return nullptr;
   }
-  RefPtr<Element> newElement = CreateNode(&aTag, pointToInsert);
+  RefPtr<Element> newElement = CreateNodeWithTransaction(aTag, pointToInsert);
 
   // We want the selection to be just after the new node
   EditorRawDOMPoint afterNewElement(newElement);
   MOZ_ASSERT(afterNewElement.IsSetAndValid());
   DebugOnly<bool> advanced = afterNewElement.AdvanceOffset();
   NS_WARNING_ASSERTION(advanced,
                        "Failed to move offset next to the new element");
   ErrorResult error;
--- a/editor/libeditor/EditorBase.h
+++ b/editor/libeditor/EditorBase.h
@@ -518,18 +518,18 @@ protected:
    *                        end of the container or after, the transaction
    *                        will append the element to the container.
    *                        Otherwise, will insert the element before the
    *                        child node referred by this.
    * @return                The created new element node.
    */
   template<typename PT, typename CT>
   already_AddRefed<Element>
-  CreateNode(nsAtom* aTag,
-             const EditorDOMPointBase<PT, CT>& aPointToInsert);
+  CreateNodeWithTransaction(nsAtom& aTag,
+                            const EditorDOMPointBase<PT, CT>& aPointToInsert);
 
   /**
    * Create an aggregate transaction for delete selection.  The result may
    * include DeleteNodeTransactions and/or DeleteTextTransactions as its
    * children.
    *
    * @param aAction             The action caused removing the selection.
    * @param aRemovingNode       The node to be removed.
--- a/editor/libeditor/EditorUtils.h
+++ b/editor/libeditor/EditorUtils.h
@@ -201,17 +201,17 @@ public:
                 mGivenSplitPoint.GetChild() : nullptr;
     }
     return mNextNode;
   }
 
   /**
    * SplitPoint() returns the split point in the container.
    * This is useful when callers insert an element at split point with
-   * EditorBase::CreateNode() or something similar methods.
+   * EditorBase::CreateNodeWithTransaction() or something similar methods.
    *
    * Note that the result is EditorRawDOMPoint but the nodes are grabbed
    * by this instance.  Therefore, the life time of both container node
    * and child node are guaranteed while using the result temporarily.
    */
   EditorRawDOMPoint SplitPoint() const
   {
     if (Failed()) {
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -3586,24 +3586,30 @@ HTMLEditRules::WillMakeList(Selection* a
     }
 
     SplitNodeResult splitAtSelectionStartResult =
       MaybeSplitAncestorsForInsert(listType, atStartOfSelection);
     if (NS_WARN_IF(splitAtSelectionStartResult.Failed())) {
       return splitAtSelectionStartResult.Rv();
     }
     RefPtr<Element> theList =
-      htmlEditor->CreateNode(listType,
-                             splitAtSelectionStartResult.SplitPoint());
-    NS_ENSURE_STATE(theList);
+      htmlEditor->CreateNodeWithTransaction(
+                    *listType,
+                    splitAtSelectionStartResult.SplitPoint());
+    if (NS_WARN_IF(!theList)) {
+      return NS_ERROR_FAILURE;
+    }
 
     EditorRawDOMPoint atFirstListItemToInsertBefore(theList, 0);
     RefPtr<Element> theListItem =
-      htmlEditor->CreateNode(itemType, atFirstListItemToInsertBefore);
-    NS_ENSURE_STATE(theListItem);
+      htmlEditor->CreateNodeWithTransaction(*itemType,
+                                            atFirstListItemToInsertBefore);
+    if (NS_WARN_IF(!theListItem)) {
+      return NS_ERROR_FAILURE;
+    }
 
     // remember our new block for postprocessing
     mNewBlock = theListItem;
     // put selection in new list item
     *aHandled = true;
     ErrorResult error;
     aSelection->Collapse(EditorRawDOMPoint(theListItem, 0), error);
     // Don't restore the selection
@@ -3692,18 +3698,21 @@ HTMLEditRules::WillMakeList(Selection* a
           ErrorResult error;
           nsCOMPtr<nsIContent> newLeftNode =
             htmlEditor->SplitNode(atCurNode, error);
           if (NS_WARN_IF(error.Failed())) {
             return error.StealNSResult();
           }
           newBlock = newLeftNode ? newLeftNode->AsElement() : nullptr;
           EditorRawDOMPoint atParentOfCurNode(atCurNode.GetContainer());
-          curList = htmlEditor->CreateNode(listType, atParentOfCurNode);
-          NS_ENSURE_STATE(curList);
+          curList = htmlEditor->CreateNodeWithTransaction(*listType,
+                                                          atParentOfCurNode);
+          if (NS_WARN_IF(!curList)) {
+            return NS_ERROR_FAILURE;
+          }
         }
         // move list item to new list
         rv = htmlEditor->MoveNode(curNode, curList, -1);
         NS_ENSURE_SUCCESS(rv, rv);
         // convert list item type if needed
         if (!curNode->IsHTMLElement(itemType)) {
           newBlock = htmlEditor->ReplaceContainer(curNode->AsElement(),
                                                   itemType);
@@ -3756,17 +3765,18 @@ HTMLEditRules::WillMakeList(Selection* a
     // need to make a list to put things in if we haven't already,
     if (!curList) {
       SplitNodeResult splitCurNodeResult =
         MaybeSplitAncestorsForInsert(listType, atCurNode);
       if (NS_WARN_IF(splitCurNodeResult.Failed())) {
         return splitCurNodeResult.Rv();
       }
       curList =
-        htmlEditor->CreateNode(listType, splitCurNodeResult.SplitPoint());
+        htmlEditor->CreateNodeWithTransaction(*listType,
+                                              splitCurNodeResult.SplitPoint());
       if (NS_WARN_IF(!curList)) {
         return NS_ERROR_FAILURE;
       }
       // remember our new block for postprocessing
       mNewBlock = curList;
       // curList is now the correct thing to put curNode in
       prevListItem = nullptr;
 
@@ -3984,18 +3994,21 @@ HTMLEditRules::MakeBasicBlock(Selection&
     }
     // Make sure we can put a block here.
     SplitNodeResult splitNodeResult =
       MaybeSplitAncestorsForInsert(blockType, pointToInsertBlock);
     if (NS_WARN_IF(splitNodeResult.Failed())) {
       return splitNodeResult.Rv();
     }
     RefPtr<Element> block =
-      htmlEditor->CreateNode(&blockType, splitNodeResult.SplitPoint());
-    NS_ENSURE_STATE(block);
+      htmlEditor->CreateNodeWithTransaction(blockType,
+                                            splitNodeResult.SplitPoint());
+    if (NS_WARN_IF(!block)) {
+      return NS_ERROR_FAILURE;
+    }
     // Remember our new block for postprocessing
     mNewBlock = block;
     // Delete anything that was in the list of nodes
     while (!arrayOfNodes.IsEmpty()) {
       OwningNonNull<nsINode> curNode = arrayOfNodes[0];
       rv = htmlEditor->DeleteNode(curNode);
       NS_ENSURE_SUCCESS(rv, rv);
       arrayOfNodes.RemoveElementAt(0);
@@ -4133,18 +4146,21 @@ HTMLEditRules::WillCSSIndent(Selection* 
 
     // make sure we can put a block here
     SplitNodeResult splitNodeResult =
       MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atStartOfSelection);
     if (NS_WARN_IF(splitNodeResult.Failed())) {
       return splitNodeResult.Rv();
     }
     RefPtr<Element> theBlock =
-      htmlEditor->CreateNode(nsGkAtoms::div, splitNodeResult.SplitPoint());
-    NS_ENSURE_STATE(theBlock);
+      htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::div,
+                                            splitNodeResult.SplitPoint());
+    if (NS_WARN_IF(!theBlock)) {
+      return NS_ERROR_FAILURE;
+    }
     // remember our new block for postprocessing
     mNewBlock = theBlock;
     ChangeIndentation(*theBlock, Change::plus);
     // delete anything that was in the list of nodes
     while (!arrayOfNodes.IsEmpty()) {
       OwningNonNull<nsINode> curNode = arrayOfNodes[0];
       rv = htmlEditor->DeleteNode(curNode);
       NS_ENSURE_SUCCESS(rv, rv);
@@ -4220,19 +4236,22 @@ HTMLEditRules::WillCSSIndent(Selection* 
         nsAtom* containerName =
           atCurNode.GetContainer()->NodeInfo()->NameAtom();
         // Create a new nested list of correct type.
         SplitNodeResult splitNodeResult =
           MaybeSplitAncestorsForInsert(*containerName, atCurNode);
         if (NS_WARN_IF(splitNodeResult.Failed())) {
           return splitNodeResult.Rv();
         }
-        curList = htmlEditor->CreateNode(containerName,
-                                         splitNodeResult.SplitPoint());
-        NS_ENSURE_STATE(curList);
+        curList =
+          htmlEditor->CreateNodeWithTransaction(*containerName,
+                                                splitNodeResult.SplitPoint());
+        if (NS_WARN_IF(!curList)) {
+          return NS_ERROR_FAILURE;
+        }
         // curList is now the correct thing to put curNode in
         // remember our new block for postprocessing
         mNewBlock = curList;
       }
       // tuck the node into the end of the active list
       uint32_t listLen = curList->Length();
       rv = htmlEditor->MoveNode(curNode->AsContent(), curList, listLen);
       NS_ENSURE_SUCCESS(rv, rv);
@@ -4256,18 +4275,21 @@ HTMLEditRules::WillCSSIndent(Selection* 
       }
 
       SplitNodeResult splitNodeResult =
         MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atCurNode);
       if (NS_WARN_IF(splitNodeResult.Failed())) {
         return splitNodeResult.Rv();
       }
       curQuote =
-        htmlEditor->CreateNode(nsGkAtoms::div, splitNodeResult.SplitPoint());
-      NS_ENSURE_STATE(curQuote);
+        htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::div,
+                                              splitNodeResult.SplitPoint());
+      if (NS_WARN_IF(!curQuote)) {
+        return NS_ERROR_FAILURE;
+      }
       ChangeIndentation(*curQuote, Change::plus);
       // remember our new block for postprocessing
       mNewBlock = curQuote;
       // curQuote is now the correct thing to put curNode in
     }
 
     // tuck the node into the end of the active blockquote
     uint32_t quoteLen = curQuote->Length();
@@ -4331,19 +4353,21 @@ HTMLEditRules::WillHTMLIndent(Selection*
     // Make sure we can put a block here.
     SplitNodeResult splitNodeResult =
       MaybeSplitAncestorsForInsert(*nsGkAtoms::blockquote,
                                    atStartOfSelection);
     if (NS_WARN_IF(splitNodeResult.Failed())) {
       return splitNodeResult.Rv();
     }
     RefPtr<Element> theBlock =
-      htmlEditor->CreateNode(nsGkAtoms::blockquote,
-                             splitNodeResult.SplitPoint());
-    NS_ENSURE_STATE(theBlock);
+      htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::blockquote,
+                                            splitNodeResult.SplitPoint());
+    if (NS_WARN_IF(!theBlock)) {
+      return NS_ERROR_FAILURE;
+    }
     // remember our new block for postprocessing
     mNewBlock = theBlock;
     // delete anything that was in the list of nodes
     while (!arrayOfNodes.IsEmpty()) {
       OwningNonNull<nsINode> curNode = arrayOfNodes[0];
       rv = htmlEditor->DeleteNode(curNode);
       NS_ENSURE_SUCCESS(rv, rv);
       arrayOfNodes.RemoveElementAt(0);
@@ -4419,18 +4443,21 @@ HTMLEditRules::WillHTMLIndent(Selection*
           atCurNode.GetContainer()->NodeInfo()->NameAtom();
         // Create a new nested list of correct type.
         SplitNodeResult splitNodeResult =
           MaybeSplitAncestorsForInsert(*containerName, atCurNode);
         if (NS_WARN_IF(splitNodeResult.Failed())) {
           return splitNodeResult.Rv();
         }
         curList =
-          htmlEditor->CreateNode(containerName, splitNodeResult.SplitPoint());
-        NS_ENSURE_STATE(curList);
+          htmlEditor->CreateNodeWithTransaction(*containerName,
+                                                splitNodeResult.SplitPoint());
+        if (NS_WARN_IF(!curList)) {
+          return NS_ERROR_FAILURE;
+        }
         // curList is now the correct thing to put curNode in
         // remember our new block for postprocessing
         mNewBlock = curList;
       }
       // tuck the node into the end of the active list
       rv = htmlEditor->MoveNode(curNode->AsContent(), curList, -1);
       NS_ENSURE_SUCCESS(rv, rv);
       // forget curQuote, if any
@@ -4467,19 +4494,22 @@ HTMLEditRules::WillHTMLIndent(Selection*
         nsAtom* containerName =
           atListItem.GetContainer()->NodeInfo()->NameAtom();
         // Create a new nested list of correct type.
         SplitNodeResult splitNodeResult =
           MaybeSplitAncestorsForInsert(*containerName, atListItem);
         if (NS_WARN_IF(splitNodeResult.Failed())) {
           return splitNodeResult.Rv();
         }
-        curList = htmlEditor->CreateNode(containerName,
-                                         splitNodeResult.SplitPoint());
-        NS_ENSURE_STATE(curList);
+        curList =
+          htmlEditor->CreateNodeWithTransaction(*containerName,
+                                                splitNodeResult.SplitPoint());
+        if (NS_WARN_IF(!curList)) {
+          return NS_ERROR_FAILURE;
+        }
       }
 
       rv = htmlEditor->MoveNode(listItem, curList, -1);
       NS_ENSURE_SUCCESS(rv, rv);
 
       // remember we indented this li
       indentedLI = listItem;
 
@@ -4502,19 +4532,21 @@ HTMLEditRules::WillHTMLIndent(Selection*
       }
 
       SplitNodeResult splitNodeResult =
         MaybeSplitAncestorsForInsert(*nsGkAtoms::blockquote, atCurNode);
       if (NS_WARN_IF(splitNodeResult.Failed())) {
         return splitNodeResult.Rv();
       }
       curQuote =
-        htmlEditor->CreateNode(nsGkAtoms::blockquote,
-                               splitNodeResult.SplitPoint());
-      NS_ENSURE_STATE(curQuote);
+        htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::blockquote,
+                                              splitNodeResult.SplitPoint());
+      if (NS_WARN_IF(!curQuote)) {
+        return NS_ERROR_FAILURE;
+      }
       // remember our new block for postprocessing
       mNewBlock = curQuote;
       // curQuote is now the correct thing to put curNode in
     }
 
     // tuck the node into the end of the active blockquote
     rv = htmlEditor->MoveNode(curNode->AsContent(), curQuote, -1);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -5130,18 +5162,20 @@ HTMLEditRules::WillAlign(Selection& aSel
       }
       if (sibling && !IsBlockNode(*sibling)) {
         AutoEditorDOMPointChildInvalidator lockOffset(pointToInsertDiv);
         rv = htmlEditor->DeleteNode(brContent);
         NS_ENSURE_SUCCESS(rv, rv);
       }
     }
     RefPtr<Element> div =
-      htmlEditor->CreateNode(nsGkAtoms::div, pointToInsertDiv);
-    NS_ENSURE_STATE(div);
+      htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::div, pointToInsertDiv);
+    if (NS_WARN_IF(!div)) {
+      return NS_ERROR_FAILURE;
+    }
     // Remember our new block for postprocessing
     mNewBlock = div;
     // Set up the alignment on the div, using HTML or CSS
     rv = AlignBlock(*div, aAlignType, ContentsOnly::yes);
     NS_ENSURE_SUCCESS(rv, rv);
     *aHandled = true;
     // Put in a moz-br so that it won't get deleted
     RefPtr<Element> brElement = CreateMozBR(EditorRawDOMPoint(div, 0));
@@ -5244,18 +5278,21 @@ HTMLEditRules::WillAlign(Selection& aSel
       }
 
       SplitNodeResult splitNodeResult =
         MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atCurNode);
       if (NS_WARN_IF(splitNodeResult.Failed())) {
         return splitNodeResult.Rv();
       }
       curDiv =
-        htmlEditor->CreateNode(nsGkAtoms::div, splitNodeResult.SplitPoint());
-      NS_ENSURE_STATE(curDiv);
+        htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::div,
+                                              splitNodeResult.SplitPoint());
+      if (NS_WARN_IF(!curDiv)) {
+        return NS_ERROR_FAILURE;
+      }
       // Remember our new block for postprocessing
       mNewBlock = curDiv;
       // Set up the alignment on the div
       rv = AlignBlock(*curDiv, aAlignType, ContentsOnly::yes);
     }
 
     // Tuck the node into the end of the active div
     rv = htmlEditor->MoveNode(curNode->AsContent(), curDiv, -1);
@@ -5317,17 +5354,17 @@ HTMLEditRules::AlignBlockContents(nsINod
                                                 nsGkAtoms::align,
                                                 aAlignType, false);
   }
 
   // else we need to put in a div, set the alignment, and toss in all the
   // children
   EditorRawDOMPoint atStartOfNode(&aNode, 0);
   RefPtr<Element> divElem =
-    htmlEditor->CreateNode(nsGkAtoms::div, atStartOfNode);
+    htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::div, atStartOfNode);
   if (NS_WARN_IF(!divElem)) {
     return NS_ERROR_FAILURE;
   }
   // set up the alignment on the div
   nsresult rv =
     htmlEditor->SetAttributeOrEquivalent(divElem, nsGkAtoms::align,
                                          aAlignType, false);
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -6871,20 +6908,22 @@ HTMLEditRules::ReturnInHeader(Selection&
       ClearCachedStyles();
       htmlEditor->mTypeInState->ClearAllProps();
 
       // Create a paragraph
       nsAtom& paraAtom = DefaultParagraphSeparator();
       // We want a wrapper element even if we separate with <br>
       EditorRawDOMPoint nextToHeader(headerParent, offset + 1);
       RefPtr<Element> pNode =
-        htmlEditor->CreateNode(&paraAtom == nsGkAtoms::br ?
-                                 nsGkAtoms::p : &paraAtom,
-                               nextToHeader);
-      NS_ENSURE_STATE(pNode);
+        htmlEditor->CreateNodeWithTransaction(&paraAtom == nsGkAtoms::br ?
+                                                *nsGkAtoms::p : paraAtom,
+                                              nextToHeader);
+      if (NS_WARN_IF(!pNode)) {
+        return NS_ERROR_FAILURE;
+      }
 
       // Append a <br> to it
       RefPtr<Element> brNode =
         htmlEditor->CreateBR(EditorRawDOMPoint(pNode, 0));
       if (NS_WARN_IF(!brNode)) {
         return NS_ERROR_FAILURE;
       }
 
@@ -7238,20 +7277,22 @@ HTMLEditRules::ReturnInListItem(Selectio
       // Otherwise kill this item
       nsresult rv = htmlEditor->DeleteNode(&aListItem);
       NS_ENSURE_SUCCESS(rv, rv);
 
       // Time to insert a paragraph
       nsAtom& paraAtom = DefaultParagraphSeparator();
       // We want a wrapper even if we separate with <br>
       RefPtr<Element> pNode =
-        htmlEditor->CreateNode(&paraAtom == nsGkAtoms::br ?
-                                 nsGkAtoms::p : &paraAtom,
-                               atNextSiblingOfLeftList);
-      NS_ENSURE_STATE(pNode);
+        htmlEditor->CreateNodeWithTransaction(&paraAtom == nsGkAtoms::br ?
+                                                *nsGkAtoms::p : paraAtom,
+                                              atNextSiblingOfLeftList);
+      if (NS_WARN_IF(!pNode)) {
+        return NS_ERROR_FAILURE;
+      }
 
       // Append a <br> to it
       RefPtr<Element> brNode =
         htmlEditor->CreateBR(EditorRawDOMPoint(pNode, 0));
       if (NS_WARN_IF(!brNode)) {
         return NS_ERROR_FAILURE;
       }
 
@@ -7306,18 +7347,20 @@ HTMLEditRules::ReturnInListItem(Selectio
           int32_t itemOffset = list ? list->ComputeIndexOf(&aListItem) : -1;
 
           nsAtom* listAtom = nodeAtom == nsGkAtoms::dt ? nsGkAtoms::dd
                                                         : nsGkAtoms::dt;
           MOZ_DIAGNOSTIC_ASSERT(itemOffset != -1);
           EditorRawDOMPoint atNextListItem(list, aListItem.GetNextSibling(),
                                            itemOffset + 1);
           RefPtr<Element> newListItem =
-            htmlEditor->CreateNode(listAtom, atNextListItem);
-          NS_ENSURE_STATE(newListItem);
+            htmlEditor->CreateNodeWithTransaction(*listAtom, atNextListItem);
+          if (NS_WARN_IF(!newListItem)) {
+            return NS_ERROR_FAILURE;
+          }
           rv = htmlEditor->DeleteNode(&aListItem);
           NS_ENSURE_SUCCESS(rv, rv);
           rv = aSelection.Collapse(newListItem, 0);
           NS_ENSURE_SUCCESS(rv, rv);
 
           return NS_OK;
         }
 
@@ -7423,19 +7466,22 @@ HTMLEditRules::MakeBlockquote(nsTArray<O
     // If no curBlock, make one
     if (!curBlock) {
       EditorDOMPoint atCurNode(curNode);
       SplitNodeResult splitNodeResult =
         MaybeSplitAncestorsForInsert(*nsGkAtoms::blockquote, atCurNode);
       if (NS_WARN_IF(splitNodeResult.Failed())) {
         return splitNodeResult.Rv();
       }
-      curBlock = htmlEditor->CreateNode(nsGkAtoms::blockquote,
-                                        splitNodeResult.SplitPoint());
-      NS_ENSURE_STATE(curBlock);
+      curBlock =
+        htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::blockquote,
+                                              splitNodeResult.SplitPoint());
+      if (NS_WARN_IF(!curBlock)) {
+        return NS_ERROR_FAILURE;
+      }
       // remember our new block for postprocessing
       mNewBlock = curBlock;
       // note: doesn't matter if we set mNewBlock multiple times.
     }
 
     nsresult rv = htmlEditor->MoveNode(curNode->AsContent(), curBlock, -1);
     NS_ENSURE_SUCCESS(rv, rv);
   }
@@ -7601,18 +7647,21 @@ HTMLEditRules::ApplyBlockStyle(nsTArray<
 
       // Make sure we can put a block here
       SplitNodeResult splitNodeResult =
         MaybeSplitAncestorsForInsert(aBlockTag, atCurNode);
       if (NS_WARN_IF(splitNodeResult.Failed())) {
         return splitNodeResult.Rv();
       }
       RefPtr<Element> theBlock =
-        htmlEditor->CreateNode(&aBlockTag, splitNodeResult.SplitPoint());
-      NS_ENSURE_STATE(theBlock);
+        htmlEditor->CreateNodeWithTransaction(aBlockTag,
+                                              splitNodeResult.SplitPoint());
+      if (NS_WARN_IF(!theBlock)) {
+        return NS_ERROR_FAILURE;
+      }
       // Remember our new block for postprocessing
       mNewBlock = theBlock;
       continue;
     }
 
     if (curNode->IsHTMLElement(nsGkAtoms::br)) {
       // If the node is a break, we honor it by putting further nodes in a new
       // parent
@@ -7627,18 +7676,21 @@ HTMLEditRules::ApplyBlockStyle(nsTArray<
       // The break is the first (or even only) node we encountered.  Create a
       // block for it.
       SplitNodeResult splitNodeResult =
         MaybeSplitAncestorsForInsert(aBlockTag, atCurNode);
       if (NS_WARN_IF(splitNodeResult.Failed())) {
         return splitNodeResult.Rv();
       }
       curBlock =
-        htmlEditor->CreateNode(&aBlockTag, splitNodeResult.SplitPoint());
-      NS_ENSURE_STATE(curBlock);
+        htmlEditor->CreateNodeWithTransaction(aBlockTag,
+                                              splitNodeResult.SplitPoint());
+      if (NS_WARN_IF(!curBlock)) {
+        return NS_ERROR_FAILURE;
+      }
       // Remember our new block for postprocessing
       mNewBlock = curBlock;
       // Note: doesn't matter if we set mNewBlock multiple times.
       nsresult rv = htmlEditor->MoveNode(curNode->AsContent(), curBlock, -1);
       NS_ENSURE_SUCCESS(rv, rv);
       continue;
     }
 
@@ -7660,18 +7712,21 @@ HTMLEditRules::ApplyBlockStyle(nsTArray<
         AutoEditorDOMPointOffsetInvalidator lockChild(atCurNode);
 
         SplitNodeResult splitNodeResult =
           MaybeSplitAncestorsForInsert(aBlockTag, atCurNode);
         if (NS_WARN_IF(splitNodeResult.Failed())) {
           return splitNodeResult.Rv();
         }
         curBlock =
-          htmlEditor->CreateNode(&aBlockTag, splitNodeResult.SplitPoint());
-        NS_ENSURE_STATE(curBlock);
+          htmlEditor->CreateNodeWithTransaction(aBlockTag,
+                                                splitNodeResult.SplitPoint());
+        if (NS_WARN_IF(!curBlock)) {
+          return NS_ERROR_FAILURE;
+        }
         // Remember our new block for postprocessing
         mNewBlock = curBlock;
         // Note: doesn't matter if we set mNewBlock multiple times.
       }
 
       if (NS_WARN_IF(!atCurNode.IsSet())) {
         // This is possible due to mutation events, let's not assert
         return NS_ERROR_UNEXPECTED;
@@ -9337,18 +9392,21 @@ HTMLEditRules::WillAbsolutePosition(Sele
 
     // Make sure we can put a block here.
     SplitNodeResult splitNodeResult =
       MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atStartOfSelection);
     if (NS_WARN_IF(splitNodeResult.Failed())) {
       return splitNodeResult.Rv();
     }
     RefPtr<Element> positionedDiv =
-      htmlEditor->CreateNode(nsGkAtoms::div, splitNodeResult.SplitPoint());
-    NS_ENSURE_STATE(positionedDiv);
+      htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::div,
+                                            splitNodeResult.SplitPoint());
+    if (NS_WARN_IF(!positionedDiv)) {
+      return NS_ERROR_FAILURE;
+    }
     // Remember our new block for postprocessing
     mNewBlock = positionedDiv;
     // Delete anything that was in the list of nodes
     while (!arrayOfNodes.IsEmpty()) {
       OwningNonNull<nsINode> curNode = arrayOfNodes[0];
       rv = htmlEditor->DeleteNode(curNode);
       NS_ENSURE_SUCCESS(rv, rv);
       arrayOfNodes.RemoveElementAt(0);
@@ -9393,25 +9451,30 @@ HTMLEditRules::WillAbsolutePosition(Sele
         // Create a new nested list of correct type.
         SplitNodeResult splitNodeResult =
           MaybeSplitAncestorsForInsert(*containerName, atCurNode);
         if (NS_WARN_IF(splitNodeResult.Failed())) {
           return splitNodeResult.Rv();
         }
         if (!curPositionedDiv) {
           curPositionedDiv =
-            htmlEditor->CreateNode(nsGkAtoms::div,
-                                   splitNodeResult.SplitPoint());
+            htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::div,
+                                                  splitNodeResult.SplitPoint());
+          NS_WARNING_ASSERTION(curPositionedDiv,
+            "Failed to create current positioned div element");
           mNewBlock = curPositionedDiv;
         }
         EditorRawDOMPoint atEndOfCurPositionedDiv;
         atEndOfCurPositionedDiv.SetToEndOf(curPositionedDiv);
         curList =
-          htmlEditor->CreateNode(containerName, atEndOfCurPositionedDiv);
-        NS_ENSURE_STATE(curList);
+          htmlEditor->CreateNodeWithTransaction(*containerName,
+                                                atEndOfCurPositionedDiv);
+        if (NS_WARN_IF(!curList)) {
+          return NS_ERROR_FAILURE;
+        }
         // curList is now the correct thing to put curNode in.  Remember our
         // new block for postprocessing.
       }
       // Tuck the node into the end of the active list
       rv = htmlEditor->MoveNode(curNode->AsContent(), curList, -1);
       NS_ENSURE_SUCCESS(rv, rv);
       continue;
     }
@@ -9445,24 +9508,30 @@ HTMLEditRules::WillAbsolutePosition(Sele
         SplitNodeResult splitNodeResult =
           MaybeSplitAncestorsForInsert(*containerName, atListItem);
         if (NS_WARN_IF(splitNodeResult.Failed())) {
           return splitNodeResult.Rv();
         }
         if (!curPositionedDiv) {
           EditorRawDOMPoint atListItemParent(atListItem.GetContainer());
           curPositionedDiv =
-            htmlEditor->CreateNode(nsGkAtoms::div, atListItemParent);
+            htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::div,
+                                                  atListItemParent);
+          NS_WARNING_ASSERTION(curPositionedDiv,
+            "Failed to create current positioned div element");
           mNewBlock = curPositionedDiv;
         }
         EditorRawDOMPoint atEndOfCurPositionedDiv;
         atEndOfCurPositionedDiv.SetToEndOf(curPositionedDiv);
         curList =
-          htmlEditor->CreateNode(containerName, atEndOfCurPositionedDiv);
-        NS_ENSURE_STATE(curList);
+          htmlEditor->CreateNodeWithTransaction(*containerName,
+                                                atEndOfCurPositionedDiv);
+        if (NS_WARN_IF(!curList)) {
+          return NS_ERROR_FAILURE;
+        }
       }
       rv = htmlEditor->MoveNode(listItem, curList, -1);
       NS_ENSURE_SUCCESS(rv, rv);
       // Remember we indented this li
       indentedLI = listItem;
       continue;
     }
 
@@ -9475,18 +9544,21 @@ HTMLEditRules::WillAbsolutePosition(Sele
         continue;
       }
       SplitNodeResult splitNodeResult =
         MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atCurNode);
       if (NS_WARN_IF(splitNodeResult.Failed())) {
         return splitNodeResult.Rv();
       }
       curPositionedDiv =
-        htmlEditor->CreateNode(nsGkAtoms::div, splitNodeResult.SplitPoint());
-      NS_ENSURE_STATE(curPositionedDiv);
+        htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::div,
+                                              splitNodeResult.SplitPoint());
+      if (NS_WARN_IF(!curPositionedDiv)) {
+        return NS_ERROR_FAILURE;
+      }
       // Remember our new block for postprocessing
       mNewBlock = curPositionedDiv;
       // curPositionedDiv is now the correct thing to put curNode in
     }
 
     // Tuck the node into the end of the active blockquote
     rv = htmlEditor->MoveNode(curNode->AsContent(), curPositionedDiv, -1);
     NS_ENSURE_SUCCESS(rv, rv);
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -2043,24 +2043,33 @@ HTMLEditor::MakeOrChangeList(const nsASt
       if (NS_WARN_IF(!pointToInsertList.IsSet())) {
         return NS_ERROR_FAILURE;
       }
     }
 
     // Create a list and insert it before the right node if we split some
     // parents of start of selection above, or just start of selection
     // otherwise.
-    RefPtr<Element> newList = CreateNode(listAtom, pointToInsertList);
-    NS_ENSURE_STATE(newList);
+    RefPtr<Element> newList =
+      CreateNodeWithTransaction(*listAtom, pointToInsertList);
+    if (NS_WARN_IF(!newList)) {
+      return NS_ERROR_FAILURE;
+    }
     // make a list item
     EditorRawDOMPoint atStartOfNewList(newList, 0);
-    RefPtr<Element> newItem = CreateNode(nsGkAtoms::li, atStartOfNewList);
-    NS_ENSURE_STATE(newItem);
-    rv = selection->Collapse(newItem, 0);
-    NS_ENSURE_SUCCESS(rv, rv);
+    RefPtr<Element> newItem =
+      CreateNodeWithTransaction(*nsGkAtoms::li, atStartOfNewList);
+    if (NS_WARN_IF(!newItem)) {
+      return NS_ERROR_FAILURE;
+    }
+    ErrorResult error;
+    selection->Collapse(RawRangeBoundary(newItem, 0), error);
+    if (NS_WARN_IF(error.Failed())) {
+      return error.StealNSResult();
+    }
   }
 
   return rules->DidDoAction(selection, &ruleInfo, rv);
 }
 
 NS_IMETHODIMP
 HTMLEditor::RemoveList(const nsAString& aListType)
 {
@@ -2193,22 +2202,28 @@ HTMLEditor::InsertBasicBlock(const nsASt
       if (NS_WARN_IF(!pointToInsertBlock.IsSet())) {
         return NS_ERROR_FAILURE;
       }
     }
 
     // Create a block and insert it before the right node if we split some
     // parents of start of selection above, or just start of selection
     // otherwise.
-    RefPtr<Element> newBlock = CreateNode(blockAtom, pointToInsertBlock);
-    NS_ENSURE_STATE(newBlock);
+    RefPtr<Element> newBlock =
+      CreateNodeWithTransaction(*blockAtom, pointToInsertBlock);
+    if (NS_WARN_IF(!newBlock)) {
+      return NS_ERROR_FAILURE;
+    }
 
     // reposition selection to inside the block
-    rv = selection->Collapse(newBlock, 0);
-    NS_ENSURE_SUCCESS(rv, rv);
+    ErrorResult error;
+    selection->Collapse(RawRangeBoundary(newBlock, 0), error);
+    if (NS_WARN_IF(error.Failed())) {
+      return error.StealNSResult();
+    }
   }
 
   return rules->DidDoAction(selection, &ruleInfo, rv);
 }
 
 NS_IMETHODIMP
 HTMLEditor::Indent(const nsAString& aIndent)
 {
@@ -2276,21 +2291,27 @@ HTMLEditor::Indent(const nsAString& aInd
         return NS_ERROR_FAILURE;
       }
     }
 
     // Create a list and insert it before the right node if we split some
     // parents of start of selection above, or just start of selection
     // otherwise.
     RefPtr<Element> newBQ =
-      CreateNode(nsGkAtoms::blockquote, pointToInsertBlockquote);
-    NS_ENSURE_STATE(newBQ);
+      CreateNodeWithTransaction(*nsGkAtoms::blockquote,
+                                pointToInsertBlockquote);
+    if (NS_WARN_IF(!newBQ)) {
+      return NS_ERROR_FAILURE;
+    }
     // put a space in it so layout will draw the list item
-    rv = selection->Collapse(newBQ, 0);
-    NS_ENSURE_SUCCESS(rv, rv);
+    ErrorResult error;
+    selection->Collapse(RawRangeBoundary(newBQ, 0), error);
+    if (NS_WARN_IF(error.Failed())) {
+      return error.StealNSResult();
+    }
     rv = InsertText(NS_LITERAL_STRING(" "));
     NS_ENSURE_SUCCESS(rv, rv);
     // reposition selection to before the space character
     NS_ENSURE_STATE(selection->GetRangeAt(0));
     rv = selection->Collapse(selection->GetRangeAt(0)->GetStartContainer(),
                              0);
     NS_ENSURE_SUCCESS(rv, rv);
   }
@@ -4477,18 +4498,21 @@ HTMLEditor::CopyLastEditableChildStyles(
         childElement->IsHTMLElement(nsGkAtoms::span)) {
       if (newStyles) {
         newStyles = InsertContainerAbove(newStyles,
                                          childElement->NodeInfo()->NameAtom());
         NS_ENSURE_STATE(newStyles);
       } else {
         EditorRawDOMPoint atStartOfNewBlock(newBlock, 0);
         deepestStyle = newStyles =
-          CreateNode(childElement->NodeInfo()->NameAtom(), atStartOfNewBlock);
-        NS_ENSURE_STATE(newStyles);
+          CreateNodeWithTransaction(*childElement->NodeInfo()->NameAtom(),
+                                    atStartOfNewBlock);
+        if (NS_WARN_IF(!newStyles)) {
+          return NS_ERROR_FAILURE;
+        }
       }
       CloneAttributes(newStyles, childElement);
     }
     childElement = childElement->GetParentElement();
   }
   if (deepestStyle) {
     RefPtr<Element> retVal = CreateBR(EditorRawDOMPoint(deepestStyle, 0));
     retVal.forget(aOutBrNode);
--- a/editor/libeditor/TextEditor.cpp
+++ b/editor/libeditor/TextEditor.cpp
@@ -239,27 +239,28 @@ TextEditor::SetDocumentCharacterSet(cons
 
   nsCOMPtr<nsIContent> headNode = headList->Item(0);
   if (NS_WARN_IF(!headNode)) {
     return NS_OK;
   }
 
   // Create a new meta charset tag
   EditorRawDOMPoint atStartOfHeadNode(headNode, 0);
-  RefPtr<Element> metaElement = CreateNode(nsGkAtoms::meta, atStartOfHeadNode);
+  RefPtr<Element> metaElement =
+    CreateNodeWithTransaction(*nsGkAtoms::meta, atStartOfHeadNode);
   if (NS_WARN_IF(!metaElement)) {
     return NS_OK;
   }
 
   // Set attributes to the created element
   if (characterSet.IsEmpty()) {
     return NS_OK;
   }
 
-  // not undoable, undo should undo CreateNode
+  // not undoable, undo should undo CreateNodeWithTransaction().
   metaElement->SetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv,
                        NS_LITERAL_STRING("Content-Type"), true);
   metaElement->SetAttr(kNameSpaceID_None, nsGkAtoms::content,
                        NS_LITERAL_STRING("text/html;charset=") +
                          NS_ConvertASCIItoUTF16(characterSet),
                        true);
   return NS_OK;
 }
@@ -464,22 +465,22 @@ TextEditor::CreateBRImpl(Selection& aSel
         error.SuppressException();
         return nullptr;
       }
       Unused << newLeftNode;
       // Insert new <br> before the right node.
       pointInContainer.Set(aPointToInsert.GetContainer());
     }
     // Create a <br> node.
-    newBRElement = CreateNode(nsGkAtoms::br, pointInContainer);
+    newBRElement = CreateNodeWithTransaction(*nsGkAtoms::br, pointInContainer);
     if (NS_WARN_IF(!newBRElement)) {
       return nullptr;
     }
   } else {
-    newBRElement = CreateNode(nsGkAtoms::br, aPointToInsert);
+    newBRElement = CreateNodeWithTransaction(*nsGkAtoms::br, aPointToInsert);
     if (NS_WARN_IF(!newBRElement)) {
       return nullptr;
     }
   }
 
   switch (aSelect) {
     case eNone:
       break;