Bug 1620504 - part 13: Clean up warnings in editor/txmgr r=m_kato

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Masayuki Nakano 2020-03-10 13:59:36 +00:00
Родитель 2cffc808c8
Коммит 8371d74f49
5 изменённых файлов: 333 добавлений и 312 удалений

Просмотреть файл

@ -59,97 +59,37 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(TransactionItem, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(TransactionItem, Release)
nsresult TransactionItem::AddChild(TransactionItem* aTransactionItem) {
NS_ENSURE_TRUE(aTransactionItem, NS_ERROR_NULL_POINTER);
nsresult TransactionItem::AddChild(TransactionItem& aTransactionItem) {
if (!mUndoStack) {
mUndoStack = new TransactionStack(TransactionStack::FOR_UNDO);
}
mUndoStack->Push(aTransactionItem);
mUndoStack->Push(&aTransactionItem);
return NS_OK;
}
already_AddRefed<nsITransaction> TransactionItem::GetTransaction() {
nsCOMPtr<nsITransaction> txn = mTransaction;
return txn.forget();
}
nsresult TransactionItem::GetIsBatch(bool* aIsBatch) {
NS_ENSURE_TRUE(aIsBatch, NS_ERROR_NULL_POINTER);
*aIsBatch = !mTransaction;
return NS_OK;
}
nsresult TransactionItem::GetNumberOfChildren(int32_t* aNumChildren) {
NS_ENSURE_TRUE(aNumChildren, NS_ERROR_NULL_POINTER);
*aNumChildren = 0;
int32_t ui = 0;
nsresult rv = GetNumberOfUndoItems(&ui);
NS_ENSURE_SUCCESS(rv, rv);
int32_t ri = 0;
rv = GetNumberOfRedoItems(&ri);
NS_ENSURE_SUCCESS(rv, rv);
*aNumChildren = ui + ri;
return NS_OK;
}
nsresult TransactionItem::GetChild(int32_t aIndex, TransactionItem** aChild) {
NS_ENSURE_TRUE(aChild, NS_ERROR_NULL_POINTER);
*aChild = 0;
int32_t numItems = 0;
nsresult rv = GetNumberOfChildren(&numItems);
NS_ENSURE_SUCCESS(rv, rv);
if (aIndex < 0 || aIndex >= numItems) {
return NS_ERROR_FAILURE;
}
// Children are expected to be in the order they were added,
// so the child first added would be at the bottom of the undo
// stack, or if there are no items on the undo stack, it would
// be at the top of the redo stack.
rv = GetNumberOfUndoItems(&numItems);
NS_ENSURE_SUCCESS(rv, rv);
if (numItems > 0 && aIndex < numItems) {
NS_ENSURE_TRUE(mUndoStack, NS_ERROR_FAILURE);
RefPtr<TransactionItem> child = mUndoStack->GetItem(aIndex);
child.forget(aChild);
return *aChild ? NS_OK : NS_ERROR_FAILURE;
}
// Adjust the index for the redo stack:
aIndex -= numItems;
rv = GetNumberOfRedoItems(&numItems);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(mRedoStack && numItems != 0 && aIndex < numItems,
NS_ERROR_FAILURE);
RefPtr<TransactionItem> child = mRedoStack->GetItem(aIndex);
child.forget(aChild);
return *aChild ? NS_OK : NS_ERROR_FAILURE;
return do_AddRef(mTransaction);
}
nsresult TransactionItem::DoTransaction() {
if (mTransaction) {
return mTransaction->DoTransaction();
if (!mTransaction) {
return NS_OK;
}
return NS_OK;
nsresult rv = mTransaction->DoTransaction();
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"nsITransaction::DoTransaction() failed");
return rv;
}
nsresult TransactionItem::UndoTransaction(
TransactionManager* aTransactionManager) {
nsresult rv = UndoChildren(aTransactionManager);
if (NS_FAILED(rv)) {
RecoverFromUndoError(aTransactionManager);
NS_WARNING("TransactionItem::UndoChildren() failed");
DebugOnly<nsresult> rvIgnored = RecoverFromUndoError(aTransactionManager);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"TransactionItem::RecoverFromUndoError() failed");
return rv;
}
@ -158,59 +98,66 @@ nsresult TransactionItem::UndoTransaction(
}
rv = mTransaction->UndoTransaction();
if (NS_FAILED(rv)) {
RecoverFromUndoError(aTransactionManager);
return rv;
if (NS_SUCCEEDED(rv)) {
return NS_OK;
}
return NS_OK;
NS_WARNING("TransactionItem::UndoTransaction() failed");
DebugOnly<nsresult> rvIgnored = RecoverFromUndoError(aTransactionManager);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"TransactionItem::RecoverFromUndoError() failed");
return rv;
}
nsresult TransactionItem::UndoChildren(
TransactionManager* aTransactionManager) {
if (mUndoStack) {
if (!mRedoStack && mUndoStack) {
mRedoStack = new TransactionStack(TransactionStack::FOR_REDO);
}
/* Undo all of the transaction items children! */
int32_t sz = mUndoStack->GetSize();
nsresult rv = NS_OK;
while (sz-- > 0) {
RefPtr<TransactionItem> transactionItem = mUndoStack->Peek();
if (!transactionItem) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsITransaction> transaction = transactionItem->GetTransaction();
bool doInterrupt = false;
rv = aTransactionManager->WillUndoNotify(transaction, &doInterrupt);
if (NS_FAILED(rv)) {
return rv;
}
if (doInterrupt) {
return NS_OK;
}
rv = transactionItem->UndoTransaction(aTransactionManager);
if (NS_SUCCEEDED(rv)) {
transactionItem = mUndoStack->Pop();
mRedoStack->Push(transactionItem.forget());
}
nsresult rv2 = aTransactionManager->DidUndoNotify(transaction, rv);
if (NS_SUCCEEDED(rv)) {
rv = rv2;
}
}
// XXX NS_OK if there is no Undo items or all methods work fine, otherwise,
// the result of the last item's UndoTransaction() or
// DidUndoNotify() if UndoTransaction() succeeded.
return rv;
if (!mUndoStack) {
return NS_OK;
}
return NS_OK;
if (!mRedoStack) {
mRedoStack = new TransactionStack(TransactionStack::FOR_REDO);
}
size_t undoStackSize = mUndoStack->GetSize();
nsresult rv = NS_OK;
while (undoStackSize-- > 0) {
RefPtr<TransactionItem> transactionItem = mUndoStack->Peek();
if (!transactionItem) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsITransaction> transaction = transactionItem->GetTransaction();
bool doInterrupt = false;
rv = aTransactionManager->WillUndoNotify(transaction, &doInterrupt);
if (NS_FAILED(rv)) {
NS_WARNING("TransactionManager::WillUndoNotify() failed");
return rv;
}
if (doInterrupt) {
return NS_OK;
}
rv = transactionItem->UndoTransaction(aTransactionManager);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"TransactionItem::UndoTransaction() failed");
if (NS_SUCCEEDED(rv)) {
transactionItem = mUndoStack->Pop();
mRedoStack->Push(transactionItem.forget());
}
nsresult rv2 = aTransactionManager->DidUndoNotify(transaction, rv);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv2),
"TransactionManager::DidUndoNotify() failed");
if (NS_SUCCEEDED(rv)) {
rv = rv2;
}
}
// XXX NS_OK if there is no Undo items or all methods work fine, otherwise,
// the result of the last item's UndoTransaction() or
// DidUndoNotify() if UndoTransaction() succeeded.
return rv;
}
nsresult TransactionItem::RedoTransaction(
@ -218,16 +165,22 @@ nsresult TransactionItem::RedoTransaction(
nsCOMPtr<nsITransaction> transaction(mTransaction);
if (transaction) {
nsresult rv = transaction->RedoTransaction();
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv)) {
NS_WARNING("nsITransaction::RedoTransaction() failed");
return rv;
}
}
nsresult rv = RedoChildren(aTransactionManager);
if (NS_FAILED(rv)) {
RecoverFromRedoError(aTransactionManager);
return rv;
if (NS_SUCCEEDED(rv)) {
return NS_OK;
}
return NS_OK;
NS_WARNING("TransactionItem::RedoChildren() failed");
DebugOnly<nsresult> rvIgnored = RecoverFromRedoError(aTransactionManager);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"TransactionItem::RecoverFromRedoError() failed");
return rv;
}
nsresult TransactionItem::RedoChildren(
@ -237,12 +190,12 @@ nsresult TransactionItem::RedoChildren(
}
/* Redo all of the transaction items children! */
int32_t sz = mRedoStack->GetSize();
size_t redoStackSize = mRedoStack->GetSize();
nsresult rv = NS_OK;
while (sz-- > 0) {
while (redoStackSize-- > 0) {
RefPtr<TransactionItem> transactionItem = mRedoStack->Peek();
if (!transactionItem) {
if (NS_WARN_IF(!transactionItem)) {
return NS_ERROR_FAILURE;
}
@ -250,6 +203,7 @@ nsresult TransactionItem::RedoChildren(
bool doInterrupt = false;
rv = aTransactionManager->WillRedoNotify(transaction, &doInterrupt);
if (NS_FAILED(rv)) {
NS_WARNING("TransactionManager::WillRedoNotify() failed");
return rv;
}
if (doInterrupt) {
@ -257,6 +211,8 @@ nsresult TransactionItem::RedoChildren(
}
rv = transactionItem->RedoTransaction(aTransactionManager);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"TransactionItem::RedoTransaction() failed");
if (NS_SUCCEEDED(rv)) {
transactionItem = mRedoStack->Pop();
mUndoStack->Push(transactionItem.forget());
@ -264,6 +220,8 @@ nsresult TransactionItem::RedoChildren(
// XXX Shouldn't this DidRedoNotify()? (bug 1311626)
nsresult rv2 = aTransactionManager->DidUndoNotify(transaction, rv);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv2),
"TransactionManager::DidUndoNotify() failed");
if (NS_SUCCEEDED(rv)) {
rv = rv2;
}
@ -274,28 +232,16 @@ nsresult TransactionItem::RedoChildren(
return rv;
}
nsresult TransactionItem::GetNumberOfUndoItems(int32_t* aNumItems) {
NS_ENSURE_TRUE(aNumItems, NS_ERROR_NULL_POINTER);
if (!mUndoStack) {
*aNumItems = 0;
return NS_OK;
}
*aNumItems = mUndoStack->GetSize();
return *aNumItems ? NS_OK : NS_ERROR_FAILURE;
size_t TransactionItem::NumberOfUndoItems() const {
NS_WARNING_ASSERTION(!mUndoStack || mUndoStack->GetSize() > 0,
"UndoStack cannot have no children");
return mUndoStack ? mUndoStack->GetSize() : 0;
}
nsresult TransactionItem::GetNumberOfRedoItems(int32_t* aNumItems) {
NS_ENSURE_TRUE(aNumItems, NS_ERROR_NULL_POINTER);
if (!mRedoStack) {
*aNumItems = 0;
return NS_OK;
}
*aNumItems = mRedoStack->GetSize();
return *aNumItems ? NS_OK : NS_ERROR_FAILURE;
size_t TransactionItem::NumberOfRedoItems() const {
NS_WARNING_ASSERTION(!mRedoStack || mRedoStack->GetSize() > 0,
"UndoStack cannot have no children");
return mRedoStack ? mRedoStack->GetSize() : 0;
}
nsresult TransactionItem::RecoverFromUndoError(
@ -303,7 +249,10 @@ nsresult TransactionItem::RecoverFromUndoError(
// If this method gets called, we never got to the point where we
// successfully called UndoTransaction() for the transaction item itself.
// Just redo any children that successfully called undo!
return RedoChildren(aTransactionManager);
nsresult rv = RedoChildren(aTransactionManager);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"TransactionItem::RedoChildren() failed");
return rv;
}
nsresult TransactionItem::RecoverFromRedoError(
@ -314,6 +263,7 @@ nsresult TransactionItem::RecoverFromRedoError(
// then undo the transaction item itself.
nsresult rv = UndoChildren(aTransactionManager);
if (NS_FAILED(rv)) {
NS_WARNING("TransactionItem::UndoChildren() failed");
return rv;
}
@ -321,7 +271,10 @@ nsresult TransactionItem::RecoverFromRedoError(
return NS_OK;
}
return mTransaction->UndoTransaction();
rv = mTransaction->UndoTransaction();
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"nsITransaction::UndoTransaction() failed");
return rv;
}
} // namespace mozilla

Просмотреть файл

@ -27,11 +27,12 @@ class TransactionItem final {
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(TransactionItem)
nsresult AddChild(TransactionItem* aTransactionItem);
nsresult AddChild(TransactionItem& aTransactionItem);
already_AddRefed<nsITransaction> GetTransaction();
nsresult GetIsBatch(bool* aIsBatch);
nsresult GetNumberOfChildren(int32_t* aNumChildren);
nsresult GetChild(int32_t aIndex, TransactionItem** aChild);
size_t NumberOfChildren() const {
return NumberOfUndoItems() + NumberOfRedoItems();
}
nsresult GetChild(size_t aIndex, TransactionItem** aChild);
nsresult DoTransaction();
nsresult UndoTransaction(TransactionManager* aTransactionManager);
@ -46,8 +47,8 @@ class TransactionItem final {
nsresult RecoverFromUndoError(TransactionManager* aTransactionManager);
nsresult RecoverFromRedoError(TransactionManager* aTransactionManager);
nsresult GetNumberOfUndoItems(int32_t* aNumItems);
nsresult GetNumberOfRedoItems(int32_t* aNumItems);
size_t NumberOfUndoItems() const;
size_t NumberOfRedoItems() const;
void CleanUp();

Просмотреть файл

@ -52,14 +52,16 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(TransactionManager)
NS_IMPL_CYCLE_COLLECTING_RELEASE(TransactionManager)
NS_IMETHODIMP
TransactionManager::DoTransaction(nsITransaction* aTransaction) {
NS_ENSURE_TRUE(aTransaction, NS_ERROR_NULL_POINTER);
NS_IMETHODIMP TransactionManager::DoTransaction(nsITransaction* aTransaction) {
if (NS_WARN_IF(!aTransaction)) {
return NS_ERROR_INVALID_ARG;
}
bool doInterrupt = false;
nsresult rv = WillDoNotify(aTransaction, &doInterrupt);
if (NS_FAILED(rv)) {
NS_WARNING("TransactionManager::WillDoNotify() failed");
return rv;
}
if (doInterrupt) {
@ -68,31 +70,35 @@ TransactionManager::DoTransaction(nsITransaction* aTransaction) {
rv = BeginTransaction(aTransaction, nullptr);
if (NS_FAILED(rv)) {
DidDoNotify(aTransaction, rv);
NS_WARNING("TransactionManager::BeginTransaction() failed");
DebugOnly<nsresult> rvIgnored = DidDoNotify(aTransaction, rv);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"TransactionManager::DidDoNotify() failed, but ignored");
return rv;
}
rv = EndTransaction(false);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"TransactionManager::EndTransaction() failed");
nsresult rv2 = DidDoNotify(aTransaction, rv);
if (NS_SUCCEEDED(rv)) {
rv = rv2;
}
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv2),
"TransactionManager::DidDoNotify() failed");
// XXX The result of EndTransaction() or DidDoNotify() if EndTransaction()
// succeeded.
return rv;
return NS_SUCCEEDED(rv) ? rv2 : rv;
}
NS_IMETHODIMP
TransactionManager::UndoTransaction() { return Undo(); }
NS_IMETHODIMP TransactionManager::UndoTransaction() { return Undo(); }
nsresult TransactionManager::Undo() {
// It's possible to be called Undo() again while the transaction manager is
// executing a transaction's DoTransaction() method. If this happens,
// the Undo() request is ignored, and we return NS_ERROR_FAILURE. This
// may occur if a mutation event listener calls document.execCommand("undo").
if (!mDoStack.IsEmpty()) {
if (NS_WARN_IF(!mDoStack.IsEmpty())) {
return NS_ERROR_FAILURE;
}
@ -108,6 +114,7 @@ nsresult TransactionManager::Undo() {
bool doInterrupt = false;
nsresult rv = WillUndoNotify(transaction, &doInterrupt);
if (NS_FAILED(rv)) {
NS_WARNING("TransactionManager::WillUndoNotify() failed");
return rv;
}
if (doInterrupt) {
@ -115,30 +122,30 @@ nsresult TransactionManager::Undo() {
}
rv = transactionItem->UndoTransaction(this);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"TransactionItem::UndoTransaction() failed");
if (NS_SUCCEEDED(rv)) {
transactionItem = mUndoStack.Pop();
mRedoStack.Push(transactionItem.forget());
}
nsresult rv2 = DidUndoNotify(transaction, rv);
if (NS_SUCCEEDED(rv)) {
rv = rv2;
}
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv2),
"TransactionManager::DidUndoNotify() failed");
// XXX The result of UndoTransaction() or DidUndoNotify() if UndoTransaction()
// succeeded.
return rv;
return NS_SUCCEEDED(rv) ? rv2 : rv;
}
NS_IMETHODIMP
TransactionManager::RedoTransaction() { return Redo(); }
NS_IMETHODIMP TransactionManager::RedoTransaction() { return Redo(); }
nsresult TransactionManager::Redo() {
// It's possible to be called Redo() again while the transaction manager is
// executing a transaction's DoTransaction() method. If this happens,
// the Redo() request is ignored, and we return NS_ERROR_FAILURE. This
// may occur if a mutation event listener calls document.execCommand("redo").
if (!mDoStack.IsEmpty()) {
if (NS_WARN_IF(!mDoStack.IsEmpty())) {
return NS_ERROR_FAILURE;
}
@ -154,6 +161,7 @@ nsresult TransactionManager::Redo() {
bool doInterrupt = false;
nsresult rv = WillRedoNotify(transaction, &doInterrupt);
if (NS_FAILED(rv)) {
NS_WARNING("TransactionManager::WillRedoNotify() failed");
return rv;
}
if (doInterrupt) {
@ -161,33 +169,31 @@ nsresult TransactionManager::Redo() {
}
rv = transactionItem->RedoTransaction(this);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"TransactionItem::RedoTransaction() failed");
if (NS_SUCCEEDED(rv)) {
transactionItem = mRedoStack.Pop();
mUndoStack.Push(transactionItem.forget());
}
nsresult rv2 = DidRedoNotify(transaction, rv);
if (NS_SUCCEEDED(rv)) {
rv = rv2;
}
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv2),
"TransactionManager::DidRedoNotify() failed");
// XXX The result of RedoTransaction() or DidRedoNotify() if RedoTransaction()
// succeeded.
return rv;
return NS_SUCCEEDED(rv) ? rv2 : rv;
}
NS_IMETHODIMP
TransactionManager::Clear() {
return ClearUndoRedo() ? NS_OK : NS_ERROR_FAILURE;
NS_IMETHODIMP TransactionManager::Clear() {
return NS_WARN_IF(!ClearUndoRedo()) ? NS_ERROR_FAILURE : NS_OK;
}
NS_IMETHODIMP
TransactionManager::BeginBatch(nsISupports* aData) {
NS_IMETHODIMP TransactionManager::BeginBatch(nsISupports* aData) {
nsresult rv = BeginBatchInternal(aData);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"TransactionManager::BeginBatchInternal() failed");
return rv;
}
nsresult TransactionManager::BeginBatchInternal(nsISupports* aData) {
@ -198,6 +204,7 @@ nsresult TransactionManager::BeginBatchInternal(nsISupports* aData) {
bool doInterrupt = false;
nsresult rv = WillBeginBatchNotify(&doInterrupt);
if (NS_FAILED(rv)) {
NS_WARNING("TransactionManager::WillBeginBatchNotify() failed");
return rv;
}
if (doInterrupt) {
@ -205,24 +212,23 @@ nsresult TransactionManager::BeginBatchInternal(nsISupports* aData) {
}
rv = BeginTransaction(0, aData);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"TransactionManager::BeginTransaction() failed");
nsresult rv2 = DidBeginBatchNotify(rv);
if (NS_SUCCEEDED(rv)) {
rv = rv2;
}
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv2),
"TransactionManager::DidBeginBatchNotify() failed");
// XXX The result of BeginTransaction() or DidBeginBatchNotify() if
// BeginTransaction() succeeded.
return rv;
return NS_SUCCEEDED(rv) ? rv2 : rv;
}
NS_IMETHODIMP
TransactionManager::EndBatch(bool aAllowEmpty) {
NS_IMETHODIMP TransactionManager::EndBatch(bool aAllowEmpty) {
nsresult rv = EndBatchInternal(aAllowEmpty);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"TransactionManager::EndBatchInternal() failed");
return rv;
}
nsresult TransactionManager::EndBatchInternal(bool aAllowEmpty) {
@ -237,17 +243,18 @@ nsresult TransactionManager::EndBatchInternal(bool aAllowEmpty) {
// future when we allow users to execute a transaction when beginning
// a batch!!!!
RefPtr<TransactionItem> transactionItem = mDoStack.Peek();
if (!transactionItem) {
if (NS_WARN_IF(!transactionItem)) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsITransaction> transaction = transactionItem->GetTransaction();
if (transaction) {
if (NS_WARN_IF(transaction)) {
return NS_ERROR_FAILURE;
}
bool doInterrupt = false;
nsresult rv = WillEndBatchNotify(&doInterrupt);
if (NS_FAILED(rv)) {
NS_WARNING("TransactionManager::WillEndBatchNotify() failed");
return rv;
}
if (doInterrupt) {
@ -255,40 +262,40 @@ nsresult TransactionManager::EndBatchInternal(bool aAllowEmpty) {
}
rv = EndTransaction(aAllowEmpty);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"TransactionManager::EndTransaction() failed");
nsresult rv2 = DidEndBatchNotify(rv);
if (NS_SUCCEEDED(rv)) {
rv = rv2;
}
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv2),
"TransactionManager::DidEndBatchNotify() failed");
// XXX The result of EndTransaction() or DidEndBatchNotify() if
// EndTransaction() succeeded.
return rv;
return NS_SUCCEEDED(rv) ? rv2 : rv;
}
NS_IMETHODIMP
TransactionManager::GetNumberOfUndoItems(int32_t* aNumItems) {
NS_IMETHODIMP TransactionManager::GetNumberOfUndoItems(int32_t* aNumItems) {
*aNumItems = static_cast<int32_t>(NumberOfUndoItems());
MOZ_ASSERT(*aNumItems >= 0);
return NS_OK;
}
NS_IMETHODIMP
TransactionManager::GetNumberOfRedoItems(int32_t* aNumItems) {
NS_IMETHODIMP TransactionManager::GetNumberOfRedoItems(int32_t* aNumItems) {
*aNumItems = static_cast<int32_t>(NumberOfRedoItems());
MOZ_ASSERT(*aNumItems >= 0);
return NS_OK;
}
NS_IMETHODIMP
TransactionManager::GetMaxTransactionCount(int32_t* aMaxCount) {
NS_ENSURE_TRUE(aMaxCount, NS_ERROR_NULL_POINTER);
NS_IMETHODIMP TransactionManager::GetMaxTransactionCount(int32_t* aMaxCount) {
if (NS_WARN_IF(!aMaxCount)) {
return NS_ERROR_INVALID_ARG;
}
*aMaxCount = mMaxTransactionCount;
return NS_OK;
}
NS_IMETHODIMP
TransactionManager::SetMaxTransactionCount(int32_t aMaxCount) {
return EnableUndoRedo(aMaxCount) ? NS_OK : NS_ERROR_FAILURE;
NS_IMETHODIMP TransactionManager::SetMaxTransactionCount(int32_t aMaxCount) {
return NS_WARN_IF(!EnableUndoRedo(aMaxCount)) ? NS_ERROR_FAILURE : NS_OK;
}
bool TransactionManager::EnableUndoRedo(int32_t aMaxTransactionCount) {
@ -355,8 +362,7 @@ bool TransactionManager::EnableUndoRedo(int32_t aMaxTransactionCount) {
return true;
}
NS_IMETHODIMP
TransactionManager::PeekUndoStack(nsITransaction** aTransaction) {
NS_IMETHODIMP TransactionManager::PeekUndoStack(nsITransaction** aTransaction) {
MOZ_ASSERT(aTransaction);
*aTransaction = PeekUndoStack().take();
return NS_OK;
@ -370,8 +376,7 @@ already_AddRefed<nsITransaction> TransactionManager::PeekUndoStack() {
return transactionItem->GetTransaction();
}
NS_IMETHODIMP
TransactionManager::PeekRedoStack(nsITransaction** aTransaction) {
NS_IMETHODIMP TransactionManager::PeekRedoStack(nsITransaction** aTransaction) {
MOZ_ASSERT(aTransaction);
*aTransaction = PeekRedoStack().take();
return NS_OK;
@ -397,13 +402,17 @@ nsresult TransactionManager::BatchTopUndo() {
RefPtr<TransactionItem> previousUndo = mUndoStack.Peek();
MOZ_ASSERT(previousUndo, "There should be at least two transactions.");
nsresult rv = previousUndo->AddChild(lastUndo);
nsresult rv = previousUndo->AddChild(*lastUndo);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "TransactionItem::AddChild() failed");
// Transfer data from the transactions that is going to be
// merged to the transaction that it is being merged with.
nsCOMArray<nsISupports>& lastData = lastUndo->GetData();
nsCOMArray<nsISupports>& previousData = previousUndo->GetData();
NS_ENSURE_TRUE(previousData.AppendObjects(lastData), NS_ERROR_UNEXPECTED);
if (!previousData.AppendObjects(lastData)) {
NS_WARNING("nsISupports::AppendObjects() failed");
return NS_ERROR_FAILURE;
}
lastData.Clear();
return rv;
}
@ -417,24 +426,25 @@ nsresult TransactionManager::RemoveTopUndo() {
return NS_OK;
}
NS_IMETHODIMP
TransactionManager::AddListener(nsITransactionListener* aListener) {
NS_IMETHODIMP TransactionManager::AddListener(
nsITransactionListener* aListener) {
if (NS_WARN_IF(!aListener)) {
return NS_ERROR_INVALID_ARG;
}
return AddTransactionListener(*aListener) ? NS_OK : NS_ERROR_FAILURE;
return NS_WARN_IF(!AddTransactionListener(*aListener)) ? NS_ERROR_FAILURE
: NS_OK;
}
NS_IMETHODIMP
TransactionManager::RemoveListener(nsITransactionListener* aListener) {
NS_IMETHODIMP TransactionManager::RemoveListener(
nsITransactionListener* aListener) {
if (NS_WARN_IF(!aListener)) {
return NS_ERROR_INVALID_ARG;
}
return RemoveTransactionListener(*aListener) ? NS_OK : NS_ERROR_FAILURE;
return NS_WARN_IF(!RemoveTransactionListener(*aListener)) ? NS_ERROR_FAILURE
: NS_OK;
}
NS_IMETHODIMP
TransactionManager::ClearUndoStack() {
NS_IMETHODIMP TransactionManager::ClearUndoStack() {
if (NS_WARN_IF(!mDoStack.IsEmpty())) {
return NS_ERROR_FAILURE;
}
@ -442,8 +452,7 @@ TransactionManager::ClearUndoStack() {
return NS_OK;
}
NS_IMETHODIMP
TransactionManager::ClearRedoStack() {
NS_IMETHODIMP TransactionManager::ClearRedoStack() {
if (NS_WARN_IF(!mDoStack.IsEmpty())) {
return NS_ERROR_FAILURE;
}
@ -453,26 +462,33 @@ TransactionManager::ClearRedoStack() {
nsresult TransactionManager::WillDoNotify(nsITransaction* aTransaction,
bool* aInterrupt) {
for (int32_t i = 0, lcount = mListeners.Count(); i < lcount; i++) {
nsITransactionListener* listener = mListeners[i];
NS_ENSURE_TRUE(listener, NS_ERROR_FAILURE);
nsCOMArray<nsITransactionListener> listeners(mListeners);
for (nsITransactionListener* listener : listeners) {
if (NS_WARN_IF(!listener)) {
return NS_ERROR_FAILURE;
}
nsresult rv = listener->WillDo(this, aTransaction, aInterrupt);
if (NS_FAILED(rv) || *aInterrupt) {
if (NS_FAILED(rv)) {
NS_WARNING("nsITransactionListener::WillDo() failed");
return rv;
}
if (*aInterrupt) {
return NS_OK;
}
}
return NS_OK;
}
nsresult TransactionManager::DidDoNotify(nsITransaction* aTransaction,
nsresult aDoResult) {
for (int32_t i = 0, lcount = mListeners.Count(); i < lcount; i++) {
nsITransactionListener* listener = mListeners[i];
NS_ENSURE_TRUE(listener, NS_ERROR_FAILURE);
nsCOMArray<nsITransactionListener> listeners(mListeners);
for (nsITransactionListener* listener : listeners) {
if (NS_WARN_IF(!listener)) {
return NS_ERROR_FAILURE;
}
nsresult rv = listener->DidDo(this, aTransaction, aDoResult);
if (NS_FAILED(rv)) {
NS_WARNING("nsITransactionListener::DidDo() failed");
return rv;
}
}
@ -481,26 +497,33 @@ nsresult TransactionManager::DidDoNotify(nsITransaction* aTransaction,
nsresult TransactionManager::WillUndoNotify(nsITransaction* aTransaction,
bool* aInterrupt) {
for (int32_t i = 0, lcount = mListeners.Count(); i < lcount; i++) {
nsITransactionListener* listener = mListeners[i];
NS_ENSURE_TRUE(listener, NS_ERROR_FAILURE);
nsCOMArray<nsITransactionListener> listeners(mListeners);
for (nsITransactionListener* listener : listeners) {
if (NS_WARN_IF(!listener)) {
return NS_ERROR_FAILURE;
}
nsresult rv = listener->WillUndo(this, aTransaction, aInterrupt);
if (NS_FAILED(rv) || *aInterrupt) {
if (NS_FAILED(rv)) {
NS_WARNING("nsITransactionListener::WillUndo() failed");
return rv;
}
if (*aInterrupt) {
return NS_OK;
}
}
return NS_OK;
}
nsresult TransactionManager::DidUndoNotify(nsITransaction* aTransaction,
nsresult aUndoResult) {
for (int32_t i = 0, lcount = mListeners.Count(); i < lcount; i++) {
nsITransactionListener* listener = mListeners[i];
NS_ENSURE_TRUE(listener, NS_ERROR_FAILURE);
nsCOMArray<nsITransactionListener> listeners(mListeners);
for (nsITransactionListener* listener : listeners) {
if (NS_WARN_IF(!listener)) {
return NS_ERROR_FAILURE;
}
nsresult rv = listener->DidUndo(this, aTransaction, aUndoResult);
if (NS_FAILED(rv)) {
NS_WARNING("nsITransactionListener::DidUndo() failed");
return rv;
}
}
@ -509,26 +532,33 @@ nsresult TransactionManager::DidUndoNotify(nsITransaction* aTransaction,
nsresult TransactionManager::WillRedoNotify(nsITransaction* aTransaction,
bool* aInterrupt) {
for (int32_t i = 0, lcount = mListeners.Count(); i < lcount; i++) {
nsITransactionListener* listener = mListeners[i];
NS_ENSURE_TRUE(listener, NS_ERROR_FAILURE);
nsCOMArray<nsITransactionListener> listeners(mListeners);
for (nsITransactionListener* listener : listeners) {
if (NS_WARN_IF(!listener)) {
return NS_ERROR_FAILURE;
}
nsresult rv = listener->WillRedo(this, aTransaction, aInterrupt);
if (NS_FAILED(rv) || *aInterrupt) {
if (NS_FAILED(rv)) {
NS_WARNING("nsITransactionListener::WillRedo() failed");
return rv;
}
if (*aInterrupt) {
return NS_OK;
}
}
return NS_OK;
}
nsresult TransactionManager::DidRedoNotify(nsITransaction* aTransaction,
nsresult aRedoResult) {
for (int32_t i = 0, lcount = mListeners.Count(); i < lcount; i++) {
nsITransactionListener* listener = mListeners[i];
NS_ENSURE_TRUE(listener, NS_ERROR_FAILURE);
nsCOMArray<nsITransactionListener> listeners(mListeners);
for (nsITransactionListener* listener : listeners) {
if (NS_WARN_IF(!listener)) {
return NS_ERROR_FAILURE;
}
nsresult rv = listener->DidRedo(this, aTransaction, aRedoResult);
if (NS_FAILED(rv)) {
NS_WARNING("nsITransactionListener::DidRedo() failed");
return rv;
}
}
@ -536,25 +566,32 @@ nsresult TransactionManager::DidRedoNotify(nsITransaction* aTransaction,
}
nsresult TransactionManager::WillBeginBatchNotify(bool* aInterrupt) {
for (int32_t i = 0, lcount = mListeners.Count(); i < lcount; i++) {
nsITransactionListener* listener = mListeners[i];
NS_ENSURE_TRUE(listener, NS_ERROR_FAILURE);
nsCOMArray<nsITransactionListener> listeners(mListeners);
for (nsITransactionListener* listener : listeners) {
if (NS_WARN_IF(!listener)) {
return NS_ERROR_FAILURE;
}
nsresult rv = listener->WillBeginBatch(this, aInterrupt);
if (NS_FAILED(rv) || *aInterrupt) {
if (NS_FAILED(rv)) {
NS_WARNING("nsITransactionListener::WillBeginBatch() failed");
return rv;
}
if (*aInterrupt) {
return NS_OK;
}
}
return NS_OK;
}
nsresult TransactionManager::DidBeginBatchNotify(nsresult aResult) {
for (int32_t i = 0, lcount = mListeners.Count(); i < lcount; i++) {
nsITransactionListener* listener = mListeners[i];
NS_ENSURE_TRUE(listener, NS_ERROR_FAILURE);
nsCOMArray<nsITransactionListener> listeners(mListeners);
for (nsITransactionListener* listener : listeners) {
if (NS_WARN_IF(!listener)) {
return NS_ERROR_FAILURE;
}
nsresult rv = listener->DidBeginBatch(this, aResult);
if (NS_FAILED(rv)) {
NS_WARNING("nsITransactionListener::DidBeginBatch() failed");
return rv;
}
}
@ -562,25 +599,32 @@ nsresult TransactionManager::DidBeginBatchNotify(nsresult aResult) {
}
nsresult TransactionManager::WillEndBatchNotify(bool* aInterrupt) {
for (int32_t i = 0, lcount = mListeners.Count(); i < lcount; i++) {
nsITransactionListener* listener = mListeners[i];
NS_ENSURE_TRUE(listener, NS_ERROR_FAILURE);
nsCOMArray<nsITransactionListener> listeners(mListeners);
for (nsITransactionListener* listener : listeners) {
if (NS_WARN_IF(!listener)) {
return NS_ERROR_FAILURE;
}
nsresult rv = listener->WillEndBatch(this, aInterrupt);
if (NS_FAILED(rv) || *aInterrupt) {
if (NS_FAILED(rv)) {
NS_WARNING("nsITransactionListener::WillEndBatch() failed");
return rv;
}
if (*aInterrupt) {
return NS_OK;
}
}
return NS_OK;
}
nsresult TransactionManager::DidEndBatchNotify(nsresult aResult) {
for (int32_t i = 0, lcount = mListeners.Count(); i < lcount; i++) {
nsITransactionListener* listener = mListeners[i];
NS_ENSURE_TRUE(listener, NS_ERROR_FAILURE);
nsCOMArray<nsITransactionListener> listeners(mListeners);
for (nsITransactionListener* listener : listeners) {
if (NS_WARN_IF(!listener)) {
return NS_ERROR_FAILURE;
}
nsresult rv = listener->DidEndBatch(this, aResult);
if (NS_FAILED(rv)) {
NS_WARNING("nsITransactionListener::DidEndBatch() failed");
return rv;
}
}
@ -590,14 +634,19 @@ nsresult TransactionManager::DidEndBatchNotify(nsresult aResult) {
nsresult TransactionManager::WillMergeNotify(nsITransaction* aTop,
nsITransaction* aTransaction,
bool* aInterrupt) {
for (int32_t i = 0, lcount = mListeners.Count(); i < lcount; i++) {
nsITransactionListener* listener = mListeners[i];
NS_ENSURE_TRUE(listener, NS_ERROR_FAILURE);
nsCOMArray<nsITransactionListener> listeners(mListeners);
for (nsITransactionListener* listener : listeners) {
if (NS_WARN_IF(!listener)) {
return NS_ERROR_FAILURE;
}
nsresult rv = listener->WillMerge(this, aTop, aTransaction, aInterrupt);
if (NS_FAILED(rv) || *aInterrupt) {
if (NS_FAILED(rv)) {
NS_WARNING("nsITransactionListener::WillMerge() failed");
return rv;
}
if (*aInterrupt) {
return NS_OK;
}
}
return NS_OK;
}
@ -606,13 +655,15 @@ nsresult TransactionManager::DidMergeNotify(nsITransaction* aTop,
nsITransaction* aTransaction,
bool aDidMerge,
nsresult aMergeResult) {
for (int32_t i = 0, lcount = mListeners.Count(); i < lcount; i++) {
nsITransactionListener* listener = mListeners[i];
NS_ENSURE_TRUE(listener, NS_ERROR_FAILURE);
nsCOMArray<nsITransactionListener> listeners(mListeners);
for (nsITransactionListener* listener : listeners) {
if (NS_WARN_IF(!listener)) {
return NS_ERROR_FAILURE;
}
nsresult rv =
listener->DidMerge(this, aTop, aTransaction, aDidMerge, aMergeResult);
if (NS_FAILED(rv)) {
NS_WARNING("nsITransactionListener::DidMerge() failed");
return rv;
}
}
@ -634,15 +685,15 @@ nsresult TransactionManager::BeginTransaction(nsITransaction* aTransaction,
nsresult rv = transactionItem->DoTransaction();
if (NS_FAILED(rv)) {
NS_WARNING("TransactionItem::DoTransaction() failed");
transactionItem = mDoStack.Pop();
return rv;
}
return NS_OK;
return rv;
}
nsresult TransactionManager::EndTransaction(bool aAllowEmpty) {
RefPtr<TransactionItem> transactionItem = mDoStack.Pop();
if (!transactionItem) {
if (NS_WARN_IF(!transactionItem)) {
return NS_ERROR_FAILURE;
}
@ -650,21 +701,29 @@ nsresult TransactionManager::EndTransaction(bool aAllowEmpty) {
if (!transaction && !aAllowEmpty) {
// If we get here, the transaction must be a dummy batch transaction
// created by BeginBatch(). If it contains no children, get rid of it!
int32_t nc = 0;
transactionItem->GetNumberOfChildren(&nc);
if (!nc) {
if (!transactionItem->NumberOfChildren()) {
return NS_OK;
}
}
// Check if the transaction is transient. If it is, there's nothing
// more to do, just return.
bool isTransient = false;
nsresult rv = transaction ? transaction->GetIsTransient(&isTransient) : NS_OK;
if (NS_FAILED(rv) || isTransient || !mMaxTransactionCount) {
if (transaction) {
bool isTransient = false;
nsresult rv = transaction->GetIsTransient(&isTransient);
if (NS_FAILED(rv)) {
NS_WARNING("nsITransaction::GetIsTransient() failed");
return rv;
}
// XXX: Should we be clearing the redo stack if the transaction
// is transient and there is nothing on the do stack?
return rv;
if (isTransient) {
return NS_OK;
}
}
if (!mMaxTransactionCount) {
return NS_OK;
}
// Check if there is a transaction on the do stack. If there is,
@ -673,7 +732,10 @@ nsresult TransactionManager::EndTransaction(bool aAllowEmpty) {
RefPtr<TransactionItem> topTransactionItem = mDoStack.Peek();
if (topTransactionItem) {
// XXX: What do we do if this fails?
return topTransactionItem->AddChild(transactionItem);
nsresult rv = topTransactionItem->AddChild(*transactionItem);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"TransactionItem::AddChild() failed");
return rv;
}
// The transaction succeeded, so clear the redo stack.
@ -688,22 +750,25 @@ nsresult TransactionManager::EndTransaction(bool aAllowEmpty) {
topTransactionItem->GetTransaction();
if (topTransaction) {
bool doInterrupt = false;
rv = WillMergeNotify(topTransaction, transaction, &doInterrupt);
NS_ENSURE_SUCCESS(rv, rv);
nsresult rv = WillMergeNotify(topTransaction, transaction, &doInterrupt);
if (NS_FAILED(rv)) {
NS_WARNING("TransactionManager::WillMergeNotify() failed");
return rv;
}
if (!doInterrupt) {
rv = topTransaction->Merge(transaction, &didMerge);
nsresult rv = topTransaction->Merge(transaction, &didMerge);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"nsITransaction::Merge() failed");
nsresult rv2 =
DidMergeNotify(topTransaction, transaction, didMerge, rv);
if (NS_SUCCEEDED(rv)) {
rv = rv2;
}
if (NS_FAILED(rv)) {
// XXX: What do we do if this fails?
}
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv2),
"TransactionManager::DidMergeNotify() failed");
if (didMerge) {
return rv;
return NS_SUCCEEDED(rv) ? rv2 : rv;
}
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"The previous error was ignored");
}
}
}

Просмотреть файл

@ -3,10 +3,11 @@
* 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/TransactionStack.h"
#include "TransactionStack.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsDebug.h"
#include "nsISupportsUtils.h"
#include "nscore.h"
#include "TransactionItem.h"
@ -26,7 +27,7 @@ TransactionStack::TransactionStack(Type aType)
TransactionStack::~TransactionStack() { Clear(); }
void TransactionStack::Push(TransactionItem* aTransactionItem) {
if (!aTransactionItem) {
if (NS_WARN_IF(!aTransactionItem)) {
return;
}
@ -36,12 +37,12 @@ void TransactionStack::Push(TransactionItem* aTransactionItem) {
void TransactionStack::Push(
already_AddRefed<TransactionItem> aTransactionItem) {
RefPtr<TransactionItem> item(aTransactionItem);
if (!item) {
RefPtr<TransactionItem> transactionItem(aTransactionItem);
if (NS_WARN_IF(!transactionItem)) {
return;
}
nsDeque::Push(item.forget().take());
nsDeque::Push(transactionItem.forget().take());
}
already_AddRefed<TransactionItem> TransactionStack::Pop() {
@ -61,8 +62,9 @@ already_AddRefed<TransactionItem> TransactionStack::Peek() {
return item.forget();
}
already_AddRefed<TransactionItem> TransactionStack::GetItem(int32_t aIndex) {
if (aIndex < 0 || aIndex >= static_cast<int32_t>(nsDeque::GetSize())) {
already_AddRefed<TransactionItem> TransactionStack::GetItemAt(
size_t aIndex) const {
if (NS_WARN_IF(aIndex >= nsDeque::GetSize())) {
return nullptr;
}
RefPtr<TransactionItem> item =
@ -71,7 +73,7 @@ already_AddRefed<TransactionItem> TransactionStack::GetItem(int32_t aIndex) {
}
void TransactionStack::Clear() {
while (GetSize() != 0) {
while (GetSize()) {
RefPtr<TransactionItem> item = mType == FOR_UNDO ? Pop() : PopBottom();
}
}

Просмотреть файл

@ -26,9 +26,9 @@ class TransactionStack : private nsDeque {
already_AddRefed<TransactionItem> Pop();
already_AddRefed<TransactionItem> PopBottom();
already_AddRefed<TransactionItem> Peek();
already_AddRefed<TransactionItem> GetItem(int32_t aIndex);
already_AddRefed<TransactionItem> GetItemAt(size_t aIndex) const;
void Clear();
int32_t GetSize() const { return static_cast<int32_t>(nsDeque::GetSize()); }
size_t GetSize() const { return nsDeque::GetSize(); }
bool IsEmpty() const { return GetSize() == 0; }
void DoUnlink() { Clear(); }