Bug 1460509 - part 53: Make HTMLEditRules::WillInsertText() 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 14:05:10 +0900
changeset 798771 9c4903ab97c67f78c72047867a80401357646840
parent 798770 916a369f60b3f0230cc18fcb11915bc52f9af9d3
child 798772 1e792c98bfdbc481c6b360a85bcdda6a6bcd6b5a
push id110840
push usermasayuki@d-toybox.com
push dateWed, 23 May 2018 13:41:58 +0000
reviewersm_kato
bugs1460509
milestone62.0a1
Bug 1460509 - part 53: Make HTMLEditRules::WillInsertText() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato MozReview-Commit-ID: 22xxFFECNbi
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditRules.h
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -1435,16 +1435,19 @@ HTMLEditRules::WillInsertText(EditAction
   *aCancel = false;
   *aHandled = true;
   // If the selection isn't collapsed, delete it.  Don't delete existing inline
   // tags, because we're hopefully going to insert text (bug 787432).
   if (!SelectionRef().IsCollapsed()) {
     nsresult rv =
       HTMLEditorRef().DeleteSelectionAsAction(nsIEditor::eNone,
                                               nsIEditor::eNoStrip);
+    if (NS_WARN_IF(!CanHandleEditAction())) {
+      return NS_ERROR_EDITOR_DESTROYED;
+    }
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
 
   WillInsert(aCancel);
   // initialize out param
   // we want to ignore result of WillInsert()
@@ -1491,24 +1494,30 @@ HTMLEditRules::WillInsertText(EditAction
                         pointToInsert.GetContainer());
     if (IMESelectionOffset >= 0) {
       pointToInsert.Set(pointToInsert.GetContainer(), IMESelectionOffset);
     }
 
     if (inString->IsEmpty()) {
       rv = HTMLEditorRef().InsertTextWithTransaction(
                              *doc, *inString, EditorRawDOMPoint(pointToInsert));
+      if (NS_WARN_IF(!CanHandleEditAction())) {
+        return NS_ERROR_EDITOR_DESTROYED;
+      }
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
       return NS_OK;
     }
 
     WSRunObject wsObj(&HTMLEditorRef(), pointToInsert);
     rv = wsObj.InsertText(*doc, *inString, pointToInsert);
+    if (NS_WARN_IF(!CanHandleEditAction())) {
+      return NS_ERROR_EDITOR_DESTROYED;
+    }
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
     return NS_OK;
   }
 
   // aAction == kInsertText
 
@@ -1559,16 +1568,19 @@ HTMLEditRules::WillInsertText(EditAction
         nsDependentSubstring subStr(tString, oldPos, subStrLen);
 
         // is it a return?
         if (subStr.Equals(newlineStr)) {
           RefPtr<Element> brElement =
             HTMLEditorRef().InsertBrElementWithTransaction(SelectionRef(),
                                                            currentPoint,
                                                            nsIEditor::eNone);
+          if (NS_WARN_IF(!CanHandleEditAction())) {
+            return NS_ERROR_EDITOR_DESTROYED;
+          }
           if (NS_WARN_IF(!brElement)) {
             return NS_ERROR_FAILURE;
           }
           pos++;
           if (brElement->GetNextSibling()) {
             pointToInsert.Set(brElement->GetNextSibling());
           } else {
             pointToInsert.SetToEndOf(currentPoint.GetContainer());
@@ -1584,16 +1596,19 @@ HTMLEditRules::WillInsertText(EditAction
             "Perhaps, <br> element position has been moved to different point "
             "by mutation observer");
         } else {
           EditorRawDOMPoint pointAfterInsertedString;
           rv = HTMLEditorRef().InsertTextWithTransaction(
                                  *doc, subStr,
                                  EditorRawDOMPoint(currentPoint),
                                  &pointAfterInsertedString);
+          if (NS_WARN_IF(!CanHandleEditAction())) {
+            return NS_ERROR_EDITOR_DESTROYED;
+          }
           if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
           }
           currentPoint = pointAfterInsertedString;
           pointToInsert = pointAfterInsertedString;
         }
       }
     } else {
@@ -1620,27 +1635,33 @@ HTMLEditRules::WillInsertText(EditAction
         nsDependentSubstring subStr(tString, oldPos, subStrLen);
         WSRunObject wsObj(&HTMLEditorRef(), currentPoint);
 
         // is it a tab?
         if (subStr.Equals(tabStr)) {
           EditorRawDOMPoint pointAfterInsertedSpaces;
           rv = wsObj.InsertText(*doc, spacesStr, currentPoint,
                                 &pointAfterInsertedSpaces);
+          if (NS_WARN_IF(!CanHandleEditAction())) {
+            return NS_ERROR_EDITOR_DESTROYED;
+          }
           if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
           }
           pos++;
           currentPoint = pointAfterInsertedSpaces;
           pointToInsert = pointAfterInsertedSpaces;
         }
         // is it a return?
         else if (subStr.Equals(newlineStr)) {
           RefPtr<Element> newBRElement =
             wsObj.InsertBreak(SelectionRef(), currentPoint, nsIEditor::eNone);
+          if (NS_WARN_IF(!CanHandleEditAction())) {
+            return NS_ERROR_EDITOR_DESTROYED;
+          }
           if (NS_WARN_IF(!newBRElement)) {
             return NS_ERROR_FAILURE;
           }
           pos++;
           if (newBRElement->GetNextSibling()) {
             pointToInsert.Set(newBRElement->GetNextSibling());
           } else {
             pointToInsert.SetToEndOf(currentPoint.GetContainer());
@@ -1654,16 +1675,19 @@ HTMLEditRules::WillInsertText(EditAction
           //     newBRElement is in expected point, though, we must have
           //     a lot of same bugs...
           NS_WARNING_ASSERTION(currentPoint == pointToInsert,
             "Perhaps, newBRElement has been moved or removed unexpectedly");
         } else {
           EditorRawDOMPoint pointAfterInsertedString;
           rv = wsObj.InsertText(*doc, subStr, currentPoint,
                                 &pointAfterInsertedString);
+          if (NS_WARN_IF(!CanHandleEditAction())) {
+            return NS_ERROR_EDITOR_DESTROYED;
+          }
           if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
           }
           currentPoint = pointAfterInsertedString;
           pointToInsert = pointAfterInsertedString;
         }
       }
     }
