Bug 1415445 - part 3: nsIEditActionListener's WillCreateElement() and DidCreateElement() should take child node at insertion point or new node itself rather than the container node and offset in it r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 08 Nov 2017 18:16:46 +0900
changeset 695543 907b989894a9c9e454962fb86bf9e928b31aec98
parent 695542 995baa1558a8896a03bb109f47bd88aff42b6a46
child 695544 4eb7d47b4e7df6ce3bed6504901423c172ccb451
push id88462
push usermasayuki@d-toybox.com
push dateThu, 09 Nov 2017 12:16:29 +0000
reviewersm_kato
bugs1415445
milestone58.0a1
Bug 1415445 - part 3: nsIEditActionListener's WillCreateElement() and DidCreateElement() should take child node at insertion point or new node itself rather than the container node and offset in it r?m_kato nsIEditActionListener::WillCreateElement() and nsIEditActionListener::DidCreateElement() are implemented only by m-c. So, we can remove a set of container node and offset in it from their argument. Instead, WillCreateElement() should take a node which will be next sibling of the new node. Note that only implementation of them is, HTMLEditRules::DidCreateElement(). So, we can get rid of them and can call HTMLEditRules::DidCreateElement() directly from EditorBase::CreateNode(). However, such change should be done in another bug which checks all nsIEditActionListener method implementations. MozReview-Commit-ID: 4LQEs2WwrVC
editor/libeditor/EditorBase.cpp
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditRules.h
editor/nsIEditActionListener.idl
editor/txtsvc/nsTextServicesDocument.cpp
editor/txtsvc/nsTextServicesDocument.h
extensions/spellcheck/src/mozInlineSpellChecker.cpp
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -1425,53 +1425,51 @@ EditorBase::CreateNode(nsAtom* aTag,
 {
   MOZ_ASSERT(aTag && aParent);
 
   EditorRawDOMPoint pointToInsert;
   if (aPosition == -1) {
     pointToInsert.Set(aParent, aParent->Length());
   } else if (aChildAtPosition) {
     pointToInsert.Set(aChildAtPosition);
-    // Ensure pointToInsert has offset for sending same offset for both
-    // WillCreateNode() and DidCreateNode().
-    Unused << pointToInsert.Offset();
   } else {
     pointToInsert.Set(aParent, aPosition);
   }
+  // XXX We need to offset at new node to mRangeUpdater.  Therefore, we need
+  //     to compute the offset now but this is expensive.  So, if it's possible,
+  //     we need to redesign mRangeUpdater as avoiding using indices.
+  int32_t offset = static_cast<int32_t>(pointToInsert.Offset());
 
   AutoRules beginRulesSniffing(this, EditAction::createNode, nsIEditor::eNext);
 
   {
     AutoActionListenerArray listeners(mActionListeners);
     for (auto& listener : listeners) {
       listener->WillCreateNode(nsDependentAtomString(aTag),
-                               GetAsDOMNode(pointToInsert.Container()),
-                               pointToInsert.Offset());
+                               GetAsDOMNode(pointToInsert.GetChildAtOffset()));
     }
   }
 
   nsCOMPtr<Element> ret;
 
   RefPtr<CreateElementTransaction> transaction =
     CreateTxnForCreateElement(*aTag, pointToInsert);
   nsresult rv = DoTransaction(transaction);
   if (NS_SUCCEEDED(rv)) {
     ret = transaction->GetNewNode();
     MOZ_ASSERT(ret);
   }
 
-  mRangeUpdater.SelAdjCreateNode(pointToInsert.Container(),
-                                 pointToInsert.Offset());
+  mRangeUpdater.SelAdjCreateNode(pointToInsert.Container(), offset);
 
   {
     AutoActionListenerArray listeners(mActionListeners);
     for (auto& listener : listeners) {
-      listener->DidCreateNode(nsDependentAtomString(aTag), GetAsDOMNode(ret),
-                              GetAsDOMNode(pointToInsert.Container()),
-                              pointToInsert.Offset(), rv);
+      listener->DidCreateNode(nsDependentAtomString(aTag),
+                              GetAsDOMNode(ret), rv);
     }
   }
 
   return ret.forget();
 }
 
 NS_IMETHODIMP
 EditorBase::InsertNode(nsIDOMNode* aNode,
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -8513,34 +8513,31 @@ HTMLEditRules::InsertBRIfNeededInternal(
   }
 
   return aInsertMozBR ? CreateMozBR(aNode.AsDOMNode(), 0) :
                         CreateBR(aNode.AsDOMNode(), 0);
 }
 
 NS_IMETHODIMP
 HTMLEditRules::WillCreateNode(const nsAString& aTag,
-                              nsIDOMNode* aParent,
-                              int32_t aPosition)
+                              nsIDOMNode* aNextSiblingOfNewNode)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLEditRules::DidCreateNode(const nsAString& aTag,
-                             nsIDOMNode* aNode,
-                             nsIDOMNode* aParent,
-                             int32_t aPosition,
+                             nsIDOMNode* aNewNode,
                              nsresult aResult)
 {
   if (!mListenerEnabled) {
     return NS_OK;
   }
   // assumption that Join keeps the righthand node
-  nsresult rv = mUtilRange->SelectNode(aNode);
+  nsresult rv = mUtilRange->SelectNode(aNewNode);
   NS_ENSURE_SUCCESS(rv, rv);
   return UpdateDocChangeRange(mUtilRange);
 }
 
 NS_IMETHODIMP
 HTMLEditRules::WillInsertNode(nsIDOMNode* aNode,
                               nsIDOMNode* aParent,
                               int32_t aPosition)
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -101,20 +101,19 @@ public:
   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 MakeSureElemStartsOrEndsOnCR(nsINode& aNode);
 
   // nsIEditActionListener methods
 
