EditAggregateTransaction.cpp (5155B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #include "EditAggregateTransaction.h" 7 8 #include "mozilla/Logging.h" 9 #include "mozilla/ReverseIterator.h" // for Reversed 10 #include "nsAString.h" 11 #include "nsAtom.h" 12 #include "nsCOMPtr.h" // for nsCOMPtr 13 #include "nsError.h" // for NS_OK, etc. 14 #include "nsGkAtoms.h" 15 #include "nsISupportsUtils.h" // for NS_ADDREF 16 #include "nsString.h" // for nsAutoString 17 18 namespace mozilla { 19 20 NS_IMPL_CYCLE_COLLECTION_INHERITED(EditAggregateTransaction, 21 EditTransactionBase, mChildren) 22 23 NS_IMPL_ADDREF_INHERITED(EditAggregateTransaction, EditTransactionBase) 24 NS_IMPL_RELEASE_INHERITED(EditAggregateTransaction, EditTransactionBase) 25 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(EditAggregateTransaction) 26 NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase) 27 28 NS_IMETHODIMP EditAggregateTransaction::DoTransaction() { 29 MOZ_LOG(GetLogModule(), LogLevel::Info, 30 ("%p EditAggregateTransaction::%s this={ mName=%s, mChildren=%zu } " 31 "Start==============================", 32 this, __FUNCTION__, 33 nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get(), 34 mChildren.Length())); 35 // FYI: It's legal (but not very useful) to have an empty child list. 36 for (const OwningNonNull<EditTransactionBase>& childTransaction : 37 CopyableAutoTArray<OwningNonNull<EditTransactionBase>, 10>(mChildren)) { 38 nsresult rv = MOZ_KnownLive(childTransaction)->DoTransaction(); 39 if (NS_FAILED(rv)) { 40 NS_WARNING("EditTransactionBase::DoTransaction() failed"); 41 return rv; 42 } 43 } 44 MOZ_LOG(GetLogModule(), LogLevel::Info, 45 ("%p EditAggregateTransaction::%s this={ mName=%s } " 46 "End================================", 47 this, __FUNCTION__, 48 nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get())); 49 return NS_OK; 50 } 51 52 NS_IMETHODIMP EditAggregateTransaction::UndoTransaction() { 53 MOZ_LOG(GetLogModule(), LogLevel::Info, 54 ("%p EditAggregateTransaction::%s this={ mName=%s, mChildren=%zu } " 55 "Start==============================", 56 this, __FUNCTION__, 57 nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get(), 58 mChildren.Length())); 59 // FYI: It's legal (but not very useful) to have an empty child list. 60 // Undo goes through children backwards. 61 const CopyableAutoTArray<OwningNonNull<EditTransactionBase>, 10> children( 62 mChildren); 63 for (const OwningNonNull<EditTransactionBase>& childTransaction : 64 Reversed(children)) { 65 nsresult rv = MOZ_KnownLive(childTransaction)->UndoTransaction(); 66 if (NS_FAILED(rv)) { 67 NS_WARNING("EditTransactionBase::UndoTransaction() failed"); 68 return rv; 69 } 70 } 71 MOZ_LOG(GetLogModule(), LogLevel::Info, 72 ("%p EditAggregateTransaction::%s this={ mName=%s } " 73 "End================================", 74 this, __FUNCTION__, 75 nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get())); 76 return NS_OK; 77 } 78 79 NS_IMETHODIMP EditAggregateTransaction::RedoTransaction() { 80 MOZ_LOG(GetLogModule(), LogLevel::Info, 81 ("%p EditAggregateTransaction::%s this={ mName=%s, mChildren=%zu } " 82 "Start==============================", 83 this, __FUNCTION__, 84 nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get(), 85 mChildren.Length())); 86 // It's legal (but not very useful) to have an empty child list. 87 const CopyableAutoTArray<OwningNonNull<EditTransactionBase>, 10> children( 88 mChildren); 89 for (const OwningNonNull<EditTransactionBase>& childTransaction : children) { 90 nsresult rv = MOZ_KnownLive(childTransaction)->RedoTransaction(); 91 if (NS_FAILED(rv)) { 92 NS_WARNING("EditTransactionBase::RedoTransaction() failed"); 93 return rv; 94 } 95 } 96 MOZ_LOG(GetLogModule(), LogLevel::Info, 97 ("%p EditAggregateTransaction::%s this={ mName=%s } " 98 "End================================", 99 this, __FUNCTION__, 100 nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get())); 101 return NS_OK; 102 } 103 104 NS_IMETHODIMP EditAggregateTransaction::Merge(nsITransaction* aOtherTransaction, 105 bool* aDidMerge) { 106 if (aDidMerge) { 107 *aDidMerge = false; 108 } 109 if (mChildren.IsEmpty()) { 110 MOZ_LOG(GetLogModule(), LogLevel::Debug, 111 ("%p EditAggregateTransaction::%s this={ mName=%s } returned false " 112 "due to no children", 113 this, __FUNCTION__, 114 nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get())); 115 return NS_OK; 116 } 117 // FIXME: Is this really intended not to loop? It looks like the code 118 // that used to be here sort of intended to loop, but didn't. 119 return mChildren[0]->Merge(aOtherTransaction, aDidMerge); 120 } 121 122 nsAtom* EditAggregateTransaction::GetName() const { return mName; } 123 124 } // namespace mozilla