@@ -1672,22 +1696,23 @@ HTMLEditRules::WillInsertText(EditAction
   }
 
   IgnoredErrorResult ignoredError;
   SelectionRef().SetInterlinePosition(false, ignoredError);
   NS_WARNING_ASSERTION(!ignoredError.Failed(),
     "Failed to unset interline position");
 
   if (currentPoint.IsSet()) {
-    ErrorResult error;
-    SelectionRef().Collapse(currentPoint, error);
-    if (error.Failed()) {
-      NS_WARNING("Failed to collapse at current point");
-      error.SuppressException();
-    }
+    IgnoredErrorResult ignoredError;
+    SelectionRef().Collapse(currentPoint, ignoredError);
+    if (NS_WARN_IF(!CanHandleEditAction())) {
+      return NS_ERROR_EDITOR_DESTROYED;
+    }
+    NS_WARNING_ASSERTION(!ignoredError.Failed(),
+      "Failed to collapse at current point");
   }
 
   // manually update the doc changed range so that AfterEdit will clean up
   // the correct portion of the document.
   if (!mDocChangeRange) {
     mDocChangeRange = new nsRange(pointToInsert.GetContainer());
   }
 
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -146,22 +146,35 @@ protected:
   {
     kStart,
     kEnd
   };
 
   void InitFields();
 
   void WillInsert(bool* aCancel);
-  nsresult WillInsertText(EditAction aAction,
-                          bool* aCancel,
-                          bool* aHandled,
-                          const nsAString* inString,
-                          nsAString* outString,
-                          int32_t aMaxLength);
+
+  /**
+   * Called before inserting text.
+   * This method may actually inserts text into the editor.  Therefore, this
+   * might cause destroying the editor.
+   *
+   * @param aAction             Must be EditAction::insertIMEText or
+   *                            EditAction::insertText.
+   * @param aCancel             Returns true if the operation is canceled.
+   * @param aHandled            Returns true if the edit action is handled.
+   * @param inString            String to be inserted.
+   * @param outString           String actually inserted.
+   * @param aMaxLength          The maximum string length which the editor
+   *                            allows to set.
+   */
+  MOZ_MUST_USE nsresult
+  WillInsertText(EditAction aAction, bool* aCancel, bool* aHandled,
+                 const nsAString* inString, nsAString* outString,
+                 int32_t aMaxLength);
 
   /**
    * WillLoadHTML() is called before loading enter document from source.
    * This removes bogus node if there is.
    */
   MOZ_MUST_USE nsresult WillLoadHTML();
 
   /**