Bug 1890689 accumulate input in LargerReceiverBlockSizeThanDesiredBuffering GTest...
[gecko.git] / editor / libeditor / ReplaceTextTransaction.cpp
blob6887fc6011de0a922e2dd91ab0b14f31edef6a27
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/. */
6 #include "ReplaceTextTransaction.h"
8 #include "HTMLEditUtils.h"
10 #include "mozilla/Logging.h"
11 #include "mozilla/OwningNonNull.h"
12 #include "mozilla/ToString.h"
14 namespace mozilla {
16 using namespace dom;
18 std::ostream& operator<<(std::ostream& aStream,
19 const ReplaceTextTransaction& aTransaction) {
20 aStream << "{ mTextNode=" << aTransaction.mTextNode.get();
21 if (aTransaction.mTextNode) {
22 aStream << " (" << *aTransaction.mTextNode << ")";
24 aStream << ", mStringToInsert=\""
25 << NS_ConvertUTF16toUTF8(aTransaction.mStringToInsert).get() << "\""
26 << ", mStringToBeReplaced=\""
27 << NS_ConvertUTF16toUTF8(aTransaction.mStringToBeReplaced).get()
28 << "\", mOffset=" << aTransaction.mOffset
29 << ", mEditorBase=" << aTransaction.mEditorBase.get() << " }";
30 return aStream;
33 NS_IMPL_CYCLE_COLLECTION_INHERITED(ReplaceTextTransaction, EditTransactionBase,
34 mEditorBase, mTextNode)
36 NS_IMPL_ADDREF_INHERITED(ReplaceTextTransaction, EditTransactionBase)
37 NS_IMPL_RELEASE_INHERITED(ReplaceTextTransaction, EditTransactionBase)
38 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ReplaceTextTransaction)
39 NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)
41 NS_IMETHODIMP ReplaceTextTransaction::DoTransaction() {
42 MOZ_LOG(GetLogModule(), LogLevel::Info,
43 ("%p ReplaceTextTransaction::%s this=%s", this, __FUNCTION__,
44 ToString(*this).c_str()));
46 if (MOZ_UNLIKELY(
47 NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode) ||
48 NS_WARN_IF(!HTMLEditUtils::IsSimplyEditableNode(*mTextNode)))) {
49 return NS_ERROR_NOT_AVAILABLE;
52 OwningNonNull<EditorBase> editorBase = *mEditorBase;
53 OwningNonNull<Text> textNode = *mTextNode;
55 IgnoredErrorResult error;
56 editorBase->DoReplaceText(textNode, mOffset, mStringToBeReplaced.Length(),
57 mStringToInsert, error);
58 if (MOZ_UNLIKELY(error.Failed())) {
59 NS_WARNING("EditorBase::DoReplaceText() failed");
60 return error.StealNSResult();
62 // XXX What should we do if mutation event listener changed the node?
63 editorBase->RangeUpdaterRef().SelAdjReplaceText(textNode, mOffset,
64 mStringToBeReplaced.Length(),
65 mStringToInsert.Length());
66 return NS_OK;
69 NS_IMETHODIMP ReplaceTextTransaction::UndoTransaction() {
70 MOZ_LOG(GetLogModule(), LogLevel::Info,
71 ("%p ReplaceTextTransaction::%s this=%s", this, __FUNCTION__,
72 ToString(*this).c_str()));
74 if (MOZ_UNLIKELY(
75 NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode) ||
76 NS_WARN_IF(!HTMLEditUtils::IsSimplyEditableNode(*mTextNode)))) {
77 return NS_ERROR_NOT_AVAILABLE;
80 IgnoredErrorResult error;
81 nsAutoString insertedString;
82 mTextNode->SubstringData(mOffset, mStringToInsert.Length(), insertedString,
83 error);
84 if (MOZ_UNLIKELY(error.Failed())) {
85 NS_WARNING("CharacterData::SubstringData() failed");
86 return error.StealNSResult();
88 if (MOZ_UNLIKELY(insertedString != mStringToInsert)) {
89 NS_WARNING(
90 "ReplaceTextTransaction::UndoTransaction() did nothing due to "
91 "unexpected text");
92 return NS_OK;
95 OwningNonNull<EditorBase> editorBase = *mEditorBase;
96 OwningNonNull<Text> textNode = *mTextNode;
98 editorBase->DoReplaceText(textNode, mOffset, mStringToInsert.Length(),
99 mStringToBeReplaced, error);
100 if (MOZ_UNLIKELY(error.Failed())) {
101 NS_WARNING("EditorBase::DoReplaceText() failed");
102 return error.StealNSResult();
104 // XXX What should we do if mutation event listener changed the node?
105 editorBase->RangeUpdaterRef().SelAdjReplaceText(textNode, mOffset,
106 mStringToInsert.Length(),
107 mStringToBeReplaced.Length());
109 if (!editorBase->AllowsTransactionsToChangeSelection()) {
110 return NS_OK;
113 // XXX Should we stop setting selection when mutation event listener
114 // modifies the text node?
115 editorBase->CollapseSelectionTo(
116 EditorRawDOMPoint(textNode, mOffset + mStringToBeReplaced.Length()),
117 error);
118 if (MOZ_UNLIKELY(error.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED))) {
119 NS_WARNING(
120 "EditorBase::CollapseSelectionTo() caused destroying the editor");
121 return NS_ERROR_EDITOR_DESTROYED;
123 NS_ASSERTION(!error.Failed(),
124 "EditorBase::CollapseSelectionTo() failed, but ignored");
125 return NS_OK;
128 NS_IMETHODIMP ReplaceTextTransaction::RedoTransaction() {
129 MOZ_LOG(GetLogModule(), LogLevel::Info,
130 ("%p ReplaceTextTransaction::%s this=%s", this, __FUNCTION__,
131 ToString(*this).c_str()));
133 if (MOZ_UNLIKELY(
134 NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode) ||
135 NS_WARN_IF(!HTMLEditUtils::IsSimplyEditableNode(*mTextNode)))) {
136 return NS_ERROR_NOT_AVAILABLE;
139 IgnoredErrorResult error;
140 nsAutoString undoneString;
141 mTextNode->SubstringData(mOffset, mStringToBeReplaced.Length(), undoneString,
142 error);
143 if (MOZ_UNLIKELY(error.Failed())) {
144 NS_WARNING("CharacterData::SubstringData() failed");
145 return error.StealNSResult();
147 if (MOZ_UNLIKELY(undoneString != mStringToBeReplaced)) {
148 NS_WARNING(
149 "ReplaceTextTransaction::RedoTransaction() did nothing due to "
150 "unexpected text");
151 return NS_OK;
154 OwningNonNull<EditorBase> editorBase = *mEditorBase;
155 OwningNonNull<Text> textNode = *mTextNode;
157 editorBase->DoReplaceText(textNode, mOffset, mStringToBeReplaced.Length(),
158 mStringToInsert, error);
159 if (MOZ_UNLIKELY(error.Failed())) {
160 NS_WARNING("EditorBase::DoReplaceText() failed");
161 return error.StealNSResult();
163 // XXX What should we do if mutation event listener changed the node?
164 editorBase->RangeUpdaterRef().SelAdjReplaceText(textNode, mOffset,
165 mStringToBeReplaced.Length(),
166 mStringToInsert.Length());
168 if (!editorBase->AllowsTransactionsToChangeSelection()) {
169 return NS_OK;
172 // XXX Should we stop setting selection when mutation event listener
173 // modifies the text node?
174 editorBase->CollapseSelectionTo(SuggestPointToPutCaret<EditorRawDOMPoint>(),
175 error);
176 if (MOZ_UNLIKELY(error.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED))) {
177 NS_WARNING(
178 "EditorBase::CollapseSelectionTo() caused destroying the editor");
179 return NS_ERROR_EDITOR_DESTROYED;
181 NS_ASSERTION(!error.Failed(),
182 "EditorBase::CollapseSelectionTo() failed, but ignored");
183 return NS_OK;
186 } // namespace mozilla