Bug 1460509 - part 18: Make HTMLEditRules::ChangeIndentation() 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 10:29:41 +0900
changeset 798736 76dcff52103c4b865b15677c0819392a6335f2a8
parent 798735 f38656bd5025dc67547854c02553c9e5aa57432a
child 798737 bb22d5472d3e6a58c5369d0a65216eb823c88f8d
push id110840
push usermasayuki@d-toybox.com
push dateWed, 23 May 2018 13:41:58 +0000
reviewersm_kato
bugs1460509
milestone62.0a1
Bug 1460509 - part 18: Make HTMLEditRules::ChangeIndentation() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato Additionally, this patch renames it to ChangeMarginStart() for making its job clearer and add two inline wrapper methods. MozReview-Commit-ID: L2GfLKhT6sa
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditRules.h
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -4457,17 +4457,21 @@ HTMLEditRules::WillCSSIndent(bool* aCanc
     RefPtr<Element> theBlock =
       HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::div,
                                                 splitNodeResult.SplitPoint());
     if (NS_WARN_IF(!theBlock)) {
       return NS_ERROR_FAILURE;
     }
     // remember our new block for postprocessing
     mNewBlock = theBlock;
-    ChangeIndentation(*theBlock, Change::plus);
+    nsresult rv = IncreaseMarginToIndent(*theBlock);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return NS_ERROR_EDITOR_DESTROYED;
+    }
+    NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to increase indentation");
     // delete anything that was in the list of nodes
     while (!arrayOfNodes.IsEmpty()) {
       OwningNonNull<nsINode> curNode = arrayOfNodes[0];
       rv = HTMLEditorRef().DeleteNodeWithTransaction(*curNode);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
       arrayOfNodes.RemoveElementAt(0);
@@ -4572,17 +4576,21 @@ HTMLEditRules::WillCSSIndent(bool* aCanc
         return rv;
       }
       continue;
     }
 
     // Not a list item.
 
     if (IsBlockNode(*curNode)) {
-      ChangeIndentation(*curNode->AsElement(), Change::plus);
+      nsresult rv = IncreaseMarginToIndent(*curNode->AsElement());
+      if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
+        return NS_ERROR_EDITOR_DESTROYED;
+      }
+      NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to inrease indentation");
       curQuote = nullptr;
       continue;
     }
 
     if (!curQuote) {
       // First, check that our element can contain a div.
       if (!HTMLEditorRef().CanContainTag(*atCurNode.GetContainer(),
                                          *nsGkAtoms::div)) {
@@ -4595,17 +4603,21 @@ HTMLEditRules::WillCSSIndent(bool* aCanc
         return splitNodeResult.Rv();
       }
       curQuote =
         HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::div,
                                                   splitNodeResult.SplitPoint());
       if (NS_WARN_IF(!curQuote)) {
         return NS_ERROR_FAILURE;
       }
-      ChangeIndentation(*curQuote, Change::plus);
+      nsresult rv = IncreaseMarginToIndent(*curQuote);
+      if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
+        return NS_ERROR_EDITOR_DESTROYED;
+      }
+      NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to increase indentation");
       // remember our new block for postprocessing
       mNewBlock = curQuote;
       // curQuote is now the correct thing to put curNode in
     }
 
     // tuck the node into the end of the active blockquote
     rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(),
                                                       *curQuote);