-  NS_IMETHOD WillCreateNode(const nsAString& aTag, nsIDOMNode* aParent,
-                            int32_t aPosition) override;
-  NS_IMETHOD DidCreateNode(const nsAString& aTag, nsIDOMNode* aNode,
-                           nsIDOMNode* aParent, int32_t aPosition,
+  NS_IMETHOD WillCreateNode(const nsAString& aTag,
+                            nsIDOMNode* aNextSiblingOfNewNode) override;
+  NS_IMETHOD DidCreateNode(const nsAString& aTag, nsIDOMNode* aNewNode,
                            nsresult aResult) override;
   NS_IMETHOD WillInsertNode(nsIDOMNode* aNode, nsIDOMNode* aParent,
                             int32_t aPosition) override;
   NS_IMETHOD DidInsertNode(nsIDOMNode* aNode, nsIDOMNode* aParent,
                            int32_t aPosition, nsresult aResult) override;
   NS_IMETHOD WillDeleteNode(nsIDOMNode* aChild) override;
   NS_IMETHOD DidDeleteNode(nsIDOMNode* aChild, nsresult aResult) override;
   NS_IMETHOD WillSplitNode(nsIDOMNode* aExistingRightNode,
--- a/editor/nsIEditActionListener.idl
+++ b/editor/nsIEditActionListener.idl
@@ -25,41 +25,33 @@ Editor Action Listener interface to outs
  * nsIDocumentObserver.
  */
 [scriptable, uuid(b22907b1-ee93-11d2-8d50-000064657374)]
 
 interface nsIEditActionListener : nsISupports{
 
   /**
    * Called before the editor creates a node.
-   * @param aTag      The tag name of the DOM Node to create.
-   * @param aParent   The node to insert the new object into
-   * @param aPosition The place in aParent to insert the new node
-   *                  0=first child, 1=second child, etc.
-   *                  any number > number of current children = last child
+   * @param aTag                    The tag name of the DOM Node to create.
+   * @param aNextSiblingOfNewNode   The node which will be next sibling of
+   *                                new node.  If the new node will be appended,
+   *                                this is null.
    */
   void WillCreateNode(in DOMString aTag,
-                            in nsIDOMNode   aParent,
-                            in long aPosition);
+                      in nsIDOMNode aNextSiblingOfNewNode);
 
   /**
    * Called after the editor creates a node.
    * @param aTag      The tag name of the DOM Node to create.
-   * @param aNode     The DOM Node that was created.
-   * @param aParent   The node to insert the new object into
-   * @param aPosition The place in aParent to insert the new node
-   *                  0=first child, 1=second child, etc.
-   *                  any number > number of current children = last child
+   * @param aNewNode  The DOM Node that was created.
    * @param aResult   The result of the create node operation.
    */
   void DidCreateNode(in DOMString aTag,
-                           in nsIDOMNode aNode,
-                           in nsIDOMNode aParent,
-                           in long          aPosition,
-                           in nsresult      aResult);
+                     in nsIDOMNode aNewNode,
+                     in nsresult aResult);
 
   /**
    * Called before the editor inserts a node.
    * @param aNode     The DOM Node to insert.
    * @param aParent   The node to insert the new object into
    * @param aPosition The place in aParent to insert the new node
    *                  0=first child, 1=second child, etc.
    *                  any number > number of current children = last child
--- a/editor/txtsvc/nsTextServicesDocument.cpp
+++ b/editor/txtsvc/nsTextServicesDocument.cpp
@@ -3368,23 +3368,26 @@ nsTextServicesDocument::WillJoinNodes(ns
   return NS_OK;
 }
 
 // -------------------------------
 // stubs for unused listen methods
 // -------------------------------
 
 NS_IMETHODIMP
-nsTextServicesDocument::WillCreateNode(const nsAString& aTag, nsIDOMNode *aParent, int32_t aPosition)
+nsTextServicesDocument::WillCreateNode(const nsAString& aTag,
+                                       nsIDOMNode* aNextSiblingOfNewNode)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsTextServicesDocument::DidCreateNode(const nsAString& aTag, nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t aPosition, nsresult aResult)
+nsTextServicesDocument::DidCreateNode(const nsAString& aTag,
+                                      nsIDOMNode* aNewNode,
+                                      nsresult aResult)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsTextServicesDocument::WillInsertText(nsIDOMCharacterData *aTextNode, int32_t aOffset, const nsAString &aString)
 {
   return NS_OK;
--- a/editor/txtsvc/nsTextServicesDocument.h
+++ b/editor/txtsvc/nsTextServicesDocument.h
@@ -113,18 +113,21 @@ public:
   NS_IMETHOD WillJoinNodes(nsIDOMNode  *aLeftNode,
                            nsIDOMNode  *aRightNode,
                            nsIDOMNode  *aParent) override;
   NS_IMETHOD DidJoinNodes(nsIDOMNode  *aLeftNode,
                           nsIDOMNode  *aRightNode,
                           nsIDOMNode  *aParent,
                           nsresult     aResult) override;
   // these listen methods are unused:
-  NS_IMETHOD WillCreateNode(const nsAString& aTag, nsIDOMNode *aParent, int32_t aPosition) override;
-  NS_IMETHOD DidCreateNode(const nsAString& aTag, nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t aPosition, nsresult aResult) override;
+  NS_IMETHOD WillCreateNode(const nsAString& aTag,
+                            nsIDOMNode* aNextSiblingOfNewNode) override;
+  NS_IMETHOD DidCreateNode(const nsAString& aTag,
+                           nsIDOMNode* aNewNode,
+                           nsresult aResult) override;
   NS_IMETHOD WillInsertText(nsIDOMCharacterData *aTextNode, int32_t aOffset, const nsAString &aString) override;
   NS_IMETHOD DidInsertText(nsIDOMCharacterData *aTextNode, int32_t aOffset, const nsAString &aString, nsresult aResult) override;
   NS_IMETHOD WillDeleteText(nsIDOMCharacterData *aTextNode, int32_t aOffset, int32_t aLength) override;
   NS_IMETHOD DidDeleteText(nsIDOMCharacterData *aTextNode, int32_t aOffset, int32_t aLength, nsresult aResult) override;
   NS_IMETHOD WillDeleteSelection(nsISelection *aSelection) override;
   NS_IMETHOD DidDeleteSelection(nsISelection *aSelection) override;
 
   /* Helper functions */
--- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
@@ -1049,23 +1049,27 @@ mozInlineSpellChecker::IgnoreWords(const
     mSpellCheck->IgnoreWordAllOccurrences(aWordsToIgnore[index]);
 
   auto status = MakeUnique<mozInlineSpellStatus>(this);
   nsresult rv = status->InitForSelection();
   NS_ENSURE_SUCCESS(rv, rv);
   return ScheduleSpellCheck(Move(status));
 }
 
-NS_IMETHODIMP mozInlineSpellChecker::WillCreateNode(const nsAString & aTag, nsIDOMNode *aParent, int32_t aPosition)
+NS_IMETHODIMP
+mozInlineSpellChecker::WillCreateNode(const nsAString& aTag,
+                                      nsIDOMNode* aNextSiblingOfNewNode)
 {
   return NS_OK;
 }
 
-NS_IMETHODIMP mozInlineSpellChecker::DidCreateNode(const nsAString & aTag, nsIDOMNode *aNode, nsIDOMNode *aParent,
-                                                   int32_t aPosition, nsresult aResult)
+NS_IMETHODIMP
+mozInlineSpellChecker::DidCreateNode(const nsAString& aTag,
+                                     nsIDOMNode* aNewNode,
+                                     nsresult aResult)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP mozInlineSpellChecker::WillInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent,
                                                     int32_t aPosition)
 {
   return NS_OK;