Bug 1735777 [wpt PR 31236] - webrtc wpt: fix invalid unicode indexOf method call...
[gecko.git] / editor / libeditor / ReplaceTextTransaction.cpp
blob4193062ae20831a800d395d1acc17659a2bc13a5
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 (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode) ||
47 NS_WARN_IF(!HTMLEditUtils::IsSimplyEditableNode(*mTextNode))) {
48 return NS_ERROR_NOT_AVAILABLE;
51 OwningNonNull<EditorBase> editorBase = *mEditorBase;
52 OwningNonNull<Text> textNode = *mTextNode;
54 ErrorResult error;
55 editorBase->DoReplaceText(textNode, mOffset, mStringToBeReplaced.Length(),
56 mStringToInsert, error);
57 if (error.Failed()) {
58 NS_WARNING("EditorBase::DoReplaceText() failed");
59 return error.StealNSResult();
61 // XXX What should we do if mutation event listener changed the node?
62 editorBase->RangeUpdaterRef().SelAdjReplaceText(textNode, mOffset,
63 mStringToBeReplaced.Length(),
64 mStringToInsert.Length());
66 if (!editorBase->AllowsTransactionsToChangeSelection()) {
67 return NS_OK;
70 // XXX Should we stop setting selection when mutation event listener
71 // modifies the text node?
72 RefPtr<Selection> selection = editorBase->GetSelection();
73 if (NS_WARN_IF(!selection)) {
74 return NS_ERROR_FAILURE;
76 DebugOnly<nsresult> rvIgnored = selection->CollapseInLimiter(
77 textNode, mOffset + mStringToInsert.Length());
78 if (NS_WARN_IF(editorBase->Destroyed())) {
79 return NS_ERROR_EDITOR_DESTROYED;
81 NS_ASSERTION(NS_SUCCEEDED(rvIgnored),
82 "Selection::CollapseInLimiter() failed, but ignored");
83 return NS_OK;
86 NS_IMETHODIMP ReplaceTextTransaction::UndoTransaction() {
87 MOZ_LOG(GetLogModule(), LogLevel::Info,
88 ("%p ReplaceTextTransaction::%s this=%s", this, __FUNCTION__,
89 ToString(*this).c_str()));
91 if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode) ||
92 NS_WARN_IF(!HTMLEditUtils::IsSimplyEditableNode(*mTextNode))) {
93 return NS_ERROR_NOT_AVAILABLE;
96 ErrorResult error;
97 nsAutoString insertedString;
98 mTextNode->SubstringData(mOffset, mStringToInsert.Length(), insertedString,
99 error);
100 if (error.Failed()) {
101 NS_WARNING("CharacterData::SubstringData() failed");
102 return error.StealNSResult();
104 if (insertedString != mStringToInsert) {
105 NS_WARNING(
106 "ReplaceTextTransaction::UndoTransaction() did nothing due to "
107 "unexpected text");
108 return NS_OK;
111 OwningNonNull<EditorBase> editorBase = *mEditorBase;
112 OwningNonNull<Text> textNode = *mTextNode;
114 editorBase->DoReplaceText(textNode, mOffset, mStringToInsert.Length(),
115 mStringToBeReplaced, error);
116 if (error.Failed()) {
117 NS_WARNING("EditorBase::DoReplaceText() failed");
118 return error.StealNSResult();
120 // XXX What should we do if mutation event listener changed the node?
121 editorBase->RangeUpdaterRef().SelAdjReplaceText(textNode, mOffset,
122 mStringToInsert.Length(),
123 mStringToBeReplaced.Length());
125 if (!editorBase->AllowsTransactionsToChangeSelection()) {
126 return NS_OK;
129 // XXX Should we stop setting selection when mutation event listener
130 // modifies the text node?
131 RefPtr<Selection> selection = editorBase->GetSelection();
132 if (NS_WARN_IF(!selection)) {
133 return NS_ERROR_FAILURE;
135 DebugOnly<nsresult> rvIgnored = selection->CollapseInLimiter(
136 textNode, mOffset + mStringToBeReplaced.Length());
137 if (NS_WARN_IF(editorBase->Destroyed())) {
138 return NS_ERROR_EDITOR_DESTROYED;
140 NS_ASSERTION(NS_SUCCEEDED(rvIgnored),
141 "Selection::CollapseInLimiter() failed, but ignored");
142 return NS_OK;
145 NS_IMETHODIMP ReplaceTextTransaction::RedoTransaction() {
146 MOZ_LOG(GetLogModule(), LogLevel::Info,
147 ("%p ReplaceTextTransaction::%s this=%s", this, __FUNCTION__,
148 ToString(*this).c_str()));
150 if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode) ||
151 NS_WARN_IF(!HTMLEditUtils::IsSimplyEditableNode(*mTextNode))) {
152 return NS_ERROR_NOT_AVAILABLE;
155 ErrorResult error;
156 nsAutoString undoneString;
157 mTextNode->SubstringData(mOffset, mStringToBeReplaced.Length(), undoneString,
158 error);
159 if (error.Failed()) {
160 NS_WARNING("CharacterData::SubstringData() failed");
161 return error.StealNSResult();
163 if (undoneString != mStringToBeReplaced) {
164 NS_WARNING(
165 "ReplaceTextTransaction::RedoTransaction() did nothing due to "
166 "unexpected text");
167 return NS_OK;
170 OwningNonNull<EditorBase> editorBase = *mEditorBase;
171 OwningNonNull<Text> textNode = *mTextNode;
173 editorBase->DoReplaceText(textNode, mOffset, mStringToBeReplaced.Length(),
174 mStringToInsert, error);
175 if (error.Failed()) {
176 NS_WARNING("EditorBase::DoReplaceText() failed");
177 return error.StealNSResult();
179 // XXX What should we do if mutation event listener changed the node?
180 editorBase->RangeUpdaterRef().SelAdjReplaceText(textNode, mOffset,
181 mStringToBeReplaced.Length(),
182 mStringToInsert.Length());
184 if (!editorBase->AllowsTransactionsToChangeSelection()) {
185 return NS_OK;
188 // XXX Should we stop setting selection when mutation event listener
189 // modifies the text node?
190 RefPtr<Selection> selection = editorBase->GetSelection();
191 if (NS_WARN_IF(!selection)) {
192 return NS_ERROR_FAILURE;
194 DebugOnly<nsresult> rvIgnored = selection->CollapseInLimiter(
195 textNode, mOffset + mStringToInsert.Length());
196 if (NS_WARN_IF(editorBase->Destroyed())) {
197 return NS_ERROR_EDITOR_DESTROYED;
199 NS_ASSERTION(NS_SUCCEEDED(rvIgnored),
200 "Selection::CollapseInLimiter() failed, but ignored");
201 return NS_OK;
204 } // namespace mozilla