@@ -4971,17 +4983,22 @@ HTMLEditRules::WillOutdent(bool* aCancel
       if (useCSS && IsBlockNode(curNode)) {
         nsAtom& marginProperty = MarginPropertyAtomForIndent(curNode);
         nsAutoString value;
         CSSEditUtils::GetSpecifiedProperty(curNode, marginProperty, value);
         float f;
         RefPtr<nsAtom> unit;
         CSSEditUtils::ParseLength(value, &f, getter_AddRefs(unit));
         if (f > 0) {
-          ChangeIndentation(*curNode->AsElement(), Change::minus);
+          nsresult rv = DecreaseMarginToOutdent(*curNode->AsElement());
+          if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
+            return NS_ERROR_EDITOR_DESTROYED;
+          }
+          NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
+            "Failed to decrease indentation");
           continue;
         }
       }
       // Is it a list item?
       if (HTMLEditUtils::IsListItem(curNode)) {
         // If it is a list item, that means we are not outdenting whole list.
         // So we need to finish up dealing with any curBlockQuote, and then pop
         // this list item.
@@ -5109,17 +5126,22 @@ HTMLEditRules::WillOutdent(bool* aCancel
           nsCOMPtr<Element> element;
           if (curNode->GetAsText()) {
             // We want to outdent the parent of text nodes
             element = curNode->GetParentElement();
           } else if (curNode->IsElement()) {
             element = curNode->AsElement();
           }
           if (element) {
-            ChangeIndentation(*element, Change::minus);
+            nsresult rv = DecreaseMarginToOutdent(*element);
+            if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
+              return NS_ERROR_EDITOR_DESTROYED;
+            }
+            NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
+              "Failed to decrease indentation");
           }
         }
       }
     }
     if (curBlockQuote) {
       // We have a blockquote we haven't finished handling
       rv = OutdentPartOfBlock(*curBlockQuote, *firstBQChild, *lastBQChild,
                               curBlockQuoteIsIndentedWithCSS,
@@ -5278,17 +5300,17 @@ HTMLEditRules::OutdentPartOfBlock(Elemen
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
     return NS_OK;
   }
 
   if (middleNode->IsElement()) {
     // We do nothing if middleNode isn't an element
-    nsresult rv = ChangeIndentation(*middleNode->AsElement(), Change::minus);
+    nsresult rv = DecreaseMarginToOutdent(*middleNode->AsElement());
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
     return NS_OK;
   }
 
   return NS_OK;
 }
@@ -9877,33 +9899,36 @@ HTMLEditRules::AlignBlock(Element& aElem
                                                 aAlignType, false);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
 nsresult
-HTMLEditRules::ChangeIndentation(Element& aElement,
-                                 Change aChange)
+HTMLEditRules::ChangeMarginStart(Element& aElement,
+                                 bool aIncrease)
 {
   MOZ_ASSERT(IsEditorDataAvailable());
 
   nsAtom& marginProperty = MarginPropertyAtomForIndent(aElement);
   nsAutoString value;
   CSSEditUtils::GetSpecifiedProperty(aElement, marginProperty, value);
+  if (NS_WARN_IF(!CanHandleEditAction())) {
+    return NS_ERROR_EDITOR_DESTROYED;
+  }
   float f;
   RefPtr<nsAtom> unit;
   CSSEditUtils::ParseLength(value, &f, getter_AddRefs(unit));
   if (!f) {
     nsAutoString defaultLengthUnit;
     CSSEditUtils::GetDefaultLengthUnit(defaultLengthUnit);
     unit = NS_Atomize(defaultLengthUnit);
   }
-  int8_t multiplier = aChange == Change::plus ? +1 : -1;
+  int8_t multiplier = aIncrease ? +1 : -1;
   if (nsGkAtoms::in == unit) {
     f += NS_EDITOR_INDENT_INCREMENT_IN * multiplier;
   } else if (nsGkAtoms::cm == unit) {
     f += NS_EDITOR_INDENT_INCREMENT_CM * multiplier;
   } else if (nsGkAtoms::mm == unit) {
     f += NS_EDITOR_INDENT_INCREMENT_MM * multiplier;
   } else if (nsGkAtoms::pt == unit) {
     f += NS_EDITOR_INDENT_INCREMENT_PT * multiplier;
@@ -9920,31 +9945,40 @@ HTMLEditRules::ChangeIndentation(Element
   }
 
   if (0 < f) {
     nsAutoString newValue;
     newValue.AppendFloat(f);
     newValue.Append(nsDependentAtomString(unit));
     HTMLEditorRef().mCSSEditUtils->SetCSSProperty(aElement, marginProperty,
                                                   newValue);
+    if (NS_WARN_IF(!CanHandleEditAction())) {
+      return NS_ERROR_EDITOR_DESTROYED;
+    }
     return NS_OK;
   }
 
   HTMLEditorRef().mCSSEditUtils->RemoveCSSProperty(aElement, marginProperty,
                                                    value);
+  if (NS_WARN_IF(!CanHandleEditAction())) {
+    return NS_ERROR_EDITOR_DESTROYED;
+  }
 
   // Remove unnecessary divs
   if (!aElement.IsHTMLElement(nsGkAtoms::div) ||
       &aElement == HTMLEditorRef().GetActiveEditingHost() ||
       !HTMLEditorRef().IsDescendantOfEditorRoot(&aElement) ||
       HTMLEditor::HasAttributes(&aElement)) {
     return NS_OK;
   }
 
   nsresult rv = HTMLEditorRef().RemoveContainerWithTransaction(aElement);
+  if (NS_WARN_IF(!CanHandleEditAction())) {
+    return NS_ERROR_EDITOR_DESTROYED;
+  }
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
 nsresult
 HTMLEditRules::WillAbsolutePosition(bool* aCancel,
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -588,18 +588,53 @@ protected:
   bool IsEmptyInline(nsINode& aNode);
   bool ListIsEmptyLine(nsTArray<OwningNonNull<nsINode>>& arrayOfNodes);
   nsresult RemoveAlignment(nsINode& aNode, const nsAString& aAlignType,
                            bool aChildrenOnly);
   nsresult MakeSureElemStartsOrEndsOnCR(nsINode& aNode, bool aStarts);
   enum class ContentsOnly { no, yes };
   nsresult AlignBlock(Element& aElement,
                       const nsAString& aAlignType, ContentsOnly aContentsOnly);
-  enum class Change { minus, plus };
-  nsresult ChangeIndentation(Element& aElement, Change aChange);
+
+  /**
+   * IncreaseMarginToIndent() increases the margin of aElement.  See the
+   * document of ChangeMarginStart() for the detail.
+   * XXX This is not aware of vertical writing-mode.
+   *
+   * @param aElement            The element to be indented.
+   */
+  MOZ_MUST_USE nsresult IncreaseMarginToIndent(Element& aElement)
+  {
+    return ChangeMarginStart(aElement, true);
+  }
+
+  /**
+   * DecreaseMarginToOutdent() decreases the margin of aElement.  See the
+   * document of ChangeMarginStart() for the detail.
+   * XXX This is not aware of vertical writing-mode.
+   *
+   * @param aElement            The element to be outdented.
+   */
+  MOZ_MUST_USE nsresult DecreaseMarginToOutdent(Element& aElement)
+  {
+    return ChangeMarginStart(aElement, false);
+  }
+
+  /**
+   * ChangeMarginStart() changes margin of aElement to indent or outdent.
+   * However, use IncreaseMarginToIndent() and DecreaseMarginToOutdent()
+   * instead.  If it's rtl text, margin-right will be changed.  Otherwise,
+   * margin-left.
+   * XXX This is not aware of vertical writing-mode.
+   *
+   * @param aElement            The element to be indented or outdented.
+   * @param aIncrease           true for indent, false for outdent.
+   */
+  MOZ_MUST_USE nsresult ChangeMarginStart(Element& aElement, bool aIncrease);
+
   void DocumentModifiedWorker();
 
   /**
    * InitStyleCacheArray() initializes aStyleCache for usable with
    * GetInlineStyles().
    */
   void InitStyleCacheArray(StyleCache aStyleCache[SIZE_STYLE_TABLE]);