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 PlaceholderTransaction_h
7 #define PlaceholderTransaction_h
8 
9 #include "EditAggregateTransaction.h"
10 #include "mozilla/Maybe.h"
11 #include "mozilla/SelectionState.h"
12 #include "mozilla/WeakPtr.h"
13 
14 namespace mozilla {
15 
16 class EditorBase;
17 
18 /**
19  * An aggregate transaction that knows how to absorb all subsequent
20  * transactions with the same name.  This transaction does not "Do" anything.
21  * But it absorbs other transactions via merge, and can undo/redo the
22  * transactions it has absorbed.
23  */
24 
25 class PlaceholderTransaction final
26     : public EditAggregateTransaction,
27       public SupportsWeakPtr<PlaceholderTransaction> {
28  protected:
29   PlaceholderTransaction(EditorBase& aEditorBase, nsStaticAtom& aName,
30                          Maybe<SelectionState>&& aSelState);
31 
32  public:
33   /**
34    * Creates a placeholder transaction.  This never returns nullptr.
35    *
36    * @param aEditorBase     The editor.
37    * @param aName           The name of creating transaction.
38    * @param aSelState       The selection state of aEditorBase.
39    */
Create(EditorBase & aEditorBase,nsStaticAtom & aName,Maybe<SelectionState> && aSelState)40   static already_AddRefed<PlaceholderTransaction> Create(
41       EditorBase& aEditorBase, nsStaticAtom& aName,
42       Maybe<SelectionState>&& aSelState) {
43     // Make sure to move aSelState into a local variable to null out the
44     // original Maybe<SelectionState> variable.
45     Maybe<SelectionState> selState(std::move(aSelState));
46     RefPtr<PlaceholderTransaction> transaction =
47         new PlaceholderTransaction(aEditorBase, aName, std::move(selState));
48     return transaction.forget();
49   }
50 
51   MOZ_DECLARE_WEAKREFERENCE_TYPENAME(PlaceholderTransaction)
52 
53   NS_DECL_ISUPPORTS_INHERITED
54 
55   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PlaceholderTransaction,
56                                            EditAggregateTransaction)
57   // ------------ EditAggregateTransaction -----------------------
58 
59   NS_DECL_EDITTRANSACTIONBASE
60   NS_DECL_EDITTRANSACTIONBASE_GETASMETHODS_OVERRIDE(PlaceholderTransaction)
61 
62   MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() override;
63   NS_IMETHOD Merge(nsITransaction* aTransaction, bool* aDidMerge) override;
64 
65   bool StartSelectionEquals(SelectionState& aSelectionState);
66 
67   nsresult EndPlaceHolderBatch();
68 
ForwardEndBatchTo(PlaceholderTransaction & aForwardingTransaction)69   void ForwardEndBatchTo(PlaceholderTransaction& aForwardingTransaction) {
70     mForwardingTransaction = &aForwardingTransaction;
71   }
72 
Commit()73   void Commit() { mCommitted = true; }
74 
75   nsresult RememberEndingSelection();
76 
77  protected:
78   virtual ~PlaceholderTransaction() = default;
79 
80   // The editor for this transaction.
81   RefPtr<EditorBase> mEditorBase;
82 
83   WeakPtr<PlaceholderTransaction> mForwardingTransaction;
84 
85   // First IME txn in this placeholder - used for IME merging.
86   WeakPtr<CompositionTransaction> mCompositionTransaction;
87 
88   // These next two members store the state of the selection in a safe way.
89   // Selection at the start of the transaction is stored, as is the selection
90   // at the end.  This is so that UndoTransaction() and RedoTransaction() can
91   // restore the selection properly.
92 
93   SelectionState mStartSel;
94   SelectionState mEndSel;
95 
96   // Do we auto absorb any and all transaction?
97   bool mAbsorb;
98   // Do we stop auto absorbing any matching placeholder transactions?
99   bool mCommitted;
100 };
101 
102 }  // namespace mozilla
103 
104 #endif  // #ifndef PlaceholderTransaction_h
105