--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -1382,36 +1382,42 @@ already_AddRefed<Element>
EditorBase::CreateNode(nsIAtom* aTag,
nsINode* aParent,
int32_t aPosition)
{
MOZ_ASSERT(aTag && aParent);
AutoRules beginRulesSniffing(this, EditAction::createNode, nsIEditor::eNext);
- for (auto& listener : mActionListeners) {
- listener->WillCreateNode(nsDependentAtomString(aTag),
- GetAsDOMNode(aParent), aPosition);
+ {
+ AutoActionListenerArray listeners(mActionListeners);
+ for (auto& listener : listeners) {
+ listener->WillCreateNode(nsDependentAtomString(aTag),
+ GetAsDOMNode(aParent), aPosition);
+ }
}
nsCOMPtr<Element> ret;
RefPtr<CreateElementTransaction> transaction =
CreateTxnForCreateElement(*aTag, *aParent, aPosition);
nsresult rv = DoTransaction(transaction);
if (NS_SUCCEEDED(rv)) {
ret = transaction->GetNewNode();
MOZ_ASSERT(ret);
}
mRangeUpdater.SelAdjCreateNode(aParent, aPosition);
- for (auto& listener : mActionListeners) {
- listener->DidCreateNode(nsDependentAtomString(aTag), GetAsDOMNode(ret),
- GetAsDOMNode(aParent), aPosition, rv);
+ {
+ AutoActionListenerArray listeners(mActionListeners);
+ for (auto& listener : listeners) {
+ listener->DidCreateNode(nsDependentAtomString(aTag), GetAsDOMNode(ret),
+ GetAsDOMNode(aParent), aPosition, rv);
+ }
}
return ret.forget();
}
NS_IMETHODIMP
EditorBase::InsertNode(nsIDOMNode* aNode,
nsIDOMNode* aParent,
@@ -1426,30 +1432,36 @@ EditorBase::InsertNode(nsIDOMNode* aNode
nsresult
EditorBase::InsertNode(nsIContent& aNode,
nsINode& aParent,
int32_t aPosition)
{
AutoRules beginRulesSniffing(this, EditAction::insertNode, nsIEditor::eNext);
- for (auto& listener : mActionListeners) {
- listener->WillInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(),
- aPosition);
+ {
+ AutoActionListenerArray listeners(mActionListeners);
+ for (auto& listener : listeners) {
+ listener->WillInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(),
+ aPosition);
+ }
}
RefPtr<InsertNodeTransaction> transaction =
CreateTxnForInsertNode(aNode, aParent, aPosition);
nsresult rv = DoTransaction(transaction);
mRangeUpdater.SelAdjInsertNode(aParent.AsDOMNode(), aPosition);
- for (auto& listener : mActionListeners) {
- listener->DidInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(), aPosition,
- rv);
+ {
+ AutoActionListenerArray listeners(mActionListeners);
+ for (auto& listener : listeners) {
+ listener->DidInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(), aPosition,
+ rv);
+ }
}
return rv;
}
NS_IMETHODIMP
EditorBase::SplitNode(nsIDOMNode* aNode,
int32_t aOffset,
@@ -1465,33 +1477,39 @@ EditorBase::SplitNode(nsIDOMNode* aNode,
nsIContent*
EditorBase::SplitNode(nsIContent& aNode,
int32_t aOffset,
ErrorResult& aResult)
{
AutoRules beginRulesSniffing(this, EditAction::splitNode, nsIEditor::eNext);
- for (auto& listener : mActionListeners) {
- listener->WillSplitNode(aNode.AsDOMNode(), aOffset);
+ {
+ AutoActionListenerArray listeners(mActionListeners);
+ for (auto& listener : listeners) {
+ listener->WillSplitNode(aNode.AsDOMNode(), aOffset);
+ }
}
RefPtr<SplitNodeTransaction> transaction =
CreateTxnForSplitNode(aNode, aOffset);
aResult = DoTransaction(transaction);
nsCOMPtr<nsIContent> newNode = aResult.Failed() ? nullptr
: transaction->GetNewNode();
mRangeUpdater.SelAdjSplitNode(aNode, aOffset, newNode);
nsresult rv = aResult.StealNSResult();
- for (auto& listener : mActionListeners) {
- listener->DidSplitNode(aNode.AsDOMNode(), aOffset, GetAsDOMNode(newNode),
- rv);
+ {
+ AutoActionListenerArray listeners(mActionListeners);
+ for (auto& listener : listeners) {
+ listener->DidSplitNode(aNode.AsDOMNode(), aOffset, GetAsDOMNode(newNode),
+ rv);
+ }
}
// Note: result might be a success code, so we can't use Throw() to
// set it on aResult.
aResult = rv;
return newNode;
}
@@ -1517,34 +1535,40 @@ EditorBase::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 (auto& listener : mActionListeners) {
- listener->WillJoinNodes(aLeftNode.AsDOMNode(), aRightNode.AsDOMNode(),
- parent->AsDOMNode());
+ {
+ AutoActionListenerArray listeners(mActionListeners);
+ for (auto& listener : listeners) {
+ listener->WillJoinNodes(aLeftNode.AsDOMNode(), aRightNode.AsDOMNode(),
+ parent->AsDOMNode());
+ }
}
nsresult rv = NS_OK;
RefPtr<JoinNodeTransaction> transaction =
CreateTxnForJoinNode(aLeftNode, aRightNode);
if (transaction) {
rv = DoTransaction(transaction);
}
mRangeUpdater.SelAdjJoinNodes(aLeftNode, aRightNode, *parent, offset,
(int32_t)oldLeftNodeLen);
- for (auto& listener : mActionListeners) {
- listener->DidJoinNodes(aLeftNode.AsDOMNode(), aRightNode.AsDOMNode(),
- parent->AsDOMNode(), rv);
+ {
+ AutoActionListenerArray listeners(mActionListeners);
+ for (auto& listener : listeners) {
+ listener->DidJoinNodes(aLeftNode.AsDOMNode(), aRightNode.AsDOMNode(),
+ parent->AsDOMNode(), rv);
+ }
}
return rv;
}
NS_IMETHODIMP
EditorBase::DeleteNode(nsIDOMNode* aNode)
{
@@ -1555,28 +1579,34 @@ EditorBase::DeleteNode(nsIDOMNode* aNode
nsresult
EditorBase::DeleteNode(nsINode* aNode)
{
AutoRules beginRulesSniffing(this, EditAction::createNode,
nsIEditor::ePrevious);
// save node location for selection updating code.
- for (auto& listener : mActionListeners) {
- listener->WillDeleteNode(aNode->AsDOMNode());
+ {
+ AutoActionListenerArray listeners(mActionListeners);
+ for (auto& listener : listeners) {
+ listener->WillDeleteNode(aNode->AsDOMNode());
+ }
}
RefPtr<DeleteNodeTransaction> transaction;
nsresult rv = CreateTxnForDeleteNode(aNode, getter_AddRefs(transaction));
if (NS_SUCCEEDED(rv)) {
rv = DoTransaction(transaction);
}
- for (auto& listener : mActionListeners) {
- listener->DidDeleteNode(aNode->AsDOMNode(), rv);
+ {
+ AutoActionListenerArray listeners(mActionListeners);
+ for (auto& listener : listeners) {
+ listener->DidDeleteNode(aNode->AsDOMNode(), rv);
+ }
}
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
/**
* ReplaceContainer() replaces inNode with a new node (outNode) which is
@@ -2503,33 +2533,39 @@ EditorBase::InsertTextIntoTextNodeImpl(c
insertedTextNode = mIMETextNode;
insertedOffset = mIMETextOffset;
mIMETextLength = aStringToInsert.Length();
} else {
transaction = CreateTxnForInsertText(aStringToInsert, aTextNode, aOffset);
}
// Let listeners know what's up
- for (auto& listener : mActionListeners) {
- listener->WillInsertText(
- static_cast<nsIDOMCharacterData*>(insertedTextNode->AsDOMNode()),
- insertedOffset, aStringToInsert);
+ {
+ AutoActionListenerArray listeners(mActionListeners);
+ for (auto& listener : listeners) {
+ listener->WillInsertText(
+ static_cast<nsIDOMCharacterData*>(insertedTextNode->AsDOMNode()),
+ insertedOffset, aStringToInsert);
+ }
}
// XXX We may not need these view batches anymore. This is handled at a
// higher level now I believe.
BeginUpdateViewBatch();
nsresult rv = DoTransaction(transaction);
EndUpdateViewBatch();
// let listeners know what happened
- for (auto& listener : mActionListeners) {
- listener->DidInsertText(
- static_cast<nsIDOMCharacterData*>(insertedTextNode->AsDOMNode()),
- insertedOffset, aStringToInsert, rv);
+ {
+ AutoActionListenerArray listeners(mActionListeners);
+ for (auto& listener : listeners) {
+ listener->DidInsertText(
+ static_cast<nsIDOMCharacterData*>(insertedTextNode->AsDOMNode()),
+ insertedOffset, aStringToInsert, rv);
+ }
}
// 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
// want future IME txns trying to put their text into a node that is no
// longer in the document. This does not break undo/redo, because all these
@@ -2654,29 +2690,35 @@ EditorBase::DeleteText(nsGenericDOMDataN
RefPtr<DeleteTextTransaction> transaction =
CreateTxnForDeleteText(aCharData, aOffset, aLength);
NS_ENSURE_STATE(transaction);
AutoRules beginRulesSniffing(this, EditAction::deleteText,
nsIEditor::ePrevious);
// Let listeners know what's up
- for (auto& listener : mActionListeners) {
- listener->WillDeleteText(
- static_cast<nsIDOMCharacterData*>(GetAsDOMNode(&aCharData)), aOffset,
- aLength);
+ {
+ AutoActionListenerArray listeners(mActionListeners);
+ for (auto& listener : listeners) {
+ listener->WillDeleteText(
+ static_cast<nsIDOMCharacterData*>(GetAsDOMNode(&aCharData)), aOffset,
+ aLength);
+ }
}
nsresult rv = DoTransaction(transaction);
// Let listeners know what happened
- for (auto& listener : mActionListeners) {
- listener->DidDeleteText(
- static_cast<nsIDOMCharacterData*>(GetAsDOMNode(&aCharData)), aOffset,
- aLength, rv);
+ {
+ AutoActionListenerArray listeners(mActionListeners);
+ for (auto& listener : listeners) {
+ listener->DidDeleteText(
+ static_cast<nsIDOMCharacterData*>(GetAsDOMNode(&aCharData)), aOffset,
+ aLength, rv);
+ }
}
return rv;
}
already_AddRefed<DeleteTextTransaction>
EditorBase::CreateTxnForDeleteText(nsGenericDOMDataNode& aCharData,
uint32_t aOffset,
@@ -4030,45 +4072,51 @@ EditorBase::DeleteSelectionImpl(EDirecti
getter_AddRefs(deleteNode),
&deleteCharOffset,
&deleteCharLength);
nsCOMPtr<nsIDOMCharacterData> deleteCharData(do_QueryInterface(deleteNode));
if (NS_SUCCEEDED(rv)) {
AutoRules beginRulesSniffing(this, EditAction::deleteSelection, aAction);
// Notify nsIEditActionListener::WillDelete[Selection|Text|Node]
- 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());
+ {
+ AutoActionListenerArray listeners(mActionListeners);
+ if (!deleteNode) {
+ for (auto& listener : listeners) {
+ listener->WillDeleteSelection(selection);
+ }
+ } else if (deleteCharData) {
+ for (auto& listener : listeners) {
+ listener->WillDeleteText(deleteCharData, deleteCharOffset, 1);
+ }
+ } else {
+ for (auto& listener : listeners) {
+ listener->WillDeleteNode(deleteNode->AsDOMNode());
+ }
}
}
// Delete the specified amount
rv = DoTransaction(transaction);
// Notify nsIEditActionListener::DidDelete[Selection|Text|Node]
- if (!deleteNode) {
- for (auto& listener : mActionListeners) {
- listener->DidDeleteSelection(selection);
- }
- } else if (deleteCharData) {
- for (auto& listener : mActionListeners) {
- listener->DidDeleteText(deleteCharData, deleteCharOffset, 1, rv);
- }
- } else {
- for (auto& listener : mActionListeners) {
- listener->DidDeleteNode(deleteNode->AsDOMNode(), rv);
+ {
+ AutoActionListenerArray listeners(mActionListeners);
+ if (!deleteNode) {
+ for (auto& listener : mActionListeners) {
+ listener->DidDeleteSelection(selection);
+ }
+ } else if (deleteCharData) {
+ for (auto& listener : mActionListeners) {
+ listener->DidDeleteText(deleteCharData, deleteCharOffset, 1, rv);
+ }
+ } else {
+ for (auto& listener : mActionListeners) {
+ listener->DidDeleteNode(deleteNode->AsDOMNode(), rv);
+ }
}
}
}
return rv;
}
already_AddRefed<Element>