Bug 1797247 - part 1: Add delete transaction classes to use build time type checks r=m_kato

First, `EditorBase::CreateTransactionForDeleteSelection` returns an instance of
`EditAggregateTransaction`. It's a base class of `PlaceholderTransaction` and
`DeleteRangeTransaction` but it's also a concrete class.  However, it's too
generic.  Therefore, this patch creates `DeleteMultipleRangesTransaction` which
is a simple sub-class of it, and makes `EditAggregateTransaction` be an abstract
class.  Then, add `AddChild` methods to each concrete class to restrict the
type of child transactions.

Next, `DeleteRangeTransaction` contains only `DeleteNodeTransaction` and
`DeleteTextTransaction`.  Therefore, once they have a common base class,
we can check the type easier.  Therefore, this patch also adds
`DeleteContentTransactionBase` and
`EditorBase::CreateTransactionForCollapsedRange` becomes clearer what it
returns.

With these changes, `DeleteRangeTransaction` obviously contains only
`DeleteContentTransactionBase`, `DeleteMultipleRangesTransaction` contains only
`DeleteRangeTransaction`, `DeleteNodeTransaction` and `DeleteTextTransaction`.
And they are guaranteed at build time (at least from outside the classes).
***
fix

Differential Revision: https://phabricator.services.mozilla.com/D169038
This commit is contained in:
Masayuki Nakano 2023-02-15 22:17:17 +00:00
parent 5b5580f50e
commit 2c93600238
21 changed files with 356 additions and 185 deletions

View File

@ -0,0 +1,24 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
#include "DeleteContentTransactionBase.h"
#include "EditorBase.h"
namespace mozilla {
DeleteContentTransactionBase::DeleteContentTransactionBase(
EditorBase& aEditorBase)
: mEditorBase(&aEditorBase) {}
NS_IMPL_CYCLE_COLLECTION_INHERITED(DeleteContentTransactionBase,
EditTransactionBase, mEditorBase)
NS_IMPL_ADDREF_INHERITED(DeleteContentTransactionBase, EditTransactionBase)
NS_IMPL_RELEASE_INHERITED(DeleteContentTransactionBase, EditTransactionBase)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeleteContentTransactionBase)
NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)
} // namespace mozilla

View File

@ -0,0 +1,46 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 DeleteContentTransactionBase_h
#define DeleteContentTransactionBase_h
#include "EditTransactionBase.h"
#include "EditorForwards.h"
#include "mozilla/RefPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsISupportsImpl.h"
namespace mozilla {
/**
* An abstract transaction that removes text or node.
*/
class DeleteContentTransactionBase : public EditTransactionBase {
public:
/**
* Return a point to put caret if the transaction instance has an idea.
*/
virtual EditorDOMPoint SuggestPointToPutCaret() const = 0;
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DeleteContentTransactionBase,
EditTransactionBase)
NS_DECL_EDITTRANSACTIONBASE_GETASMETHODS_OVERRIDE(
DeleteContentTransactionBase)
protected:
explicit DeleteContentTransactionBase(EditorBase& aEditorBase);
~DeleteContentTransactionBase() = default;
RefPtr<EditorBase> mEditorBase;
};
} // namespace mozilla
#endif // #ifndef DeleteContentTransactionBase_h

View File

@ -0,0 +1,90 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
#include "DeleteMultipleRangesTransaction.h"
#include "DeleteContentTransactionBase.h"
#include "DeleteRangeTransaction.h"
#include "EditorBase.h"
namespace mozilla {
NS_IMPL_CYCLE_COLLECTION_INHERITED(DeleteMultipleRangesTransaction,
EditAggregateTransaction)
NS_IMPL_ADDREF_INHERITED(DeleteMultipleRangesTransaction,
EditAggregateTransaction)
NS_IMPL_RELEASE_INHERITED(DeleteMultipleRangesTransaction,
EditAggregateTransaction)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeleteMultipleRangesTransaction)
NS_INTERFACE_MAP_END_INHERITING(EditAggregateTransaction)
NS_IMETHODIMP DeleteMultipleRangesTransaction::DoTransaction() {
MOZ_LOG(GetLogModule(), LogLevel::Info,
("%p DeleteMultipleRangesTransaction::%s this={ mName=%s } "
"Start==============================",
this, __FUNCTION__,
nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get()));
nsresult rv = EditAggregateTransaction::DoTransaction();
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"EditAggregateTransaction::DoTransaction() failed");
MOZ_LOG(GetLogModule(), LogLevel::Info,
("%p DeleteMultipleRangesTransaction::%s this={ mName=%s } "
"End==============================",
this, __FUNCTION__,
nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get()));
return rv;
}
NS_IMETHODIMP DeleteMultipleRangesTransaction::UndoTransaction() {
MOZ_LOG(GetLogModule(), LogLevel::Info,
("%p DeleteMultipleRangesTransaction::%s this={ mName=%s } "
"Start==============================",
this, __FUNCTION__,
nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get()));
nsresult rv = EditAggregateTransaction::UndoTransaction();
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"EditAggregateTransaction::UndoTransaction() failed");
MOZ_LOG(GetLogModule(), LogLevel::Info,
("%p DeleteMultipleRangesTransaction::%s this={ mName=%s } "
"End==============================",
this, __FUNCTION__,
nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get()));
return rv;
}
NS_IMETHODIMP DeleteMultipleRangesTransaction::RedoTransaction() {
MOZ_LOG(GetLogModule(), LogLevel::Info,
("%p DeleteMultipleRangesTransaction::%s this={ mName=%s } "
"Start==============================",
this, __FUNCTION__,
nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get()));
nsresult rv = EditAggregateTransaction::RedoTransaction();
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"EditAggregateTransaction::RedoTransaction() failed");
MOZ_LOG(GetLogModule(), LogLevel::Info,
("%p DeleteMultipleRangesTransaction::%s this={ mName=%s } "
"End==============================",
this, __FUNCTION__,
nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get()));
return rv;
}
void DeleteMultipleRangesTransaction::AppendChild(
DeleteContentTransactionBase& aTransaction) {
mChildren.AppendElement(aTransaction);
}
void DeleteMultipleRangesTransaction::AppendChild(
DeleteRangeTransaction& aTransaction) {
mChildren.AppendElement(aTransaction);
}
} // namespace mozilla

