Bug 1460509 - part 20: Make HTMLEditRules::MakeSureElemStartsAndEndsOnCR() and HTMLEditRules::MakeSureElemStartsOrEndsOnCR() return NS_ERROR_EDITOR_DESTROYED if they cause destroying the editor r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Sat, 12 May 2018 11:25:23 +0900
changeset 798738 480d29911294d302799629cc7d02468726744a56
parent 798737 bb22d5472d3e6a58c5369d0a65216eb823c88f8d
child 798739 de2a818efa2802c6a5c30bc1bad0167ef6dbfd75
push id110840
push usermasayuki@d-toybox.com
push dateWed, 23 May 2018 13:41:58 +0000
reviewersm_kato
bugs1460509
milestone62.0a1
Bug 1460509 - part 20: Make HTMLEditRules::MakeSureElemStartsAndEndsOnCR() and HTMLEditRules::MakeSureElemStartsOrEndsOnCR() return NS_ERROR_EDITOR_DESTROYED if they cause destroying the editor r?m_kato MozReview-Commit-ID: I8HcvO9IB7x
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditRules.h
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -9797,19 +9797,16 @@ HTMLEditRules::RemoveAlignment(nsINode& 
         }
       }
     }
     child = tmp;
   }
   return NS_OK;
 }
 
-// Let's insert a BR as first (resp. last) child of aNode if its
-// first (resp. last) child is not a block nor a BR, and if the
-// previous (resp. next) sibling is not a block nor a BR
 nsresult
 HTMLEditRules::MakeSureElemStartsOrEndsOnCR(nsINode& aNode,
                                             bool aStarts)
 {
   MOZ_ASSERT(IsEditorDataAvailable());
 
   nsINode* child = aStarts ? HTMLEditorRef().GetFirstEditableChild(aNode) :
                              HTMLEditorRef().GetLastEditableChild(aNode);
@@ -9837,16 +9834,19 @@ HTMLEditRules::MakeSureElemStartsOrEndsO
     if (!aStarts) {
       pointToInsert.SetToEndOf(&aNode);
     } else {
       pointToInsert.Set(&aNode, 0);
     }
     RefPtr<Element> brElement =
       HTMLEditorRef().InsertBrElementWithTransaction(SelectionRef(),
                                                      pointToInsert);
+    if (NS_WARN_IF(!CanHandleEditAction())) {
+      return NS_ERROR_EDITOR_DESTROYED;
+    }
     if (NS_WARN_IF(!brElement)) {
       return NS_ERROR_FAILURE;
     }
   }
   return NS_OK;
 }
 
 nsresult
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -97,17 +97,27 @@ public:
   virtual bool DocumentIsEmpty() override;
   virtual nsresult DocumentModified() override;
 
   nsresult GetListState(bool* aMixed, bool* aOL, bool* aUL, bool* aDL);
   nsresult GetListItemState(bool* aMixed, bool* aLI, bool* aDT, bool* aDD);
   nsresult GetIndentState(bool* aCanIndent, bool* aCanOutdent);
   nsresult GetAlignment(bool* aMixed, nsIHTMLEditor::EAlignment* aAlign);
   nsresult GetParagraphState(bool* aMixed, nsAString& outFormat);
-  nsresult MakeSureElemStartsAndEndsOnCR(nsINode& aNode);
+
+  /**
+   * MakeSureElemStartsAndEndsOnCR() inserts <br> element at start (and/or 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.
+   *
+   * @param aNode               The node which may be inserted <br> elements.
+   */
+  MOZ_MUST_USE nsresult MakeSureElemStartsAndEndsOnCR(nsINode& aNode);
 
   void DidCreateNode(Selection& aSelection, Element& aNewElement);
   void DidInsertNode(Selection& aSelection, nsIContent& aNode);
   void WillDeleteNode(Selection& aSelection, nsINode& aChild);
   void DidSplitNode(Selection& aSelection,
                     nsINode& aExistingRightNode,
                     nsINode& aNewLeftNode);
   void WillJoinNodes(nsINode& aLeftNode, nsINode& aRightNode);
@@ -584,17 +594,30 @@ protected:
   {
     return InsertBRIfNeededInternal(aNode, true);
   }
 
   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);
+
+  /**
+   * 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.
+   *
+   * @param aNode               The node which may be inserted <br> element.
+   * @param aStarts             true for trying to insert <br> to the start.
+   *                            false for trying to insert <br> to the end.
+   */
+  MOZ_MUST_USE nsresult
+  MakeSureElemStartsOrEndsOnCR(nsINode& aNode, bool aStarts);
 
   /**
    * AlignBlock() resets align attribute, text-align property, etc first.
    * Then, aligns contents of aElement on aAlignType.
    *
    * @param aElement            The element whose contents will be aligned.
    * @param aAlignType          Boundary or "center" which contents should be
    *                            aligned on.