Bug 1797247 - part 2: Make DeleteTextTransaction::DoTransaction and DeleteRangeTransaction::DoTransaction stop updating Selection directly r=m_kato

Differential Revision: https://phabricator.services.mozilla.com/D169039
This commit is contained in:
Masayuki Nakano 2023-02-15 22:23:34 +00:00
parent 2c93600238
commit b8589fff01
6 changed files with 115 additions and 21 deletions

View File

@ -8,6 +8,10 @@
#include "DeleteContentTransactionBase.h"
#include "DeleteRangeTransaction.h"
#include "EditorBase.h"
#include "EditorDOMPoint.h"
#include "EditTransactionBase.h"
#include "nsDebug.h"
namespace mozilla {
@ -87,4 +91,32 @@ void DeleteMultipleRangesTransaction::AppendChild(
mChildren.AppendElement(aTransaction);
}
EditorDOMPoint DeleteMultipleRangesTransaction::SuggestPointToPutCaret() const {
for (const OwningNonNull<EditTransactionBase>& transaction :
Reversed(mChildren)) {
if (const DeleteContentTransactionBase* deleteContentTransaction =
transaction->GetAsDeleteContentTransactionBase()) {
EditorDOMPoint pointToPutCaret =
deleteContentTransaction->SuggestPointToPutCaret();
if (pointToPutCaret.IsSet()) {
return pointToPutCaret;
}
continue;
}
if (const DeleteRangeTransaction* deleteRangeTransaction =
transaction->GetAsDeleteRangeTransaction()) {
EditorDOMPoint pointToPutCaret =
deleteRangeTransaction->SuggestPointToPutCaret();
if (pointToPutCaret.IsSet()) {
return pointToPutCaret;
}
continue;
}
MOZ_ASSERT_UNREACHABLE(
"Child transactions must be DeleteContentTransactionBase or "
"DeleteRangeTransaction");
}
return EditorDOMPoint();
}
} // namespace mozilla

View File

@ -40,6 +40,11 @@ class DeleteMultipleRangesTransaction final : public EditAggregateTransaction {
void AppendChild(DeleteContentTransactionBase& aTransaction);
void AppendChild(DeleteRangeTransaction& aTransaction);
/**
* Return latest caret point suggestion of child transaction.
*/
EditorDOMPoint SuggestPointToPutCaret() const;
protected:
~DeleteMultipleRangesTransaction() = default;
};

View File

