Bug 1359396 - Redesign HTMLEditRules::IsEmptyBlock() r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 20 Dec 2017 22:25:12 +0900
changeset 449027 39bcda54a789453e8e018f2dd6ccfd4f70ce204b
parent 449026 2a84ee8f73414ef95ab094cf7fe928971289a3f1
child 449028 38d0846ab899566e513c24014f47645e914b47f1
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1359396
milestone59.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 1359396 - Redesign HTMLEditRules::IsEmptyBlock() r=m_kato HTMLEditRules::IsEmptyBlock() won't return error in most cases. Additionally, HTMLEditRules::WillInsertBreak() doesn't check it. So, just returning bool is simpler. MozReview-Commit-ID: 5DfRv7lIyuS
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditRules.h
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -1776,19 +1776,17 @@ HTMLEditRules::WillInsertBreak(Selection
       return NS_OK;
     }
   }
 
   // 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.)
-  bool isEmpty;
-  IsEmptyBlock(*blockParent, &isEmpty);
-  if (isEmpty) {
+  if (IsEmptyBlockElement(*blockParent, IgnoreSingleBR::eNo)) {
     AutoEditorDOMPointChildInvalidator lockOffset(atStartOfSelection);
     EditorRawDOMPoint endOfBlockParent;
     endOfBlockParent.SetToEndOf(blockParent);
     RefPtr<Element> br = htmlEditor->CreateBR(endOfBlockParent);
     NS_ENSURE_STATE(br);
   }
 
   nsCOMPtr<Element> listItem = IsInListItem(blockParent);
@@ -4981,37 +4979,32 @@ HTMLEditRules::CreateStyleForInsertText(
   }
   if (weDidSomething) {
     return aSelection.Collapse(node, offset);
   }
 
   return NS_OK;
 }
 
-
-/**
- * Figure out if aNode is (or is inside) an empty block.  A block can have
- * children and still be considered empty, if the children are empty or
- * non-editable.
- */
-nsresult
-HTMLEditRules::IsEmptyBlock(Element& aNode,
-                            bool* aOutIsEmptyBlock,
-                            MozBRCounts aMozBRCounts)
-{
-  MOZ_ASSERT(aOutIsEmptyBlock);
-  *aOutIsEmptyBlock = true;
-
-  NS_ENSURE_TRUE(IsBlockNode(aNode), NS_ERROR_NULL_POINTER);
-
-  return mHTMLEditor->IsEmptyNode(aNode.AsDOMNode(), aOutIsEmptyBlock,
-                                  aMozBRCounts == MozBRCounts::yes ? false
-                                                                   : true);
-}
-
+bool
+HTMLEditRules::IsEmptyBlockElement(Element& aElement,
+                                   IgnoreSingleBR aIgnoreSingleBR)
+{
+  if (NS_WARN_IF(!IsBlockNode(aElement))) {
+    return false;
+  }
+  bool isEmpty = true;
+  nsresult rv =
+    mHTMLEditor->IsEmptyNode(&aElement, &isEmpty,
+                             aIgnoreSingleBR == IgnoreSingleBR::eYes);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return false;
+  }
+  return isEmpty;
+}
 
 nsresult
 HTMLEditRules::WillAlign(Selection& aSelection,
                          const nsAString& aAlignType,
                          bool* aCancel,
                          bool* aHandled)
 {
   MOZ_ASSERT(aCancel && aHandled);
@@ -6821,20 +6814,17 @@ HTMLEditRules::ReturnInHeader(Selection&
       RefPtr<Element> brElement = CreateMozBR(EditorRawDOMPoint(prevItem, 0));
       if (NS_WARN_IF(!brElement)) {
         return NS_ERROR_FAILURE;
       }
     }
   }
 
   // If the new (righthand) header node is empty, delete it
