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 #ifndef mozilla_TransactionManager_h
7 #define mozilla_TransactionManager_h
8
9 #include "mozilla/TransactionStack.h"
10
11 #include "nsCOMArray.h"
12 #include "nsCOMPtr.h"
13 #include "nsCycleCollectionParticipant.h"
14 #include "nsISupportsImpl.h"
15 #include "nsITransactionManager.h"
16 #include "nsWeakReference.h"
17 #include "nscore.h"
18
19 class nsITransaction;
20 class nsITransactionListener;
21
22 namespace mozilla {
23
24 class TransactionManager final : public nsITransactionManager,
25 public nsSupportsWeakReference {
26 public:
27 explicit TransactionManager(int32_t aMaxTransactionCount = -1);
28
29 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
30 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(TransactionManager,
31 nsITransactionManager)
32
33 NS_DECL_NSITRANSACTIONMANAGER
34
35 already_AddRefed<nsITransaction> PeekUndoStack();
36 already_AddRefed<nsITransaction> PeekRedoStack();
37
38 MOZ_CAN_RUN_SCRIPT nsresult Undo();
39 MOZ_CAN_RUN_SCRIPT nsresult Redo();
40
NumberOfUndoItems()41 size_t NumberOfUndoItems() const { return mUndoStack.GetSize(); }
NumberOfRedoItems()42 size_t NumberOfRedoItems() const { return mRedoStack.GetSize(); }
43
NumberOfMaximumTransactions()44 int32_t NumberOfMaximumTransactions() const { return mMaxTransactionCount; }
45
46 bool EnableUndoRedo(int32_t aMaxTransactionCount = -1);
DisableUndoRedo()47 bool DisableUndoRedo() { return EnableUndoRedo(0); }
ClearUndoRedo()48 bool ClearUndoRedo() {
49 if (NS_WARN_IF(!mDoStack.IsEmpty())) {
50 return false;
51 }
52 mUndoStack.Clear();
53 mRedoStack.Clear();
54 return true;
55 }
56
AddTransactionListener(nsITransactionListener & aListener)57 bool AddTransactionListener(nsITransactionListener& aListener) {
58 // XXX Shouldn't we check if aListener has already been in mListeners?
59 return mListeners.AppendObject(&aListener);
60 }
RemoveTransactionListener(nsITransactionListener & aListener)61 bool RemoveTransactionListener(nsITransactionListener& aListener) {
62 return mListeners.RemoveObject(&aListener);
63 }
64
65 // FYI: We don't need to treat the following methods as `MOZ_CAN_RUN_SCRIPT`
66 // for now because only ComposerCommandUpdater is the listener and it
67 // does not do something dangerous synchronously.
68 MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
69 WillDoNotify(nsITransaction* aTransaction, bool* aInterrupt);
70 MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult DidDoNotify(nsITransaction* aTransaction,
71 nsresult aExecuteResult);
72 MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
73 WillUndoNotify(nsITransaction* aTransaction, bool* aInterrupt);
74 MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
75 DidUndoNotify(nsITransaction* aTransaction, nsresult aUndoResult);
76 MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
77 WillRedoNotify(nsITransaction* aTransaction, bool* aInterrupt);
78 MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
79 DidRedoNotify(nsITransaction* aTransaction, nsresult aRedoResult);
80 MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult WillBeginBatchNotify(bool* aInterrupt);
81 MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult DidBeginBatchNotify(nsresult aResult);
82 MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult WillEndBatchNotify(bool* aInterrupt);
83 MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult DidEndBatchNotify(nsresult aResult);
84 MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult WillMergeNotify(
85 nsITransaction* aTop, nsITransaction* aTransaction, bool* aInterrupt);
86 MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
87 DidMergeNotify(nsITransaction* aTop, nsITransaction* aTransaction,
88 bool aDidMerge, nsresult aMergeResult);
89
90 /**
91 * Exposing non-virtual methods of nsITransactionManager methods.
92 */
93 MOZ_CAN_RUN_SCRIPT nsresult BeginBatchInternal(nsISupports* aData);
94 nsresult EndBatchInternal(bool aAllowEmpty);
95
96 private:
97 virtual ~TransactionManager() = default;
98
99 MOZ_CAN_RUN_SCRIPT nsresult BeginTransaction(nsITransaction* aTransaction,
100 nsISupports* aData);
101 nsresult EndTransaction(bool aAllowEmpty);
102
103 int32_t mMaxTransactionCount;
104 TransactionStack mDoStack;
105 TransactionStack mUndoStack;
106 TransactionStack mRedoStack;
107 nsCOMArray<nsITransactionListener> mListeners;
108 };
109
110 } // namespace mozilla
111
AsTransactionManager()112 mozilla::TransactionManager* nsITransactionManager::AsTransactionManager() {
113 return static_cast<mozilla::TransactionManager*>(this);
114 }
115
116 #endif // #ifndef mozilla_TransactionManager_h
117