@ -8,6 +8,7 @@
#include "DeleteContentTransactionBase.h"
#include "DeleteNodeTransaction.h"
#include "DeleteTextTransaction.h"
#include "EditTransactionBase.h"
#include "EditorBase.h"
#include "EditorDOMPoint.h"
#include "EditorUtils.h"
@ -21,6 +22,7 @@
#include "mozilla/StaticPrefs_editor.h"
#include "mozilla/ToString.h"
#include "mozilla/dom/Selection.h"
#include "nsAtom.h"
#include "nsCOMPtr.h"
#include "nsDebug.h"
@ -42,7 +44,7 @@ DeleteRangeTransaction::DeleteRangeTransaction(EditorBase& aEditorBase,
NS_IMPL_CYCLE_COLLECTION_INHERITED(DeleteRangeTransaction,
EditAggregateTransaction, mEditorBase,
mRangeToDelete)
mRangeToDelete, mPointToPutCaret)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeleteRangeTransaction)
NS_INTERFACE_MAP_END_INHERITING(EditAggregateTransaction)
@ -197,16 +199,23 @@ NS_IMETHODIMP DeleteRangeTransaction::DoTransaction() {
this, __FUNCTION__,
nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get()));
if (!mEditorBase->AllowsTransactionsToChangeSelection()) {
return NS_OK;
mPointToPutCaret = rangeToDelete->StartRef();
if (MOZ_UNLIKELY(!mPointToPutCaret.IsSetAndValid())) {
for (const OwningNonNull<EditTransactionBase>& transaction :
Reversed(mChildren)) {
if (const DeleteContentTransactionBase* deleteContentTransaction =
transaction->GetAsDeleteContentTransactionBase()) {
mPointToPutCaret = deleteContentTransaction->SuggestPointToPutCaret();
if (mPointToPutCaret.IsSetAndValid()) {
break;
}
continue;
}
MOZ_ASSERT_UNREACHABLE(
"Child transactions must be DeleteContentTransactionBase");
}
}
OwningNonNull<EditorBase> editorBase = *mEditorBase;
rv = editorBase->CollapseSelectionTo(
EditorRawDOMPoint(rangeToDelete->StartRef()));
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"EditorBase::CollapseSelectionTo() failed");
return rv;
return NS_OK;
}
NS_IMETHODIMP DeleteRangeTransaction::UndoTransaction() {

View File

@ -10,6 +10,7 @@
#include "EditAggregateTransaction.h"
#include "EditorBase.h"
#include "EditorDOMPoint.h"
#include "EditorForwards.h"
#include "mozilla/RefPtr.h"
@ -58,6 +59,14 @@ class DeleteRangeTransaction final : public EditAggregateTransaction {
MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() override;
/**
* Return a good point to put caret after calling DoTransaction().
*/
EditorDOMPoint SuggestPointToPutCaret() const {
return mPointToPutCaret.IsSetAndValid() ? mPointToPutCaret
: EditorDOMPoint();
}
protected:
/**
* Extend the range by adding a surrounding whitespace character to the range
@ -138,6 +147,8 @@ class DeleteRangeTransaction final : public EditAggregateTransaction {
// P1 in the range. This is only non-null until DoTransaction is called and
// we convert it into child transactions.
RefPtr<nsRange> mRangeToDelete;
EditorDOMPoint mPointToPutCaret;
};
} // namespace mozilla

View File

@ -142,15 +142,7 @@ NS_IMETHODIMP DeleteTextTransaction::DoTransaction() {
editorBase->RangeUpdaterRef().SelAdjDeleteText(textNode, mOffset,
mLengthToDelete);
if (!editorBase->AllowsTransactionsToChangeSelection()) {
return NS_OK;
}
editorBase->CollapseSelectionTo(SuggestPointToPutCaret(), error);
NS_WARNING_ASSERTION(!error.Failed(),
"EditorBase::CollapseSelectionTo() failed");
return error.StealNSResult();
return NS_OK;
}
EditorDOMPoint DeleteTextTransaction::SuggestPointToPutCaret() const {
@ -182,7 +174,21 @@ NS_IMETHODIMP DeleteTextTransaction::RedoTransaction() {
MOZ_LOG(GetLogModule(), LogLevel::Info,
("%p DeleteTextTransaction::%s this=%s", this, __FUNCTION__,
ToString(*this).c_str()));
return DoTransaction();
nsresult rv = DoTransaction();
if (NS_FAILED(rv)) {
NS_WARNING("DeleteTextTransaction::DoTransaction() failed");
return rv;
}
if (!mEditorBase || !mEditorBase->AllowsTransactionsToChangeSelection()) {
return NS_OK;
}
OwningNonNull<EditorBase> editorBase = *mEditorBase;
rv = editorBase->CollapseSelectionTo(SuggestPointToPutCaret());
if (NS_FAILED(rv)) {
NS_WARNING("EditorBase::CollapseSelectionTo() failed");
return rv;
}
return NS_OK;
}
} // namespace mozilla

View File

@ -3225,7 +3225,24 @@ nsresult EditorBase::DeleteTextWithTransaction(Text& aTextNode,
*this, EditorRawDOMPoint(&aTextNode, aOffset));
}
return rv;
if (NS_FAILED(rv)) {
return rv;
}
if (AllowsTransactionsToChangeSelection()) {
EditorDOMPoint pointToPutCaret = transaction->SuggestPointToPutCaret();
if (MOZ_LIKELY(pointToPutCaret.IsSet())) {
nsresult rv = CollapseSelectionTo(pointToPutCaret);
if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
return NS_ERROR_EDITOR_DESTROYED;
}
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rv),
"EditorBase::CollapseSelectionTo() failed, but ignored");
}
}
return NS_OK;
}
bool EditorBase::IsRoot(const nsINode* inNode) const {
@ -4774,6 +4791,20 @@ nsresult EditorBase::DeleteRangesWithTransaction(
return rv;
}
if (AllowsTransactionsToChangeSelection()) {
EditorDOMPoint pointToPutCaret =
deleteSelectionTransaction->SuggestPointToPutCaret();
if (pointToPutCaret.IsSet()) {
nsresult rv = CollapseSelectionTo(pointToPutCaret);
if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
return NS_ERROR_EDITOR_DESTROYED;
}
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rv),
"EditorBase::CollapseSelectionTo() failed, but ignored");
}
}
if (IsTextEditor() || aStripWrappers == nsIEditor::eNoStrip) {
return NS_OK;
}