Bug 1154701 part 10 - Switch nsEditor::mActionListeners to nsTArray; r=ehsan
☠☠ backed out by 329dd852c06b ☠ ☠
authorAryeh Gregor <ayg@aryeh.name>
Wed, 22 Apr 2015 14:27:18 +0300
changeset 240526 9bd74af965fdfbbfd4b6f484adc7aa9c05d99ae8
parent 240525 69f9ae64772d35a51f0a5fab59b6abc4b6b9c5b9
child 240527 a57f36dc00b483e10d050eeb39de8f1d954702f4
push id28636
push userkwierso@gmail.com
push dateThu, 23 Apr 2015 00:16:12 +0000
treeherdermozilla-central@a5af73b32ac8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1154701
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1154701 part 10 - Switch nsEditor::mActionListeners to nsTArray; r=ehsan
editor/libeditor/nsEditor.cpp
editor/libeditor/nsEditor.h
--- a/editor/libeditor/nsEditor.cpp
+++ b/editor/libeditor/nsEditor.cpp
@@ -1348,38 +1348,36 @@ already_AddRefed<Element>
 nsEditor::CreateNode(nsIAtom* aTag,
                      nsINode* aParent,
                      int32_t aPosition)
 {
   MOZ_ASSERT(aTag && aParent);
 
   nsAutoRules beginRulesSniffing(this, EditAction::createNode, nsIEditor::eNext);
 
-  for (int32_t i = 0; i < mActionListeners.Count(); i++) {
-    mActionListeners[i]->WillCreateNode(nsDependentAtomString(aTag),
-                                        GetAsDOMNode(aParent), aPosition);
+  for (auto& listener : mActionListeners) {
+    listener->WillCreateNode(nsDependentAtomString(aTag),
+                             GetAsDOMNode(aParent), aPosition);
   }
 
   nsCOMPtr<Element> ret;
 
   nsRefPtr<CreateElementTxn> txn =
     CreateTxnForCreateElement(*aTag, *aParent, aPosition);
   nsresult res = DoTransaction(txn);
   if (NS_SUCCEEDED(res)) {
     ret = txn->GetNewNode();
     MOZ_ASSERT(ret);
   }
 
   mRangeUpdater.SelAdjCreateNode(aParent, aPosition);
 
-  for (int32_t i = 0; i < mActionListeners.Count(); i++) {
-    mActionListeners[i]->DidCreateNode(nsDependentAtomString(aTag),
-                                       GetAsDOMNode(ret),
-                                       GetAsDOMNode(aParent), aPosition,
-                                       res);
+  for (auto& listener : mActionListeners) {
+    listener->DidCreateNode(nsDependentAtomString(aTag), GetAsDOMNode(ret),
+                            GetAsDOMNode(aParent), aPosition, res);
   }
 
   return ret.forget();
 }
 
 
 NS_IMETHODIMP
 nsEditor::InsertNode(nsIDOMNode* aNode, nsIDOMNode* aParent, int32_t aPosition)
@@ -1391,30 +1389,30 @@ nsEditor::InsertNode(nsIDOMNode* aNode, 
   return InsertNode(*node, *parent, aPosition);
 }
 
 nsresult
 nsEditor::InsertNode(nsIContent& aNode, nsINode& aParent, int32_t aPosition)
 {
   nsAutoRules beginRulesSniffing(this, EditAction::insertNode, nsIEditor::eNext);
 
-  for (int32_t i = 0; i < mActionListeners.Count(); i++) {
-    mActionListeners[i]->WillInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(),
-                                        aPosition);
+  for (auto& listener : mActionListeners) {
+    listener->WillInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(),
+                             aPosition);
   }
 
   nsRefPtr<InsertNodeTxn> txn = CreateTxnForInsertNode(aNode, aParent,
                                                        aPosition);
   nsresult res = DoTransaction(txn);
 
   mRangeUpdater.SelAdjInsertNode(aParent.AsDOMNode(), aPosition);
 
-  for (int32_t i = 0; i < mActionListeners.Count(); i++) {
-    mActionListeners[i]->DidInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(),
-                                       aPosition, res);
+  for (auto& listener : mActionListeners) {
+    listener->DidInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(), aPosition,
+                            res);
   }
 
   return res;
 }
 
 
 NS_IMETHODIMP
 nsEditor::SplitNode(nsIDOMNode* aNode,
@@ -1430,32 +1428,31 @@ nsEditor::SplitNode(nsIDOMNode* aNode,
 }
 
 nsIContent*
 nsEditor::SplitNode(nsIContent& aNode, int32_t aOffset, ErrorResult& aResult)
 {
   nsAutoRules beginRulesSniffing(this, EditAction::splitNode,
                                  nsIEditor::eNext);
 
-  for (int32_t i = 0; i < mActionListeners.Count(); i++) {
-    mActionListeners[i]->WillSplitNode(aNode.AsDOMNode(), aOffset);
+  for (auto& listener : mActionListeners) {
+    listener->WillSplitNode(aNode.AsDOMNode(), aOffset);
   }
 
   nsRefPtr<SplitNodeTxn> txn = CreateTxnForSplitNode(aNode, aOffset);
   aResult = DoTransaction(txn);
 
   nsCOMPtr<nsIContent> newNode = aResult.Failed() ? nullptr
                                                   : txn->GetNewNode();
 
   mRangeUpdater.SelAdjSplitNode(aNode, aOffset, newNode);
 
-  for (int32_t i = 0; i < mActionListeners.Count(); i++) {
-    mActionListeners[i]->DidSplitNode(aNode.AsDOMNode(), aOffset,
-                                      GetAsDOMNode(newNode),
-                                      aResult.ErrorCode());
+  for (auto& listener : mActionListeners) {
+    listener->DidSplitNode(aNode.AsDOMNode(), aOffset, GetAsDOMNode(newNode),
+                           aResult.ErrorCode());
   }
 
   return newNode;
 }
 
 
 NS_IMETHODIMP
 nsEditor::JoinNodes(nsIDOMNode* aLeftNode,
@@ -1478,35 +1475,33 @@ nsEditor::JoinNodes(nsINode& aLeftNode, 
                                  nsIEditor::ePrevious);
 
   // Remember some values; later used for saved selection updating.
   // Find the offset between the nodes to be joined.
   int32_t offset = parent->IndexOf(&aRightNode);
   // Find the number of children of the lefthand node
   uint32_t oldLeftNodeLen = aLeftNode.Length();
 
-  for (int32_t i = 0; i < mActionListeners.Count(); i++) {
-    mActionListeners[i]->WillJoinNodes(aLeftNode.AsDOMNode(),
-                                       aRightNode.AsDOMNode(),
-                                       parent->AsDOMNode());
+  for (auto& listener : mActionListeners) {
+    listener->WillJoinNodes(aLeftNode.AsDOMNode(), aRightNode.AsDOMNode(),
+                            parent->AsDOMNode());
   }
 
   nsresult result;
   nsRefPtr<JoinNodeTxn> txn = CreateTxnForJoinNode(aLeftNode, aRightNode);
   if (txn)  {
     result = DoTransaction(txn);
   }
 
   mRangeUpdater.SelAdjJoinNodes(aLeftNode, aRightNode, *parent, offset,
                                 (int32_t)oldLeftNodeLen);
 
-  for (int32_t i = 0; i < mActionListeners.Count(); i++) {
-    mActionListeners[i]->DidJoinNodes(aLeftNode.AsDOMNode(),
-                                      aRightNode.AsDOMNode(),
-                                      parent->AsDOMNode(), result);
+  for (auto& listener : mActionListeners) {
+    listener->DidJoinNodes(aLeftNode.AsDOMNode(), aRightNode.AsDOMNode(),
+                           parent->AsDOMNode(), result);
   }
 
   return result;
 }
 
 
 NS_IMETHODIMP
 nsEditor::DeleteNode(nsIDOMNode* aNode)
@@ -1517,28 +1512,28 @@ nsEditor::DeleteNode(nsIDOMNode* aNode)
 }
 
 nsresult
 nsEditor::DeleteNode(nsINode* aNode)
 {
   nsAutoRules beginRulesSniffing(this, EditAction::createNode, nsIEditor::ePrevious);
 
   // save node location for selection updating code.
-  for (int32_t i = 0; i < mActionListeners.Count(); i++) {
-    mActionListeners[i]->WillDeleteNode(aNode->AsDOMNode());
+  for (auto& listener : mActionListeners) {
+    listener->WillDeleteNode(aNode->AsDOMNode());
   }
 
   nsRefPtr<DeleteNodeTxn> txn;
   nsresult res = CreateTxnForDeleteNode(aNode, getter_AddRefs(txn));
   if (NS_SUCCEEDED(res))  {
     res = DoTransaction(txn);
   }
 
-  for (int32_t i = 0; i < mActionListeners.Count(); i++) {
-    mActionListeners[i]->DidDeleteNode(aNode->AsDOMNode(), res);
+  for (auto& listener : mActionListeners) {
+    listener->DidDeleteNode(aNode->AsDOMNode(), res);
   }
 
   NS_ENSURE_SUCCESS(res, res);
   return NS_OK;
 }
 
 ///////////////////////////////////////////////////////////////////////////
 // ReplaceContainer: replace inNode with a new node (outNode) which is contructed 
@@ -1861,33 +1856,30 @@ nsEditor::FireInputEvent()
 }
 
 NS_IMETHODIMP
 nsEditor::AddEditActionListener(nsIEditActionListener *aListener)
 {
   NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER);
 
   // Make sure the listener isn't already on the list
-  if (mActionListeners.IndexOf(aListener) == -1) 
-  {
-    if (!mActionListeners.AppendObject(aListener))
-      return NS_ERROR_FAILURE;
+  if (!mActionListeners.Contains(aListener)) {
+    mActionListeners.AppendElement(*aListener);
   }
 
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsEditor::RemoveEditActionListener(nsIEditActionListener *aListener)
 {
   NS_ENSURE_TRUE(aListener, NS_ERROR_FAILURE);
 
-  if (!mActionListeners.RemoveObject(aListener))
-    return NS_ERROR_FAILURE;
+  mActionListeners.RemoveElement(aListener);
 
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsEditor::AddDocumentStateListener(nsIDocumentStateListener *aListener)
 {
@@ -2387,33 +2379,33 @@ nsEditor::InsertTextIntoTextNodeImpl(con
 
     txn = CreateTxnForIMEText(aStringToInsert);
     isIMETransaction = true;
   } else {
     txn = CreateTxnForInsertText(aStringToInsert, aTextNode, aOffset);
   }
 
   // Let listeners know what's up
-  for (int32_t i = 0; i < mActionListeners.Count(); i++) {
-    mActionListeners[i]->WillInsertText(
+  for (auto& listener : mActionListeners) {
+    listener->WillInsertText(
       static_cast<nsIDOMCharacterData*>(aTextNode.AsDOMNode()), aOffset,
       aStringToInsert);
   }
 
   // XXX We may not need these view batches anymore.  This is handled at a
   // higher level now I believe.
   BeginUpdateViewBatch();
   nsresult res = DoTransaction(txn);
   EndUpdateViewBatch();
 
   mRangeUpdater.SelAdjInsertText(aTextNode, aOffset, aStringToInsert);
 
   // let listeners know what happened
-  for (int32_t i = 0; i < mActionListeners.Count(); i++) {
-    mActionListeners[i]->DidInsertText(
+  for (auto& listener : mActionListeners) {
+    listener->DidInsertText(
       static_cast<nsIDOMCharacterData*>(aTextNode.AsDOMNode()),
       aOffset, aStringToInsert, res);
   }
 
   // Added some cruft here for bug 43366.  Layout was crashing because we left
   // an empty text node lying around in the document.  So I delete empty text
   // nodes caused by IME.  I have to mark the IME transaction as "fixed", which
   // means that furure IME txns won't merge with it.  This is because we don't
@@ -2537,27 +2529,27 @@ nsEditor::DeleteText(nsGenericDOMDataNod
 {
   nsRefPtr<DeleteTextTxn> txn =
     CreateTxnForDeleteText(aCharData, aOffset, aLength);
   NS_ENSURE_STATE(txn);
 
   nsAutoRules beginRulesSniffing(this, EditAction::deleteText, nsIEditor::ePrevious);
 
   // Let listeners know what's up
-  for (int32_t i = 0; i < mActionListeners.Count(); i++) {
-    mActionListeners[i]->WillDeleteText(
+  for (auto& listener : mActionListeners) {
+    listener->WillDeleteText(
         static_cast<nsIDOMCharacterData*>(GetAsDOMNode(&aCharData)), aOffset,
         aLength);
   }
 
   nsresult res = DoTransaction(txn);
 
   // Let listeners know what happened
-  for (int32_t i = 0; i < mActionListeners.Count(); i++) {
-    mActionListeners[i]->DidDeleteText(
+  for (auto& listener : mActionListeners) {
+    listener->DidDeleteText(
         static_cast<nsIDOMCharacterData*>(GetAsDOMNode(&aCharData)), aOffset,
         aLength, res);
   }
 
   return res;
 }
 
 
@@ -3915,41 +3907,48 @@ nsEditor::DeleteSelectionImpl(EDirection
                                              getter_AddRefs(deleteNode),
                                              &deleteCharOffset,
                                              &deleteCharLength);
   nsCOMPtr<nsIDOMCharacterData> deleteCharData(do_QueryInterface(deleteNode));
 
   if (NS_SUCCEEDED(res))  
   {
     nsAutoRules beginRulesSniffing(this, EditAction::deleteSelection, aAction);
-    int32_t i;
     // Notify nsIEditActionListener::WillDelete[Selection|Text|Node]
-    if (!deleteNode)
-      for (i = 0; i < mActionListeners.Count(); i++)
-        mActionListeners[i]->WillDeleteSelection(selection);
-    else if (deleteCharData)
-      for (i = 0; i < mActionListeners.Count(); i++)
-        mActionListeners[i]->WillDeleteText(deleteCharData, deleteCharOffset, 1);
-    else
-      for (i = 0; i < mActionListeners.Count(); i++)
-        mActionListeners[i]->WillDeleteNode(deleteNode->AsDOMNode());
+    if (!deleteNode) {
+      for (auto& listener : mActionListeners) {
+        listener->WillDeleteSelection(selection);
+      }
+    } else if (deleteCharData) {
+      for (auto& listener : mActionListeners) {
+        listener->WillDeleteText(deleteCharData, deleteCharOffset, 1);
+      }
+    } else {
+      for (auto& listener : mActionListeners) {
+        listener->WillDeleteNode(deleteNode->AsDOMNode());
+      }
+    }
 
     // Delete the specified amount
     res = DoTransaction(txn);  
 
     // Notify nsIEditActionListener::DidDelete[Selection|Text|Node]
-    if (!deleteNode)
-      for (i = 0; i < mActionListeners.Count(); i++)
-        mActionListeners[i]->DidDeleteSelection(selection);
-    else if (deleteCharData)
-      for (i = 0; i < mActionListeners.Count(); i++)
-        mActionListeners[i]->DidDeleteText(deleteCharData, deleteCharOffset, 1, res);
-    else
-      for (i = 0; i < mActionListeners.Count(); i++)
-        mActionListeners[i]->DidDeleteNode(deleteNode->AsDOMNode(), res);
+    if (!deleteNode) {
+      for (auto& listener : mActionListeners) {
+        listener->DidDeleteSelection(selection);
+      }
+    } else if (deleteCharData) {
+      for (auto& listener : mActionListeners) {
+        listener->DidDeleteText(deleteCharData, deleteCharOffset, 1, res);
+      }
+    } else {
+      for (auto& listener : mActionListeners) {
+        listener->DidDeleteNode(deleteNode->AsDOMNode(), res);
+      }
+    }
   }
 
   return res;
 }
 
 already_AddRefed<Element>
 nsEditor::DeleteSelectionAndCreateElement(nsIAtom& aTag)
 {
--- a/editor/libeditor/nsEditor.h
+++ b/editor/libeditor/nsEditor.h
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __editor_h__
 #define __editor_h__
 
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc.
+#include "mozilla/dom/OwningNonNull.h"  // for OwningNonNull
 #include "mozilla/dom/Text.h"
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCOMArray.h"                 // for nsCOMArray
 #include "nsCOMPtr.h"                   // for already_AddRefed, nsCOMPtr
 #include "nsCycleCollectionParticipant.h"
 #include "nsGkAtoms.h"
 #include "nsIEditor.h"                  // for nsIEditor::EDirection, etc
 #include "nsIEditorIMESupport.h"        // for NS_DECL_NSIEDITORIMESUPPORT, etc
@@ -825,17 +826,18 @@ protected:
   nsIAtom          *mPlaceHolderName;    // name of placeholder transaction
   nsSelectionState *mSelState;           // saved selection state for placeholder txn batching
   nsString         *mPhonetic;
   // IME composition this is not null between compositionstart and
   // compositionend.
   nsRefPtr<mozilla::TextComposition> mComposition;
 
   // various listeners
-  nsCOMArray<nsIEditActionListener> mActionListeners;  // listens to all low level actions on the doc
+  // Listens to all low level actions on the doc
+  nsTArray<mozilla::dom::OwningNonNull<nsIEditActionListener>> mActionListeners;
   nsCOMArray<nsIEditorObserver> mEditorObservers;  // just notify once per high level change
   nsCOMArray<nsIDocumentStateListener> mDocStateListeners;// listen to overall doc state (dirty or not, just created, etc)
 
   nsSelectionState  mSavedSel;           // cached selection for nsAutoSelectionReset
   nsRangeUpdater    mRangeUpdater;       // utility class object for maintaining preserved ranges
 
   uint32_t          mModCount;     // number of modifications (for undo/redo stack)
   uint32_t          mFlags;        // behavior flags. See nsIPlaintextEditor.idl for the flags we use.