This is an automated email from the git hooks/post-receive script.
richard pushed a commit to branch tor-browser-91.8.0esr-11.0-1 in repository tor-browser.
commit b79bd94ff5159e62617ef4e06f7d8e2988b97e79 Author: Masayuki Nakano masayuki@d-toybox.com AuthorDate: Fri Mar 11 02:24:24 2022 +0000
Bug 1753508 - Make `EditorBase::AutoEditActionDataSetter::UpdateSelectionCache` clean up and restart selection batch which the editor started. r=smaug, a=RyanVM
When `Selection` instance is updated, the old selection may be in batch. In the case, `UpdateSelectionCache` should clean up the batch in the old selection and start new one in the new selection instead.
Differential Revision: https://phabricator.services.mozilla.com/D139349 --- editor/libeditor/EditorBase.cpp | 57 +++++++++++++++++++++++++++++++++++++++++ editor/libeditor/EditorBase.h | 13 ++-------- 2 files changed, 59 insertions(+), 11 deletions(-)
diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index a9d6b6121eca2..c2ee66105aad2 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -6135,6 +6135,63 @@ EditorBase::AutoEditActionDataSetter::~AutoEditActionDataSetter() { "mTopLevelEditSubActionData.mSelectedRange should've been cleared"); }
+void EditorBase::AutoEditActionDataSetter::UpdateSelectionCache( + Selection& aSelection) { + MOZ_ASSERT(aSelection.GetType() == SelectionType::eNormal); + + if (mSelection == &aSelection) { + return; + } + + AutoEditActionDataSetter& topLevelEditActionData = + [&]() -> AutoEditActionDataSetter& { + for (AutoEditActionDataSetter* editActionData = this;; + editActionData = editActionData->mParentData) { + if (!editActionData->mParentData) { + return *editActionData; + } + } + MOZ_ASSERT_UNREACHABLE("You do something wrong"); + }(); + + // Keep grabbing the old selection in the top level edit action data until the + // all owners end handling it. + if (mSelection) { + topLevelEditActionData.mRetiredSelections.AppendElement(*mSelection); + } + + // If the old selection is in batch, we should end the batch which + // `EditorBase::BeginUpdateViewBatch` started. + if (mEditorBase.mUpdateCount && mSelection) { + mSelection->EndBatchChanges(); + } + + Selection* previousSelection = mSelection; + mSelection = &aSelection; + for (AutoEditActionDataSetter* parentActionData = mParentData; + parentActionData; parentActionData = parentActionData->mParentData) { + if (!parentActionData->mSelection) { + continue; + } + // Skip scanning mRetiredSelections if we've already handled the selection + // previous time. + if (parentActionData->mSelection != previousSelection) { + if (!topLevelEditActionData.mRetiredSelections.Contains( + OwningNonNull<Selection>(*parentActionData->mSelection))) { + topLevelEditActionData.mRetiredSelections.AppendElement( + *parentActionData->mSelection); + } + previousSelection = parentActionData->mSelection; + } + parentActionData->mSelection = &aSelection; + } + + // Restart the batching in the new selection. + if (mEditorBase.mUpdateCount) { + aSelection.StartBatchChanges(); + } +} + void EditorBase::AutoEditActionDataSetter::SetColorData( const nsAString& aData) { MOZ_ASSERT(!HasTriedToDispatchBeforeInputEvent(), diff --git a/editor/libeditor/EditorBase.h b/editor/libeditor/EditorBase.h index 8a551d92f9b84..dbc64780e84f5 100644 --- a/editor/libeditor/EditorBase.h +++ b/editor/libeditor/EditorBase.h @@ -1304,17 +1304,7 @@ class EditorBase : public nsIEditor, return mParentData ? mParentData->RangeUpdaterRef() : mRangeUpdater; }
- void UpdateSelectionCache(Selection& aSelection) { - MOZ_ASSERT(aSelection.GetType() == SelectionType::eNormal); - - AutoEditActionDataSetter* actionData = this; - while (actionData) { - if (actionData->mSelection) { - actionData->mSelection = &aSelection; - } - actionData = actionData->mParentData; - } - } + void UpdateSelectionCache(Selection& aSelection);
private: bool IsBeforeInputEventEnabled() const; @@ -1378,6 +1368,7 @@ class EditorBase : public nsIEditor,
EditorBase& mEditorBase; RefPtr<Selection> mSelection; + nsTArray<OwningNonNull<Selection>> mRetiredSelections; nsCOMPtr<nsIPrincipal> mPrincipal; // EditAction may be nested, for example, a command may be executed // from mutation event listener which is run while editor changes