View File

@ -0,0 +1,49 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 DeleteMultipleRangesTransactionBase_h
#define DeleteMultipleRangesTransactionBase_h
#include "DeleteContentTransactionBase.h"
#include "EditAggregateTransaction.h"
#include "EditorForwards.h"
#include "nsCycleCollectionParticipant.h"
#include "nsISupportsImpl.h"
namespace mozilla {
/**
* An abstract transaction that removes text or node.
*/
class DeleteMultipleRangesTransaction final : public EditAggregateTransaction {
public:
static already_AddRefed<DeleteMultipleRangesTransaction> Create() {
RefPtr<DeleteMultipleRangesTransaction> transaction =
new DeleteMultipleRangesTransaction();
return transaction.forget();
}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DeleteMultipleRangesTransaction,
EditAggregateTransaction)
NS_DECL_EDITTRANSACTIONBASE
NS_DECL_EDITTRANSACTIONBASE_GETASMETHODS_OVERRIDE(
DeleteMultipleRangesTransaction)
MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() final;
void AppendChild(DeleteContentTransactionBase& aTransaction);
void AppendChild(DeleteRangeTransaction& aTransaction);
protected:
~DeleteMultipleRangesTransaction() = default;
};
} // namespace mozilla
#endif // #ifndef DeleteMultipleRangesTransaction_h

View File

