Bug 1460509 - part 49: Make HTMLEditRules::SplitMailCites() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 16 May 2018 01:30:44 +0900
changeset 798767 635141382655a9adfa90161da1c6ce32b428d582
parent 798766 cbe591df0fc84b8ea8024f018da458a55008bd6b
child 798768 4b8964cc9f1759bbdff80dda48bfde1817697c33
push id110840
push usermasayuki@d-toybox.com
push dateWed, 23 May 2018 13:41:58 +0000
reviewersm_kato
bugs1460509
milestone62.0a1
Bug 1460509 - part 49: Make HTMLEditRules::SplitMailCites() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato MozReview-Commit-ID: 1Jy6bHAmtkT
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditRules.h
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -2185,16 +2185,19 @@ HTMLEditRules::SplitMailCites(bool* aHan
   if (NS_WARN_IF(!pointToSplit.GetContainerAsContent())) {
     return NS_ERROR_FAILURE;
   }
 
   SplitNodeResult splitCiteNodeResult =
     HTMLEditorRef().SplitNodeDeepWithTransaction(
                       *citeNode, pointToSplit,
                       SplitAtEdges::eDoNotCreateEmptyContainer);
+  if (NS_WARN_IF(!CanHandleEditAction())) {
+    return NS_ERROR_EDITOR_DESTROYED;
+  }
   if (NS_WARN_IF(splitCiteNodeResult.Failed())) {
     return splitCiteNodeResult.Rv();
   }
   pointToSplit.Clear();
 
   // Add an invisible <br> to the end of current cite node (If new left cite
   // has not been created, we're at the end of it.  Otherwise, we're still at
   // the right node) if it was a <span> of style="display: block". This is
@@ -2215,43 +2218,53 @@ HTMLEditRules::SplitMailCites(bool* aHan
     if (lastChild && !lastChild->IsHTMLElement(nsGkAtoms::br)) {
       // We ignore the result here.
       EditorRawDOMPoint endOfPreviousNodeOfSplitPoint;
       endOfPreviousNodeOfSplitPoint.SetToEndOf(previousNodeOfSplitPoint);
       RefPtr<Element> invisibleBrElement =
         HTMLEditorRef().InsertBrElementWithTransaction(
                           SelectionRef(),
                           endOfPreviousNodeOfSplitPoint);
+      if (NS_WARN_IF(!CanHandleEditAction())) {
+        return NS_ERROR_EDITOR_DESTROYED;
+      }
       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> brElement =
     HTMLEditorRef().InsertBrElementWithTransaction(SelectionRef(),
                                                    pointToInsertBrNode);
+  if (NS_WARN_IF(!CanHandleEditAction())) {
+    return NS_ERROR_EDITOR_DESTROYED;
+  }
   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(brElement);
   Unused << atBrNode.Offset(); // Needs offset after collapsing the selection.
   ErrorResult error;
   SelectionRef().SetInterlinePosition(true, error);
   NS_WARNING_ASSERTION(!error.Failed(),
     "Failed to set interline position");
   error = NS_OK;
   SelectionRef().Collapse(atBrNode, error);
+  if (NS_WARN_IF(!CanHandleEditAction())) {
+    error.SuppressException();
+    return NS_ERROR_EDITOR_DESTROYED;
+  }
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
   // if citeNode wasn't a block, we might also want another break before it.
   // We need to examine the content both before the br we just added and also
   // just after it.  If we don't have another br or block boundary adjacent,
   // then we will need a 2nd br added to achieve blank line that user expects.
@@ -2277,16 +2290,19 @@ HTMLEditRules::SplitMailCites(bool* aHan
                                    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) {
         brElement =
           HTMLEditorRef().InsertBrElementWithTransaction(
                             SelectionRef(), pointToCreateNewBrNode);
+        if (NS_WARN_IF(!CanHandleEditAction())) {
+          return NS_ERROR_EDITOR_DESTROYED;
+        }
         if (NS_WARN_IF(!brElement)) {
           return NS_ERROR_FAILURE;
         }
         // Now, those points may be invalid.
         pointToCreateNewBrNode.Clear();
         pointAfterNewBrNode.Clear();
       }
     }
@@ -2298,30 +2314,36 @@ HTMLEditRules::SplitMailCites(bool* aHan
     nsresult rv =
       HTMLEditorRef().IsEmptyNode(previousNodeOfSplitPoint, &bEmptyCite,
                                   true, false);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
     if (bEmptyCite) {
       rv = HTMLEditorRef().DeleteNodeWithTransaction(*previousNodeOfSplitPoint);
+      if (NS_WARN_IF(!CanHandleEditAction())) {
+        return NS_ERROR_EDITOR_DESTROYED;
+      }
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     }
   }
 
   if (citeNode) {
     nsresult rv =
       HTMLEditorRef().IsEmptyNode(citeNode, &bEmptyCite, true, false);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
     if (bEmptyCite) {
       rv = HTMLEditorRef().DeleteNodeWithTransaction(*citeNode);
+      if (NS_WARN_IF(!CanHandleEditAction())) {
+        return NS_ERROR_EDITOR_DESTROYED;
+      }
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     }
   }
 
   *aHandled = true;
   return NS_OK;
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -165,17 +165,27 @@ protected:
   /**
    * InsertBRElement() inserts a <br> element into aInsertToBreak.
    *
    * @param aInsertToBreak      The point where new <br> element will be
    *                            inserted before.
    */
   nsresult InsertBRElement(const EditorDOMPoint& aInsertToBreak);
 
-  nsresult SplitMailCites(bool* aHandled);
+  /**
+   * SplitMailCites() splits mail-cite elements at start of Selection if
+   * Selection starts from inside a mail-cite element.  Of course, if it's
+   * necessary, this inserts <br> node to new left nodes or existing right
+   * nodes.
+   *
+   * @param aHandled            Returns true if succeeded to split mail-cite
+   *                            elements.
+   */
+  MOZ_MUST_USE nsresult SplitMailCites(bool* aHandled);
+
   nsresult WillDeleteSelection(nsIEditor::EDirection aAction,
                                nsIEditor::EStripWrappers aStripWrappers,
                                bool* aCancel, bool* aHandled);
   nsresult DidDeleteSelection(nsIEditor::EDirection aDir,
                               nsresult aResult);
   nsresult InsertBRIfNeeded();
 
   /**