Bug 1460509 - part 21: Make HTMLEditRules::RemoveAlignment() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Sat, 12 May 2018 11:39:01 +0900
changeset 798739 de2a818efa2802c6a5c30bc1bad0167ef6dbfd75
parent 798738 480d29911294d302799629cc7d02468726744a56
child 798740 03d9b44f58d72c3a1613937ea47586c215321442
push id110840
push usermasayuki@d-toybox.com
push dateWed, 23 May 2018 13:41:58 +0000
reviewersm_kato
bugs1460509
milestone62.0a1
Bug 1460509 - part 21: Make HTMLEditRules::RemoveAlignment() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato MozReview-Commit-ID: JV2vdZXoYIL
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditRules.h
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -5698,17 +5698,19 @@ HTMLEditRules::WillAlign(const nsAString
     }
 
     // If it's a list item, or a list inside a list, forget any "current" div,
     // and instead put divs inside the appropriate block (td, li, etc.)
     if (HTMLEditUtils::IsListItem(curNode) ||
         HTMLEditUtils::IsList(curNode)) {
       AutoEditorDOMPointOffsetInvalidator lockChild(atCurNode);
       rv = RemoveAlignment(*curNode, aAlignType, true);
-      NS_ENSURE_SUCCESS(rv, rv);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return rv;
+      }
       if (useCSS) {
         HTMLEditorRef().mCSSEditUtils->SetCSSEquivalentToHTMLStyle(
                                          curNode->AsElement(), nullptr,
                                          nsGkAtoms::align, &aAlignType, false);
         curDiv = nullptr;
         continue;
       }
       if (HTMLEditUtils::IsList(atCurNode.GetContainer())) {
@@ -9708,35 +9710,35 @@ HTMLEditRules::WillDeleteSelection(Selec
 
 // Let's remove all alignment hints in the children of aNode; it can
 // be an ALIGN attribute (in case we just remove it) or a CENTER
 // element (here we have to remove the container and keep its
 // children). We break on tables and don't look at their children.
 nsresult
 HTMLEditRules::RemoveAlignment(nsINode& aNode,
                                const nsAString& aAlignType,
-                               bool aChildrenOnly)
+                               bool aDescendantsOnly)
 {
   MOZ_ASSERT(IsEditorDataAvailable());
 
   if (EditorBase::IsTextNode(&aNode) || HTMLEditUtils::IsTable(&aNode)) {
     return NS_OK;
   }
 
   nsCOMPtr<nsINode> child, tmp;
-  if (aChildrenOnly) {
+  if (aDescendantsOnly) {
     child = aNode.GetFirstChild();
   } else {
     child = &aNode;
   }
 
   bool useCSS = HTMLEditorRef().IsCSSEnabled();
 
   while (child) {
-    if (aChildrenOnly) {
+    if (aDescendantsOnly) {
       // get the next sibling right now because we could have to remove child
       tmp = child->GetNextSibling();
     } else {
       tmp = nullptr;
     }
 
     if (child->IsHTMLElement(nsGkAtoms::center)) {
       // the current node is a CENTER element
@@ -9750,45 +9752,57 @@ HTMLEditRules::RemoveAlignment(nsINode& 
       // if the nodes before/after are not blocks and not BRs
       rv = MakeSureElemStartsAndEndsOnCR(*child);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
 
       // now remove the CENTER container
       rv = HTMLEditorRef().RemoveContainerWithTransaction(*child->AsElement());
+      if (NS_WARN_IF(!CanHandleEditAction())) {
+        return NS_ERROR_EDITOR_DESTROYED;
+      }
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     } else if (IsBlockNode(*child) || child->IsHTMLElement(nsGkAtoms::hr)) {
       // the current node is a block element
       if (HTMLEditUtils::SupportsAlignAttr(*child)) {
         // remove the ALIGN attribute if this element can have it
         nsresult rv =
           HTMLEditorRef().RemoveAttributeWithTransaction(*child->AsElement(),
                                                          *nsGkAtoms::align);
+        if (NS_WARN_IF(!CanHandleEditAction())) {
+          return NS_ERROR_EDITOR_DESTROYED;
+        }
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
       }
       if (useCSS) {
         if (child->IsAnyOfHTMLElements(nsGkAtoms::table, nsGkAtoms::hr)) {
           nsresult rv =
             HTMLEditorRef().SetAttributeOrEquivalent(child->AsElement(),
                                                      nsGkAtoms::align,
                                                      aAlignType, false);
+          if (NS_WARN_IF(!CanHandleEditAction())) {
+            return NS_ERROR_EDITOR_DESTROYED;
+          }
           if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
           }
         } else {
           nsAutoString dummyCssValue;
           nsresult rv = HTMLEditorRef().mCSSEditUtils->RemoveCSSInlineStyle(
                                                          *child,
                                                          nsGkAtoms::textAlign,
                                                          dummyCssValue);
+          if (NS_WARN_IF(!CanHandleEditAction())) {
+            return NS_ERROR_EDITOR_DESTROYED;
+          }
           if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
           }
         }
       }
       if (!child->IsHTMLElement(nsGkAtoms::table)) {
         // unless this is a table, look at children
         nsresult rv = RemoveAlignment(*child, aAlignType, true);
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -592,18 +592,34 @@ protected:
    */
   nsresult InsertMozBRIfNeeded(nsINode& aNode)
   {
     return InsertBRIfNeededInternal(aNode, true);
   }
 
   bool IsEmptyInline(nsINode& aNode);
   bool ListIsEmptyLine(nsTArray<OwningNonNull<nsINode>>& arrayOfNodes);
-  nsresult RemoveAlignment(nsINode& aNode, const nsAString& aAlignType,
-                           bool aChildrenOnly);
+
+  /**
+   * RemoveAlignment() removes align attributes, text-align properties and
+   * <center> elements in aNode.
+   *
+   * @param aNode               Alignment information of the node and/or its
+   *                            descendants will be removed.
+   * @param aAlignType          New align value to be set only when it's in
+   *                            CSS mode and this method meets <table> or <hr>.
+   *                            XXX This is odd and not clear when you see
+   *                                caller of this method.  Do you have better
+   *                                idea?
+   * @param aDescendantsOnly    true if align information of aNode itself
+   *                            shouldn't be removed.  Otherwise, false.
+   */
+  MOZ_MUST_USE nsresult
+  RemoveAlignment(nsINode& aNode, const nsAString& aAlignType,
+                  bool aDescendantsOnly);
 
   /**
    * MakeSureElemStartsOrEndsOnCR() inserts <br> element at start (end) of
    * aNode if neither:
    * - first (last) editable child of aNode is a block or a <br>,
    * - previous (next) sibling of aNode is block or a <br>
    * - nor no previous (next) sibling of aNode.
    *