Bug 1460509 - part 26: Make HTMLEditRules::AdjustSelection() 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 19:25:48 +0900
changeset 798744 cd0a5bf636e7703a9cf541189834f1367e4d6932
parent 798743 a5c1b6709a9979a75a21a81cd44185314133c64e
child 798745 6995f85de581a856cccf1d73df1b6eba2602a7b7
push id110840
push usermasayuki@d-toybox.com
push dateWed, 23 May 2018 13:41:58 +0000
reviewersm_kato
bugs1460509
milestone62.0a1
Bug 1460509 - part 26: Make HTMLEditRules::AdjustSelection() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato MozReview-Commit-ID: JCEvhhxNBgg
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditRules.h
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -8811,24 +8811,24 @@ HTMLEditRules::AdjustSelection(nsIEditor
     }
   }
 
   // make sure we aren't in an empty block - user will see no cursor.  If this
   // is happening, put a <br> in the block if allowed.
   RefPtr<Element> theblock = HTMLEditorRef().GetBlock(*point.GetContainer());
 
   if (theblock && HTMLEditorRef().IsEditable(theblock)) {
-    bool bIsEmptyNode;
+    bool isEmptyNode;
     nsresult rv =
-      HTMLEditorRef().IsEmptyNode(theblock, &bIsEmptyNode, false, false);
+      HTMLEditorRef().IsEmptyNode(theblock, &isEmptyNode, false, false);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
     // check if br can go into the destination node
-    if (bIsEmptyNode &&
+    if (isEmptyNode &&
         HTMLEditorRef().CanContainTag(*point.GetContainer(), *nsGkAtoms::br)) {
       Element* rootElement = HTMLEditorRef().GetRoot();
       if (NS_WARN_IF(!rootElement)) {
         return NS_ERROR_FAILURE;
       }
       if (point.GetContainer() == rootElement) {
         // Our root node is completely empty. Don't add a <br> here.
         // AfterEditInner() will add one for us when it calls
@@ -8870,20 +8870,28 @@ HTMLEditRules::AdjustSelection(nsIEditor
           CreateElementResult createMozBrResult = CreateMozBR(point);
           if (NS_WARN_IF(createMozBrResult.Failed())) {
             return createMozBrResult.Rv();
           }
           point.Set(createMozBrResult.GetNewNode());
           // selection stays *before* moz-br, sticking to it
           ErrorResult error;
           SelectionRef().SetInterlinePosition(true, error);
+          if (NS_WARN_IF(!CanHandleEditAction())) {
+            error.SuppressException();
+            return NS_ERROR_EDITOR_DESTROYED;
+          }
           NS_WARNING_ASSERTION(!error.Failed(),
             "Failed to set interline position");
           error = NS_OK;
           SelectionRef().Collapse(point, error);
+          if (NS_WARN_IF(!CanHandleEditAction())) {
+            error.SuppressException();
+            return NS_ERROR_EDITOR_DESTROYED;
+          }
           if (NS_WARN_IF(error.Failed())) {
             return error.StealNSResult();
           }
         } else {
           nsCOMPtr<nsIContent> nextNode =
             HTMLEditorRef().GetNextEditableHTMLNodeInBlock(*nearNode);
           if (nextNode && TextEditUtils::IsMozBR(nextNode)) {
             // selection between br and mozbr.  make it stick to mozbr
@@ -8920,16 +8928,20 @@ HTMLEditRules::AdjustSelection(nsIEditor
   nearNode = FindNearEditableNode(point, aAction);
   if (!nearNode) {
     return NS_OK;
   }
 
   EditorDOMPoint pt = GetGoodSelPointForNode(*nearNode, aAction);
   ErrorResult error;
   SelectionRef().Collapse(pt, 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;
 }
 
 template<typename PT, typename CT>
 nsIContent*
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -592,17 +592,25 @@ protected:
 
   nsresult CacheInlineStyles(nsINode* aNode);
   nsresult ReapplyCachedStyles();
   void ClearCachedStyles();
   void AdjustSpecialBreaks();
   nsresult AdjustWhitespace();
   nsresult PinSelectionToNewBlock();
   void CheckInterlinePosition();
-  nsresult AdjustSelection(nsIEditor::EDirection aAction);
+
+  /**
+   * 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.
+   */
+  MOZ_MUST_USE nsresult AdjustSelection(nsIEditor::EDirection aAction);
 
   /**
    * FindNearEditableNode() tries to find an editable node near aPoint.
    *
    * @param aPoint      The DOM point where to start to search from.
    * @param aDirection  If nsIEditor::ePrevious is set, this searches an
    *                    editable node from next nodes.  Otherwise, from
    *                    previous nodes.