Bug 1451672 - part 15: Rename EditorBase::RemoveContainer() and HTMLEditor::RemoveBlockContainer() with "WithTransaction" postfix and make their argument |Element&| r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Thu, 12 Apr 2018 22:23:04 +0900
changeset 468368 3bd18c2b985162bf4fa3a5d74214861839036325
parent 468367 24e17127ec4875531ef46308dde8169bf35cea67
child 468369 1871811c637d761880fb4af87f20bfb0feff7b50
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1451672
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1451672 - part 15: Rename EditorBase::RemoveContainer() and HTMLEditor::RemoveBlockContainer() with "WithTransaction" postfix and make their argument |Element&| r=m_kato MozReview-Commit-ID: 2toj48mqHM9
editor/libeditor/CSSEditUtils.cpp
editor/libeditor/EditorBase.cpp
editor/libeditor/EditorBase.h
editor/libeditor/HTMLAbsPositionEditor.cpp
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditor.cpp
editor/libeditor/HTMLEditor.h
editor/libeditor/HTMLStyleEditor.cpp
--- a/editor/libeditor/CSSEditUtils.cpp
+++ b/editor/libeditor/CSSEditUtils.cpp
@@ -578,17 +578,17 @@ CSSEditUtils::RemoveCSSInlineStyle(nsINo
   nsresult rv = RemoveCSSProperty(*element, *aProperty, aPropertyValue);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!element->IsHTMLElement(nsGkAtoms::span) ||
       HTMLEditor::HasAttributes(element)) {
     return NS_OK;
   }
 
-  return mHTMLEditor->RemoveContainer(element);
+  return mHTMLEditor->RemoveContainerWithTransaction(*element);
 }
 
 // Answers true if the property can be removed by setting a "none" CSS value
 // on a node
 
 // static
 bool
 CSSEditUtils::IsCSSInvertible(nsAtom& aProperty,
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -1723,39 +1723,33 @@ EditorBase::ReplaceContainerWithTransact
   rv = DeleteNodeWithTransaction(aOldContainer);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return nullptr;
   }
 
   return newContainer.forget();
 }
 
-/**
- * RemoveContainer() removes inNode, reparenting its children (if any) into the
- * parent of inNode.
- */
 nsresult
