Bug 1460509 - part 11: Make TextEditRules::CollapseSelectionToTrailingBRIfNeeded() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 11 May 2018 18:40:47 +0900
changeset 798729 e53a1cb59fd67c40304bd568da3d3a7e2569b87f
parent 798728 8c820293c9b1e29b8f170c001f985920de16a060
child 798730 b86c8a4d3ec013edef48ebc5519070ff38a83bd2
push id110840
push usermasayuki@d-toybox.com
push dateWed, 23 May 2018 13:41:58 +0000
reviewersm_kato
bugs1460509
milestone62.0a1
Bug 1460509 - part 11: Make TextEditRules::CollapseSelectionToTrailingBRIfNeeded() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato MozReview-Commit-ID: 3ulGUfu1af1
editor/libeditor/TextEditRules.cpp
editor/libeditor/TextEditRules.h
--- a/editor/libeditor/TextEditRules.cpp
+++ b/editor/libeditor/TextEditRules.cpp
@@ -287,18 +287,24 @@ TextEditRules::AfterEdit(EditAction aAct
     }
 
     // ensure trailing br node
     rv = CreateTrailingBRIfNeeded();
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
-    // collapse the selection to the trailing BR if it's at the end of our text node
-    CollapseSelectionToTrailingBRIfNeeded();
+    // Collapse the selection to the trailing moz-<br> if it's at the end of
+    // our text node.
+    rv = CollapseSelectionToTrailingBRIfNeeded();
+    if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
+      return NS_ERROR_EDITOR_DESTROYED;
+    }
+    NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
+      "Failed to selection to after the text node in TextEditor");
   }
   return NS_OK;
 }
 
 nsresult
 TextEditRules::WillDoAction(Selection* aSelection,
                             RulesInfo* aInfo,
                             bool* aCancel,
@@ -489,19 +495,18 @@ TextEditRules::CollapseSelectionToTraili
     return NS_OK;
   }
 
   // If there is no selection ranges, we should set to the end of the editor.
   // This is usually performed in TextEditRules::Init(), however, if the
   // editor is reframed, this may be called by AfterEdit().
   if (!SelectionRef().RangeCount()) {
     TextEditorRef().CollapseSelectionToEnd(&SelectionRef());
-    if (TextEditorRef().Destroyed()) {
-      // The editor has been destroyed.
-      return NS_ERROR_FAILURE;
+    if (NS_WARN_IF(!CanHandleEditAction())) {
+      return NS_ERROR_EDITOR_DESTROYED;
     }
   }
 
   // If we are at the end of the <textarea> element, we need to set the
   // selection to stick to the moz-<br> at the end of the <textarea>.
   EditorRawDOMPoint selectionStartPoint(
                       EditorBase::GetStartPoint(&SelectionRef()));
   if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
@@ -529,16 +534,20 @@ TextEditRules::CollapseSelectionToTraili
   }
 
   EditorRawDOMPoint afterStartContainer(selectionStartPoint.GetContainer());
   if (NS_WARN_IF(!afterStartContainer.AdvanceOffset())) {
     return NS_ERROR_FAILURE;
   }
   ErrorResult error;
   SelectionRef().Collapse(afterStartContainer, 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;
 }
 
 static inline already_AddRefed<nsINode>
 GetTextNode(Selection* aSelection)
--- a/editor/libeditor/TextEditRules.h
+++ b/editor/libeditor/TextEditRules.h
@@ -310,17 +310,24 @@ protected:
 
   /**
    * HideLastPWInput() replaces last password characters which have not
    * been replaced with mask character like '*' with with the mask character.
    * This method may cause destroying the editor.
    */
   MOZ_MUST_USE nsresult HideLastPWInput();
 
-  nsresult CollapseSelectionToTrailingBRIfNeeded();
+  /**
+   * CollapseSelectionToTrailingBRIfNeeded() collapses selection after the
+   * text node if:
+   * - the editor is text editor
+   * - and Selection is collapsed at the end of the text node
+   * - and the text node is followed by moz-<br>.
+   */
+  MOZ_MUST_USE nsresult CollapseSelectionToTrailingBRIfNeeded();
 
   bool IsPasswordEditor() const;
   bool IsSingleLineEditor() const;
   bool IsPlaintextEditor() const;
   bool IsReadonly() const;
   bool IsDisabled() const;
   bool IsMailEditor() const;
   bool DontEchoPassword() const;