@ -5,12 +5,15 @@
#include "DeleteNodeTransaction.h"
#include "EditorBase.h"
#include "EditorDOMPoint.h"
#include "HTMLEditUtils.h"
#include "mozilla/EditorBase.h"
#include "SelectionState.h" // RangeUpdater
#include "TextEditor.h"
#include "mozilla/Logging.h"
#include "mozilla/SelectionState.h" // RangeUpdater
#include "mozilla/TextEditor.h"
#include "mozilla/ToString.h"
#include "nsDebug.h"
#include "nsError.h"
#include "nsAString.h"
@ -30,7 +33,7 @@ already_AddRefed<DeleteNodeTransaction> DeleteNodeTransaction::MaybeCreate(
DeleteNodeTransaction::DeleteNodeTransaction(EditorBase& aEditorBase,
nsIContent& aContentToDelete)
: mEditorBase(&aEditorBase),
: DeleteContentTransactionBase(aEditorBase),
mContentToDelete(&aContentToDelete),
mParentNode(aContentToDelete.GetParentNode()) {
MOZ_DIAGNOSTIC_ASSERT_IF(
@ -64,14 +67,14 @@ std::ostream& operator<<(std::ostream& aStream,
return aStream;
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(DeleteNodeTransaction, EditTransactionBase,
mEditorBase, mContentToDelete, mParentNode,
mRefContent)
NS_IMPL_CYCLE_COLLECTION_INHERITED(DeleteNodeTransaction,
DeleteContentTransactionBase,
mContentToDelete, mParentNode, mRefContent)
NS_IMPL_ADDREF_INHERITED(DeleteNodeTransaction, EditTransactionBase)
NS_IMPL_RELEASE_INHERITED(DeleteNodeTransaction, EditTransactionBase)
NS_IMPL_ADDREF_INHERITED(DeleteNodeTransaction, DeleteContentTransactionBase)
NS_IMPL_RELEASE_INHERITED(DeleteNodeTransaction, DeleteContentTransactionBase)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeleteNodeTransaction)
NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)
NS_INTERFACE_MAP_END_INHERITING(DeleteContentTransactionBase)
bool DeleteNodeTransaction::CanDoIt() const {
if (NS_WARN_IF(!mContentToDelete) || NS_WARN_IF(!mEditorBase) ||
@ -110,6 +113,10 @@ NS_IMETHODIMP DeleteNodeTransaction::DoTransaction() {
return error.StealNSResult();
}
EditorDOMPoint DeleteNodeTransaction::SuggestPointToPutCaret() const {
return EditorDOMPoint();
}
NS_IMETHODIMP DeleteNodeTransaction::UndoTransaction() {
MOZ_LOG(GetLogModule(), LogLevel::Info,
("%p DeleteNodeTransaction::%s this=%s", this, __FUNCTION__,

View File

@ -6,7 +6,7 @@
#ifndef DeleteNodeTransaction_h
#define DeleteNodeTransaction_h
#include "EditTransactionBase.h"
#include "DeleteContentTransactionBase.h"
#include "EditorForwards.h"
@ -22,7 +22,7 @@ namespace mozilla {
/**
* A transaction that deletes a single element
*/
class DeleteNodeTransaction final : public EditTransactionBase {
class DeleteNodeTransaction final : public DeleteContentTransactionBase {
protected:
DeleteNodeTransaction(EditorBase& aEditorBase, nsIContent& aContentToDelete);
@ -45,12 +45,14 @@ class DeleteNodeTransaction final : public EditTransactionBase {
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DeleteNodeTransaction,
EditTransactionBase)
DeleteContentTransactionBase)
NS_DECL_EDITTRANSACTIONBASE
NS_DECL_EDITTRANSACTIONBASE_GETASMETHODS_OVERRIDE(DeleteNodeTransaction)
MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() override;
MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() final;
EditorDOMPoint SuggestPointToPutCaret() const final;
nsIContent* GetContent() const { return mContentToDelete; }
@ -60,9 +62,6 @@ class DeleteNodeTransaction final : public EditTransactionBase {
protected:
virtual ~DeleteNodeTransaction() = default;
// The editor for this transaction.
RefPtr<EditorBase> mEditorBase;
// The element to delete.
nsCOMPtr<nsIContent> mContentToDelete;

View File

@ -5,6 +5,7 @@
#include "DeleteRangeTransaction.h"
#include "DeleteContentTransactionBase.h"
#include "DeleteNodeTransaction.h"
#include "DeleteTextTransaction.h"
#include "EditorBase.h"
@ -46,6 +47,11 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(DeleteRangeTransaction,
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeleteRangeTransaction)
NS_INTERFACE_MAP_END_INHERITING(EditAggregateTransaction)
void DeleteRangeTransaction::AppendChild(
DeleteContentTransactionBase& aTransaction) {
mChildren.AppendElement(aTransaction);
}
nsresult
DeleteRangeTransaction::MaybeExtendDeletingRangeWithSurroundingWhitespace(
nsRange& aRange) const {
@ -280,10 +286,7 @@ nsresult DeleteRangeTransaction::AppendTransactionsToDeleteIn(
NS_WARNING("DeleteTextTransaction::MaybeCreate() failed");
return NS_ERROR_FAILURE;
}
DebugOnly<nsresult> rvIgnored = AppendChild(deleteTextTransaction);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"DeleteRangeTransaction::AppendChild() failed, but ignored");
AppendChild(*deleteTextTransaction);
return NS_OK;
}
@ -302,10 +305,7 @@ nsresult DeleteRangeTransaction::AppendTransactionsToDeleteIn(
RefPtr<DeleteNodeTransaction> deleteNodeTransaction =
DeleteNodeTransaction::MaybeCreate(*mEditorBase, *child);
if (deleteNodeTransaction) {
DebugOnly<nsresult> rvIgnored = AppendChild(deleteNodeTransaction);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"DeleteRangeTransaction::AppendChild() failed, but ignored");
AppendChild(*deleteNodeTransaction);
}
}
@ -350,10 +350,7 @@ nsresult DeleteRangeTransaction::AppendTransactionToDeleteText(
NS_WARNING("DeleteTextTransaction::MaybeCreate() failed");
return NS_ERROR_FAILURE;
}
DebugOnly<nsresult> rvIgnored = AppendChild(deleteTextTransaction);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"DeleteRangeTransaction::AppendChild() failed, but ignored");
AppendChild(*deleteTextTransaction);
return NS_OK;
}
@ -384,10 +381,7 @@ DeleteRangeTransaction::AppendTransactionsToDeleteNodesWhoseEndBoundaryIn(
RefPtr<DeleteNodeTransaction> deleteNodeTransaction =
DeleteNodeTransaction::MaybeCreate(*mEditorBase, *node->AsContent());
if (deleteNodeTransaction) {
DebugOnly<nsresult> rvIgnored = AppendChild(deleteNodeTransaction);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"DeleteRangeTransaction::AppendChild() failed, but ignored");
AppendChild(*deleteNodeTransaction);
}
}
return NS_OK;

View File

@ -6,6 +6,7 @@
#ifndef DeleteRangeTransaction_h
#define DeleteRangeTransaction_h
#include "DeleteContentTransactionBase.h"
#include "EditAggregateTransaction.h"
#include "EditorBase.h"
@ -53,6 +54,8 @@ class DeleteRangeTransaction final : public EditAggregateTransaction {
NS_DECL_EDITTRANSACTIONBASE
NS_DECL_EDITTRANSACTIONBASE_GETASMETHODS_OVERRIDE(DeleteRangeTransaction)
void AppendChild(DeleteContentTransactionBase& aTransaction);
MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() override;
protected:

View File

@ -5,12 +5,14 @@
#include "DeleteTextTransaction.h"
#include "EditorBase.h"
#include "EditorDOMPoint.h"
#include "HTMLEditUtils.h"
#include "SelectionState.h"
#include "mozilla/Assertions.h"
#include "mozilla/EditorBase.h"
#include "mozilla/EditorDOMPoint.h"
#include "mozilla/SelectionState.h"
#include "mozilla/dom/Selection.h"
#include "nsDebug.h"
#include "nsError.h"
#include "nsISupportsImpl.h"
@ -77,7 +79,7 @@ DeleteTextTransaction::MaybeCreateForNextCharacter(EditorBase& aEditorBase,
DeleteTextTransaction::DeleteTextTransaction(EditorBase& aEditorBase,
Text& aTextNode, uint32_t aOffset,
uint32_t aLengthToDelete)
: mEditorBase(&aEditorBase),
: DeleteContentTransactionBase(aEditorBase),
mTextNode(&aTextNode),
mOffset(aOffset),
mLengthToDelete(aLengthToDelete) {
@ -99,11 +101,11 @@ std::ostream& operator<<(std::ostream& aStream,
return aStream;
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(DeleteTextTransaction, EditTransactionBase,
mEditorBase, mTextNode)
NS_IMPL_CYCLE_COLLECTION_INHERITED(DeleteTextTransaction,
DeleteContentTransactionBase, mTextNode)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeleteTextTransaction)
NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)
NS_INTERFACE_MAP_END_INHERITING(DeleteContentTransactionBase)
bool DeleteTextTransaction::CanDoIt() const {
if (NS_WARN_IF(!mTextNode) || NS_WARN_IF(!mEditorBase)) {
@ -145,12 +147,19 @@ NS_IMETHODIMP DeleteTextTransaction::DoTransaction() {
return NS_OK;
}
editorBase->CollapseSelectionTo(EditorRawDOMPoint(textNode, mOffset), error);
editorBase->CollapseSelectionTo(SuggestPointToPutCaret(), error);
NS_WARNING_ASSERTION(!error.Failed(),
"EditorBase::CollapseSelectionTo() failed");
return error.StealNSResult();
}
EditorDOMPoint DeleteTextTransaction::SuggestPointToPutCaret() const {
if (NS_WARN_IF(!mTextNode) || NS_WARN_IF(!mTextNode->IsInComposedDoc())) {
return EditorDOMPoint();
}
return EditorDOMPoint(mTextNode, mOffset);
}
// XXX: We may want to store the selection state and restore it properly. Was
// it an insertion point or an extended selection?
NS_IMETHODIMP DeleteTextTransaction::UndoTransaction() {

View File

@ -6,11 +6,12 @@
#ifndef DeleteTextTransaction_h
#define DeleteTextTransaction_h
#include "EditTransactionBase.h"
#include "DeleteContentTransactionBase.h"
#include "EditorForwards.h"
#include "mozilla/dom/Text.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsID.h"
@ -22,7 +23,7 @@ namespace mozilla {
/**
* A transaction that removes text from a content node.
*/
class DeleteTextTransaction final : public EditTransactionBase {
class DeleteTextTransaction final : public DeleteContentTransactionBase {
protected:
DeleteTextTransaction(EditorBase& aEditorBase, dom::Text& aTextNode,
uint32_t aOffset, uint32_t aLengthToDelete);
@ -62,13 +63,15 @@ class DeleteTextTransaction final : public EditTransactionBase {
bool CanDoIt() const;
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DeleteTextTransaction,
EditTransactionBase)
DeleteContentTransactionBase)
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
NS_DECL_EDITTRANSACTIONBASE
NS_DECL_EDITTRANSACTIONBASE_GETASMETHODS_OVERRIDE(DeleteTextTransaction)
MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() override;
MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() final;
EditorDOMPoint SuggestPointToPutCaret() const final;
dom::Text* GetText() const { return mTextNode; }
uint32_t Offset() const { return mOffset; }
@ -78,9 +81,6 @@ class DeleteTextTransaction final : public EditTransactionBase {
const DeleteTextTransaction& aTransaction);
protected:
// The provider of basic editing operations.
RefPtr<EditorBase> mEditorBase;
// The CharacterData node to operate upon.
RefPtr<dom::Text> mTextNode;

View File

@ -119,25 +119,6 @@ NS_IMETHODIMP EditAggregateTransaction::Merge(nsITransaction* aOtherTransaction,
return mChildren[0]->Merge(aOtherTransaction, aDidMerge);
}
NS_IMETHODIMP EditAggregateTransaction::AppendChild(
EditTransactionBase* aTransaction) {
if (NS_WARN_IF(!aTransaction)) {
return NS_ERROR_INVALID_ARG;
}
mChildren.AppendElement(*aTransaction);
return NS_OK;
}
NS_IMETHODIMP EditAggregateTransaction::GetName(nsAtom** aName) {
if (NS_WARN_IF(!aName)) {
return NS_ERROR_INVALID_ARG;
}
if (NS_WARN_IF(!mName)) {
return NS_ERROR_FAILURE;
}
*aName = do_AddRef(mName).take();
return NS_OK;
}
nsAtom* EditAggregateTransaction::GetName() const { return mName; }
} // namespace mozilla

View File

@ -9,12 +9,13 @@
#include "EditTransactionBase.h"
#include "mozilla/OwningNonNull.h"
#include "mozilla/RefPtr.h"
#include "nsAtom.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsAtom.h"
#include "nsISupportsImpl.h"
#include "nsTArray.h"
#include "nscore.h"
#include "nsISupportsImpl.h"
namespace mozilla {
@ -23,19 +24,7 @@ namespace mozilla {
* provides a list of child transactions.
*/
class EditAggregateTransaction : public EditTransactionBase {
protected:
EditAggregateTransaction() = default;
public:
/**
* Creates an edit aggregate transaction. This never returns nullptr.
*/
static already_AddRefed<EditAggregateTransaction> Create() {
RefPtr<EditAggregateTransaction> transaction =
new EditAggregateTransaction();
return transaction.forget();
}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(EditAggregateTransaction,
EditTransactionBase)
@ -45,15 +34,10 @@ class EditAggregateTransaction : public EditTransactionBase {
MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() override;
NS_IMETHOD Merge(nsITransaction* aOtherTransaction, bool* aDidMerge) override;
/**
* Append a transaction to this aggregate.
*/
NS_IMETHOD AppendChild(EditTransactionBase* aTransaction);
/**
* Get the name assigned to this transaction.
*/
NS_IMETHOD GetName(nsAtom** aName);
nsAtom* GetName() const;
const nsTArray<OwningNonNull<EditTransactionBase>>& ChildTransactions()
const {
@ -61,6 +45,7 @@ class EditAggregateTransaction : public EditTransactionBase {
}
protected:
EditAggregateTransaction() = default;
virtual ~EditAggregateTransaction() = default;
nsTArray<OwningNonNull<EditTransactionBase>> mChildren;

View File

@ -3,13 +3,15 @@
* 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/. */
#include "mozilla/EditTransactionBase.h"
#include "EditTransactionBase.h"
#include "mozilla/Logging.h"
#include "ChangeAttributeTransaction.h"
#include "ChangeStyleTransaction.h"
#include "CompositionTransaction.h"
#include "DeleteContentTransactionBase.h"
#include "DeleteMultipleRangesTransaction.h"
#include "DeleteNodeTransaction.h"
#include "DeleteRangeTransaction.h"
#include "DeleteTextTransaction.h"
@ -76,6 +78,8 @@ LogModule* EditTransactionBase::GetLogModule() {
NS_IMPL_EDITTRANSACTIONBASE_GETASMETHODS(ChangeAttributeTransaction)
NS_IMPL_EDITTRANSACTIONBASE_GETASMETHODS(ChangeStyleTransaction)
NS_IMPL_EDITTRANSACTIONBASE_GETASMETHODS(CompositionTransaction)
NS_IMPL_EDITTRANSACTIONBASE_GETASMETHODS(DeleteContentTransactionBase)
NS_IMPL_EDITTRANSACTIONBASE_GETASMETHODS(DeleteMultipleRangesTransaction)
NS_IMPL_EDITTRANSACTIONBASE_GETASMETHODS(DeleteNodeTransaction)
NS_IMPL_EDITTRANSACTIONBASE_GETASMETHODS(DeleteRangeTransaction)
NS_IMPL_EDITTRANSACTIONBASE_GETASMETHODS(DeleteTextTransaction)

View File

@ -51,6 +51,8 @@ class EditTransactionBase : public nsITransaction {
NS_DECL_GETASTRANSACTION_BASE(ChangeAttributeTransaction)
NS_DECL_GETASTRANSACTION_BASE(ChangeStyleTransaction)
NS_DECL_GETASTRANSACTION_BASE(CompositionTransaction)
NS_DECL_GETASTRANSACTION_BASE(DeleteContentTransactionBase)
NS_DECL_GETASTRANSACTION_BASE(DeleteMultipleRangesTransaction)
NS_DECL_GETASTRANSACTION_BASE(DeleteNodeTransaction)
NS_DECL_GETASTRANSACTION_BASE(DeleteRangeTransaction)
NS_DECL_GETASTRANSACTION_BASE(DeleteTextTransaction)

View File

@ -8,20 +8,20 @@
#include <stdio.h> // for nullptr, stdout
#include <string.h> // for strcmp
#include "AutoRangeArray.h" // for AutoRangeArray
#include "ChangeAttributeTransaction.h" // for ChangeAttributeTransaction
#include "CompositionTransaction.h" // for CompositionTransaction
#include "DeleteNodeTransaction.h" // for DeleteNodeTransaction
#include "DeleteRangeTransaction.h" // for DeleteRangeTransaction
#include "DeleteTextTransaction.h" // for DeleteTextTransaction
#include "EditAction.h" // for EditSubAction
#include "EditAggregateTransaction.h" // for EditAggregateTransaction
#include "EditorDOMPoint.h" // for EditorDOMPoint
#include "EditorUtils.h" // for various helper classes.
#include "EditTransactionBase.h" // for EditTransactionBase
#include "EditTransactionBase.h" // for EditTransactionBase
#include "EditorEventListener.h" // for EditorEventListener
#include "HTMLEditor.h" // for HTMLEditor
#include "AutoRangeArray.h" // for AutoRangeArray
#include "ChangeAttributeTransaction.h"
#include "CompositionTransaction.h"
#include "DeleteContentTransactionBase.h"
#include "DeleteMultipleRangesTransaction.h"
#include "DeleteNodeTransaction.h"
#include "DeleteRangeTransaction.h"
#include "DeleteTextTransaction.h"
#include "EditAction.h" // for EditSubAction
#include "EditorDOMPoint.h" // for EditorDOMPoint
#include "EditorUtils.h" // for various helper classes.
#include "EditTransactionBase.h" // for EditTransactionBase
#include "EditorEventListener.h" // for EditorEventListener
#include "HTMLEditor.h" // for HTMLEditor
#include "HTMLEditorInlines.h"
#include "HTMLEditUtils.h" // for HTMLEditUtils
#include "InsertNodeTransaction.h" // for InsertNodeTransaction
@ -3733,7 +3733,7 @@ void EditorBase::DoAfterRedoTransaction() {
MOZ_ALWAYS_SUCCEEDS(IncrementModificationCount(1));
}
already_AddRefed<EditAggregateTransaction>
already_AddRefed<DeleteMultipleRangesTransaction>
EditorBase::CreateTransactionForDeleteSelection(
HowToHandleCollapsedRange aHowToHandleCollapsedRange,
const AutoRangeArray& aRangesToDelete) {
@ -3748,8 +3748,8 @@ EditorBase::CreateTransactionForDeleteSelection(
}
// allocate the out-param transaction
RefPtr<EditAggregateTransaction> aggregateTransaction =
EditAggregateTransaction::Create();
RefPtr<DeleteMultipleRangesTransaction> transaction =
DeleteMultipleRangesTransaction::Create();
for (const OwningNonNull<nsRange>& range : aRangesToDelete.Ranges()) {
// Same with range as with selection; if it is collapsed and action
// is eNone, do nothing.
@ -3757,11 +3757,7 @@ EditorBase::CreateTransactionForDeleteSelection(
RefPtr<DeleteRangeTransaction> deleteRangeTransaction =
DeleteRangeTransaction::Create(*this, range);
// XXX Oh, not checking if deleteRangeTransaction can modify the range...
DebugOnly<nsresult> rvIgnored =
aggregateTransaction->AppendChild(deleteRangeTransaction);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"EditAggregationTransaction::AppendChild() failed, but ignored");
transaction->AppendChild(*deleteRangeTransaction);
continue;
}
@ -3770,7 +3766,7 @@ EditorBase::CreateTransactionForDeleteSelection(
}
// Let's extend the collapsed range to delete content around it.
RefPtr<EditTransactionBase> deleteNodeOrTextTransaction =
RefPtr<DeleteContentTransactionBase> deleteNodeOrTextTransaction =
CreateTransactionForCollapsedRange(range, aHowToHandleCollapsedRange);
// XXX When there are two or more ranges and at least one of them is
// not editable, deleteNodeOrTextTransaction may be nullptr.
@ -3779,19 +3775,15 @@ EditorBase::CreateTransactionForDeleteSelection(
NS_WARNING("EditorBase::CreateTransactionForCollapsedRange() failed");
return nullptr;
}
DebugOnly<nsresult> rvIgnored =
aggregateTransaction->AppendChild(deleteNodeOrTextTransaction);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"EditAggregationTransaction::AppendChild() failed, but ignored");
transaction->AppendChild(*deleteNodeOrTextTransaction);
}
return aggregateTransaction.forget();
return transaction.forget();
}
// XXX: currently, this doesn't handle edge conditions because GetNext/GetPrior
// are not implemented
already_AddRefed<EditTransactionBase>
already_AddRefed<DeleteContentTransactionBase>
EditorBase::CreateTransactionForCollapsedRange(
const nsRange& aCollapsedRange,
HowToHandleCollapsedRange aHowToHandleCollapsedRange) {
@ -4651,7 +4643,7 @@ nsresult EditorBase::DeleteRangesWithTransaction(
return NS_ERROR_FAILURE;
}
RefPtr<EditAggregateTransaction> deleteSelectionTransaction =
RefPtr<DeleteMultipleRangesTransaction> deleteSelectionTransaction =
CreateTransactionForDeleteSelection(howToHandleCollapsedRange,
aRangesToDelete);
if (!deleteSelectionTransaction) {

View File

@ -2553,26 +2553,23 @@ class EditorBase : public nsIEditor,
const AutoRangeArray& aRangesToDelete);
/**
* Create an aggregate transaction for delete the content in aRangesToDelete.
* The result may include DeleteNodeTransactions and/or DeleteTextTransactions
* as its children.
* Create a transaction for delete the content in aRangesToDelete.
* The result may include DeleteRangeTransaction (for deleting non-collapsed
* range), DeleteNodeTransactions and DeleteTextTransactions (for deleting
* collapsed range) as its children.
*
* @param aHowToHandleCollapsedRange
* How to handle collapsed ranges.
* @param aRangesToDelete The ranges to delete content.
* @return If it can remove the content in ranges, returns
* an aggregate transaction which has some
* DeleteNodeTransactions and/or
* DeleteTextTransactions as its children.
*/
already_AddRefed<EditAggregateTransaction>
already_AddRefed<DeleteMultipleRangesTransaction>
CreateTransactionForDeleteSelection(
HowToHandleCollapsedRange aHowToHandleCollapsedRange,
const AutoRangeArray& aRangesToDelete);
/**
* Create a transaction for removing the nodes and/or text around
* aRangeToDelete.
* Create a DeleteNodeTransaction or DeleteTextTransaction for removing a
* nodes or some text around aRangeToDelete.
*
* @param aCollapsedRange The range to be removed. This must be
* collapsed.
@ -2580,11 +2577,9 @@ class EditorBase : public nsIEditor,
* How to handle aCollapsedRange. Must
* be HowToHandleCollapsedRange::ExtendBackward or
* HowToHandleCollapsedRange::ExtendForward.
* @return The transaction to remove content around the
* range. Its type is DeleteNodeTransaction or
* DeleteTextTransaction.
*/
already_AddRefed<EditTransactionBase> CreateTransactionForCollapsedRange(
already_AddRefed<DeleteContentTransactionBase>
CreateTransactionForCollapsedRange(
const nsRange& aCollapsedRange,
HowToHandleCollapsedRange aHowToHandleCollapsedRange);

View File

@ -91,32 +91,34 @@ class RangeUpdater; // mozilla/SelectionState.h
class SelectionState; // mozilla/SelectionState.h
class TextEditor; // mozilla/TextEditor.h
class AutoRangeArray; // AutoRangeArray.h
class ChangeAttributeTransaction; // ChangeAttributeTransaction.h
class CompositionTransaction; // CompositionTransaction.h
class DeleteNodeTransaction; // DeleteNodeTransaction.h
class DeleteRangeTransaction; // DeleteRangeTransaction.h
class DeleteTextTransaction; // DeleteTextTransaction.h
class EditAggregateTransaction; // EditAggregateTransaction.h
class EditorEventListener; // EditorEventListener.h
class EditResult; // HTMLEditHelpers.h
class HTMLEditorEventListener; // HTMLEditorEventListener.h
class InsertNodeTransaction; // InsertNodeTransaction.h
class InsertTextTransaction; // InsertTextTransaction.h
class InterCiter; // InterCiter.h
class JoinNodesResult; // HTMLEditHelpers.h
class JoinNodesTransaction; // JoinNodesTransaction.h
class MoveNodeResult; // HTMLEditHelpers.h
class MoveNodeTransaction; // MoveNodeTransaction.h
class PlaceholderTransaction; // PlaceholderTransaction.h
class ReplaceTextTransaction; // ReplaceTextTransaction.h
class SplitNodeResult; // HTMLEditHelpers.h
class SplitNodeTransaction; // SplitNodeTransaction.h
class SplitRangeOffFromNodeResult; // HTMLEditHelpers.h
class SplitRangeOffResult; // HTMLEditHelpers.h
class WhiteSpaceVisibilityKeeper; // WSRunObject.h
class WSRunScanner; // WSRunObject.h
class WSScanResult; // WSRunObject.h
class AutoRangeArray; // AutoRangeArray.h
class ChangeAttributeTransaction; // ChangeAttributeTransaction.h
class CompositionTransaction; // CompositionTransaction.h
class DeleteContentTransactionBase; // DeleteContentTransactionBase.h
class DeleteMultipleRangesTransaction; // DeleteMultipleRangesTransaction.h
class DeleteNodeTransaction; // DeleteNodeTransaction.h
class DeleteRangeTransaction; // DeleteRangeTransaction.h
class DeleteTextTransaction; // DeleteTextTransaction.h
class EditAggregateTransaction; // EditAggregateTransaction.h
class EditorEventListener; // EditorEventListener.h
class EditResult; // HTMLEditHelpers.h
class HTMLEditorEventListener; // HTMLEditorEventListener.h
class InsertNodeTransaction; // InsertNodeTransaction.h
class InsertTextTransaction; // InsertTextTransaction.h
class InterCiter; // InterCiter.h
class JoinNodesResult; // HTMLEditHelpers.h
class JoinNodesTransaction; // JoinNodesTransaction.h
class MoveNodeResult; // HTMLEditHelpers.h
class MoveNodeTransaction; // MoveNodeTransaction.h
class PlaceholderTransaction; // PlaceholderTransaction.h
class ReplaceTextTransaction; // ReplaceTextTransaction.h
class SplitNodeResult; // HTMLEditHelpers.h
class SplitNodeTransaction; // SplitNodeTransaction.h
class SplitRangeOffFromNodeResult; // HTMLEditHelpers.h
class SplitRangeOffResult; // HTMLEditHelpers.h
class WhiteSpaceVisibilityKeeper; // WSRunObject.h
class WSRunScanner; // WSRunObject.h
class WSScanResult; // WSRunObject.h
/******************************************************************************
* structs

View File

@ -52,6 +52,10 @@ NS_INTERFACE_MAP_END_INHERITING(EditAggregateTransaction)
NS_IMPL_ADDREF_INHERITED(PlaceholderTransaction, EditAggregateTransaction)
NS_IMPL_RELEASE_INHERITED(PlaceholderTransaction, EditAggregateTransaction)
void PlaceholderTransaction::AppendChild(EditTransactionBase& aTransaction) {
mChildren.AppendElement(aTransaction);
}
NS_IMETHODIMP PlaceholderTransaction::DoTransaction() {
MOZ_LOG(
GetLogModule(), LogLevel::Info,
@ -165,11 +169,7 @@ NS_IMETHODIMP PlaceholderTransaction::Merge(nsITransaction* aOtherTransaction,
if (!mCompositionTransaction) {
// this is the first IME txn in the placeholder
mCompositionTransaction = otherCompositionTransaction;
DebugOnly<nsresult> rvIgnored =
AppendChild(otherCompositionTransaction);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"EditAggregateTransaction::AppendChild() failed, but ignored");
AppendChild(*otherCompositionTransaction);
} else {
bool didMerge;
mCompositionTransaction->Merge(otherCompositionTransaction, &didMerge);
@ -178,11 +178,7 @@ NS_IMETHODIMP PlaceholderTransaction::Merge(nsITransaction* aOtherTransaction,
// not absorb further IME txns. So just stack this one after it
// and remember it as a candidate for further merges.
mCompositionTransaction = otherCompositionTransaction;
DebugOnly<nsresult> rvIgnored =
AppendChild(otherCompositionTransaction);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"EditAggregateTransaction::AppendChild() failed, but ignored");
AppendChild(*otherCompositionTransaction);
}
}
} else {
@ -191,10 +187,7 @@ NS_IMETHODIMP PlaceholderTransaction::Merge(nsITransaction* aOtherTransaction,
if (!otherPlaceholderTransaction) {
// See bug 171243: just drop incoming placeholders on the floor.
// Their children will be swallowed by this preexisting one.
DebugOnly<nsresult> rvIgnored = AppendChild(otherTransactionBase);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"EditAggregateTransaction::AppendChild() failed, but ignored");
AppendChild(*otherTransactionBase);
}
}
*aDidMerge = true;
@ -228,11 +221,7 @@ NS_IMETHODIMP PlaceholderTransaction::Merge(nsITransaction* aOtherTransaction,
return NS_OK;
}
RefPtr<nsAtom> otherTransactionName;
DebugOnly<nsresult> rvIgnored = otherPlaceholderTransaction->GetName(
getter_AddRefs(otherTransactionName));
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"PlaceholderTransaction::GetName() failed, but ignored");
RefPtr<nsAtom> otherTransactionName = otherPlaceholderTransaction->GetName();
if (!otherTransactionName || otherTransactionName == nsGkAtoms::_empty ||
otherTransactionName != mName) {
MOZ_LOG(GetLogModule(), LogLevel::Debug,
@ -312,7 +301,7 @@ NS_IMETHODIMP PlaceholderTransaction::Merge(nsITransaction* aOtherTransaction,
// pre-existing placeholder and drop the new one on the floor. The
// EndPlaceHolderBatch() call on the new placeholder will be
// forwarded to this older one.
rvIgnored = RememberEndingSelection();
DebugOnly<nsresult> rvIgnored = RememberEndingSelection();
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"PlaceholderTransaction::RememberEndingSelection() failed, but "

View File

@ -51,7 +51,6 @@ class PlaceholderTransaction final : public EditAggregateTransaction,
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PlaceholderTransaction,
EditAggregateTransaction)
// ------------ EditAggregateTransaction -----------------------
NS_DECL_EDITTRANSACTIONBASE
NS_DECL_EDITTRANSACTIONBASE_GETASMETHODS_OVERRIDE(PlaceholderTransaction)
@ -59,6 +58,8 @@ class PlaceholderTransaction final : public EditAggregateTransaction,
MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() override;
NS_IMETHOD Merge(nsITransaction* aTransaction, bool* aDidMerge) override;
void AppendChild(EditTransactionBase& aTransaction);
nsresult EndPlaceHolderBatch();
void ForwardEndBatchTo(PlaceholderTransaction& aForwardingTransaction) {

View File

@ -35,6 +35,8 @@ UNIFIED_SOURCES += [
"ChangeStyleTransaction.cpp",
"CompositionTransaction.cpp",
"CSSEditUtils.cpp",
"DeleteContentTransactionBase.cpp",
"DeleteMultipleRangesTransaction.cpp",
"DeleteNodeTransaction.cpp",
"DeleteRangeTransaction.cpp",
"DeleteTextTransaction.cpp",

View File

@ -14,9 +14,6 @@ webidl Range;
#include "mozilla/EditorDOMPoint.h"
class nsINode;
class nsIContent;
namespace mozilla {
template class EditorDOMPointBase<nsINode*, nsIContent*>;
} // namespace mozilla
%}
[ref] native EditorRawDOMPointRef(mozilla::EditorDOMPointBase<nsINode*, nsIContent*>);