Bug 1451672 - part 19: Remove TextEditor::CreateBR() and rename TextEditor::CreateBRImpl() to TextEditor::InsertBrElementWithTransaction() r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 16 Apr 2018 19:21:29 +0900
changeset 786102 96640269bcb75fab3ea7fd639c833a11f6823da9
parent 786101 d33c78c67c5bc79b0f7963254727cdcf91441571
child 786103 32f663e5c3f60896022a1955276842ad23553b63
push id107393
push usermasayuki@d-toybox.com
push dateSat, 21 Apr 2018 04:40:12 +0000
reviewersm_kato
bugs1451672
milestone61.0a1
Bug 1451672 - part 19: Remove TextEditor::CreateBR() and rename TextEditor::CreateBRImpl() to TextEditor::InsertBrElementWithTransaction() r?m_kato TextEditor::CreateBR() is just a wrapper of TextEditor::CreateBRImpl() for automatically retrieving Selection of the editor. And TextEditor::CreateBRImpl() should be renamed to TextEditor::InsertBrElementWithTransaction() for making it clearer what it does. MozReview-Commit-ID: D8sjVdLrVrd
editor/libeditor/HTMLAbsPositionEditor.cpp
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditor.cpp
editor/libeditor/TextEditRules.cpp
editor/libeditor/TextEditor.cpp
editor/libeditor/TextEditor.h
editor/libeditor/WSRunObject.cpp
--- a/editor/libeditor/HTMLAbsPositionEditor.cpp
+++ b/editor/libeditor/HTMLAbsPositionEditor.cpp
@@ -486,19 +486,20 @@ HTMLEditor::SetPositionToAbsolute(Elemen
   // we may need to create a br if the positioned element is alone in its
   // container
   nsINode* parentNode = aElement.GetParentNode();
   if (parentNode->GetChildCount() == 1) {
     RefPtr<Selection> selection = GetSelection();
     if (NS_WARN_IF(!selection)) {
       return NS_ERROR_FAILURE;
     }
-    RefPtr<Element> newBRElement =
-      CreateBRImpl(*selection, EditorRawDOMPoint(parentNode, 0), eNone);
-    if (NS_WARN_IF(!newBRElement)) {
+    RefPtr<Element> newBrElement =
+      InsertBrElementWithTransaction(*selection,
+                                     EditorRawDOMPoint(parentNode, 0));
+    if (NS_WARN_IF(!newBrElement)) {
       return NS_ERROR_FAILURE;
     }
   }
   return NS_OK;
 }
 
 nsresult
 HTMLEditor::SetPositionToStatic(Element& aElement)
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -1422,32 +1422,33 @@ HTMLEditRules::WillInsertText(EditAction
           subStrLen = tString.Length() - oldPos;
           pos = tString.Length();
         }
 
         nsDependentSubstring subStr(tString, oldPos, subStrLen);
 
         // is it a return?
         if (subStr.Equals(newlineStr)) {
-          nsCOMPtr<Element> br =
-            htmlEditor->CreateBRImpl(*aSelection, currentPoint,
-                                     nsIEditor::eNone);
-          if (NS_WARN_IF(!br)) {
+          RefPtr<Element> brElement =
+            htmlEditor->InsertBrElementWithTransaction(*aSelection,
+                                                       currentPoint,
+                                                       nsIEditor::eNone);
+          if (NS_WARN_IF(!brElement)) {
             return NS_ERROR_FAILURE;
           }
           pos++;
-          if (br->GetNextSibling()) {
-            pointToInsert.Set(br->GetNextSibling());
+          if (brElement->GetNextSibling()) {
+            pointToInsert.Set(brElement->GetNextSibling());
           } else {
             pointToInsert.SetToEndOf(currentPoint.GetContainer());
           }
           // XXX In most cases, pointToInsert and currentPoint are same here.
           //     But if the <br> element has been moved to different point by
           //     mutation observer, those points become different.
-          currentPoint.Set(br);
+          currentPoint.Set(brElement);
           DebugOnly<bool> advanced = currentPoint.AdvanceOffset();
           NS_WARNING_ASSERTION(advanced,
             "Failed to advance offset after the new <br> element");
           NS_WARNING_ASSERTION(currentPoint == pointToInsert,
             "Perhaps, <br> element position has been moved to different point "
             "by mutation observer");
         } else {
           EditorRawDOMPoint pointAfterInsertedString;
@@ -1783,18 +1784,21 @@ HTMLEditRules::WillInsertBreak(Selection
   // If block is empty, populate with br.  (For example, imagine a div that
   // contains the word "text".  The user selects "text" and types return.
   // "Text" is deleted leaving an empty block.  We want to put in one br to
   // make block have a line.  Then code further below will put in a second br.)
   if (IsEmptyBlockElement(*blockParent, IgnoreSingleBR::eNo)) {
     AutoEditorDOMPointChildInvalidator lockOffset(atStartOfSelection);
     EditorRawDOMPoint endOfBlockParent;
     endOfBlockParent.SetToEndOf(blockParent);
-    RefPtr<Element> br = htmlEditor->CreateBR(endOfBlockParent);
-    NS_ENSURE_STATE(br);
+    RefPtr<Element> brElement =
+      htmlEditor->InsertBrElementWithTransaction(aSelection, endOfBlockParent);
+    if (NS_WARN_IF(!brElement)) {
+      return NS_ERROR_FAILURE;
+    }
   }
 
   nsCOMPtr<Element> listItem = IsInListItem(blockParent);
   if (listItem && listItem != host) {
     ReturnInListItem(aSelection, *listItem, *atStartOfSelection.GetContainer(),
                      atStartOfSelection.Offset());
     *aHandled = true;
     return NS_OK;
@@ -1864,17 +1868,18 @@ HTMLEditRules::InsertBRElement(Selection
   RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
 
   bool brElementIsAfterBlock = false;
   bool brElementIsBeforeBlock = false;
 
   // First, insert a <br> element.
   RefPtr<Element> brElement;
   if (IsPlaintextEditor()) {
-    brElement = htmlEditor->CreateBR(aPointToBreak);
+    brElement =
+      htmlEditor->InsertBrElementWithTransaction(aSelection, aPointToBreak);
     if (NS_WARN_IF(!brElement)) {
       return NS_ERROR_FAILURE;
     }
   } else {
     EditorDOMPoint pointToBreak(aPointToBreak);
     WSRunObject wsObj(htmlEditor, pointToBreak);
     int32_t visOffset = 0;
     WSType wsType;
@@ -2066,34 +2071,40 @@ HTMLEditRules::SplitMailCites(Selection*
       previousNodeOfSplitPoint->GetPrimaryFrame()->
                                   IsFrameOfType(nsIFrame::eBlockFrame)) {
     nsCOMPtr<nsINode> lastChild =
       previousNodeOfSplitPoint->GetLastChild();
     if (lastChild && !lastChild->IsHTMLElement(nsGkAtoms::br)) {
       // We ignore the result here.
       EditorRawDOMPoint endOfPreviousNodeOfSplitPoint;
       endOfPreviousNodeOfSplitPoint.SetToEndOf(previousNodeOfSplitPoint);
-      RefPtr<Element> invisBR =
-        htmlEditor->CreateBR(endOfPreviousNodeOfSplitPoint);
+      RefPtr<Element> invisibleBrElement =
+        htmlEditor->InsertBrElementWithTransaction(
+                      *aSelection,
+                      endOfPreviousNodeOfSplitPoint);
+      NS_WARNING_ASSERTION(invisibleBrElement,
+        "Failed to create an invisible <br> element");
     }
   }
 
   // In most cases, <br> should be inserted after current cite.  However, if
   // left cite hasn't been created because the split point was start of the
   // cite node, <br> should be inserted before the current cite.
   EditorRawDOMPoint pointToInsertBrNode(splitCiteNodeResult.SplitPoint());
-  RefPtr<Element> brNode = htmlEditor->CreateBR(pointToInsertBrNode);
-  if (NS_WARN_IF(!brNode)) {
+  RefPtr<Element> brElement =
+    htmlEditor->InsertBrElementWithTransaction(*aSelection,
+                                               pointToInsertBrNode);
+  if (NS_WARN_IF(!brElement)) {
     return NS_ERROR_FAILURE;
   }
   // Now, offset of pointToInsertBrNode is invalid.  Let's clear it.
   pointToInsertBrNode.Clear();
 
   // Want selection before the break, and on same line.
-  EditorDOMPoint atBrNode(brNode);
+  EditorDOMPoint atBrNode(brElement);
   Unused << atBrNode.Offset(); // Needs offset after collapsing the selection.
   aSelection->SetInterlinePosition(true);
   ErrorResult error;
   aSelection->Collapse(atBrNode, error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
@@ -2120,18 +2131,20 @@ HTMLEditRules::SplitMailCites(Selection*
         "Failed to advance offset after the <br> node");
       WSRunObject wsObjAfterBR(htmlEditor, pointAfterNewBrNode);
       wsObjAfterBR.NextVisibleNode(pointAfterNewBrNode,
                                    address_of(visNode), &visOffset, &wsType);
       if (wsType == WSType::normalWS || wsType == WSType::text ||
           wsType == WSType::special ||
           // In case we're at the very end.
           wsType == WSType::thisBlock) {
-        brNode = htmlEditor->CreateBR(pointToCreateNewBrNode);
-        if (NS_WARN_IF(!brNode)) {
+        brElement =
+          htmlEditor->InsertBrElementWithTransaction(*aSelection,
+                                                     pointToCreateNewBrNode);
+        if (NS_WARN_IF(!brElement)) {
           return NS_ERROR_FAILURE;
         }
         // Now, those points may be invalid.
         pointToCreateNewBrNode.Clear();
         pointAfterNewBrNode.Clear();
       }
     }
   }
@@ -2969,19 +2982,21 @@ HTMLEditRules::InsertBRIfNeeded(Selectio
   WSRunObject wsObj(htmlEditor, atStartOfSelection);
   if (((wsObj.mStartReason & WSType::block) ||
        (wsObj.mStartReason & WSType::br)) &&
       (wsObj.mEndReason & WSType::block)) {
     // if we are tucked between block boundaries then insert a br
     // first check that we are allowed to
     if (htmlEditor->CanContainTag(*atStartOfSelection.GetContainer(),
                                   *nsGkAtoms::br)) {
-      RefPtr<Element> br =
-        htmlEditor->CreateBR(atStartOfSelection, nsIEditor::ePrevious);
-      if (NS_WARN_IF(!br)) {
+      RefPtr<Element> brElement =
+        htmlEditor->InsertBrElementWithTransaction(*aSelection,
+                                                   atStartOfSelection,
+                                                   nsIEditor::ePrevious);
+      if (NS_WARN_IF(!brElement)) {
         return NS_ERROR_FAILURE;
       }
       return NS_OK;
     }
   }
   return NS_OK;
 }
 
@@ -3551,22 +3566,23 @@ HTMLEditRules::DidDeleteSelection(Select
       {
         AutoEditorDOMPointChildInvalidator lockOffset(atCiteNode);
         nsresult rv = htmlEditor->DeleteNodeWithTransaction(*citeNode);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
       }
       if (atCiteNode.IsSet() && seenBR) {
-        RefPtr<Element> brNode = htmlEditor->CreateBR(atCiteNode);
-        if (NS_WARN_IF(!brNode)) {
+        RefPtr<Element> brElement =
+          htmlEditor->InsertBrElementWithTransaction(*aSelection, atCiteNode);
+        if (NS_WARN_IF(!brElement)) {
           return NS_ERROR_FAILURE;
         }
         IgnoredErrorResult error;
-        aSelection->Collapse(EditorRawDOMPoint(brNode), error);
+        aSelection->Collapse(EditorRawDOMPoint(brElement), error);
         NS_WARNING_ASSERTION(!error.Failed(),
           "Failed to collapse selection at the new <br> element");
       }
     }
   }
 
   // call through to base class
   return TextEditRules::DidDeleteSelection(aSelection, aDir, aResult);
@@ -4054,39 +4070,43 @@ HTMLEditRules::MakeBasicBlock(Selection&
       }
       if (!HTMLEditUtils::IsFormatNode(curBlock)) {
         return NS_OK;
       }
 
       // If the first editable node after selection is a br, consume it.
       // Otherwise it gets pushed into a following block after the split,
       // which is visually bad.
-      nsCOMPtr<nsIContent> brNode =
+      nsCOMPtr<nsIContent> brContent =
         htmlEditor->GetNextEditableHTMLNode(pointToInsertBlock);
-      if (brNode && brNode->IsHTMLElement(nsGkAtoms::br)) {
+      if (brContent && brContent->IsHTMLElement(nsGkAtoms::br)) {
         AutoEditorDOMPointChildInvalidator lockOffset(pointToInsertBlock);
-        rv = htmlEditor->DeleteNodeWithTransaction(*brNode);
+        rv = htmlEditor->DeleteNodeWithTransaction(*brContent);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
       }
       // Do the splits!
       SplitNodeResult splitNodeResult =
         htmlEditor->SplitNodeDeepWithTransaction(
                       *curBlock, pointToInsertBlock,
                       SplitAtEdges::eDoNotCreateEmptyContainer);
       if (NS_WARN_IF(splitNodeResult.Failed())) {
         return splitNodeResult.Rv();
       }
       EditorRawDOMPoint pointToInsertBrNode(splitNodeResult.SplitPoint());
-      // Put a br at the split point
-      brNode = htmlEditor->CreateBR(pointToInsertBrNode);
-      NS_ENSURE_STATE(brNode);
+      // Put a <br> element at the split point
+      brContent =
+        htmlEditor->InsertBrElementWithTransaction(aSelection,
+                                                   pointToInsertBrNode);
+      if (NS_WARN_IF(!brContent)) {
+        return NS_ERROR_FAILURE;
+      }
       // Put selection at the split point
-      EditorRawDOMPoint atBrNode(brNode);
+      EditorRawDOMPoint atBrNode(brContent);
       ErrorResult error;
       aSelection.Collapse(atBrNode, error);
       // Don't restore the selection
       selectionRestorer.Abort();
       if (NS_WARN_IF(error.Failed())) {
         return error.StealNSResult();
       }
       return NS_OK;
@@ -5609,23 +5629,25 @@ HTMLEditRules::CheckForEmptyBlock(nsINod
       if (htmlEditor->IsFirstEditableChild(emptyBlock)) {
         EditorDOMPoint atBlockParent(blockParent);
         if (NS_WARN_IF(!atBlockParent.IsSet())) {
           return NS_ERROR_FAILURE;
         }
         // If we are a sublist, skip the br creation
         if (!HTMLEditUtils::IsList(atBlockParent.GetContainer())) {
           // Create a br before list
-          RefPtr<Element> br = htmlEditor->CreateBR(atBlockParent);
-          if (NS_WARN_IF(!br)) {
+          RefPtr<Element> brElement =
+            htmlEditor->InsertBrElementWithTransaction(*aSelection,
+                                                       atBlockParent);
+          if (NS_WARN_IF(!brElement)) {
             return NS_ERROR_FAILURE;
           }
           // Adjust selection to be right before it
           ErrorResult error;
-          aSelection->Collapse(EditorRawDOMPoint(br), error);
+          aSelection->Collapse(EditorRawDOMPoint(brElement), error);
           if (NS_WARN_IF(error.Failed())) {
             return error.StealNSResult();
           }
         }
         // Else just let selection percolate up.  We'll adjust it in
         // AfterEdit()
       }
     } else {
@@ -7104,19 +7126,20 @@ HTMLEditRules::ReturnInHeader(Selection&
         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)) {
+      RefPtr<Element> brElement =
+        htmlEditor->InsertBrElementWithTransaction(aSelection,
+                                                   EditorRawDOMPoint(pNode, 0));
+      if (NS_WARN_IF(!brElement)) {
         return NS_ERROR_FAILURE;
       }
 
       // Set selection to before the break
       ErrorResult error;
       aSelection.Collapse(EditorRawDOMPoint(pNode, 0), error);
       if (NS_WARN_IF(error.Failed())) {
         return error.StealNSResult();
@@ -7222,50 +7245,50 @@ HTMLEditRules::ReturnInParagraph(Selecti
         foundBRElement = true;
       }
     }
   }
 
   bool doesCRCreateNewP = htmlEditor->GetReturnInParagraphCreatesNewParagraph();
 
   bool splitAfterNewBR = false;
-  nsCOMPtr<nsIContent> brNode;
+  nsCOMPtr<nsIContent> brContent;
 
   EditorDOMPoint pointToSplitParentDivOrP(atStartOfSelection);
 
   EditorRawDOMPoint pointToInsertBR;
   if (doesCRCreateNewP &&
       atStartOfSelection.GetContainer() == &aParentDivOrP) {
     // We are at the edges of the block, so, we don't need to create new <br>.
-    brNode = nullptr;
+    brContent = nullptr;
   } else if (atStartOfSelection.IsInTextNode()) {
     // at beginning of text node?
     if (atStartOfSelection.IsStartOfContainer()) {
       // is there a BR prior to it?
-      brNode =
+      brContent =
         htmlEditor->GetPriorHTMLSibling(atStartOfSelection.GetContainer());
-      if (!brNode ||
-          !htmlEditor->IsVisibleBRElement(brNode) ||
-          TextEditUtils::HasMozAttr(brNode)) {
+      if (!brContent ||
+          !htmlEditor->IsVisibleBRElement(brContent) ||
+          TextEditUtils::HasMozAttr(brContent)) {
         pointToInsertBR.Set(atStartOfSelection.GetContainer());
-        brNode = nullptr;
+        brContent = nullptr;
       }
     } else if (atStartOfSelection.IsEndOfContainer()) {
       // we're at the end of text node...
       // is there a BR after to it?
-      brNode =
+      brContent =
         htmlEditor->GetNextHTMLSibling(atStartOfSelection.GetContainer());
-      if (!brNode ||
-          !htmlEditor->IsVisibleBRElement(brNode) ||
-          TextEditUtils::HasMozAttr(brNode)) {
+      if (!brContent ||
+          !htmlEditor->IsVisibleBRElement(brContent) ||
+          TextEditUtils::HasMozAttr(brContent)) {
         pointToInsertBR.Set(atStartOfSelection.GetContainer());
         DebugOnly<bool> advanced = pointToInsertBR.AdvanceOffset();
         NS_WARNING_ASSERTION(advanced,
           "Failed to advance offset to after the container of selection start");
-        brNode = nullptr;
+        brContent = nullptr;
       }
     } else {
       if (doesCRCreateNewP) {
         ErrorResult error;
         nsCOMPtr<nsIContent> newLeftDivOrP =
           htmlEditor->SplitNodeWithTransaction(pointToSplitParentDivOrP, error);
         if (NS_WARN_IF(error.Failed())) {
           return EditActionResult(error.StealNSResult());
@@ -7293,42 +7316,44 @@ HTMLEditRules::ReturnInParagraph(Selecti
         htmlEditor->GetNextEditableHTMLNode(atStartOfSelection);
       if (!nearNode || !htmlEditor->IsVisibleBRElement(nearNode) ||
           TextEditUtils::HasMozAttr(nearNode)) {
         pointToInsertBR = atStartOfSelection;
         splitAfterNewBR = true;
       }
     }
     if (!pointToInsertBR.IsSet() && TextEditUtils::IsBreak(nearNode)) {
-      brNode = nearNode;
+      brContent = nearNode;
     }
   }
   if (pointToInsertBR.IsSet()) {
     // Don't modify the DOM tree if mHTMLEditor disappeared.
     if (NS_WARN_IF(!mHTMLEditor)) {
       return EditActionResult(NS_ERROR_NOT_AVAILABLE);
     }
 
     // if CR does not create a new P, default to BR creation
     if (NS_WARN_IF(!doesCRCreateNewP)) {
       return EditActionResult(NS_OK);
     }
 
-    brNode = htmlEditor->CreateBR(pointToInsertBR);
+    brContent =
+      htmlEditor->InsertBrElementWithTransaction(aSelection, pointToInsertBR);
+    NS_WARNING_ASSERTION(brContent, "Failed to create a <br> element");
     if (splitAfterNewBR) {
       // We split the parent after the br we've just inserted.
-      pointToSplitParentDivOrP.Set(brNode);
+      pointToSplitParentDivOrP.Set(brContent);
       DebugOnly<bool> advanced = pointToSplitParentDivOrP.AdvanceOffset();
       NS_WARNING_ASSERTION(advanced,
         "Failed to advance offset after the new <br>");
     }
   }
   EditActionResult result(
     SplitParagraph(aSelection, aParentDivOrP, pointToSplitParentDivOrP,
-                   brNode));
+                   brContent));
   result.MarkAsHandled();
   if (NS_WARN_IF(result.Failed())) {
     return result;
   }
   return result;
 }
 
 template<typename PT, typename CT>
@@ -7482,20 +7507,26 @@ HTMLEditRules::ReturnInListItem(Selectio
       RefPtr<Element> pNode =
         htmlEditor->CreateNodeWithTransaction(&paraAtom == nsGkAtoms::br ?
                                                 *nsGkAtoms::p : paraAtom,
                                               atNextSiblingOfLeftList);
       if (NS_WARN_IF(!pNode)) {
         return NS_ERROR_FAILURE;
       }
 
+      RefPtr<Selection> selection = htmlEditor->GetSelection();
+      if (NS_WARN_IF(!selection)) {
+        return NS_ERROR_FAILURE;
+      }
+
       // Append a <br> to it
-      RefPtr<Element> brNode =
-        htmlEditor->CreateBR(EditorRawDOMPoint(pNode, 0));
-      if (NS_WARN_IF(!brNode)) {
+      RefPtr<Element> brElement =
+        htmlEditor->InsertBrElementWithTransaction(*selection,
+                                                   EditorRawDOMPoint(pNode, 0));
+      if (NS_WARN_IF(!brElement)) {
         return NS_ERROR_FAILURE;
       }
 
       // Set selection to before the break
       ErrorResult error;
       aSelection.Collapse(EditorRawDOMPoint(pNode, 0), error);
       if (NS_WARN_IF(error.Failed())) {
         return error.StealNSResult();
@@ -8777,20 +8808,26 @@ HTMLEditRules::RemoveEmptyNodes()
 
   // Now delete the empty mailcites.  This is a separate step because we want
   // to pull out any br's and preserve them.
   for (OwningNonNull<nsINode>& delNode : arrayOfEmptyCites) {
     bool bIsEmptyNode;
     rv = htmlEditor->IsEmptyNode(delNode, &bIsEmptyNode, false, true);
     NS_ENSURE_SUCCESS(rv, rv);
     if (!bIsEmptyNode) {
+      RefPtr<Selection> selection = htmlEditor->GetSelection();
+      if (NS_WARN_IF(!selection)) {
+        return NS_ERROR_FAILURE;
+      }
       // We are deleting a cite that has just a br.  We want to delete cite,
       // but preserve br.
-      RefPtr<Element> br = htmlEditor->CreateBR(EditorRawDOMPoint(delNode));
-      if (NS_WARN_IF(!br)) {
+      RefPtr<Element> brElement =
+        htmlEditor->InsertBrElementWithTransaction(*selection,
+                                                   EditorRawDOMPoint(delNode));
+      if (NS_WARN_IF(!brElement)) {
         return NS_ERROR_FAILURE;
       }
     }
     rv = htmlEditor->DeleteNodeWithTransaction(*delNode);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
@@ -9435,24 +9472,29 @@ HTMLEditRules::MakeSureElemStartsOrEndsO
       if (IsBlockNode(*sibling) || sibling->IsHTMLElement(nsGkAtoms::br)) {
         foundCR = true;
       }
     } else {
       foundCR = true;
     }
   }
   if (!foundCR) {
+    RefPtr<Selection> selection = htmlEditor->GetSelection();
+    if (NS_WARN_IF(!selection)) {
+      return NS_ERROR_FAILURE;
+    }
     EditorRawDOMPoint pointToInsert;
     if (!aStarts) {
       pointToInsert.SetToEndOf(&aNode);
     } else {
       pointToInsert.Set(&aNode, 0);
     }
-    RefPtr<Element> brNode = htmlEditor->CreateBR(pointToInsert);
-    if (NS_WARN_IF(!brNode)) {
+    RefPtr<Element> brElement =
+      htmlEditor->InsertBrElementWithTransaction(*selection, pointToInsert);
+    if (NS_WARN_IF(!brElement)) {
       return NS_ERROR_FAILURE;
     }
   }
   return NS_OK;
 }
 
 nsresult
 HTMLEditRules::MakeSureElemStartsOrEndsOnCR(nsINode& aNode)
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -1151,20 +1151,21 @@ HTMLEditor::InsertBR()
     }
   }
 
   EditorRawDOMPoint atStartOfSelection(GetStartPoint(selection));
   if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
     return NS_ERROR_FAILURE;
   }
 
-  // CreateBRImpl() will set selection after the new <br> element.
-  RefPtr<Element> newBRElement =
-    CreateBRImpl(*selection, atStartOfSelection, nsIEditor::eNext);
-  if (NS_WARN_IF(!newBRElement)) {
+  // InsertBrElementWithTransaction() will set selection after the new <br>
+  // element.
+  RefPtr<Element> newBrElement =
+    InsertBrElementWithTransaction(*selection, atStartOfSelection, eNext);
+  if (NS_WARN_IF(!newBrElement)) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 void
 HTMLEditor::CollapseSelectionToDeepestNonTableFirstChild(Selection* aSelection,
                                                          nsINode* aNode)
@@ -1609,19 +1610,19 @@ HTMLEditor::InsertElementAtSelection(nsI
       // check for inserting a whole table at the end of a block. If so insert
       // a br after it.
       if (HTMLEditUtils::IsTable(element) &&
           IsLastEditableChild(element)) {
         DebugOnly<bool> advanced = insertedPoint.AdvanceOffset();
         NS_WARNING_ASSERTION(advanced,
           "Failed to advance offset from inserted point");
         // Collapse selection to the new <br> element node after creating it.
-        RefPtr<Element> newBRElement =
-          CreateBRImpl(*selection, insertedPoint, ePrevious);
-        if (NS_WARN_IF(!newBRElement)) {
+        RefPtr<Element> newBrElement =
+          InsertBrElementWithTransaction(*selection, insertedPoint, ePrevious);
+        if (NS_WARN_IF(!newBrElement)) {
           return NS_ERROR_FAILURE;
         }
       }
     }
   }
   rv = rules->DidDoAction(selection, &ruleInfo, rv);
   return rv;
 }
@@ -3748,16 +3749,21 @@ HTMLEditor::SetSelectionAtDocumentStart(
 
 /**
  * Remove aNode, reparenting any children into the parent of aNode.  In
  * addition, insert any br's needed to preserve identity of removed block.
  */
 nsresult
 HTMLEditor::RemoveBlockContainerWithTransaction(Element& aElement)
 {
+  RefPtr<Selection> selection = GetSelection();
+  if (NS_WARN_IF(!selection)) {
+    return NS_ERROR_FAILURE;
+  }
+
   // Two possibilities: the container could be empty of editable content.  If
   // that is the case, we need to compare what is before and after aNode to
   // determine if we need a br.
   //
   // Or it could be not empty, in which case we have to compare previous
   // sibling and first child to determine if we need a leading br, and compare
   // following sibling and last child to determine if we need a trailing br.
 
@@ -3769,17 +3775,19 @@ HTMLEditor::RemoveBlockContainerWithTran
     // 2) previous sibling of aNode is a br, OR
     // 3) first child of aNode is a block OR
     // 4) either is null
 
     nsCOMPtr<nsIContent> sibling = GetPriorHTMLSibling(&aElement);
     if (sibling && !IsBlockNode(sibling) &&
         !sibling->IsHTMLElement(nsGkAtoms::br) && !IsBlockNode(child)) {
       // Insert br node
-      RefPtr<Element> brElement = CreateBR(EditorRawDOMPoint(&aElement, 0));
+      RefPtr<Element> brElement =
+        InsertBrElementWithTransaction(*selection,
+                                       EditorRawDOMPoint(&aElement, 0));
       if (NS_WARN_IF(!brElement)) {
         return NS_ERROR_FAILURE;
       }
     }
 
     // We need a br at end unless:
     // 1) following sibling of aNode is a block, OR
     // 2) last child of aNode is a block, OR
@@ -3789,17 +3797,18 @@ HTMLEditor::RemoveBlockContainerWithTran
     sibling = GetNextHTMLSibling(&aElement);
     if (sibling && !IsBlockNode(sibling)) {
       child = GetLastEditableChild(aElement);
       MOZ_ASSERT(child, "aNode has first editable child but not last?");
       if (!IsBlockNode(child) && !child->IsHTMLElement(nsGkAtoms::br)) {
         // Insert br node
         EditorRawDOMPoint endOfNode;
         endOfNode.SetToEndOf(&aElement);
-        RefPtr<Element> brElement = CreateBR(endOfNode);
+        RefPtr<Element> brElement =
+          InsertBrElementWithTransaction(*selection, endOfNode);
         if (NS_WARN_IF(!brElement)) {
           return NS_ERROR_FAILURE;
         }
       }
     }
   } else {
     // The case of aNode being empty.  We need a br at start unless:
     // 1) previous sibling of aNode is a block, OR
@@ -3809,17 +3818,19 @@ HTMLEditor::RemoveBlockContainerWithTran
     // 5) either is null
     nsCOMPtr<nsIContent> sibling = GetPriorHTMLSibling(&aElement);
     if (sibling && !IsBlockNode(sibling) &&
         !sibling->IsHTMLElement(nsGkAtoms::br)) {
       sibling = GetNextHTMLSibling(&aElement);
       if (sibling && !IsBlockNode(sibling) &&
           !sibling->IsHTMLElement(nsGkAtoms::br)) {
         // Insert br node
-        RefPtr<Element> brElement = CreateBR(EditorRawDOMPoint(&aElement, 0));
+        RefPtr<Element> brElement =
+          InsertBrElementWithTransaction(*selection,
+                                         EditorRawDOMPoint(&aElement, 0));
         if (NS_WARN_IF(!brElement)) {
           return NS_ERROR_FAILURE;
         }
       }
     }
   }
 
   // Now remove container
@@ -4571,19 +4582,27 @@ HTMLEditor::CopyLastEditableChildStyles(
           return NS_ERROR_FAILURE;
         }
       }
       CloneAttributesWithTransaction(*newStyles, *childElement);
     }
     childElement = childElement->GetParentElement();
   }
   if (deepestStyle) {
-    RefPtr<Element> retVal = CreateBR(EditorRawDOMPoint(deepestStyle, 0));
-    retVal.forget(aOutBrNode);
-    NS_ENSURE_STATE(*aOutBrNode);
+    RefPtr<Selection> selection = GetSelection();
+    if (NS_WARN_IF(!selection)) {
+      return NS_ERROR_FAILURE;
+    }
+    RefPtr<Element> brElement =
+      InsertBrElementWithTransaction(*selection,
+                                     EditorRawDOMPoint(deepestStyle, 0));
+    if (NS_WARN_IF(!brElement)) {
+      return NS_ERROR_FAILURE;
+    }
+    brElement.forget(aOutBrNode);
   }
   return NS_OK;
 }
 
 nsresult
 HTMLEditor::GetElementOrigin(Element& aElement,
                              int32_t& aX,
                              int32_t& aY)
--- a/editor/libeditor/TextEditRules.cpp
+++ b/editor/libeditor/TextEditRules.cpp
@@ -1671,17 +1671,23 @@ TextEditRules::CreateBRInternal(const Ed
     return nullptr;
   }
 
   if (NS_WARN_IF(!mTextEditor)) {
     return nullptr;
   }
   RefPtr<TextEditor> textEditor = mTextEditor;
 
-  RefPtr<Element> brElement = textEditor->CreateBR(aPointToInsert);
+  RefPtr<Selection> selection = textEditor->GetSelection();
+  if (NS_WARN_IF(!selection)) {
+    return nullptr;
+  }
+
+  RefPtr<Element> brElement =
+    textEditor->InsertBrElementWithTransaction(*selection, aPointToInsert);
   if (NS_WARN_IF(!brElement)) {
     return nullptr;
   }
 
   // give it special moz attr
   if (aCreateMozBR) {
     // XXX Why do we need to set this attribute with transaction?
     nsresult rv =
--- a/editor/libeditor/TextEditor.cpp
+++ b/editor/libeditor/TextEditor.cpp
@@ -60,21 +60,25 @@
 class nsIOutputStream;
 class nsISupports;
 
 namespace mozilla {
 
 using namespace dom;
 
 template already_AddRefed<Element>
-TextEditor::CreateBR(const EditorDOMPoint& aPointToInsert,
-                     EDirection aSelect);
+TextEditor::InsertBrElementWithTransaction(
+              Selection& aSelection,
+              const EditorDOMPoint& aPointToInsert,
+              EDirection aSelect);
 template already_AddRefed<Element>
-TextEditor::CreateBR(const EditorRawDOMPoint& aPointToInsert,
-                     EDirection aSelect);
+TextEditor::InsertBrElementWithTransaction(
+              Selection& aSelection,
+              const EditorRawDOMPoint& aPointToInsert,
+              EDirection aSelect);
 
 TextEditor::TextEditor()
   : mWrapColumn(0)
   , mMaxTextLength(-1)
   , mInitTriggerCounter(0)
   , mNewlineHandling(nsIPlaintextEditor::eNewlinesPasteToFirst)
 #ifdef XP_WIN
   , mCaretStyle(1)
@@ -432,32 +436,20 @@ TextEditor::TypedText(const nsAString& a
     default:
       // eTypedBR is only for HTML
       return NS_ERROR_FAILURE;
   }
 }
 
 template<typename PT, typename CT>
 already_AddRefed<Element>
-TextEditor::CreateBR(const EditorDOMPointBase<PT, CT>& aPointToInsert,
-                     EDirection aSelect /* = eNone */)
-{
-  RefPtr<Selection> selection = GetSelection();
-  if (NS_WARN_IF(!selection)) {
-    return nullptr;
-  }
-  // We assume everything is fine if newBRElement is not null.
-  return CreateBRImpl(*selection, aPointToInsert, aSelect);
-}
-
-template<typename PT, typename CT>
-already_AddRefed<Element>
-TextEditor::CreateBRImpl(Selection& aSelection,
-                         const EditorDOMPointBase<PT, CT>& aPointToInsert,
-                         EDirection aSelect)
+TextEditor::InsertBrElementWithTransaction(
+              Selection& aSelection,
+              const EditorDOMPointBase<PT, CT>& aPointToInsert,
+              EDirection aSelect /* = eNone */)
 {
   if (NS_WARN_IF(!aPointToInsert.IsSet())) {
     return nullptr;
   }
 
   // We need to insert a <br> node.
   RefPtr<Element> newBRElement;
   if (aPointToInsert.IsInTextNode()) {
--- a/editor/libeditor/TextEditor.h
+++ b/editor/libeditor/TextEditor.h
@@ -221,55 +221,37 @@ protected:
   nsresult EndEditorInit();
 
   already_AddRefed<nsIDocumentEncoder> GetAndInitDocEncoder(
                                          const nsAString& aFormatType,
                                          uint32_t aFlags,
                                          const nsACString& aCharset);
 
   /**
-   * CreateBR() creates new <br> element and inserts it before aPointToInsert,
-   * and collapse selection if it's necessary.
-   *
-   * @param aPointToInsert  The point to insert new <br> element.
-   * @param aSelect         If eNone, this won't change selection.
-   *                        If eNext, selection will be collapsed after the
-   *                        <br> element.
-   *                        If ePrevious, selection will be collapsed at the
-   *                        <br> element.
-   * @return                The new <br> node.  If failed to create new <br>
-   *                        node, returns nullptr.
-   */
-  template<typename PT, typename CT>
-  already_AddRefed<Element>
-  CreateBR(const EditorDOMPointBase<PT, CT>& aPointToInsert,
-           EDirection aSelect = eNone);
-
-  /**
-   * CreateBRImpl() creates a <br> element and inserts it before aPointToInsert.
-   * Then, tries to collapse selection at or after the new <br> node if
-   * aSelect is not eNone.
-   * XXX Perhaps, this should be merged with CreateBR().
+   * InsertBrElementWithTransaction() creates a <br> element and inserts it
+   * before aPointToInsert.  Then, tries to collapse selection at or after the
+   * new <br> node if aSelect is not eNone.
    *
    * @param aSelection          The selection of this editor.
    * @param aPointToInsert      The DOM point where should be <br> node inserted
    *                            before.
    * @param aSelect             If eNone, this won't change selection.
    *                            If eNext, selection will be collapsed after
    *                            the <br> element.
    *                            If ePrevious, selection will be collapsed at
    *                            the <br> element.
    * @return                    The new <br> node.  If failed to create new
    *                            <br> node, returns nullptr.
    */
   template<typename PT, typename CT>
   already_AddRefed<Element>
-  CreateBRImpl(Selection& aSelection,
-               const EditorDOMPointBase<PT, CT>& aPointToInsert,
-               EDirection aSelect);
+  InsertBrElementWithTransaction(
+    Selection& aSelection,
+    const EditorDOMPointBase<PT, CT>& aPointToInsert,
+    EDirection aSelect = eNone);
 
   /**
    * Factored methods for handling insertion of data from transferables
    * (drag&drop or clipboard).
    */
   NS_IMETHOD PrepareTransferable(nsITransferable** transferable);
   nsresult InsertTextFromTransferable(nsITransferable* transferable);
 
--- a/editor/libeditor/WSRunObject.cpp
+++ b/editor/libeditor/WSRunObject.cpp
@@ -259,22 +259,23 @@ WSRunObject::InsertBreak(Selection& aSel
       nsresult rv =
         ReplacePreviousNBSPIfUnncessary(beforeRun, pointToInsert);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return nullptr;
       }
     }
   }
 
-  RefPtr<Element> newBRElement =
-    mHTMLEditor->CreateBRImpl(aSelection, pointToInsert, aSelect);
-  if (NS_WARN_IF(!newBRElement)) {
+  RefPtr<Element> newBrElement =
+    mHTMLEditor->InsertBrElementWithTransaction(aSelection, pointToInsert,
+                                                aSelect);
+  if (NS_WARN_IF(!newBrElement)) {
     return nullptr;
   }
-  return newBRElement.forget();
+  return newBrElement.forget();
 }
 
 template<typename PT, typename CT>
 nsresult
 WSRunObject::InsertText(nsIDocument& aDocument,
                         const nsAString& aStringToInsert,
                         const EditorDOMPointBase<PT, CT>& aPointToInsert,
                         EditorRawDOMPoint* aPointAfterInsertedString)
@@ -1843,16 +1844,21 @@ WSRunObject::CheckTrailingNBSPOfRun(WSFr
       // nbsp with space
       if (aRun->mRightType == WSType::text ||
           aRun->mRightType == WSType::special ||
           aRun->mRightType == WSType::br) {
         rightCheck = true;
       }
       if ((aRun->mRightType & WSType::block) &&
           IsBlockNode(GetWSBoundingParent())) {
+        RefPtr<Selection> selection = htmlEditor->GetSelection();
+        if (NS_WARN_IF(!selection)) {
+          return NS_ERROR_FAILURE;
+        }
+
         // We are at a block boundary.  Insert a <br>.  Why?  Well, first note
         // that the br will have no visible effect since it is up against a
         // block boundary.  |foo<br><p>bar| renders like |foo<p>bar| and
         // similarly |<p>foo<br></p>bar| renders like |<p>foo</p>bar|.  What
         // this <br> addition gets us is the ability to convert a trailing nbsp
         // to a space.  Consider: |<body>foo. '</body>|, where ' represents
         // selection.  User types space attempting to put 2 spaces after the
         // end of their sentence.  We used to do this as: |<body>foo.
@@ -1864,18 +1870,20 @@ WSRunObject::CheckTrailingNBSPOfRun(WSFr
         // wrapping problem, where foo is on one line until you type the final
         // space, and then "foo  " jumps down to the next line.  Ugh.  The best
         // way I can find out of this is to throw in a harmless <br> here,
         // which allows us to do: |<body>foo.&nbsp <br></body>|, which doesn't
         // cause foo to jump lines, doesn't cause spaces to show up at the
         // beginning of soft wrapped lines, and lets the user see 2 spaces when
         // they type 2 spaces.
 
-        RefPtr<Element> brNode = htmlEditor->CreateBR(aRun->EndPoint());
-        if (NS_WARN_IF(!brNode)) {
+        RefPtr<Element> brElement =
+          htmlEditor->InsertBrElementWithTransaction(*selection,
+                                                     aRun->EndPoint());
+        if (NS_WARN_IF(!brElement)) {
           return NS_ERROR_FAILURE;
         }
 
         // Refresh thePoint, prevPoint
         thePoint = GetPreviousCharPoint(aRun->EndPoint());
         prevPoint = GetPreviousCharPoint(thePoint);
         rightCheck = true;
       }