Bug 1460509 - part 36: Make HTMLEditRules::RemoveBlockStyle() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 15 May 2018 00:43:07 +0900
changeset 798754 b6d111b1f3d4eae47fb96f3b00bbd3f91af8413c
parent 798753 f94116dd9e963c971e6b9bc9027188fa4646f6d6
child 798755 2593bf4ba86d0d8e489019c223cf509e8c9bde41
push id110840
push usermasayuki@d-toybox.com
push dateWed, 23 May 2018 13:41:58 +0000
reviewersm_kato
bugs1460509
milestone62.0a1
Bug 1460509 - part 36: Make HTMLEditRules::RemoveBlockStyle() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato MozReview-Commit-ID: KDfxeD9k0UN
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditRules.h
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -8044,58 +8044,62 @@ HTMLEditRules::MakeBlockquote(nsTArray<O
                                                    *curBlock);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
   return NS_OK;
 }
 
-/**
- * RemoveBlockStyle() makes the nodes have no special block type.
- */
 nsresult
 HTMLEditRules::RemoveBlockStyle(nsTArray<OwningNonNull<nsINode>>& aNodeArray)
 {
   MOZ_ASSERT(IsEditorDataAvailable());
 
   // Intent of this routine is to be used for converting to/from headers,
   // paragraphs, pre, and address.  Those blocks that pretty much just contain
   // inline things...
   nsCOMPtr<Element> curBlock;
   nsCOMPtr<nsIContent> firstNode, lastNode;
   for (auto& curNode : aNodeArray) {
-    // If curNode is a address, p, header, address, or pre, remove it
+    // If curNode is an <address>, <p>, <hn>, or <pre>, remove it.
     if (HTMLEditUtils::IsFormatNode(curNode)) {
       // Process any partial progress saved
       if (curBlock) {
         nsresult rv = RemovePartOfBlock(*curBlock, *firstNode, *lastNode);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
         firstNode = lastNode = curBlock = nullptr;
       }
       if (!HTMLEditorRef().IsEditable(curNode)) {
         continue;
       }
       // Remove current block
       nsresult rv =
         HTMLEditorRef().RemoveBlockContainerWithTransaction(
                           *curNode->AsElement());
+      if (NS_WARN_IF(!CanHandleEditAction())) {
+        return NS_ERROR_EDITOR_DESTROYED;
+      }
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
-    } else if (curNode->IsAnyOfHTMLElements(nsGkAtoms::table,
-                                            nsGkAtoms::tr,
-                                            nsGkAtoms::tbody,
-                                            nsGkAtoms::td,
-                                            nsGkAtoms::li,
-                                            nsGkAtoms::blockquote,
-                                            nsGkAtoms::div) ||
-                HTMLEditUtils::IsList(curNode)) {
+      continue;
+    }
+
+    // XXX How about, <th>, <thead>, <tfoot>, <dt>, <dl>?
+    if (curNode->IsAnyOfHTMLElements(nsGkAtoms::table,
+                                     nsGkAtoms::tr,
+                                     nsGkAtoms::tbody,
+                                     nsGkAtoms::td,
+                                     nsGkAtoms::li,
+                                     nsGkAtoms::blockquote,
+                                     nsGkAtoms::div) ||
+        HTMLEditUtils::IsList(curNode)) {
       // Process any partial progress saved
       if (curBlock) {
         nsresult rv = RemovePartOfBlock(*curBlock, *firstNode, *lastNode);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
         firstNode = lastNode = curBlock = nullptr;
       }
@@ -8104,17 +8108,20 @@ HTMLEditRules::RemoveBlockStyle(nsTArray
       }
       // Recursion time
       nsTArray<OwningNonNull<nsINode>> childArray;
       GetChildNodesForOperation(*curNode, childArray);
       nsresult rv = RemoveBlockStyle(childArray);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
-    } else if (IsInlineNode(curNode)) {
+      continue;
+    }
+
+    if (IsInlineNode(curNode)) {
       if (curBlock) {
         // If so, is this node a descendant?
         if (EditorUtils::IsDescendantOf(*curNode, *curBlock)) {
           // Then we don't need to do anything different for this node
           lastNode = curNode->AsContent();
           continue;
         }
         // Otherwise, we have progressed beyond end of curBlock, so let's
@@ -8130,24 +8137,28 @@ HTMLEditRules::RemoveBlockStyle(nsTArray
       curBlock = HTMLEditorRef().GetBlockNodeParent(curNode);
       if (!curBlock || !HTMLEditUtils::IsFormatNode(curBlock) ||
           !HTMLEditorRef().IsEditable(curBlock)) {
         // Not a block kind that we care about.
         curBlock = nullptr;
       } else {
         firstNode = lastNode = curNode->AsContent();
       }
-    } else if (curBlock) {
+      continue;
+    }
+
+    if (curBlock) {
       // Some node that is already sans block style.  Skip over it and process
       // any partial progress saved.
       nsresult rv = RemovePartOfBlock(*curBlock, *firstNode, *lastNode);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
       firstNode = lastNode = curBlock = nullptr;
+      continue;
     }
   }
   // Process any partial progress saved
   if (curBlock) {
     nsresult rv = RemovePartOfBlock(*curBlock, *firstNode, *lastNode);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -482,16 +482,25 @@ protected:
   /**
    * GetHiestInlineParent() returns the highest inline node parent between
    * aNode and the editing host.  Even if the editing host is an inline
    * element, this method never returns the editing host as the result.
    */
   nsIContent* GetHighestInlineParent(nsINode& aNode);
   void MakeTransitionList(nsTArray<OwningNonNull<nsINode>>& aNodeArray,
                           nsTArray<bool>& aTransitionArray);
+
+  /**
+   * RemoveBlockStyle() removes all format blocks, table related element,
+   * etc in aNodeArray.
+   * If aNodeArray has a format node, it will be removed and its contents
+   * will be moved to where it was.
+   * If aNodeArray has a table related element, <li>, <blockquote> or <div>,
+   * it will removed and its contents will be moved to where it was.
+   */
   nsresult RemoveBlockStyle(nsTArray<OwningNonNull<nsINode>>& aNodeArray);
 
   /**
    * ApplyBlockStyle() formats all nodes in aNodeArray with block elements
    * whose name is aBlockTag.
    * If aNodeArray has an inline element, a block element is created and the
    * inline element and following inline elements are moved into the new block
    * element.