Bug 1460509 - part 14: Make HTMLEditRules::WillRelativeChangeZIndex() 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 19:24:35 +0900
changeset 798732 7276770b8cf7ecdf9c322e5153aa6bbadb9bf228
parent 798731 b7fcbfde487a85e09afc57aa786988de6d7b264b
child 798733 b5fa0e2d42cb8d904b483d27b74088e97a2e6aa5
push id110840
push usermasayuki@d-toybox.com
push dateWed, 23 May 2018 13:41:58 +0000
reviewersm_kato
bugs1460509
milestone62.0a1
Bug 1460509 - part 14: Make HTMLEditRules::WillRelativeChangeZIndex() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato MozReview-Commit-ID: 8HEqK3DAPO4
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditRules.h
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -10260,34 +10260,46 @@ HTMLEditRules::WillRelativeChangeZIndex(
   *aHandled = true;
 
   RefPtr<Element> element =
     HTMLEditorRef().GetAbsolutelyPositionedSelectionContainer();
   if (NS_WARN_IF(!element)) {
     return NS_ERROR_FAILURE;
   }
 
-  AutoSelectionRestorer selectionRestorer(&SelectionRef(), &HTMLEditorRef());
-
-  int32_t zIndex;
-  nsresult rv = HTMLEditorRef().RelativeChangeElementZIndex(*element, aChange,
-                                                            &zIndex);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
+  {
+    AutoSelectionRestorer selectionRestorer(&SelectionRef(), &HTMLEditorRef());
+
+    int32_t zIndex;
+    nsresult rv = HTMLEditorRef().RelativeChangeElementZIndex(*element, aChange,
+                                                              &zIndex);
+    if (NS_WARN_IF(!CanHandleEditAction())) {
+      return NS_ERROR_EDITOR_DESTROYED;
+    }
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+  }
+
+  // Restoring Selection might cause destroying the HTML editor.
+  if (NS_WARN_IF(!CanHandleEditAction())) {
+    return NS_ERROR_EDITOR_DESTROYED;
   }
   return NS_OK;
 }
 
 nsresult
 HTMLEditRules::DocumentModified()
 {
   nsContentUtils::AddScriptRunner(
     NewRunnableMethod("HTMLEditRules::DocumentModifiedWorker",
                       this,
                       &HTMLEditRules::DocumentModifiedWorker));
+  // Be aware, if DocumentModifiedWorker() is called synchronously, the
+  // editor might have been destroyed here.
   return NS_OK;
 }
 
 void
 HTMLEditRules::DocumentModifiedWorker()
 {
   if (NS_WARN_IF(!CanHandleEditAction())) {
     return;
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -255,18 +255,30 @@ protected:
   nsresult WillIndent(bool* aCancel, bool* aHandled);
   nsresult WillCSSIndent(bool* aCancel, bool* aHandled);
   nsresult WillHTMLIndent(bool* aCancel, bool* aHandled);
   nsresult WillOutdent(bool* aCancel, bool* aHandled);
   nsresult WillAlign(const nsAString& aAlignType,
                      bool* aCancel, bool* aHandled);
   nsresult WillAbsolutePosition(bool* aCancel, bool* aHandled);
   nsresult WillRemoveAbsolutePosition(bool* aCancel, bool* aHandled);
-  nsresult WillRelativeChangeZIndex(int32_t aChange,
-                                    bool* aCancel, bool* aHandled);
+
+  /**
+   * Called before changing z-index.
+   * This method actually changes z-index of nearest absolute positioned
+   * element relatively.  Therefore, this might cause destroying the HTML
+   * editor.
+   *
+   * @param aChange             Amount to change z-index.
+   * @param aCancel             Returns true if the operation is canceled.
+   * @param aHandled            Returns true if the edit action is handled.
+   */
+  MOZ_MUST_USE nsresult
+  WillRelativeChangeZIndex(int32_t aChange, bool* aCancel, bool* aHandled);
+
   nsresult WillMakeDefListItem(const nsAString* aBlockType, bool aEntireList,
                                bool* aCancel, bool* aHandled);
   nsresult WillMakeBasicBlock(const nsAString& aBlockType,
                               bool* aCancel, bool* aHandled);
   nsresult MakeBasicBlock(nsAtom& aBlockType);
   nsresult DidMakeBasicBlock(RulesInfo* aInfo, nsresult aResult);
   nsresult DidAbsolutePosition();
   nsresult AlignInnerBlocks(nsINode& aNode, const nsAString& aAlignType);