Bug 1460509 - part 27: Make HTMLEditRules::PinSelectionToNewBlock() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 14 May 2018 22:37:33 +0900
changeset 798745 6995f85de581a856cccf1d73df1b6eba2602a7b7
parent 798744 cd0a5bf636e7703a9cf541189834f1367e4d6932
child 798746 b8fbae3ccecd66392b37df3b750a56c789f2f5bf
push id110840
push usermasayuki@d-toybox.com
push dateWed, 23 May 2018 13:41:58 +0000
reviewersm_kato
bugs1460509
milestone62.0a1
Bug 1460509 - part 27: Make HTMLEditRules::PinSelectionToNewBlock() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato MozReview-Commit-ID: GW0xI5BBxqU
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditRules.h
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -552,16 +552,19 @@ HTMLEditRules::AfterEditInner(EditAction
         WSRunObject(&HTMLEditorRef(), mRangeItem->mEndContainer,
                     mRangeItem->mEndOffset).AdjustWhitespace();
       }
     }
 
     // if we created a new block, make sure selection lands in it
     if (mNewBlock) {
       rv = PinSelectionToNewBlock();
+      if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
+        return NS_ERROR_EDITOR_DESTROYED;
+      }
       NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
         "Failed to pin selection to the new block");
       mNewBlock = nullptr;
     }
 
     // adjust selection for insert text, html paste, and delete actions
     if (aAction == EditAction::insertText ||
         aAction == EditAction::insertIMEText ||
@@ -8666,17 +8669,19 @@ HTMLEditRules::PinSelectionToNewBlock()
   RefPtr<nsRange> range = new nsRange(selectionStartPoint.GetContainer());
   nsresult rv = range->CollapseTo(selectionStartPoint);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   bool nodeBefore, nodeAfter;
   rv = nsRange::CompareNodeToRange(mNewBlock, range, &nodeBefore, &nodeAfter);
-  NS_ENSURE_SUCCESS(rv, rv);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
 
   if (nodeBefore && nodeAfter) {
     return NS_OK;  // selection is inside block
   }
 
   if (nodeBefore) {
     // selection is after block.  put at end of block.
     nsCOMPtr<nsINode> tmp = HTMLEditorRef().GetLastEditableChild(*mNewBlock);
@@ -8690,16 +8695,20 @@ HTMLEditRules::PinSelectionToNewBlock()
     } else {
       endPoint.Set(tmp);
       if (NS_WARN_IF(!endPoint.AdvanceOffset())) {
         return NS_ERROR_FAILURE;
       }
     }
     ErrorResult error;
     SelectionRef().Collapse(endPoint, error);
+    if (NS_WARN_IF(!CanHandleEditAction())) {
+      error.SuppressException();
+      return NS_ERROR_EDITOR_DESTROYED;
+    }
     if (NS_WARN_IF(error.Failed())) {
       return error.StealNSResult();
     }
     return NS_OK;
   }
 
   // selection is before block.  put at start of block.
   nsCOMPtr<nsINode> tmp = HTMLEditorRef().GetFirstEditableChild(*mNewBlock);
@@ -8710,16 +8719,20 @@ HTMLEditRules::PinSelectionToNewBlock()
   if (EditorBase::IsTextNode(tmp) ||
       HTMLEditorRef().IsContainer(tmp)) {
     atStartOfBlock.Set(tmp);
   } else {
     atStartOfBlock.Set(tmp, 0);
   }
   ErrorResult error;
   SelectionRef().Collapse(atStartOfBlock, error);
+  if (NS_WARN_IF(!CanHandleEditAction())) {
+    error.SuppressException();
+    return NS_ERROR_EDITOR_DESTROYED;
+  }
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
   return NS_OK;
 }
 
 void
 HTMLEditRules::CheckInterlinePosition()
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -590,17 +590,23 @@ protected:
    */
   MOZ_MUST_USE nsresult RemoveListStructure(Element& aListElement);
 
   nsresult CacheInlineStyles(nsINode* aNode);
   nsresult ReapplyCachedStyles();
   void ClearCachedStyles();
   void AdjustSpecialBreaks();
   nsresult AdjustWhitespace();
-  nsresult PinSelectionToNewBlock();
+
+  /**
+   * PinSelectionToNewBlock() may collapse Selection around mNewNode if it's
+   * necessary,
+   */
+  MOZ_MUST_USE nsresult PinSelectionToNewBlock();
+
   void CheckInterlinePosition();
 
   /**
    * AdjustSelection() may adjust Selection range to nearest editable content.
    * Despite of the name, this may change the DOM tree.  If it needs to create
    * a <br> to put caret, this tries to create a <br> element.
    *
    * @param aAction     Maybe used to look for a good point to put caret.