Bug 1413181 - part 6: Rename mozilla::EditorBase::EmptyContainers enum class to mozilla::SplitAtEdges for making its values clearer r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 13 Nov 2017 14:35:16 +0900
changeset 701126 14bf477a5041d6701f065d7f2f1d96c0aed304a3
parent 701125 127d634ffd8a14992e64d70bcae8e9814a383db1
child 701127 a31409c57a0014234c685334a608fd5057dad4a4
push id90079
push usermasayuki@d-toybox.com
push dateTue, 21 Nov 2017 08:41:26 +0000
reviewersm_kato
bugs1413181
milestone59.0a1
Bug 1413181 - part 6: Rename mozilla::EditorBase::EmptyContainers enum class to mozilla::SplitAtEdges for making its values clearer r?m_kato EmptyContainers::yes and EmptyContainers::no are not so clear name what they mean. They means whether NodeSplitDeep() creates or won't create empty nodes when split point is at start edge or end edge of an element. This patch renames them to SplitAtEdges::eDoNotCreateEmptyContainer and SplitAtEdges::eAllowToCreateEmptyContainer and make HTMLEditor::InsertNodeAtPoint() use it instead of an bool argument. Additionally, the argument of NodeSplitDeep() is now not optional because this difference is really important when you read around the callers. MozReview-Commit-ID: 9hpMRkVDvCg
editor/libeditor/EditorBase.cpp
editor/libeditor/EditorBase.h
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditor.cpp
editor/libeditor/HTMLEditor.h
editor/libeditor/HTMLEditorDataTransfer.cpp
editor/libeditor/HTMLStyleEditor.cpp
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -4055,17 +4055,17 @@ EditorBase::IsPreformatted(nsIDOMNode* a
  * unavailable or cloning the node failing.  Make sure not to use the returned
  * offset for anything without checking that it's valid!  If you're not using
  * the offset, it's okay to ignore the return value.
  */
 int32_t
 EditorBase::SplitNodeDeep(nsIContent& aNode,
                           nsIContent& aSplitPointParent,
                           int32_t aSplitPointOffset,
-                          EmptyContainers aEmptyContainers,
+                          SplitAtEdges aSplitAtEdges,
                           nsIContent** aOutLeftNode,
                           nsIContent** aOutRightNode,
                           nsCOMPtr<nsIContent>* ioChildAtSplitPointOffset)
 {
   MOZ_ASSERT(&aSplitPointParent == &aNode ||
              EditorUtils::IsDescendantOf(aSplitPointParent, aNode));
   int32_t offset = aSplitPointOffset;
 
@@ -4074,17 +4074,17 @@ EditorBase::SplitNodeDeep(nsIContent& aN
   while (true) {
     // Need to insert rules code call here to do things like not split a list
     // if you are after the last <li> or before the first, etc.  For now we
     // just have some smarts about unneccessarily splitting text nodes, which
     // should be universal enough to put straight in this EditorBase routine.
 
     bool didSplit = false;
 
-    if ((aEmptyContainers == EmptyContainers::yes &&
+    if ((aSplitAtEdges == SplitAtEdges::eAllowToCreateEmptyContainer &&
          !nodeToSplit->GetAsText()) ||
         (offset && offset != (int32_t)nodeToSplit->Length())) {
       didSplit = true;
       ErrorResult error;
       int32_t offsetAtStartOfRightNode =
         std::min(std::max(offset, 0),
                  static_cast<int32_t>(nodeToSplit->Length()));
       nsCOMPtr<nsIContent> newLeftNode =
--- a/editor/libeditor/EditorBase.h
+++ b/editor/libeditor/EditorBase.h
@@ -205,16 +205,33 @@ private:
   nsWeakPtr mWeakPtr;
   T* MOZ_NON_OWNING_REF mCache;
 };
 
 #define kMOZEditorBogusNodeAttrAtom nsGkAtoms::mozeditorbogusnode
 #define kMOZEditorBogusNodeValue NS_LITERAL_STRING("TRUE")
 
 /**
+ * SplitAtEdges is for EditorBase::SplitNodeDeep(),
+ * HTMLEditor::InsertNodeAtPoint()
+ */
+enum class SplitAtEdges
+{
+  // EditorBase::SplitNodeDeep() won't split container element nodes at
+  // their edges.  I.e., when split point is start or end of container,
+  // it won't be split.
+  eDoNotCreateEmptyContainer,
+  // EditorBase::SplitNodeDeep() always splits containers even if the split
+  // point is at edge of a container.  E.g., if split point is start of an
+  // inline element, empty inline element is created as a new left node.
+  eAllowToCreateEmptyContainer
+};
+
+
+/**
  * Implementation of an editor object.  it will be the controller/focal point
  * for the main editor services. i.e. the GUIManager, publishing, transaction
  * manager, event interfaces. the idea for the event interfaces is to have them
  * delegate the actual commands to the editor independent of the XPFE
  * implementation.
  */
 class EditorBase : public nsIEditor
                  , public nsSupportsWeakReference
@@ -1125,21 +1142,19 @@ public:
   /**
    * When you are using AppendNodeToSelectionAsRange(), call this first to
    * start a new selection.
    */
   nsresult ClearSelection();
 
   nsresult IsPreformatted(nsIDOMNode* aNode, bool* aResult);
 
-  enum class EmptyContainers { no, yes };
   int32_t SplitNodeDeep(nsIContent& aNode, nsIContent& aSplitPointParent,
                         int32_t aSplitPointOffset,
-                        EmptyContainers aEmptyContainers =
-                          EmptyContainers::yes,
+                        SplitAtEdges aSplitAtEdges,
                         nsIContent** outLeftNode = nullptr,
                         nsIContent** outRightNode = nullptr,
                         nsCOMPtr<nsIContent>* ioChildAtSplitPointOffset =
                           nullptr);
   EditorDOMPoint JoinNodeDeep(nsIContent& aLeftNode,
                               nsIContent& aRightNode);
 
   nsresult GetString(const nsAString& name, nsAString& value);
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -1852,19 +1852,19 @@ HTMLEditRules::StandardBreakImpl(nsINode
       bBeforeBlock = true;
     }
     nsCOMPtr<nsIDOMNode> linkDOMNode;
     if (htmlEditor->IsInLink(GetAsDOMNode(node), address_of(linkDOMNode))) {
       // Split the link
       nsCOMPtr<Element> linkNode = do_QueryInterface(linkDOMNode);
       NS_ENSURE_STATE(linkNode || !linkDOMNode);
       nsCOMPtr<nsINode> linkParent = linkNode->GetParentNode();
-      aOffset = htmlEditor->SplitNodeDeep(*linkNode, *node->AsContent(),
-                                          aOffset,
-                                          HTMLEditor::EmptyContainers::no);
+      aOffset =
+        htmlEditor->SplitNodeDeep(*linkNode, *node->AsContent(), aOffset,
+                                  SplitAtEdges::eDoNotCreateEmptyContainer);
       NS_ENSURE_STATE(aOffset != -1);
       node = linkParent;
     }
     brNode = wsObj.InsertBreak(address_of(node), &aOffset, nsIEditor::eNone);
     NS_ENSURE_TRUE(brNode, NS_ERROR_FAILURE);
   }
   node = brNode->GetParentNode();
   NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
@@ -1962,19 +1962,21 @@ HTMLEditRules::SplitMailCites(Selection*
         NS_ENSURE_STATE(mHTMLEditor);
         selNode = mHTMLEditor->GetNodeLocation(visNode, &selOffset);
         ++selOffset;
       }
     }
 
     NS_ENSURE_STATE(mHTMLEditor);
     NS_ENSURE_STATE(selNode->IsContent());
-    int32_t newOffset = mHTMLEditor->SplitNodeDeep(*citeNode,
-        *selNode->AsContent(), selOffset, HTMLEditor::EmptyContainers::no,
-        getter_AddRefs(leftCite), getter_AddRefs(rightCite));
+    int32_t newOffset =
+      mHTMLEditor->SplitNodeDeep(*citeNode, *selNode->AsContent(), selOffset,
+                                 SplitAtEdges::eDoNotCreateEmptyContainer,
+                                 getter_AddRefs(leftCite),
+                                 getter_AddRefs(rightCite));
     NS_ENSURE_STATE(newOffset != -1);
 
     // Add an invisible <br> to the end of the left part if it was a <span> of
     // style="display: block". This is important, since when serialising the
     // cite to plain text, the span which caused the visual break is discarded.
     // So the added <br> will guarantee that the serialiser will insert a
     // break where the user saw one.
     if (leftCite &&
@@ -3835,19 +3837,19 @@ HTMLEditRules::MakeBasicBlock(Selection&
         nsCOMPtr<nsIContent> brNode =
           htmlEditor->GetNextEditableHTMLNode(
                         EditorRawDOMPoint(container, child, offset));
         if (brNode && brNode->IsHTMLElement(nsGkAtoms::br)) {
           rv = htmlEditor->DeleteNode(brNode);
           NS_ENSURE_SUCCESS(rv, rv);
         }
         // Do the splits!
-        offset = htmlEditor->SplitNodeDeep(curBlock, *container->AsContent(),
-                                            offset,
-                                            HTMLEditor::EmptyContainers::no);
+        offset =
+          htmlEditor->SplitNodeDeep(curBlock, *container->AsContent(), offset,
+                                    SplitAtEdges::eDoNotCreateEmptyContainer);
         NS_ENSURE_STATE(offset != -1);
         // Put a br at the split point
         brNode = htmlEditor->CreateBR(curBlock->GetParentNode(), offset);
         NS_ENSURE_STATE(brNode);
         // Put selection at the split point
         rv = aSelection.Collapse(curBlock->GetParentNode(), offset);
         // Don't restore the selection
         selectionRestorer.Abort();
@@ -4711,28 +4713,28 @@ HTMLEditRules::SplitBlock(Element& aBloc
 
   // Get split point location
   OwningNonNull<nsIContent> startParent = *aStartChild.GetParent();
   int32_t startOffset = startParent->IndexOf(&aStartChild);
 
   // Do the splits!
   nsCOMPtr<nsIContent> newMiddleNode1;
   htmlEditor->SplitNodeDeep(aBlock, startParent, startOffset,
-                            HTMLEditor::EmptyContainers::no,
+                            SplitAtEdges::eDoNotCreateEmptyContainer,
                             aOutLeftNode, getter_AddRefs(newMiddleNode1));
 
   // Get split point location
   OwningNonNull<nsIContent> endParent = *aEndChild.GetParent();
   // +1 because we want to be after the child
   int32_t endOffset = 1 + endParent->IndexOf(&aEndChild);
 
   // Do the splits!
   nsCOMPtr<nsIContent> newMiddleNode2;
   htmlEditor->SplitNodeDeep(aBlock, endParent, endOffset,
-                            HTMLEditor::EmptyContainers::no,
+                            SplitAtEdges::eDoNotCreateEmptyContainer,
                             getter_AddRefs(newMiddleNode2), aOutRightNode);
 
   if (aOutMiddleNode) {
     if (newMiddleNode2) {
       newMiddleNode2.forget(aOutMiddleNode);
     } else {
       newMiddleNode1.forget(aOutMiddleNode);
     }
@@ -4846,17 +4848,19 @@ HTMLEditRules::CreateStyleForInsertText(
   item = Move(mHTMLEditor->mTypeInState->TakeSetProperty());
 
   if (item || relFontSize) {
     // we have at least one style to add; make a new text node to insert style
     // nodes above.
     if (RefPtr<Text> text = node->GetAsText()) {
       // if we are in a text node, split it
       NS_ENSURE_STATE(mHTMLEditor);
-      offset = mHTMLEditor->SplitNodeDeep(*text, *text, offset);
+      offset =
+        mHTMLEditor->SplitNodeDeep(*text, *text, offset,
+                                   SplitAtEdges::eAllowToCreateEmptyContainer);
       NS_ENSURE_STATE(offset != -1);
       node = node->GetParentNode();
     }
     if (!mHTMLEditor->IsContainer(node)) {
       return NS_OK;
     }
     OwningNonNull<Text> newNode =
       EditorBase::CreateTextNode(aDoc, EmptyString());
@@ -6401,34 +6405,34 @@ HTMLEditRules::BustUpInlinesAtRangeEndpo
   // if we have inline parents above range endpoints, split them
   if (endInline && !isCollapsed) {
     nsCOMPtr<nsINode> resultEndNode = endInline->GetParentNode();
     NS_ENSURE_STATE(mHTMLEditor);
     // item.mEndContainer must be content if endInline isn't null
     int32_t resultEndOffset =
       mHTMLEditor->SplitNodeDeep(*endInline, *item.mEndContainer->AsContent(),
                                  item.mEndOffset,
-                                 EditorBase::EmptyContainers::no);
+                                 SplitAtEdges::eDoNotCreateEmptyContainer);
     NS_ENSURE_TRUE(resultEndOffset != -1, NS_ERROR_FAILURE);
     // reset range
     item.mEndContainer = resultEndNode;
     item.mEndOffset = resultEndOffset;
   }
 
   nsCOMPtr<nsIContent> startInline =
     GetHighestInlineParent(*item.mStartContainer);
 
   if (startInline) {
     nsCOMPtr<nsINode> resultStartNode = startInline->GetParentNode();
     NS_ENSURE_STATE(mHTMLEditor);
     int32_t resultStartOffset =
       mHTMLEditor->SplitNodeDeep(*startInline,
                                  *item.mStartContainer->AsContent(),
                                  item.mStartOffset,
-                                 EditorBase::EmptyContainers::no);
+                                 SplitAtEdges::eDoNotCreateEmptyContainer);
     NS_ENSURE_TRUE(resultStartOffset != -1, NS_ERROR_FAILURE);
     // reset range
     item.mStartContainer = resultStartNode;
     item.mStartOffset = resultStartOffset;
   }
 
   return NS_OK;
 }
@@ -6462,17 +6466,17 @@ HTMLEditRules::BustUpInlinesAtBRs(
     OwningNonNull<Element> breakNode = *arrayOfBreaks[i]->AsElement();
     NS_ENSURE_TRUE(splitDeepNode, NS_ERROR_NULL_POINTER);
     NS_ENSURE_TRUE(breakNode->GetParent(), NS_ERROR_NULL_POINTER);
     OwningNonNull<nsIContent> splitParentNode = *breakNode->GetParent();
     int32_t splitOffset = splitParentNode->IndexOf(breakNode);
 
     int32_t resultOffset =
       htmlEditor->SplitNodeDeep(*splitDeepNode, splitParentNode, splitOffset,
-                                HTMLEditor::EmptyContainers::yes,
+                                SplitAtEdges::eAllowToCreateEmptyContainer,
                                 getter_AddRefs(leftNode),
                                 getter_AddRefs(rightNode));
     NS_ENSURE_STATE(resultOffset != -1);
 
     // Put left node in node list
     if (leftNode) {
       // Might not be a left node.  A break might have been at the very
       // beginning of inline container, in which case SplitNodeDeep would not
@@ -6673,17 +6677,18 @@ HTMLEditRules::ReturnInHeader(Selection&
   nsCOMPtr<nsINode> node = &aNode;
   nsresult rv = WSRunObject::PrepareToSplitAcrossBlocks(htmlEditor,
                                                         address_of(node),
                                                         &aOffset);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Split the header
   NS_ENSURE_STATE(node->IsContent());
-  htmlEditor->SplitNodeDeep(aHeader, *node->AsContent(), aOffset);
+  htmlEditor->SplitNodeDeep(aHeader, *node->AsContent(), aOffset,
+                            SplitAtEdges::eAllowToCreateEmptyContainer);
 
   // If the left-hand heading is empty, put a mozbr in it
   nsCOMPtr<nsIContent> prevItem = htmlEditor->GetPriorHTMLSibling(&aHeader);
   if (prevItem && HTMLEditUtils::IsHeader(*prevItem)) {
     bool isEmptyNode;
     rv = htmlEditor->IsEmptyNode(prevItem, &isEmptyNode);
     NS_ENSURE_SUCCESS(rv, rv);
     if (isEmptyNode) {
@@ -6892,17 +6897,17 @@ HTMLEditRules::SplitParagraph(Selection&
                                             address_of(selNode), &selOffset);
   // XXX When it fails, why do we need to return selection node?  (Why can the
   //     caller trust the result even when it returns error?)
   NS_ENSURE_SUCCESS(rv, rv);
   // split the paragraph
   NS_ENSURE_STATE(selNode->IsContent());
   int32_t offset =
     htmlEditor->SplitNodeDeep(aParentDivOrP, *selNode->AsContent(), selOffset,
-                              HTMLEditor::EmptyContainers::yes,
+                              SplitAtEdges::eAllowToCreateEmptyContainer,
                               getter_AddRefs(leftPara),
                               getter_AddRefs(rightPara));
   if (NS_WARN_IF(offset == -1)) {
     return NS_ERROR_FAILURE;
   }
   // Get rid of the break, if it is visible (otherwise it may be needed to
   // prevent an empty p).
   if (aNextBRNode && htmlEditor->IsVisibleBRElement(aNextBRNode)) {
@@ -7015,17 +7020,18 @@ HTMLEditRules::ReturnInListItem(Selectio
   // Else we want a new list item at the same list level.  Get ws code to
   // adjust any ws.
   nsCOMPtr<nsINode> selNode = &aNode;
   rv = WSRunObject::PrepareToSplitAcrossBlocks(htmlEditor,
                                                address_of(selNode), &aOffset);
   NS_ENSURE_SUCCESS(rv, rv);
   // Now split list item
   NS_ENSURE_STATE(selNode->IsContent());
-  htmlEditor->SplitNodeDeep(aListItem, *selNode->AsContent(), aOffset);
+  htmlEditor->SplitNodeDeep(aListItem, *selNode->AsContent(), aOffset,
+                            SplitAtEdges::eAllowToCreateEmptyContainer);
 
   // Hack: until I can change the damaged doc range code back to being
   // extra-inclusive, I have to manually detect certain list items that may be
   // left empty.
   nsCOMPtr<nsIContent> prevItem = htmlEditor->GetPriorHTMLSibling(&aListItem);
   if (prevItem && HTMLEditUtils::IsListItem(prevItem)) {
     bool isEmptyNode;
     rv = htmlEditor->IsEmptyNode(prevItem, &isEmptyNode);
@@ -7447,22 +7453,21 @@ HTMLEditRules::SplitAsNeeded(nsAtom& aTa
   }
   if (!tagParent) {
     // Could not find a place to build tag!
     return NS_ERROR_FAILURE;
   }
   if (splitNode && splitNode->IsContent() && inOutParent->IsContent()) {
     // We found a place for block, but above inOutParent. We need to split.
     NS_ENSURE_STATE(mHTMLEditor);
-    int32_t offset = mHTMLEditor->SplitNodeDeep(*splitNode->AsContent(),
-                                                *inOutParent->AsContent(),
-                                                inOutOffset,
-                                                EditorBase::EmptyContainers::yes,
-                                                nullptr, nullptr,
-                                                inOutChildAtOffset);
+    int32_t offset =
+      mHTMLEditor->SplitNodeDeep(*splitNode->AsContent(),
+                                 *inOutParent->AsContent(), inOutOffset,
+                                 SplitAtEdges::eAllowToCreateEmptyContainer,
+                                 nullptr, nullptr, inOutChildAtOffset);
     NS_ENSURE_STATE(offset != -1);
     inOutParent = tagParent;
     inOutOffset = offset;
   }
   return NS_OK;
 }
 
 /**
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -1517,17 +1517,18 @@ HTMLEditor::InsertElementAtSelection(nsI
       int32_t offsetForInsert = selection->AnchorOffset();
       // Adjust position based on the node we are going to insert.
       nsCOMPtr<nsIDOMNode> parentSelectedDOMNode =
         GetAsDOMNode(parentSelectedNode);
       NormalizeEOLInsertPosition(element, address_of(parentSelectedDOMNode),
                                  &offsetForInsert);
 
       rv = InsertNodeAtPoint(node, address_of(parentSelectedDOMNode),
-                             &offsetForInsert, false);
+                             &offsetForInsert,
+                             SplitAtEdges::eAllowToCreateEmptyContainer);
       NS_ENSURE_SUCCESS(rv, rv);
       // Set caret after element, but check for special case
       //  of inserting table-related elements: set in first cell instead
       if (!SetCaretInTableCell(aElement)) {
         rv = SetCaretAfterElement(aElement);
         NS_ENSURE_SUCCESS(rv, rv);
       }
       // check for inserting a whole table at the end of a block. If so insert
@@ -1559,24 +1560,24 @@ HTMLEditor::InsertElementAtSelection(nsI
  * aNode was inserted at.  aNoEmptyNodes specifies if the splitting process
  * is allowed to reslt in empty nodes.  ioChildAtOffset, if provided, is the
  * child node at offset if ioParent is non-null, and the function will update
  * *ioChildAtOffset upon returning.
  *
  * @param aNode             Node to insert.
  * @param ioParent          Insertion parent.
  * @param ioOffset          Insertion offset.
- * @param aNoEmptyNodes     Splitting can result in empty nodes?
+ * @param aSplitAtEdges     Splitting can result in empty nodes?
  * @param ioChildAtOffset   Child node at insertion offset (optional).
  */
 nsresult
 HTMLEditor::InsertNodeAtPoint(nsIDOMNode* aNode,
                               nsCOMPtr<nsIDOMNode>* ioParent,
                               int32_t* ioOffset,
-                              bool aNoEmptyNodes,
+                              SplitAtEdges aSplitAtEdges,
                               nsCOMPtr<nsIDOMNode>* ioChildAtOffset)
 {
   nsCOMPtr<nsIContent> node = do_QueryInterface(aNode);
   NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
   NS_ENSURE_TRUE(ioParent, NS_ERROR_NULL_POINTER);
   NS_ENSURE_TRUE(*ioParent, NS_ERROR_NULL_POINTER);
   NS_ENSURE_TRUE(ioOffset, NS_ERROR_NULL_POINTER);
   bool isDocumentFragment = false;
@@ -1619,18 +1620,17 @@ HTMLEditor::InsertNodeAtPoint(nsIDOMNode
   }
   if (parent != topChild) {
     nsCOMPtr<nsIContent> child;
     if (ioChildAtOffset) {
       child = do_QueryInterface(*ioChildAtOffset);
     }
     // we need to split some levels above the original selection parent
     int32_t offset = SplitNodeDeep(*topChild, *origParent, *ioOffset,
-                                   aNoEmptyNodes ? EmptyContainers::no
-                                                 : EmptyContainers::yes,
+                                   aSplitAtEdges,
                                    nullptr, nullptr, address_of(child));
     NS_ENSURE_STATE(offset != -1);
     *ioParent = GetAsDOMNode(parent);
     *ioOffset = offset;
     if (ioChildAtOffset) {
       *ioChildAtOffset = GetAsDOMNode(child);
     }
   }
@@ -1998,17 +1998,18 @@ HTMLEditor::MakeOrChangeList(const nsASt
       while (!CanContainTag(*parent, *listAtom)) {
         topChild = parent;
         parent = parent->GetParent();
       }
 
       if (parent != node) {
         // we need to split up to the child of parent
         offset = SplitNodeDeep(*topChild, *node, offset,
-                               EmptyContainers::yes, nullptr, nullptr,
+                               SplitAtEdges::eAllowToCreateEmptyContainer,
+                               nullptr, nullptr,
                                address_of(child));
         NS_ENSURE_STATE(offset != -1);
       }
 
       // make a list
       MOZ_DIAGNOSTIC_ASSERT(child);
       EditorRawDOMPoint atChild(parent, child, offset);
       RefPtr<Element> newList = CreateNode(listAtom, atChild);
@@ -2143,17 +2144,18 @@ HTMLEditor::InsertBasicBlock(const nsASt
         NS_ENSURE_TRUE(parent->GetParent(), NS_ERROR_FAILURE);
         topChild = parent;
         parent = parent->GetParent();
       }
 
       if (parent != node) {
         // we need to split up to the child of parent
         offset = SplitNodeDeep(*topChild, *node, offset,
-                               EmptyContainers::yes, nullptr, nullptr,
+                               SplitAtEdges::eAllowToCreateEmptyContainer,
+                               nullptr, nullptr,
                                address_of(child));
         NS_ENSURE_STATE(offset != -1);
       }
 
       // make a block
       MOZ_DIAGNOSTIC_ASSERT(child);
       EditorRawDOMPoint atChild(parent, child, offset);
       RefPtr<Element> newBlock = CreateNode(blockAtom, atChild);
@@ -2219,17 +2221,18 @@ HTMLEditor::Indent(const nsAString& aInd
           NS_ENSURE_TRUE(parent->GetParent(), NS_ERROR_FAILURE);
           topChild = parent;
           parent = parent->GetParent();
         }
 
         if (parent != node) {
           // we need to split up to the child of parent
           offset = SplitNodeDeep(*topChild, *node, offset,
-                                 EmptyContainers::yes, nullptr, nullptr,
+                                 SplitAtEdges::eAllowToCreateEmptyContainer,
+                                 nullptr, nullptr,
                                  address_of(child));
           NS_ENSURE_STATE(offset != -1);
         }
 
         // make a blockquote
         MOZ_DIAGNOSTIC_ASSERT(child);
         EditorRawDOMPoint atChild(parent, child, offset);
         RefPtr<Element> newBQ = CreateNode(nsGkAtoms::blockquote, atChild);
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -336,17 +336,17 @@ public:
                               bool aWasAlternate, nsresult aStatus) override;
 
   // Utility Routines, not part of public API
   NS_IMETHOD TypedText(const nsAString& aString,
                        ETypingAction aAction) override;
   nsresult InsertNodeAtPoint(nsIDOMNode* aNode,
                              nsCOMPtr<nsIDOMNode>* ioParent,
                              int32_t* ioOffset,
-                             bool aNoEmptyNodes,
+                             SplitAtEdges aSplitAtEdges,
                              nsCOMPtr<nsIDOMNode>* ioChildAtOffset = nullptr);
 
   /**
    * Use this to assure that selection is set after attribute nodes when
    * trying to collapse selection at begining of a block node
    * e.g., when setting at beginning of a table cell
    * This will stop at a table, however, since we don't want to
    * "drill down" into nested tables.
--- a/editor/libeditor/HTMLEditorDataTransfer.cpp
+++ b/editor/libeditor/HTMLEditorDataTransfer.cpp
@@ -353,18 +353,19 @@ HTMLEditor::DoInsertHTMLWithContext(cons
 
     // Remember if we are in a link.
     bool bStartedInLink = IsInLink(parentNode);
 
     // Are we in a text node? If so, split it.
     if (IsTextNode(parentNode)) {
       nsCOMPtr<nsIContent> parentContent = do_QueryInterface(parentNode);
       NS_ENSURE_STATE(parentContent || !parentNode);
-      offsetOfNewNode = SplitNodeDeep(*parentContent, *parentContent,
-                                      offsetOfNewNode);
+      offsetOfNewNode =
+        SplitNodeDeep(*parentContent, *parentContent, offsetOfNewNode,
+                      SplitAtEdges::eAllowToCreateEmptyContainer);
       NS_ENSURE_STATE(offsetOfNewNode != -1);
       nsCOMPtr<nsIDOMNode> temp;
       rv = parentNode->GetParentNode(getter_AddRefs(temp));
       NS_ENSURE_SUCCESS(rv, rv);
       parentNode = temp;
     }
 
     // build up list of parents of first node in list that are either
@@ -441,17 +442,19 @@ HTMLEditor::DoInsertHTMLWithContext(cons
       // into a table or table row, insert the appropriate children instead.
       if (HTMLEditUtils::IsTableRow(curNode) &&
           HTMLEditUtils::IsTableRow(parentNode) &&
           (HTMLEditUtils::IsTable(curNode) ||
            HTMLEditUtils::IsTable(parentNode))) {
         nsCOMPtr<nsIDOMNode> child;
         curNode->GetFirstChild(getter_AddRefs(child));
         while (child) {
-          rv = InsertNodeAtPoint(child, address_of(parentNode), &offsetOfNewNode, true);
+          rv = InsertNodeAtPoint(child, address_of(parentNode),
+                                 &offsetOfNewNode,
+                                 SplitAtEdges::eDoNotCreateEmptyContainer);
           if (NS_FAILED(rv)) {
             break;
           }
 
           bDidInsert = true;
           lastInsertNode = child;
           offsetOfNewNode++;
 
@@ -480,17 +483,19 @@ HTMLEditor::DoInsertHTMLWithContext(cons
                 nsCOMPtr<nsIDOMNode> listNode = GetNodeLocation(parentNode, &newOffset);
                 if (listNode) {
                   DeleteNode(parentNode);
                   parentNode = listNode;
                   offsetOfNewNode = newOffset;
                 }
               }
             }
-            rv = InsertNodeAtPoint(child, address_of(parentNode), &offsetOfNewNode, true);
+            rv = InsertNodeAtPoint(child, address_of(parentNode),
+                                   &offsetOfNewNode,
+                                   SplitAtEdges::eDoNotCreateEmptyContainer);
             if (NS_FAILED(rv)) {
               break;
             }
 
             bDidInsert = true;
             lastInsertNode = child;
             offsetOfNewNode++;
           } else {
@@ -499,44 +504,50 @@ HTMLEditor::DoInsertHTMLWithContext(cons
           curNode->GetFirstChild(getter_AddRefs(child));
         }
       } else if (parentBlock && HTMLEditUtils::IsPre(parentBlock) &&
                  HTMLEditUtils::IsPre(curNode)) {
         // Check for pre's going into pre's.
         nsCOMPtr<nsIDOMNode> child;
         curNode->GetFirstChild(getter_AddRefs(child));
         while (child) {
-          rv = InsertNodeAtPoint(child, address_of(parentNode), &offsetOfNewNode, true);
+          rv = InsertNodeAtPoint(child, address_of(parentNode),
+                                 &offsetOfNewNode,
+                                 SplitAtEdges::eDoNotCreateEmptyContainer);
           if (NS_FAILED(rv)) {
             break;
           }
 
           bDidInsert = true;
           lastInsertNode = child;
           offsetOfNewNode++;
 
           curNode->GetFirstChild(getter_AddRefs(child));
         }
       }
 
       if (!bDidInsert || NS_FAILED(rv)) {
         // try to insert
-        rv = InsertNodeAtPoint(curNode, address_of(parentNode), &offsetOfNewNode, true);
+        rv = InsertNodeAtPoint(curNode, address_of(parentNode),
+                               &offsetOfNewNode,
+                               SplitAtEdges::eDoNotCreateEmptyContainer);
         if (NS_SUCCEEDED(rv)) {
           bDidInsert = true;
           lastInsertNode = curNode;
         }
 
         // Assume failure means no legal parent in the document hierarchy,
         // try again with the parent of curNode in the paste hierarchy.
         nsCOMPtr<nsIDOMNode> parent;
         while (NS_FAILED(rv) && curNode) {
           curNode->GetParentNode(getter_AddRefs(parent));
           if (parent && !TextEditUtils::IsBody(parent)) {
-            rv = InsertNodeAtPoint(parent, address_of(parentNode), &offsetOfNewNode, true,
+            rv = InsertNodeAtPoint(parent, address_of(parentNode),
+                                   &offsetOfNewNode,
+                                   SplitAtEdges::eDoNotCreateEmptyContainer,
                                    address_of(lastInsertNode));
             if (NS_SUCCEEDED(rv)) {
               bDidInsert = true;
               insertedContextParent = parent;
 #ifdef DEBUG
               nsCOMPtr<nsINode> node = do_QueryInterface(parentNode);
               MOZ_ASSERT(lastInsertNode == GetAsDOMNode(node->GetChildAt(offsetOfNewNode)));
 #endif
@@ -635,17 +646,18 @@ HTMLEditor::DoInsertHTMLWithContext(cons
         // that is not visible.  If so, the code above just placed selection
         // inside that.  So I split it instead.
         nsCOMPtr<nsIContent> linkContent = do_QueryInterface(link);
         NS_ENSURE_STATE(linkContent || !link);
         nsCOMPtr<nsIContent> selContent = do_QueryInterface(selNode);
         NS_ENSURE_STATE(selContent || !selNode);
         nsCOMPtr<nsIContent> leftLink;
         SplitNodeDeep(*linkContent, *selContent, selOffset,
-                      EmptyContainers::no, getter_AddRefs(leftLink));
+                      SplitAtEdges::eDoNotCreateEmptyContainer,
+                      getter_AddRefs(leftLink));
         if (leftLink) {
           EditorRawDOMPoint afterLeftLink(leftLink);
           if (afterLeftLink.AdvanceOffset()) {
             selection->Collapse(afterLeftLink);
           }
         }
       }
     }
--- a/editor/libeditor/HTMLStyleEditor.cpp
+++ b/editor/libeditor/HTMLStyleEditor.cpp
@@ -549,18 +549,18 @@ HTMLEditor::SplitStyleAbovePoint(nsCOMPt
         // node is href - test if really <a href=...
         (aProperty == nsGkAtoms::href && HTMLEditUtils::IsLink(node)) ||
         // or node is any prop, and we asked to split them all
         (!aProperty && NodeIsProperty(node)) ||
         // or the style is specified in the style attribute
         isSet) {
       // Found a style node we need to split
       int32_t offset = SplitNodeDeep(*node, *(*aNode)->AsContent(), *aOffset,
-                                     EmptyContainers::yes, aOutLeftNode,
-                                     aOutRightNode);
+                                     SplitAtEdges::eAllowToCreateEmptyContainer,
+                                     aOutLeftNode, aOutRightNode);
       NS_ENSURE_TRUE(offset != -1, NS_ERROR_FAILURE);
       // reset startNode/startOffset
       *aNode = node->GetParent();
       *aOffset = offset;
     }
     node = node->GetParent();
   }