Bug 1460509 - part 59: Make HTMLEditRules::CreateStyleForInsertText() 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 15:36:20 +0900
changeset 798777 7b93bc7c22082f29e55b05864ee5ed6a85e8aa91
parent 798776 f61b6a2b5cf0b76912b41c18dbad8cadb7e03893
child 798778 df2b6285101f7ad3bb5c17055c0e41891d5187fa
push id110840
push usermasayuki@d-toybox.com
push dateWed, 23 May 2018 13:41:58 +0000
reviewersm_kato
bugs1460509
milestone62.0a1
Bug 1460509 - part 59: Make HTMLEditRules::CreateStyleForInsertText() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato MozReview-Commit-ID: GsBcGxfJhbb
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditRules.h
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -5510,36 +5510,31 @@ HTMLEditRules::ConvertListType(Element* 
   }
 
   RefPtr<Element> listElement =
     HTMLEditorRef().ReplaceContainerWithTransaction(*aList, *aListType);
   NS_WARNING_ASSERTION(listElement != nullptr, "Failed to create list element");
   return listElement.forget();
 }
 
-
-/**
- * CreateStyleForInsertText() takes care of clearing and setting appropriate
- * style nodes for text insertion.
- */
 nsresult
-HTMLEditRules::CreateStyleForInsertText(nsIDocument& aDoc)
+HTMLEditRules::CreateStyleForInsertText(nsIDocument& aDocument)
 {
   MOZ_ASSERT(IsEditorDataAvailable());
   MOZ_ASSERT(HTMLEditorRef().mTypeInState);
 
   bool weDidSomething = false;
   nsRange* firstRange = SelectionRef().GetRangeAt(0);
   if (NS_WARN_IF(!firstRange)) {
     return NS_ERROR_FAILURE;
   }
   nsCOMPtr<nsINode> node = firstRange->GetStartContainer();
   int32_t offset = firstRange->StartOffset();
 
-  nsCOMPtr<Element> rootElement = aDoc.GetRootElement();
+  RefPtr<Element> rootElement = aDocument.GetRootElement();
   if (NS_WARN_IF(!rootElement)) {
     return NS_ERROR_FAILURE;
   }
 
   // process clearing any styles first
   UniquePtr<PropItem> item =
     Move(HTMLEditorRef().mTypeInState->TakeClearProperty());
 
@@ -5548,16 +5543,19 @@ HTMLEditRules::CreateStyleForInsertText(
     AutoTransactionsConserveSelection dontChangeMySelection(&HTMLEditorRef());
 
     while (item && node != rootElement) {
       // XXX If we redesign ClearStyle(), we can use EditorDOMPoint in this
       //     method.
       nsresult rv =
         HTMLEditorRef().ClearStyle(address_of(node), &offset,
                                    item->tag, item->attr);
+      if (NS_WARN_IF(!CanHandleEditAction())) {
+        return NS_ERROR_EDITOR_DESTROYED;
+      }
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
       item = Move(HTMLEditorRef().mTypeInState->TakeClearProperty());
       weDidSomething = true;
     }
   }
 
@@ -5569,66 +5567,81 @@ HTMLEditRules::CreateStyleForInsertText(
     // we have at least one style to add; make a new text node to insert style
     // nodes above.
     if (RefPtr<Text> text = node->GetAsText()) {
       // if we are in a text node, split it
       SplitNodeResult splitTextNodeResult =
         HTMLEditorRef().SplitNodeDeepWithTransaction(
                           *text, EditorRawDOMPoint(text, offset),
                           SplitAtEdges::eAllowToCreateEmptyContainer);
+      if (NS_WARN_IF(!CanHandleEditAction())) {
+        return NS_ERROR_EDITOR_DESTROYED;
+      }
       if (NS_WARN_IF(splitTextNodeResult.Failed())) {
         return splitTextNodeResult.Rv();
       }
       EditorRawDOMPoint splitPoint(splitTextNodeResult.SplitPoint());
       node = splitPoint.GetContainer();
       offset = splitPoint.Offset();
     }
     if (!HTMLEditorRef().IsContainer(node)) {
       return NS_OK;
     }
     OwningNonNull<Text> newNode =
-      EditorBase::CreateTextNode(aDoc, EmptyString());
+      EditorBase::CreateTextNode(aDocument, EmptyString());
     nsresult rv =
       HTMLEditorRef().InsertNodeWithTransaction(
                         *newNode, EditorRawDOMPoint(node, offset));
+    if (NS_WARN_IF(!CanHandleEditAction())) {
+      return NS_ERROR_EDITOR_DESTROYED;
+    }
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
     node = newNode;
     offset = 0;
     weDidSomething = true;
 
     if (relFontSize) {
       // dir indicated bigger versus smaller.  1 = bigger, -1 = smaller
       HTMLEditor::FontSize dir = relFontSize > 0 ?
         HTMLEditor::FontSize::incr : HTMLEditor::FontSize::decr;
       for (int32_t j = 0; j < DeprecatedAbs(relFontSize); j++) {
         rv = HTMLEditorRef().RelativeFontChangeOnTextNode(dir, newNode, 0, -1);
+        if (NS_WARN_IF(!CanHandleEditAction())) {
+          return NS_ERROR_EDITOR_DESTROYED;
+        }
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
       }
     }
 
     while (item) {
       rv = HTMLEditorRef().SetInlinePropertyOnNode(*node->AsContent(),
                                                    *item->tag, item->attr,
                                                    item->value);
+      if (NS_WARN_IF(!CanHandleEditAction())) {
+        return NS_ERROR_EDITOR_DESTROYED;
+      }
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
       item = HTMLEditorRef().mTypeInState->TakeSetProperty();
     }
   }
 
   if (!weDidSomething) {
     return NS_OK;
   }
 
   nsresult rv = SelectionRef().Collapse(node, offset);
+  if (NS_WARN_IF(!CanHandleEditAction())) {
+    return NS_ERROR_EDITOR_DESTROYED;
+  }
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
 bool
 HTMLEditRules::IsEmptyBlockElement(Element& aElement,
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -542,17 +542,23 @@ protected:
                               nsIContent& aEndChild,
                               bool aIsBlockIndentedWithCSS,
                               nsIContent** aOutLeftNode,
                               nsIContent** aOutRightNode);
 
   already_AddRefed<Element> ConvertListType(Element* aList, nsAtom* aListType,
                                             nsAtom* aItemType);
 
-  nsresult CreateStyleForInsertText(nsIDocument& aDoc);
+  /**
+   * CreateStyleForInsertText() sets CSS properties which are stored in
+   * TypeInState to proper element node.
+   *
+   * @param aDocument           The document of the editor.
+   */
+  MOZ_MUST_USE nsresult CreateStyleForInsertText(nsIDocument& aDocument);
 
   /**
    * IsEmptyBlockElement() returns true if aElement is a block level element
    * and it doesn't have any visible content.
    */
   enum class IgnoreSingleBR
   {
     eYes,