Bug 1619914 - part 2: Mark transaction class methods and their caller methods as `MOZ_CAN_RUN_SCRIPT r=m_kato

Differential Revision: https://phabricator.services.mozilla.com/D69303

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Masayuki Nakano 2020-04-03 01:39:36 +00:00
parent 5fb2cba97c
commit eb881aff87
32 changed files with 129 additions and 108 deletions

View File

@ -58,7 +58,7 @@ class ChangeAttributeTransaction final : public EditTransactionBase {
NS_DECL_EDITTRANSACTIONBASE
NS_IMETHOD RedoTransaction() override;
MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() override;
private:
virtual ~ChangeAttributeTransaction() = default;

View File

@ -59,7 +59,7 @@ class ChangeStyleTransaction final : public EditTransactionBase {
NS_DECL_EDITTRANSACTIONBASE
NS_IMETHOD RedoTransaction() override;
MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() override;
/**
* Returns true if the list of white-space separated values contains aValue
@ -106,7 +106,8 @@ class ChangeStyleTransaction final : public EditTransactionBase {
* is empty, remove the property from element's styles. If the boolean
* is false, just remove the style attribute.
*/
nsresult SetStyle(bool aAttributeWasSet, nsAString& aValue);
MOZ_CAN_RUN_SCRIPT nsresult SetStyle(bool aAttributeWasSet,
nsAString& aValue);
// The element to operate upon.
RefPtr<nsStyledElement> mStyledElement;

View File

@ -79,8 +79,7 @@ NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)
NS_IMPL_ADDREF_INHERITED(CompositionTransaction, EditTransactionBase)
NS_IMPL_RELEASE_INHERITED(CompositionTransaction, EditTransactionBase)
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP
CompositionTransaction::DoTransaction() {
NS_IMETHODIMP CompositionTransaction::DoTransaction() {
if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode)) {
return NS_ERROR_NOT_AVAILABLE;
}
@ -152,8 +151,7 @@ CompositionTransaction::DoTransaction() {
return rv;
}
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP
CompositionTransaction::UndoTransaction() {
NS_IMETHODIMP CompositionTransaction::UndoTransaction() {
if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode)) {
return NS_ERROR_NOT_AVAILABLE;
}

View File

@ -71,14 +71,14 @@ class CompositionTransaction final : public EditTransactionBase {
void MarkFixed();
MOZ_CAN_RUN_SCRIPT_BOUNDARY static nsresult SetIMESelection(
MOZ_CAN_RUN_SCRIPT static nsresult SetIMESelection(
EditorBase& aEditorBase, dom::Text* aTextNode, uint32_t aOffsetInNode,
uint32_t aLengthOfCompositionString, const TextRangeArray* aRanges);
private:
virtual ~CompositionTransaction() = default;
nsresult SetSelectionForRanges();
MOZ_CAN_RUN_SCRIPT nsresult SetSelectionForRanges();
// The text element to operate upon.
RefPtr<dom::Text> mTextNode;

View File

@ -69,8 +69,7 @@ NS_IMPL_RELEASE_INHERITED(CreateElementTransaction, EditTransactionBase)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CreateElementTransaction)
NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP
CreateElementTransaction::DoTransaction() {
NS_IMETHODIMP CreateElementTransaction::DoTransaction() {
if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTag) ||
NS_WARN_IF(!mPointToInsert.IsSet())) {
return NS_ERROR_NOT_INITIALIZED;

View File

@ -51,7 +51,7 @@ class CreateElementTransaction final : public EditTransactionBase {
NS_DECL_EDITTRANSACTIONBASE
NS_IMETHOD RedoTransaction() override;
MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() override;
dom::Element* GetNewElement() const { return mNewElement; }
@ -61,7 +61,7 @@ class CreateElementTransaction final : public EditTransactionBase {
/**
* InsertNewNode() inserts mNewNode before the child node at mPointToInsert.
*/
void InsertNewNode(ErrorResult& aError);
MOZ_CAN_RUN_SCRIPT void InsertNewNode(ErrorResult& aError);
// The document into which the new node will be inserted.
RefPtr<EditorBase> mEditorBase;

View File

@ -48,7 +48,7 @@ class DeleteNodeTransaction final : public EditTransactionBase {
NS_DECL_EDITTRANSACTIONBASE
NS_IMETHOD RedoTransaction() override;
MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() override;
protected:
virtual ~DeleteNodeTransaction() = default;

View File

@ -49,7 +49,7 @@ class DeleteRangeTransaction final : public EditAggregateTransaction {
NS_DECL_EDITTRANSACTIONBASE
NS_IMETHOD RedoTransaction() override;
MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() override;
protected:
/**

View File

@ -97,8 +97,7 @@ bool DeleteTextTransaction::CanDoIt() const {
return mEditorBase->IsModifiableNode(*mTextNode);
}
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP
DeleteTextTransaction::DoTransaction() {
NS_IMETHODIMP DeleteTextTransaction::DoTransaction() {
if (NS_WARN_IF(!CanDoIt())) {
return NS_ERROR_NOT_AVAILABLE;
}
@ -140,8 +139,7 @@ DeleteTextTransaction::DoTransaction() {
// XXX: We may want to store the selection state and restore it properly. Was
// it an insertion point or an extended selection?
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP
DeleteTextTransaction::UndoTransaction() {
NS_IMETHODIMP DeleteTextTransaction::UndoTransaction() {
if (NS_WARN_IF(!CanDoIt())) {
return NS_ERROR_NOT_AVAILABLE;
}

View File

@ -24,8 +24,8 @@ NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)
NS_IMETHODIMP EditAggregateTransaction::DoTransaction() {
// FYI: It's legal (but not very useful) to have an empty child list.
AutoTArray<OwningNonNull<EditTransactionBase>, 10> children(mChildren);
for (auto& childTransaction : children) {
nsresult rv = childTransaction->DoTransaction();
for (OwningNonNull<EditTransactionBase>& childTransaction : children) {
nsresult rv = MOZ_KnownLive(childTransaction)->DoTransaction();
if (NS_FAILED(rv)) {
NS_WARNING("EditTransactionBase::DoTransaction() failed");
return rv;
@ -38,8 +38,9 @@ NS_IMETHODIMP EditAggregateTransaction::UndoTransaction() {
// FYI: It's legal (but not very useful) to have an empty child list.
// Undo goes through children backwards.
AutoTArray<OwningNonNull<EditTransactionBase>, 10> children(mChildren);
for (auto& childTransaction : Reversed(children)) {
nsresult rv = childTransaction->UndoTransaction();
for (OwningNonNull<EditTransactionBase>& childTransaction :
Reversed(children)) {
nsresult rv = MOZ_KnownLive(childTransaction)->UndoTransaction();
if (NS_FAILED(rv)) {
NS_WARNING("EditTransactionBase::UndoTransaction() failed");
return rv;
@ -51,8 +52,8 @@ NS_IMETHODIMP EditAggregateTransaction::UndoTransaction() {
NS_IMETHODIMP EditAggregateTransaction::RedoTransaction() {
// It's legal (but not very useful) to have an empty child list.
AutoTArray<OwningNonNull<EditTransactionBase>, 10> children(mChildren);
for (auto& childTransaction : children) {
nsresult rv = childTransaction->RedoTransaction();
for (OwningNonNull<EditTransactionBase>& childTransaction : children) {
nsresult rv = MOZ_KnownLive(childTransaction)->RedoTransaction();
if (NS_FAILED(rv)) {
NS_WARNING("EditTransactionBase::RedoTransaction() failed");
return rv;

View File

@ -43,7 +43,7 @@ class EditAggregateTransaction : public EditTransactionBase {
NS_DECL_EDITTRANSACTIONBASE
NS_IMETHOD RedoTransaction() override;
MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() override;
NS_IMETHOD Merge(nsITransaction* aTransaction, bool* aDidMerge) override;
/**

View File

@ -21,7 +21,7 @@ class EditTransactionBase : public nsITransaction {
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(EditTransactionBase, nsITransaction)
NS_IMETHOD RedoTransaction(void) override;
MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction(void) override;
NS_IMETHOD GetIsTransient(bool* aIsTransient) override;
NS_IMETHOD Merge(nsITransaction* aTransaction, bool* aDidMerge) override;
@ -31,8 +31,8 @@ class EditTransactionBase : public nsITransaction {
} // namespace mozilla
#define NS_DECL_EDITTRANSACTIONBASE \
NS_IMETHOD DoTransaction() override; \
NS_IMETHOD UndoTransaction() override;
#define NS_DECL_EDITTRANSACTIONBASE \
MOZ_CAN_RUN_SCRIPT NS_IMETHOD DoTransaction() override; \
MOZ_CAN_RUN_SCRIPT NS_IMETHOD UndoTransaction() override;
#endif // #ifndef mozilla_EditTransactionBase_h

View File

@ -360,7 +360,7 @@ nsresult EditorBase::PostCreate() {
// update nsTextStateManager and caret if we have focus
nsCOMPtr<nsIContent> focusedContent = GetFocusedContent();
if (focusedContent) {
DebugOnly<nsresult> rvIgnored = InitializeSelection(focusedContent);
DebugOnly<nsresult> rvIgnored = InitializeSelection(*focusedContent);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"EditorBase::InitializeSelection() failed, but ignored");
@ -5074,14 +5074,11 @@ void EditorBase::InitializeSelectionAncestorLimit(nsIContent& aAncestorLimit) {
SelectionRefPtr()->SetAncestorLimiter(&aAncestorLimit);
}
nsresult EditorBase::InitializeSelection(EventTarget* aFocusEventTarget) {
nsresult EditorBase::InitializeSelection(nsINode& aFocusEventTargetNode) {
MOZ_ASSERT(IsEditActionDataAvailable());
nsCOMPtr<nsINode> targetNode = do_QueryInterface(aFocusEventTarget);
if (NS_WARN_IF(!targetNode)) {
return NS_ERROR_INVALID_ARG;
}
nsCOMPtr<nsIContent> selectionRootContent = FindSelectionRoot(targetNode);
nsCOMPtr<nsIContent> selectionRootContent =
FindSelectionRoot(&aFocusEventTargetNode);
if (!selectionRootContent) {
return NS_OK;
}
@ -5113,7 +5110,8 @@ nsresult EditorBase::InitializeSelection(EventTarget* aFocusEventTarget) {
// Also, make sure to always ignore it for designMode, since that effectively
// overrides everything and we allow to edit stuff with
// contenteditable="false" subtrees in such a document.
caret->SetIgnoreUserModify(targetNode->OwnerDoc()->HasFlag(NODE_IS_EDITABLE));
caret->SetIgnoreUserModify(
aFocusEventTargetNode.OwnerDoc()->HasFlag(NODE_IS_EDITABLE));
// Init selection
rvIgnored =
@ -5148,15 +5146,16 @@ nsresult EditorBase::InitializeSelection(EventTarget* aFocusEventTarget) {
EditorRawDOMPoint atStartOfFirstRange(firstRange->StartRef());
EditorRawDOMPoint betterInsertionPoint =
FindBetterInsertionPoint(atStartOfFirstRange);
Text* textNode = betterInsertionPoint.GetContainerAsText();
RefPtr<Text> textNode = betterInsertionPoint.GetContainerAsText();
MOZ_ASSERT(textNode,
"There must be text node if composition string is not empty");
if (textNode) {
MOZ_ASSERT(textNode->Length() >= mComposition->XPEndOffsetInTextNode(),
"The text node must be different from the old text node");
RefPtr<TextRangeArray> ranges = mComposition->GetRanges();
DebugOnly<nsresult> rvIgnored = CompositionTransaction::SetIMESelection(
*this, textNode, mComposition->XPOffsetInTextNode(),
mComposition->XPLengthInTextNode(), mComposition->GetRanges());
mComposition->XPLengthInTextNode(), ranges);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"CompositionTransaction::SetIMESelection() failed, but ignored");
@ -5215,7 +5214,7 @@ void EditorBase::ReinitializeSelection(Element& aElement) {
return;
}
OnFocus(&aElement);
OnFocus(aElement);
// If previous focused editor turn on spellcheck and this editor doesn't
// turn on it, spellcheck state is mismatched. So we need to re-sync it.
@ -5493,13 +5492,13 @@ bool EditorBase::IsAcceptableInputEvent(WidgetGUIEvent* aGUIEvent) {
return IsActiveInDOMWindow();
}
void EditorBase::OnFocus(EventTarget* aFocusEventTarget) {
void EditorBase::OnFocus(nsINode& aFocusEventTargetNode) {
AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
if (NS_WARN_IF(!editActionData.CanHandle())) {
return;
}
InitializeSelection(aFocusEventTarget);
InitializeSelection(aFocusEventTargetNode);
mSpellCheckerDictionaryUpdated = false;
if (mInlineSpellChecker && CanEnableSpellCheck()) {
DebugOnly<nsresult> rvIgnored =

View File

@ -590,7 +590,7 @@ class EditorBase : public nsIEditor,
* All actions that have to be done when the editor is focused needs to be
* added here.
*/
void OnFocus(dom::EventTarget* aFocusEventTarget);
MOZ_CAN_RUN_SCRIPT void OnFocus(nsINode& aFocusEventTargetNode);
/** Resyncs spellchecking state (enabled/disabled). This should be called
* when anything that affects spellchecking state changes, such as the
@ -604,7 +604,7 @@ class EditorBase : public nsIEditor,
* selection state even if this has no focus. So if destroying editor,
* we have to call this method for focused editor to set selection state.
*/
void ReinitializeSelection(Element& aElement);
MOZ_CAN_RUN_SCRIPT void ReinitializeSelection(Element& aElement);
/**
* InsertTextAsAction() inserts aStringToInsert at selection.
@ -2361,7 +2361,7 @@ class EditorBase : public nsIEditor,
* XXX What's the difference with PlaceholderTransaction? Should we always
* use it instead?
*/
void BeginTransactionInternal();
MOZ_CAN_RUN_SCRIPT void BeginTransactionInternal();
MOZ_CAN_RUN_SCRIPT void EndTransactionInternal();
protected: // Shouldn't be used by friend classes
@ -2583,7 +2583,7 @@ class EditorBase : public nsIEditor,
* a host of the editor, i.e., the editor doesn't get focus, this does
* nothing.
*/
nsresult InitializeSelection(dom::EventTarget* aFocusEventTarget);
MOZ_CAN_RUN_SCRIPT nsresult InitializeSelection(nsINode& aFocusEventTarget);
enum NotificationForEditorObservers {
eNotifyEditorObserversOfEnd,
@ -2638,7 +2638,7 @@ class EditorBase : public nsIEditor,
EditorBase& aEditorBase MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: mEditorBase(aEditorBase) {
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
mEditorBase.BeginTransactionInternal();
MOZ_KnownLive(mEditorBase).BeginTransactionInternal();
}
MOZ_CAN_RUN_SCRIPT ~AutoTransactionBatch() {

View File

@ -1175,7 +1175,7 @@ nsresult EditorEventListener::Focus(InternalFocusEvent* aFocusEvent) {
}
}
editorBase->OnFocus(target);
editorBase->OnFocus(*eventTargetNode);
if (DetachedFromEditorOrDefaultPrevented(aFocusEvent)) {
return NS_OK;
}

View File

@ -75,7 +75,7 @@ class EditorEventListener : public nsIDOMEventListener {
}
MOZ_CAN_RUN_SCRIPT virtual nsresult MouseClick(
WidgetMouseEvent* aMouseClickEvent);
nsresult Focus(InternalFocusEvent* aFocusEvent);
MOZ_CAN_RUN_SCRIPT nsresult Focus(InternalFocusEvent* aFocusEvent);
nsresult Blur(InternalFocusEvent* aBlurEvent);
MOZ_CAN_RUN_SCRIPT nsresult DragEnter(dom::DragEvent* aDragEvent);
MOZ_CAN_RUN_SCRIPT nsresult DragOverOrDrop(dom::DragEvent* aDragEvent);

View File

@ -700,7 +700,7 @@ class MOZ_RAII AutoTransactionBatchExternal final {
EditorBase& aEditorBase MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: mEditorBase(aEditorBase) {
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
mEditorBase.BeginTransaction();
MOZ_KnownLive(mEditorBase).BeginTransaction();
}
MOZ_CAN_RUN_SCRIPT ~AutoTransactionBatchExternal() {

View File

@ -5182,7 +5182,7 @@ void HTMLEditor::NotifyRootChanged() {
// new root. Otherwise, that is going to be done when this gets focus.
nsCOMPtr<nsINode> node = GetFocusedNode();
if (node) {
DebugOnly<nsresult> rvIgnored = InitializeSelection(node);
DebugOnly<nsresult> rvIgnored = InitializeSelection(*node);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"EditorBase::InitializeSelection() failed, but ignored");

View File

@ -60,8 +60,7 @@ NS_IMPL_RELEASE_INHERITED(InsertNodeTransaction, EditTransactionBase)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(InsertNodeTransaction)
NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP
InsertNodeTransaction::DoTransaction() {
NS_IMETHODIMP InsertNodeTransaction::DoTransaction() {
if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mContentToInsert) ||
NS_WARN_IF(!mPointToInsert.IsSet())) {
return NS_ERROR_NOT_AVAILABLE;

View File

@ -45,8 +45,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(InsertTextTransaction)
NS_INTERFACE_MAP_ENTRY_CONCRETE(InsertTextTransaction)
NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP
InsertTextTransaction::DoTransaction() {
NS_IMETHODIMP InsertTextTransaction::DoTransaction() {
if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode)) {
return NS_ERROR_NOT_AVAILABLE;
}
@ -82,8 +81,7 @@ InsertTextTransaction::DoTransaction() {
return NS_OK;
}
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP
InsertTextTransaction::UndoTransaction() {
NS_IMETHODIMP InsertTextTransaction::UndoTransaction() {
if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode)) {
return NS_ERROR_NOT_INITIALIZED;
}

View File

@ -54,7 +54,7 @@ bool JoinNodeTransaction::CanDoIt() const {
// After DoTransaction() and RedoTransaction(), the left node is removed from
// the content tree and right node remains.
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP JoinNodeTransaction::DoTransaction() {
NS_IMETHODIMP JoinNodeTransaction::DoTransaction() {
if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mLeftContent) ||
NS_WARN_IF(!mRightContent)) {
return NS_ERROR_NOT_AVAILABLE;
@ -87,8 +87,7 @@ MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP JoinNodeTransaction::DoTransaction() {
// XXX: What if instead of split, we just deleted the unneeded children of
// mRight and re-inserted mLeft?
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP
JoinNodeTransaction::UndoTransaction() {
NS_IMETHODIMP JoinNodeTransaction::UndoTransaction() {
if (NS_WARN_IF(!mParentNode) || NS_WARN_IF(!mLeftContent) ||
NS_WARN_IF(!mRightContent) || NS_WARN_IF(!mEditorBase)) {
return NS_ERROR_NOT_AVAILABLE;

View File

@ -55,7 +55,7 @@ class PlaceholderTransaction final : public EditAggregateTransaction,
NS_DECL_EDITTRANSACTIONBASE
NS_IMETHOD RedoTransaction() override;
MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() override;
NS_IMETHOD Merge(nsITransaction* aTransaction, bool* aDidMerge) override;
// ------------ nsIAbsorbingTransaction -----------------------

View File

@ -50,8 +50,7 @@ NS_IMPL_RELEASE_INHERITED(SplitNodeTransaction, EditTransactionBase)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SplitNodeTransaction)
NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP
SplitNodeTransaction::DoTransaction() {
NS_IMETHODIMP SplitNodeTransaction::DoTransaction() {
if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mStartOfRightContent.IsSet())) {
return NS_ERROR_NOT_AVAILABLE;
}
@ -118,8 +117,7 @@ SplitNodeTransaction::DoTransaction() {
return error.StealNSResult();
}
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP
SplitNodeTransaction::UndoTransaction() {
NS_IMETHODIMP SplitNodeTransaction::UndoTransaction() {
if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mNewLeftContent) ||
NS_WARN_IF(!mContainerParentNode) ||
NS_WARN_IF(!mStartOfRightContent.IsSet())) {
@ -143,8 +141,7 @@ SplitNodeTransaction::UndoTransaction() {
* on the redo stack may depend on the left node existing in its previous
* state.
*/
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP
SplitNodeTransaction::RedoTransaction() {
NS_IMETHODIMP SplitNodeTransaction::RedoTransaction() {
if (NS_WARN_IF(!mNewLeftContent) || NS_WARN_IF(!mContainerParentNode) ||
NS_WARN_IF(!mStartOfRightContent.IsSet()) || NS_WARN_IF(!mEditorBase)) {
return NS_ERROR_NOT_AVAILABLE;

View File

@ -51,7 +51,7 @@ class SplitNodeTransaction final : public EditTransactionBase {
NS_DECL_EDITTRANSACTIONBASE
NS_IMETHOD RedoTransaction() override;
MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() override;
nsIContent* GetNewLeftContent() const { return mNewLeftContent; }

View File

@ -261,6 +261,7 @@ interface nsIEditor : nsISupports
* Calls to beginTransaction can be nested, as long as endTransaction
* is called once per beginUpdate.
*/
[can_run_script]
void beginTransaction();
/** endTransaction is a signal to the editor that the caller is

View File

@ -6,6 +6,7 @@
#include "TransactionItem.h"
#include "mozilla/mozalloc.h"
#include "mozilla/OwningNonNull.h"
#include "mozilla/TransactionManager.h"
#include "mozilla/TransactionStack.h"
#include "nsCOMPtr.h"
@ -76,7 +77,8 @@ nsresult TransactionItem::DoTransaction() {
if (!mTransaction) {
return NS_OK;
}
nsresult rv = mTransaction->DoTransaction();
OwningNonNull<nsITransaction> transaction = *mTransaction;
nsresult rv = transaction->DoTransaction();
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"nsITransaction::DoTransaction() failed");
return rv;
@ -97,7 +99,8 @@ nsresult TransactionItem::UndoTransaction(
return NS_OK;
}
rv = mTransaction->UndoTransaction();
OwningNonNull<nsITransaction> transaction = *mTransaction;
rv = transaction->UndoTransaction();
if (NS_SUCCEEDED(rv)) {
return NS_OK;
}
@ -257,6 +260,8 @@ nsresult TransactionItem::RecoverFromUndoError(
nsresult TransactionItem::RecoverFromRedoError(
TransactionManager* aTransactionManager) {
OwningNonNull<nsITransaction> transaction = *mTransaction;
// If this method gets called, we already successfully called
// RedoTransaction() for the transaction item itself. Undo all
// the children that successfully called RedoTransaction(),
@ -271,7 +276,7 @@ nsresult TransactionItem::RecoverFromRedoError(
return NS_OK;
}
rv = mTransaction->UndoTransaction();
rv = transaction->UndoTransaction();
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"nsITransaction::UndoTransaction() failed");
return rv;

View File

@ -34,18 +34,24 @@ class TransactionItem final {
}
nsresult GetChild(size_t aIndex, TransactionItem** aChild);
nsresult DoTransaction();
nsresult UndoTransaction(TransactionManager* aTransactionManager);
nsresult RedoTransaction(TransactionManager* aTransactionManager);
MOZ_CAN_RUN_SCRIPT nsresult DoTransaction();
MOZ_CAN_RUN_SCRIPT nsresult
UndoTransaction(TransactionManager* aTransactionManager);
MOZ_CAN_RUN_SCRIPT nsresult
RedoTransaction(TransactionManager* aTransactionManager);
nsCOMArray<nsISupports>& GetData() { return mData; }
private:
nsresult UndoChildren(TransactionManager* aTransactionManager);
nsresult RedoChildren(TransactionManager* aTransactionManager);
MOZ_CAN_RUN_SCRIPT nsresult
UndoChildren(TransactionManager* aTransactionManager);
MOZ_CAN_RUN_SCRIPT nsresult
RedoChildren(TransactionManager* aTransactionManager);
nsresult RecoverFromUndoError(TransactionManager* aTransactionManager);
nsresult RecoverFromRedoError(TransactionManager* aTransactionManager);
MOZ_CAN_RUN_SCRIPT nsresult
RecoverFromUndoError(TransactionManager* aTransactionManager);
MOZ_CAN_RUN_SCRIPT nsresult
RecoverFromRedoError(TransactionManager* aTransactionManager);
size_t NumberOfUndoItems() const;
size_t NumberOfRedoItems() const;

View File

@ -211,7 +211,7 @@ nsresult TransactionManager::BeginBatchInternal(nsISupports* aData) {
return NS_OK;
}
rv = BeginTransaction(0, aData);
rv = BeginTransaction(nullptr, aData);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"TransactionManager::BeginTransaction() failed");

View File

@ -35,8 +35,8 @@ class TransactionManager final : public nsITransactionManager,
already_AddRefed<nsITransaction> PeekUndoStack();
already_AddRefed<nsITransaction> PeekRedoStack();
nsresult Undo();
nsresult Redo();
MOZ_CAN_RUN_SCRIPT nsresult Undo();
MOZ_CAN_RUN_SCRIPT nsresult Redo();
size_t NumberOfUndoItems() const { return mUndoStack.GetSize(); }
size_t NumberOfRedoItems() const { return mRedoStack.GetSize(); }
@ -62,31 +62,42 @@ class TransactionManager final : public nsITransactionManager,
return mListeners.RemoveObject(&aListener);
}
nsresult WillDoNotify(nsITransaction* aTransaction, bool* aInterrupt);
nsresult DidDoNotify(nsITransaction* aTransaction, nsresult aExecuteResult);
nsresult WillUndoNotify(nsITransaction* aTransaction, bool* aInterrupt);
nsresult DidUndoNotify(nsITransaction* aTransaction, nsresult aUndoResult);
nsresult WillRedoNotify(nsITransaction* aTransaction, bool* aInterrupt);
nsresult DidRedoNotify(nsITransaction* aTransaction, nsresult aRedoResult);
nsresult WillBeginBatchNotify(bool* aInterrupt);
nsresult DidBeginBatchNotify(nsresult aResult);
nsresult WillEndBatchNotify(bool* aInterrupt);
nsresult DidEndBatchNotify(nsresult aResult);
nsresult WillMergeNotify(nsITransaction* aTop, nsITransaction* aTransaction,
bool* aInterrupt);
nsresult DidMergeNotify(nsITransaction* aTop, nsITransaction* aTransaction,
bool aDidMerge, nsresult aMergeResult);
// FYI: We don't need to treat the following methods as `MOZ_CAN_RUN_SCRIPT`
// for now because only ComposerCommandUpdater is the listener and it
// does not do something dangerous synchronously.
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
WillDoNotify(nsITransaction* aTransaction, bool* aInterrupt);
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult DidDoNotify(nsITransaction* aTransaction,
nsresult aExecuteResult);
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
WillUndoNotify(nsITransaction* aTransaction, bool* aInterrupt);
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
DidUndoNotify(nsITransaction* aTransaction, nsresult aUndoResult);
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
WillRedoNotify(nsITransaction* aTransaction, bool* aInterrupt);
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
DidRedoNotify(nsITransaction* aTransaction, nsresult aRedoResult);
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult WillBeginBatchNotify(bool* aInterrupt);
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult DidBeginBatchNotify(nsresult aResult);
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult WillEndBatchNotify(bool* aInterrupt);
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult DidEndBatchNotify(nsresult aResult);
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult WillMergeNotify(
nsITransaction* aTop, nsITransaction* aTransaction, bool* aInterrupt);
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
DidMergeNotify(nsITransaction* aTop, nsITransaction* aTransaction,
bool aDidMerge, nsresult aMergeResult);
/**
* Exposing non-virtual methods of nsITransactionManager methods.
*/
nsresult BeginBatchInternal(nsISupports* aData);
MOZ_CAN_RUN_SCRIPT nsresult BeginBatchInternal(nsISupports* aData);
nsresult EndBatchInternal(bool aAllowEmpty);
private:
virtual ~TransactionManager() = default;
nsresult BeginTransaction(nsITransaction* aTransaction, nsISupports* aData);
MOZ_CAN_RUN_SCRIPT nsresult BeginTransaction(nsITransaction* aTransaction,
nsISupports* aData);
nsresult EndTransaction(bool aAllowEmpty);
int32_t mMaxTransactionCount;

View File

@ -17,11 +17,13 @@ interface nsITransaction : nsISupports
/**
* Executes the transaction.
*/
[can_run_script]
void doTransaction();
/**
* Restores the state to what it was before the transaction was executed.
*/
[can_run_script]
void undoTransaction();
/**
@ -31,6 +33,7 @@ interface nsITransaction : nsISupports
* In most cases, the redoTransaction() method will actually call the
* doTransaction() method to execute the transaction again.
*/
[can_run_script]
void redoTransaction();
/**

View File

@ -31,18 +31,21 @@ interface nsITransactionManager : nsISupports
* stack is pruned or when the transaction manager is destroyed.
* @param aTransaction the transaction to do.
*/
[can_run_script]
void doTransaction(in nsITransaction aTransaction);
/**
* Pops the topmost transaction on the undo stack, calls its
* undoTransaction() method, then pushes it on the redo stack.
*/
[can_run_script]
void undoTransaction();
/**
* Pops the topmost transaction on the redo stack, calls its
* redoTransaction() method, then pushes it on the undo stack.
*/
[can_run_script]
void redoTransaction();
/**
@ -69,6 +72,7 @@ interface nsITransactionManager : nsISupports
* @param aData An arbitrary nsISupports object that is associated with the
* batch. Can be retrieved from the undo or redo stacks.
*/
[can_run_script]
void beginBatch(in nsISupports aData);
/**

View File

@ -270,7 +270,7 @@ class SimpleTransaction : public TestTransaction {
~SimpleTransaction() override = default;
NS_IMETHOD DoTransaction() override {
MOZ_CAN_RUN_SCRIPT NS_IMETHOD DoTransaction() override {
//
// Make sure DoTransaction() is called in the order we expect!
// Notice that we don't check to see if we go past the end of the array.
@ -286,7 +286,7 @@ class SimpleTransaction : public TestTransaction {
return (mFlags & THROWS_DO_ERROR_FLAG) ? NS_ERROR_FAILURE : NS_OK;
}
NS_IMETHOD UndoTransaction() override {
MOZ_CAN_RUN_SCRIPT NS_IMETHOD UndoTransaction() override {
//
// Make sure UndoTransaction() is called in the order we expect!
// Notice that we don't check to see if we go past the end of the array.
@ -302,7 +302,7 @@ class SimpleTransaction : public TestTransaction {
return (mFlags & THROWS_UNDO_ERROR_FLAG) ? NS_ERROR_FAILURE : NS_OK;
}
NS_IMETHOD RedoTransaction() override {
MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() override {
//
// Make sure RedoTransaction() is called in the order we expect!
// Notice that we don't check to see if we go past the end of the array.
@ -372,7 +372,7 @@ class AggregateTransaction : public SimpleTransaction {
~AggregateTransaction() override = default;
NS_IMETHOD DoTransaction() override {
MOZ_CAN_RUN_SCRIPT NS_IMETHOD DoTransaction() override {
if (mLevel >= mMaxLevel) {
// Only leaf nodes can throw errors!
mFlags |= mErrorFlags;
@ -390,7 +390,7 @@ class AggregateTransaction : public SimpleTransaction {
}
if (mFlags & BATCH_FLAG) {
rv = mTXMgr->BeginBatch(nullptr);
rv = MOZ_KnownLive(mTXMgr)->BeginBatch(nullptr);
if (NS_FAILED(rv)) {
return rv;
}
@ -416,7 +416,7 @@ class AggregateTransaction : public SimpleTransaction {
RefPtr<AggregateTransaction> tximpl = new AggregateTransaction(
mTXMgr, cLevel, i, mMaxLevel, mNumChildrenPerNode, flags);
rv = mTXMgr->DoTransaction(tximpl);
rv = MOZ_KnownLive(mTXMgr)->DoTransaction(tximpl);
if (NS_FAILED(rv)) {
if (mFlags & BATCH_FLAG) {
mTXMgr->EndBatch(false);
@ -482,7 +482,7 @@ void reset_globals() {
/**
* Test behaviors in non-batch mode.
**/
void quick_test(TestTransactionFactory* factory) {
MOZ_CAN_RUN_SCRIPT_BOUNDARY void quick_test(TestTransactionFactory* factory) {
/*******************************************************************
*
* Create a transaction manager implementation:
@ -497,7 +497,7 @@ void quick_test(TestTransactionFactory* factory) {
*
*******************************************************************/
nsresult rv = mgr->DoTransaction(0);
nsresult rv = mgr->DoTransaction(nullptr);
EXPECT_EQ(rv, NS_ERROR_NULL_POINTER);
/*******************************************************************
@ -1229,7 +1229,8 @@ TEST(TestTXMgr, AggregationTest)
/**
* Test behaviors in batch mode.
**/
void quick_batch_test(TestTransactionFactory* factory) {
MOZ_CAN_RUN_SCRIPT_BOUNDARY void quick_batch_test(
TestTransactionFactory* factory) {
/*******************************************************************
*
* Create a transaction manager implementation:
@ -1858,7 +1859,8 @@ TEST(TestTXMgr, AggregationBatchTest)
* Create 'iterations * (iterations + 1) / 2' transactions;
* do/undo/redo/undo them.
**/
void stress_test(TestTransactionFactory* factory, int32_t iterations) {
MOZ_CAN_RUN_SCRIPT_BOUNDARY void stress_test(TestTransactionFactory* factory,
int32_t iterations) {
/*******************************************************************
*
* Create a transaction manager: