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 ReplaceTextTransaction_h
7 #define ReplaceTextTransaction_h
8 
9 #include "mozilla/Attributes.h"
10 #include "mozilla/EditorBase.h"
11 #include "mozilla/EditorDOMPoint.h"
12 #include "mozilla/EditTransactionBase.h"
13 #include "mozilla/Maybe.h"
14 #include "mozilla/RefPtr.h"
15 #include "mozilla/dom/Text.h"
16 #include "nsDebug.h"
17 #include "nsString.h"
18 
19 namespace mozilla {
20 
21 class EditorBase;
22 
23 class ReplaceTextTransaction final : public EditTransactionBase {
24  private:
ReplaceTextTransaction(EditorBase & aEditorBase,const nsAString & aStringToInsert,dom::Text & aTextNode,uint32_t aStartOffset,uint32_t aLength)25   ReplaceTextTransaction(EditorBase& aEditorBase,
26                          const nsAString& aStringToInsert, dom::Text& aTextNode,
27                          uint32_t aStartOffset, uint32_t aLength)
28       : mEditorBase(&aEditorBase),
29         mTextNode(&aTextNode),
30         mStringToInsert(aStringToInsert),
31         mOffset(aStartOffset) {
32     if (aLength) {
33       IgnoredErrorResult ignoredError;
34       mTextNode->SubstringData(mOffset, aLength, mStringToBeReplaced,
35                                ignoredError);
36       NS_WARNING_ASSERTION(
37           !ignoredError.Failed(),
38           "Failed to initialize ReplaceTextTransaction::mStringToBeReplaced, "
39           "but ignored");
40     }
41   }
42 
43   virtual ~ReplaceTextTransaction() = default;
44 
45  public:
Create(EditorBase & aEditorBase,const nsAString & aStringToInsert,dom::Text & aTextNode,uint32_t aStartOffset,uint32_t aLength)46   static already_AddRefed<ReplaceTextTransaction> Create(
47       EditorBase& aEditorBase, const nsAString& aStringToInsert,
48       dom::Text& aTextNode, uint32_t aStartOffset, uint32_t aLength) {
49     MOZ_ASSERT(aLength > 0, "Use InsertTextTransaction instead");
50     MOZ_ASSERT(!aStringToInsert.IsEmpty(), "Use DeleteTextTransaction instead");
51     MOZ_ASSERT(aTextNode.Length() >= aStartOffset);
52     MOZ_ASSERT(aTextNode.Length() >= aStartOffset + aLength);
53 
54     RefPtr<ReplaceTextTransaction> transaction = new ReplaceTextTransaction(
55         aEditorBase, aStringToInsert, aTextNode, aStartOffset, aLength);
56     return transaction.forget();
57   }
58 
59   ReplaceTextTransaction() = delete;
60   ReplaceTextTransaction(const ReplaceTextTransaction&) = delete;
61   ReplaceTextTransaction& operator=(const ReplaceTextTransaction&) = delete;
62 
63   NS_DECL_ISUPPORTS_INHERITED
64   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ReplaceTextTransaction,
65                                            EditTransactionBase)
66 
67   NS_DECL_EDITTRANSACTIONBASE
68   NS_DECL_EDITTRANSACTIONBASE_GETASMETHODS_OVERRIDE(ReplaceTextTransaction)
69 
70   MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() final;
71 
72   friend std::ostream& operator<<(std::ostream& aStream,
73                                   const ReplaceTextTransaction& aTransaction);
74 
75  private:
76   RefPtr<EditorBase> mEditorBase;
77   RefPtr<dom::Text> mTextNode;
78 
79   nsString mStringToInsert;
80   nsString mStringToBeReplaced;
81 
82   uint32_t mOffset;
83 };
84 
85 }  // namespace mozilla
86 
87 #endif  // #ifndef ReplaceTextTransaction_
88