-  bool isEmpty;
-  rv = IsEmptyBlock(aHeader, &isEmpty, MozBRCounts::no);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (isEmpty) {
+  if (IsEmptyBlockElement(aHeader, IgnoreSingleBR::eYes)) {
     rv = htmlEditor->DeleteNode(&aHeader);
     NS_ENSURE_SUCCESS(rv, rv);
     // Layout tells the caret to blink in a weird place if we don't place a
     // break after the header.
     nsCOMPtr<nsIContent> sibling;
     if (aHeader.GetNextSibling()) {
       sibling = htmlEditor->GetNextHTMLSibling(aHeader.GetNextSibling());
     }
@@ -7104,21 +7094,19 @@ HTMLEditRules::ReturnInListItem(Selectio
   RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
 
   // Get the item parent and the active editing host.
   nsCOMPtr<Element> root = htmlEditor->GetActiveEditingHost();
 
   // If we are in an empty item, then we want to pop up out of the list, but
   // only if prefs say it's okay and if the parent isn't the active editing
   // host.
-  bool isEmpty;
-  nsresult rv = IsEmptyBlock(aListItem, &isEmpty, MozBRCounts::no);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (isEmpty && root != aListItem.GetParentElement() &&
-      mReturnInEmptyLIKillsList) {
+  if (mReturnInEmptyLIKillsList &&
+      root != aListItem.GetParentElement() &&
+      IsEmptyBlockElement(aListItem, IgnoreSingleBR::eYes)) {
     nsCOMPtr<nsIContent> leftListNode = aListItem.GetParent();
     // Are we the last list item in the list?
     if (!htmlEditor->IsLastEditableChild(&aListItem)) {
       // We need to split the list!
       EditorRawDOMPoint atListItem(&aListItem);
       ErrorResult error;
       leftListNode = htmlEditor->SplitNode(atListItem, error);
       if (NS_WARN_IF(error.Failed())) {
@@ -7128,25 +7116,26 @@ HTMLEditRules::ReturnInListItem(Selectio
 
     // Are we in a sublist?
     EditorRawDOMPoint atNextSiblingOfLeftList(leftListNode);
     DebugOnly<bool> advanced = atNextSiblingOfLeftList.AdvanceOffset();
     NS_WARNING_ASSERTION(advanced,
       "Failed to advance offset after the right list node");
     if (HTMLEditUtils::IsList(atNextSiblingOfLeftList.GetContainer())) {
       // If so, move item out of this list and into the grandparent list
-      rv = htmlEditor->MoveNode(&aListItem,
-                                atNextSiblingOfLeftList.GetContainer(),
-                                atNextSiblingOfLeftList.Offset());
+      nsresult rv =
+        htmlEditor->MoveNode(&aListItem,
+                             atNextSiblingOfLeftList.GetContainer(),
+                             atNextSiblingOfLeftList.Offset());
       NS_ENSURE_SUCCESS(rv, rv);
       rv = aSelection.Collapse(&aListItem, 0);
       NS_ENSURE_SUCCESS(rv, rv);
     } else {
       // Otherwise kill this item
-      rv = htmlEditor->DeleteNode(&aListItem);
+      nsresult rv = htmlEditor->DeleteNode(&aListItem);
       NS_ENSURE_SUCCESS(rv, rv);
 
       // Time to insert a paragraph
       nsAtom& paraAtom = DefaultParagraphSeparator();
       // We want a wrapper even if we separate with <br>
       RefPtr<Element> pNode =
         htmlEditor->CreateNode(&paraAtom == nsGkAtoms::br ?
                                  nsGkAtoms::p : &paraAtom,
@@ -7168,18 +7157,19 @@ HTMLEditRules::ReturnInListItem(Selectio
       }
     }
     return NS_OK;
   }
 
   // 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);
+  nsresult rv =
+    WSRunObject::PrepareToSplitAcrossBlocks(htmlEditor,
+                                            address_of(selNode), &aOffset);
   NS_ENSURE_SUCCESS(rv, rv);
   if (NS_WARN_IF(!selNode->IsContent())) {
     return NS_ERROR_FAILURE;
   }
 
   // Now split the list item.
   SplitNodeResult splitListItemResult =
     htmlEditor->SplitNodeDeep(aListItem, EditorRawDOMPoint(selNode, aOffset),
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -356,19 +356,29 @@ protected:
                               bool aIsBlockIndentedWithCSS,
                               nsIContent** aOutLeftNode,
                               nsIContent** aOutRightNode);
 
   already_AddRefed<Element> ConvertListType(Element* aList, nsAtom* aListType,
                                             nsAtom* aItemType);
 
   nsresult CreateStyleForInsertText(Selection& aSelection, nsIDocument& aDoc);
-  enum class MozBRCounts { yes, no };
-  nsresult IsEmptyBlock(Element& aNode, bool* aOutIsEmptyBlock,
-                        MozBRCounts aMozBRCounts = MozBRCounts::yes);
+
+  /**
+   * IsEmptyBlockElement() returns true if aElement is a block level element
+   * and it doesn't have any visible content.
+   */
+  enum class IgnoreSingleBR
+  {
+    eYes,
+    eNo
+  };
+  bool IsEmptyBlockElement(Element& aElement,
+                           IgnoreSingleBR aIgnoreSingleBR);
+
   nsresult CheckForEmptyBlock(nsINode* aStartNode, Element* aBodyNode,
                               Selection* aSelection,
                               nsIEditor::EDirection aAction, bool* aHandled);
   enum class BRLocation { beforeBlock, blockEnd };
   Element* CheckForInvisibleBR(Element& aBlock, BRLocation aWhere,
                                int32_t aOffset = 0);
   nsresult ExpandSelectionForDeletion(Selection& aSelection);
   bool IsFirstNode(nsIDOMNode* aNode);