Bug 1349940. DeleteRangeTransaction should not keep its range alive longer than it needs to. r=masayuki, a=kwierso

MozReview-Commit-ID: 283P59EDFPW
This commit is contained in:
Boris Zbarsky 2017-03-24 16:07:11 -04:00
parent eaf41a48a2
commit 15cb86a93f
2 changed files with 17 additions and 13 deletions

View File

@ -48,11 +48,18 @@ DeleteRangeTransaction::DoTransaction()
return NS_ERROR_NOT_AVAILABLE;
}
// Swap mRangeToDelete out into a stack variable, so we make sure to null it
// out on return from this function. Once this function returns, we no longer
// need mRangeToDelete, and keeping it alive in the long term slows down all
// DOM mutations because it's observing them.
RefPtr<nsRange> rangeToDelete;
rangeToDelete.swap(mRangeToDelete);
// build the child transactions
nsCOMPtr<nsINode> startParent = mRangeToDelete->GetStartParent();
int32_t startOffset = mRangeToDelete->StartOffset();
nsCOMPtr<nsINode> endParent = mRangeToDelete->GetEndParent();
int32_t endOffset = mRangeToDelete->EndOffset();
nsCOMPtr<nsINode> startParent = rangeToDelete->GetStartParent();
int32_t startOffset = rangeToDelete->StartOffset();
nsCOMPtr<nsINode> endParent = rangeToDelete->GetEndParent();
int32_t endOffset = rangeToDelete->EndOffset();
MOZ_ASSERT(startParent && endParent);
if (startParent == endParent) {
@ -67,7 +74,7 @@ DeleteRangeTransaction::DoTransaction()
CreateTxnsToDeleteContent(startParent, startOffset, nsIEditor::eNext);
NS_ENSURE_SUCCESS(rv, rv);
// delete the intervening nodes
rv = CreateTxnsToDeleteNodesBetween();
rv = CreateTxnsToDeleteNodesBetween(rangeToDelete);
NS_ENSURE_SUCCESS(rv, rv);
// delete the relevant content in the end node
rv = CreateTxnsToDeleteContent(endParent, endOffset, nsIEditor::ePrevious);
@ -95,16 +102,12 @@ DeleteRangeTransaction::DoTransaction()
NS_IMETHODIMP
DeleteRangeTransaction::UndoTransaction()
{
MOZ_ASSERT(mRangeToDelete);
return EditAggregateTransaction::UndoTransaction();
}
NS_IMETHODIMP
DeleteRangeTransaction::RedoTransaction()
{
MOZ_ASSERT(mRangeToDelete);
return EditAggregateTransaction::RedoTransaction();
}
@ -211,7 +214,7 @@ DeleteRangeTransaction::CreateTxnsToDeleteContent(nsINode* aNode,
}
nsresult
DeleteRangeTransaction::CreateTxnsToDeleteNodesBetween()
DeleteRangeTransaction::CreateTxnsToDeleteNodesBetween(nsRange* aRangeToDelete)
{
if (NS_WARN_IF(!mEditorBase)) {
return NS_ERROR_NOT_AVAILABLE;
@ -219,7 +222,7 @@ DeleteRangeTransaction::CreateTxnsToDeleteNodesBetween()
nsCOMPtr<nsIContentIterator> iter = NS_NewContentSubtreeIterator();
nsresult rv = iter->Init(mRangeToDelete);
nsresult rv = iter->Init(aRangeToDelete);
NS_ENSURE_SUCCESS(rv, rv);
while (!iter->IsDone()) {

View File

@ -54,7 +54,7 @@ protected:
int32_t aStartOffset,
int32_t aEndOffset);
nsresult CreateTxnsToDeleteNodesBetween();
nsresult CreateTxnsToDeleteNodesBetween(nsRange* aRangeToDelete);
nsresult CreateTxnsToDeleteContent(nsINode* aParent,
int32_t aOffset,
@ -63,7 +63,8 @@ protected:
// The editor for this transaction.
RefPtr<EditorBase> mEditorBase;
// P1 in the range.
// P1 in the range. This is only non-null until DoTransaction is called and
// we convert it into child transactions.
RefPtr<nsRange> mRangeToDelete;
// Range updater object.