-EditorBase::RemoveContainer(nsIContent* aNode)
-{
-  MOZ_ASSERT(aNode);
-
-  EditorDOMPoint pointToInsertChildren(aNode);
+EditorBase::RemoveContainerWithTransaction(Element& aElement)
+{
+  EditorDOMPoint pointToInsertChildren(&aElement);
   if (NS_WARN_IF(!pointToInsertChildren.IsSet())) {
     return NS_ERROR_FAILURE;
   }
 
   // Notify our internal selection state listener.
-  AutoRemoveContainerSelNotify selNotify(mRangeUpdater, aNode,
+  AutoRemoveContainerSelNotify selNotify(mRangeUpdater, &aElement,
                                          pointToInsertChildren.GetContainer(),
                                          pointToInsertChildren.Offset(),
-                                         aNode->GetChildCount());
+                                         aElement.GetChildCount());
 
   // Move all children from aNode to its parent.
-  while (aNode->HasChildren()) {
-    nsCOMPtr<nsIContent> child = aNode->GetLastChild();
+  while (aElement.HasChildren()) {
+    nsCOMPtr<nsIContent> child = aElement.GetLastChild();
     if (NS_WARN_IF(!child)) {
       return NS_ERROR_FAILURE;
     }
     nsresult rv = DeleteNodeWithTransaction(*child);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
@@ -1766,17 +1760,17 @@ EditorBase::RemoveContainer(nsIContent* 
                                    EditorRawDOMPoint(
                                      pointToInsertChildren.GetContainer(),
                                      pointToInsertChildren.Offset()));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
 
-  nsresult rv = DeleteNodeWithTransaction(*aNode);
+  nsresult rv = DeleteNodeWithTransaction(aElement);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
 /**
  * InsertContainerAbove() inserts a new parent for inNode, which is contructed
--- a/editor/libeditor/EditorBase.h
+++ b/editor/libeditor/EditorBase.h
@@ -422,17 +422,24 @@ public:
   {
     return ReplaceContainerWithTransactionInternal(aOldContainer, aTagName,
                                                    aAttribute,
                                                    aAttributeValue, false);
   }
 
   void CloneAttributes(Element* aDest, Element* aSource);
 
-  nsresult RemoveContainer(nsIContent* aNode);
+  /**
+   * RemoveContainerWithTransaction() removes aElement from the DOM tree and
+   * moves all its children to the parent of aElement.
+   *
+   * @param aElement            The element to be removed.
+   */
+  nsresult RemoveContainerWithTransaction(Element& aElement);
+
   already_AddRefed<Element> InsertContainerAbove(nsIContent* aNode,
                                                  nsAtom* aNodeType,
                                                  nsAtom* aAttribute = nullptr,
                                                  const nsAString* aValue =
                                                  nullptr);
 
   /**
    * SplitNodeWithTransaction() creates a transaction to create a new node
--- a/editor/libeditor/HTMLAbsPositionEditor.cpp
+++ b/editor/libeditor/HTMLAbsPositionEditor.cpp
@@ -523,17 +523,17 @@ HTMLEditor::SetPositionToStatic(Element&
 
   if (aElement.IsHTMLElement(nsGkAtoms::div) &&
       !HasStyleOrIdOrClass(&aElement)) {
     RefPtr<HTMLEditRules> htmlRules =
       static_cast<HTMLEditRules*>(mRules.get());
     NS_ENSURE_TRUE(htmlRules, NS_ERROR_FAILURE);
     nsresult rv = htmlRules->MakeSureElemStartsOrEndsOnCR(aElement);
     NS_ENSURE_SUCCESS(rv, rv);
-    rv = RemoveContainer(&aElement);
+    rv = RemoveContainerWithTransaction(aElement);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLEditor::SetSnapToGridEnabled(bool aEnabled)
 {
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -3702,17 +3702,17 @@ HTMLEditRules::WillMakeList(Selection* a
   // Ok, now go through all the nodes and put then in the list,
   // or whatever is approriate.  Wohoo!
 
   uint32_t listCount = arrayOfNodes.Length();
   nsCOMPtr<Element> curList, prevListItem;
 
   for (uint32_t i = 0; i < listCount; i++) {
     // here's where we actually figure out what to do
-    nsCOMPtr<Element> newBlock;
+    RefPtr<Element> newBlock;
     NS_ENSURE_STATE(arrayOfNodes[i]->IsContent());
     OwningNonNull<nsIContent> curNode = *arrayOfNodes[i]->AsContent();
 
     // make sure we don't assemble content that is in different table cells
     // into the same list.  respect table cell boundaries when listifying.
     if (curList && InDifferentTableElements(curList, curNode)) {
       curList = nullptr;
     }
@@ -3729,26 +3729,26 @@ HTMLEditRules::WillMakeList(Selection* a
       }
       continue;
     }
 
     if (HTMLEditUtils::IsList(curNode)) {
       // do we have a curList already?
       if (curList && !EditorUtils::IsDescendantOf(*curNode, *curList)) {
         // move all of our children into curList.  cheezy way to do it: move
-        // whole list and then RemoveContainer() on the list.  ConvertListType
-        // first: that routine handles converting the list item types, if
-        // needed
+        // whole list and then RemoveContainerWithTransaction() on the list.
+        // ConvertListType first: that routine handles converting the list
+        // item types, if needed.
         rv = htmlEditor->MoveNode(curNode, curList, -1);
         NS_ENSURE_SUCCESS(rv, rv);
         newBlock = ConvertListType(curNode->AsElement(), listType, itemType);
         if (NS_WARN_IF(!newBlock)) {
           return NS_ERROR_FAILURE;
         }
-        rv = htmlEditor->RemoveBlockContainer(*newBlock);
+        rv = htmlEditor->RemoveBlockContainerWithTransaction(*newBlock);
         NS_ENSURE_SUCCESS(rv, rv);
       } else {
         // replace list with new list type
         curList = ConvertListType(curNode->AsElement(), listType, itemType);
         if (NS_WARN_IF(!curList)) {
           return NS_ERROR_FAILURE;
         }
       }
@@ -3836,17 +3836,17 @@ HTMLEditRules::WillMakeList(Selection* a
     }
 
     // if we hit a div clear our prevListItem, insert divs contents
     // into our node array, and remove the div
     if (curNode->IsHTMLElement(nsGkAtoms::div)) {
       prevListItem = nullptr;
       int32_t j = i + 1;
       GetInnerContent(*curNode, arrayOfNodes, &j);
-      rv = htmlEditor->RemoveContainer(curNode);
+      rv = htmlEditor->RemoveContainerWithTransaction(*curNode->AsElement());
       NS_ENSURE_SUCCESS(rv, rv);
       listCount = arrayOfNodes.Length();
       continue;
     }
 
     // need to make a list to put things in if we haven't already,
     if (!curList) {
       SplitNodeResult splitCurNodeResult =
@@ -4720,18 +4720,21 @@ HTMLEditRules::WillOutdent(Selection& aS
                                   getter_AddRefs(rememberedLeftBQ),
                                   getter_AddRefs(rememberedRightBQ));
           NS_ENSURE_SUCCESS(rv, rv);
           curBlockQuote = nullptr;
           firstBQChild = nullptr;
           lastBQChild = nullptr;
           curBlockQuoteIsIndentedWithCSS = false;
         }
-        rv = htmlEditor->RemoveBlockContainer(curNode);
-        NS_ENSURE_SUCCESS(rv, rv);
+        rv = htmlEditor->RemoveBlockContainerWithTransaction(
+                           *curNode->AsElement());
+        if (NS_WARN_IF(NS_FAILED(rv))) {
+          return rv;
+        }
         continue;
       }
       // Is it a block with a 'margin' property?
       if (useCSS && IsBlockNode(curNode)) {
         nsAtom& marginProperty = MarginPropertyAtomForIndent(curNode);
         nsAutoString value;
         CSSEditUtils::GetSpecifiedProperty(curNode, marginProperty, value);
         float f;
@@ -4823,18 +4826,21 @@ HTMLEditRules::WillOutdent(Selection& aS
       }
 
       if (!curBlockQuote) {
         // Couldn't find enclosing blockquote.  Handle list cases.
         if (HTMLEditUtils::IsList(curParent)) {
           // Move node out of list
           if (HTMLEditUtils::IsList(curNode)) {
             // Just unwrap this sublist
-            rv = htmlEditor->RemoveBlockContainer(curNode);
-            NS_ENSURE_SUCCESS(rv, rv);
+            rv = htmlEditor->RemoveBlockContainerWithTransaction(
+                               *curNode->AsElement());
+            if (NS_WARN_IF(NS_FAILED(rv))) {
+              return rv;
+            }
           }
           // handled list item case above
         } else if (HTMLEditUtils::IsList(curNode)) {
           // node is a list, but parent is non-list: move list items out
           nsCOMPtr<nsIContent> child = curNode->GetLastChild();
           while (child) {
             if (HTMLEditUtils::IsListItem(child)) {
               rv = PopListItem(*child);
@@ -4851,18 +4857,21 @@ HTMLEditRules::WillOutdent(Selection& aS
               rv = htmlEditor->DeleteNodeWithTransaction(*child);
               if (NS_WARN_IF(NS_FAILED(rv))) {
                 return rv;
               }
             }
             child = curNode->GetLastChild();
           }
           // Delete the now-empty list
-          rv = htmlEditor->RemoveBlockContainer(curNode);
-          NS_ENSURE_SUCCESS(rv, rv);
+          rv = htmlEditor->RemoveBlockContainerWithTransaction(
+                             *curNode->AsElement());
+          if (NS_WARN_IF(NS_FAILED(rv))) {
+            return rv;
+          }
         } else if (useCSS) {
           nsCOMPtr<Element> element;
           if (curNode->GetAsText()) {
             // We want to outdent the parent of text nodes
             element = curNode->GetParentElement();
           } else if (curNode->IsElement()) {
             element = curNode->AsElement();
           }
@@ -4921,17 +4930,17 @@ nsresult
 HTMLEditRules::RemovePartOfBlock(Element& aBlock,
                                  nsIContent& aStartChild,
                                  nsIContent& aEndChild)
 {
   SplitBlock(aBlock, aStartChild, aEndChild);
   // Get rid of part of blockquote we are outdenting
 
   NS_ENSURE_STATE(mHTMLEditor);
-  nsresult rv = mHTMLEditor->RemoveBlockContainer(aBlock);
+  nsresult rv = mHTMLEditor->RemoveBlockContainerWithTransaction(aBlock);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 void
 HTMLEditRules::SplitBlock(Element& aBlock,
                           nsIContent& aStartChild,
@@ -4992,21 +5001,25 @@ HTMLEditRules::OutdentPartOfBlock(Elemen
                                   nsIContent** aOutRightNode)
 {
   MOZ_ASSERT(aOutLeftNode && aOutRightNode);
 
   nsCOMPtr<nsIContent> middleNode;
   SplitBlock(aBlock, aStartChild, aEndChild, aOutLeftNode, aOutRightNode,
              getter_AddRefs(middleNode));
 
-  NS_ENSURE_STATE(middleNode);
+  if (NS_WARN_IF(!middleNode) || NS_WARN_IF(!middleNode->IsElement())) {
+    return NS_ERROR_FAILURE;
+  }
 
   if (!aIsBlockIndentedWithCSS) {
     NS_ENSURE_STATE(mHTMLEditor);
-    nsresult rv = mHTMLEditor->RemoveBlockContainer(*middleNode);
+    nsresult rv =
+      mHTMLEditor->RemoveBlockContainerWithTransaction(
+                     *middleNode->AsElement());
     NS_ENSURE_SUCCESS(rv, rv);
   } else if (middleNode->IsElement()) {
     // We do nothing if middleNode isn't an element
     nsresult rv = ChangeIndentation(*middleNode->AsElement(), Change::minus);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
@@ -7648,17 +7661,18 @@ HTMLEditRules::RemoveBlockStyle(nsTArray
         nsresult rv = RemovePartOfBlock(*curBlock, *firstNode, *lastNode);
         NS_ENSURE_SUCCESS(rv, rv);
         firstNode = lastNode = curBlock = nullptr;
       }
       if (!mHTMLEditor->IsEditable(curNode)) {
         continue;
       }
       // Remove current block
-      nsresult rv = htmlEditor->RemoveBlockContainer(*curNode->AsContent());
+      nsresult rv =
+        htmlEditor->RemoveBlockContainerWithTransaction(*curNode->AsElement());
       NS_ENSURE_SUCCESS(rv, rv);
     } else if (curNode->IsAnyOfHTMLElements(nsGkAtoms::table,
                                             nsGkAtoms::tr,
                                             nsGkAtoms::tbody,
                                             nsGkAtoms::td,
                                             nsGkAtoms::li,
                                             nsGkAtoms::blockquote,
                                             nsGkAtoms::div) ||
@@ -8881,17 +8895,18 @@ HTMLEditRules::PopListItem(nsIContent& a
     mHTMLEditor->MoveNode(&aListItem, pointToInsertListItem.GetContainer(),
                           pointToInsertListItem.Offset());
   NS_ENSURE_SUCCESS(rv, rv);
 
   // unwrap list item contents if they are no longer in a list
   if (!HTMLEditUtils::IsList(pointToInsertListItem.GetContainer()) &&
       HTMLEditUtils::IsListItem(&aListItem)) {
     NS_ENSURE_STATE(mHTMLEditor);
-    rv = mHTMLEditor->RemoveBlockContainer(*aListItem.AsElement());
+    rv = mHTMLEditor->RemoveBlockContainerWithTransaction(
+                        *aListItem.AsElement());
     NS_ENSURE_SUCCESS(rv, rv);
     if (aOutOfList) {
       *aOutOfList = true;
     }
   }
   return NS_OK;
 }
 
@@ -8918,17 +8933,17 @@ HTMLEditRules::RemoveListStructure(Eleme
       nsresult rv = htmlEditor->DeleteNodeWithTransaction(*child);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     }
   }
 
   // Delete the now-empty list
-  nsresult rv = htmlEditor->RemoveBlockContainer(aList);
+  nsresult rv = htmlEditor->RemoveBlockContainerWithTransaction(aList);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 // XXX This method is not necessary because even if selection is outside the
 //     <body> element, the element can be editable.
 nsresult
@@ -9270,17 +9285,17 @@ HTMLEditRules::RemoveAlignment(nsINode& 
 
       // we may have to insert BRs in first and last position of element's children
       // if the nodes before/after are not blocks and not BRs
       rv = MakeSureElemStartsOrEndsOnCR(*child);
       NS_ENSURE_SUCCESS(rv, rv);
 
       // now remove the CENTER container
       NS_ENSURE_STATE(mHTMLEditor);
-      rv = mHTMLEditor->RemoveContainer(child->AsElement());
+      rv = mHTMLEditor->RemoveContainerWithTransaction(*child->AsElement());
       NS_ENSURE_SUCCESS(rv, rv);
     } else if (IsBlockNode(*child) || child->IsHTMLElement(nsGkAtoms::hr)) {
       // the current node is a block element
       if (HTMLEditUtils::SupportsAlignAttr(*child)) {
         // remove the ALIGN attribute if this element can have it
         NS_ENSURE_STATE(mHTMLEditor);
         nsresult rv =
           mHTMLEditor->RemoveAttributeWithTransaction(*child->AsElement(),
@@ -9466,17 +9481,17 @@ HTMLEditRules::ChangeIndentation(Element
   // Remove unnecessary divs
   if (!aElement.IsHTMLElement(nsGkAtoms::div) ||
       &aElement == htmlEditor->GetActiveEditingHost() ||
       !htmlEditor->IsDescendantOfEditorRoot(&aElement) ||
       HTMLEditor::HasAttributes(&aElement)) {
     return NS_OK;
   }
 
-  nsresult rv = htmlEditor->RemoveContainer(&aElement);
+  nsresult rv = htmlEditor->RemoveContainerWithTransaction(aElement);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 nsresult
 HTMLEditRules::WillAbsolutePosition(Selection& aSelection,
                                     bool* aCancel,
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -3737,91 +3737,92 @@ HTMLEditor::SetSelectionAtDocumentStart(
   return aSelection->Collapse(rootElement, 0);
 }
 
 /**
  * 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::RemoveBlockContainer(nsIContent& aNode)
+HTMLEditor::RemoveBlockContainerWithTransaction(Element& aElement)
 {
   // 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.
 
-  nsCOMPtr<nsIContent> child = GetFirstEditableChild(aNode);
+  nsCOMPtr<nsIContent> child = GetFirstEditableChild(aElement);
 
   if (child) {
     // The case of aNode not being empty.  We need a br at start unless:
     // 1) previous sibling of aNode is a block, OR
     // 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(&aNode);
+    nsCOMPtr<nsIContent> sibling = GetPriorHTMLSibling(&aElement);
     if (sibling && !IsBlockNode(sibling) &&
         !sibling->IsHTMLElement(nsGkAtoms::br) && !IsBlockNode(child)) {
       // Insert br node
-      RefPtr<Element> brElement = CreateBR(EditorRawDOMPoint(&aNode, 0));
+      RefPtr<Element> brElement = CreateBR(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
     // 3) last child of aNode is a br OR
     // 4) either is null
 
-    sibling = GetNextHTMLSibling(&aNode);
+    sibling = GetNextHTMLSibling(&aElement);
     if (sibling && !IsBlockNode(sibling)) {
-      child = GetLastEditableChild(aNode);
+      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(&aNode);
+        endOfNode.SetToEndOf(&aElement);
         RefPtr<Element> brElement = CreateBR(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
     // 2) previous sibling of aNode is a br, OR
     // 3) following sibling of aNode is a block, OR
     // 4) following sibling of aNode is a br OR
     // 5) either is null
-    nsCOMPtr<nsIContent> sibling = GetPriorHTMLSibling(&aNode);
+    nsCOMPtr<nsIContent> sibling = GetPriorHTMLSibling(&aElement);
     if (sibling && !IsBlockNode(sibling) &&
         !sibling->IsHTMLElement(nsGkAtoms::br)) {
-      sibling = GetNextHTMLSibling(&aNode);
+      sibling = GetNextHTMLSibling(&aElement);
       if (sibling && !IsBlockNode(sibling) &&
           !sibling->IsHTMLElement(nsGkAtoms::br)) {
         // Insert br node
-        RefPtr<Element> brElement = CreateBR(EditorRawDOMPoint(&aNode, 0));
+        RefPtr<Element> brElement = CreateBR(EditorRawDOMPoint(&aElement, 0));
         if (NS_WARN_IF(!brElement)) {
           return NS_ERROR_FAILURE;
         }
       }
     }
   }
 
   // Now remove container
-  nsresult rv = RemoveContainer(&aNode);
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  nsresult rv = RemoveContainerWithTransaction(aElement);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
   return NS_OK;
 }
 
 /**
  * GetPriorHTMLSibling() returns the previous editable sibling, if there is
  * one within the parent.
  */
 nsIContent*
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -941,17 +941,25 @@ protected:
                              nsAtom* aAttribute,
                              const bool aChildrenOnly = false);
 
   bool NodeIsProperty(nsINode& aNode);
   bool IsAtFrontOfNode(nsINode& aNode, int32_t aOffset);
   bool IsAtEndOfNode(nsINode& aNode, int32_t aOffset);
   bool IsOnlyAttribute(const Element* aElement, nsAtom* aAttribute);
 
-  nsresult RemoveBlockContainer(nsIContent& aNode);
+  /**
+   * RemoveBlockContainerWithTransaction() removes aElement from the DOM tree
+   * but moves its all children to its parent node and if its parent needs <br>
+   * element to have at least one line-height, this inserts <br> element
+   * automatically.
+   *
+   * @param aElement            Block element to be removed.
+   */
+  nsresult RemoveBlockContainerWithTransaction(Element& aElement);
 
   nsIContent* GetPriorHTMLSibling(nsINode* aNode);
 
   nsIContent* GetNextHTMLSibling(nsINode* aNode);
 
   /**
    * GetPreviousHTMLElementOrText*() methods are similar to
    * EditorBase::GetPreviousElementOrText*() but this won't return nodes
--- a/editor/libeditor/HTMLStyleEditor.cpp
+++ b/editor/libeditor/HTMLStyleEditor.cpp
@@ -684,17 +684,17 @@ HTMLEditor::NodeIsProperty(nsINode& aNod
 }
 
 nsresult
 HTMLEditor::RemoveStyleInside(nsIContent& aNode,
                               nsAtom* aProperty,
                               nsAtom* aAttribute,
                               const bool aChildrenOnly /* = false */)
 {
-  if (aNode.GetAsText()) {
+  if (!aNode.IsElement()) {
     return NS_OK;
   }
 
   // first process the children
   RefPtr<nsIContent> child = aNode.GetFirstChild();
   while (child) {
     // cache next sibling since we might remove child
     nsCOMPtr<nsIContent> next = child->GetNextSibling();
@@ -712,20 +712,18 @@ HTMLEditor::RemoveStyleInside(nsIContent
        // and for named anchors
        (aProperty == nsGkAtoms::name && HTMLEditUtils::IsNamedAnchor(&aNode)) ||
        // or node is any prop and we asked for that
        (!aProperty && NodeIsProperty(aNode)))) {
     // if we weren't passed an attribute, then we want to
     // remove any matching inlinestyles entirely
     if (!aAttribute) {
       bool hasStyleAttr =
-        aNode.IsElement() &&
         aNode.AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::style);
       bool hasClassAttr =
-        aNode.IsElement() &&
         aNode.AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::_class);
       if (aProperty && (hasStyleAttr || hasClassAttr)) {
         // aNode carries inline styles or a class attribute so we can't
         // just remove the element... We need to create above the element
         // a span that will carry those styles or class, then we can delete
         // the node.
         RefPtr<Element> spanNode =
           InsertContainerAbove(&aNode, nsGkAtoms::span);
@@ -739,25 +737,25 @@ HTMLEditor::RemoveStyleInside(nsIContent
           return rv;
         }
         rv = CloneAttributeWithTransaction(*nsGkAtoms::_class, *spanNode,
                                            *aNode.AsElement());
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
       }
-      nsresult rv = RemoveContainer(&aNode);
+      nsresult rv = RemoveContainerWithTransaction(*aNode.AsElement());
       NS_ENSURE_SUCCESS(rv, rv);
     } else if (aNode.IsElement()) {
       // otherwise we just want to eliminate the attribute
       if (aNode.AsElement()->HasAttr(kNameSpaceID_None, aAttribute)) {
         // if this matching attribute is the ONLY one on the node,
         // then remove the whole node.  Otherwise just nix the attribute.
         if (IsOnlyAttribute(aNode.AsElement(), aAttribute)) {
-          nsresult rv = RemoveContainer(&aNode);
+          nsresult rv = RemoveContainerWithTransaction(*aNode.AsElement());
           if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
           }
         } else {
           nsresult rv =
             RemoveAttributeWithTransaction(*aNode.AsElement(), *aAttribute);
           if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
@@ -797,17 +795,17 @@ HTMLEditor::RemoveStyleInside(nsIContent
   if (aChildrenOnly) {
     return NS_OK;
   }
   if (aProperty == nsGkAtoms::font &&
       (aNode.IsHTMLElement(nsGkAtoms::big) ||
        aNode.IsHTMLElement(nsGkAtoms::small)) &&
       aAttribute == nsGkAtoms::size) {
     // if we are setting font size, remove any nested bigs and smalls
-    return RemoveContainer(&aNode);
+    return RemoveContainerWithTransaction(*aNode.AsElement());
   }
   return NS_OK;
 }
 
 bool
 HTMLEditor::IsOnlyAttribute(const Element* aElement,
                             nsAtom* aAttribute)
 {
@@ -1595,17 +1593,17 @@ HTMLEditor::RelativeFontChangeOnNode(int
 
   // Is it the opposite of what we want?
   if ((aSizeChange == 1 && aNode->IsHTMLElement(nsGkAtoms::small)) ||
        (aSizeChange == -1 && aNode->IsHTMLElement(nsGkAtoms::big))) {
     // first populate any nested font tags that have the size attr set
     nsresult rv = RelativeFontChangeHelper(aSizeChange, aNode);
     NS_ENSURE_SUCCESS(rv, rv);
     // in that case, just remove this node and pull up the children
-    return RemoveContainer(aNode);
+    return RemoveContainerWithTransaction(*aNode->AsElement());
   }
 
   // can it be put inside a "big" or "small"?
   if (TagCanContain(*atom, *aNode)) {
     // first populate any nested font tags that have the size attr set
     nsresult rv = RelativeFontChangeHelper(aSizeChange, aNode);
     NS_ENSURE_SUCCESS(rv, rv);
 
@@ -1758,12 +1756,12 @@ HTMLEditor::RemoveElementIfNoStyleOrIdOr
 {
   // early way out if node is not the right kind of element
   if ((!aElement.IsHTMLElement(nsGkAtoms::span) &&
        !aElement.IsHTMLElement(nsGkAtoms::font)) ||
       HasStyleOrIdOrClass(&aElement)) {
     return NS_OK;
   }
 
-  return RemoveContainer(&aElement);
+  return RemoveContainerWithTransaction(aElement);
 }
 
 } // namespace mozilla