File: | root/firefox-clang/editor/libeditor/TextEditor.cpp |
Warning: | line 571, column 12 Value stored to 'rv' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | #include "TextEditor.h" |
7 | |
8 | #include <algorithm> |
9 | |
10 | #include "EditAction.h" |
11 | #include "EditAggregateTransaction.h" |
12 | #include "EditorDOMPoint.h" |
13 | #include "HTMLEditor.h" |
14 | #include "HTMLEditUtils.h" |
15 | #include "InternetCiter.h" |
16 | #include "PlaceholderTransaction.h" |
17 | #include "gfxFontUtils.h" |
18 | |
19 | #include "mozilla/dom/DocumentInlines.h" |
20 | #include "mozilla/Assertions.h" |
21 | #include "mozilla/ContentIterator.h" |
22 | #include "mozilla/IMEStateManager.h" |
23 | #include "mozilla/LookAndFeel.h" |
24 | #include "mozilla/mozalloc.h" |
25 | #include "mozilla/Preferences.h" |
26 | #include "mozilla/PresShell.h" |
27 | #include "mozilla/StaticPrefs_dom.h" |
28 | #include "mozilla/StaticPrefs_editor.h" |
29 | #include "mozilla/TextComposition.h" |
30 | #include "mozilla/TextEvents.h" |
31 | #include "mozilla/TextServicesDocument.h" |
32 | #include "mozilla/Try.h" |
33 | #include "mozilla/dom/Event.h" |
34 | #include "mozilla/dom/Element.h" |
35 | #include "mozilla/dom/Selection.h" |
36 | #include "mozilla/dom/StaticRange.h" |
37 | |
38 | #include "nsAString.h" |
39 | #include "nsCRT.h" |
40 | #include "nsCaret.h" |
41 | #include "nsCharTraits.h" |
42 | #include "nsComponentManagerUtils.h" |
43 | #include "nsContentList.h" |
44 | #include "nsDebug.h" |
45 | #include "nsDependentSubstring.h" |
46 | #include "nsError.h" |
47 | #include "nsFocusManager.h" |
48 | #include "nsGkAtoms.h" |
49 | #include "nsIContent.h" |
50 | #include "nsINode.h" |
51 | #include "nsIPrincipal.h" |
52 | #include "nsISelectionController.h" |
53 | #include "nsISupportsPrimitives.h" |
54 | #include "nsITransferable.h" |
55 | #include "nsIWeakReferenceUtils.h" |
56 | #include "nsNameSpaceManager.h" |
57 | #include "nsLiteralString.h" |
58 | #include "nsPresContext.h" |
59 | #include "nsReadableUtils.h" |
60 | #include "nsServiceManagerUtils.h" |
61 | #include "nsString.h" |
62 | #include "nsStringFwd.h" |
63 | #include "nsTextFragment.h" |
64 | #include "nsTextNode.h" |
65 | #include "nsUnicharUtils.h" |
66 | #include "nsXPCOM.h" |
67 | |
68 | class nsIOutputStream; |
69 | class nsISupports; |
70 | |
71 | namespace mozilla { |
72 | |
73 | using namespace dom; |
74 | |
75 | using LeafNodeType = HTMLEditUtils::LeafNodeType; |
76 | using LeafNodeTypes = HTMLEditUtils::LeafNodeTypes; |
77 | |
78 | template EditorDOMPoint TextEditor::FindBetterInsertionPoint( |
79 | const EditorDOMPoint& aPoint) const; |
80 | template EditorRawDOMPoint TextEditor::FindBetterInsertionPoint( |
81 | const EditorRawDOMPoint& aPoint) const; |
82 | |
83 | TextEditor::TextEditor() : EditorBase(EditorBase::EditorType::Text) { |
84 | // printf("Size of TextEditor: %zu\n", sizeof(TextEditor)); |
85 | static_assert( |
86 | sizeof(TextEditor) <= 512, |
87 | "TextEditor instance should be allocatable in the quantum class bins"); |
88 | } |
89 | |
90 | TextEditor::~TextEditor() { |
91 | // Remove event listeners. Note that if we had an HTML editor, |
92 | // it installed its own instead of these |
93 | RemoveEventListeners(); |
94 | } |
95 | |
96 | NS_IMPL_CYCLE_COLLECTION_CLASS(TextEditor)TextEditor::cycleCollection TextEditor::_cycleCollectorGlobal ; |
97 | |
98 | NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(TextEditor, EditorBase)void TextEditor::cycleCollection::Unlink(void* p) { TextEditor * tmp = DowncastCCParticipant<TextEditor>(p); nsISupports * s = static_cast<nsISupports*>(p); EditorBase::cycleCollection ::Unlink(s); |
99 | if (tmp->mPasswordMaskData) { |
100 | tmp->mPasswordMaskData->CancelTimer(PasswordMaskData::ReleaseTimer::No); |
101 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mPasswordMaskData->mTimer)ImplCycleCollectionUnlink(tmp->mPasswordMaskData->mTimer ); |
102 | } |
103 | NS_IMPL_CYCLE_COLLECTION_UNLINK_END(void)tmp; } |
104 | |
105 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(TextEditor, EditorBase)nsresult TextEditor::cycleCollection::TraverseNative( void* p , nsCycleCollectionTraversalCallback& cb) { TextEditor* tmp = DowncastCCParticipant<TextEditor>(p); nsISupports* s = static_cast<nsISupports*>(p); if (EditorBase::cycleCollection ::TraverseNative(s, cb) == NS_SUCCESS_INTERRUPTED_TRAVERSE) { return NS_SUCCESS_INTERRUPTED_TRAVERSE; } |
106 | if (tmp->mPasswordMaskData) { |
107 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPasswordMaskData->mTimer)ImplCycleCollectionTraverse(cb, tmp->mPasswordMaskData-> mTimer, "mPasswordMaskData->mTimer", 0); |
108 | } |
109 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END(void)tmp; return NS_OK; } |
110 | |
111 | NS_IMPL_ADDREF_INHERITED(TextEditor, EditorBase)MozExternalRefCountType TextEditor::AddRef(void) { static_assert (!std::is_destructible_v<TextEditor>, "Reference-counted class " "TextEditor" " should not have a public destructor. " "Make this class's destructor non-public" ); nsrefcnt r = EditorBase::AddRef(); if constexpr (::mozilla ::detail::ShouldLogInheritedRefcnt<TextEditor>) { NS_LogAddRef ((this), (r), ("TextEditor"), (uint32_t)(sizeof(*this))); } return r; } |
112 | NS_IMPL_RELEASE_INHERITED(TextEditor, EditorBase)MozExternalRefCountType TextEditor::Release(void) { nsrefcnt r = EditorBase::Release(); if constexpr (::mozilla::detail::ShouldLogInheritedRefcnt <TextEditor>) { NS_LogRelease((this), (r), ("TextEditor" )); } return r; } |
113 | |
114 | NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TextEditor)nsresult TextEditor::QueryInterface(const nsIID& aIID, void ** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak( NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!" , "aInstancePtr", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 114); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface ; if (TopThreeWordsEquals( aIID, (nsXPCOMCycleCollectionParticipant ::kIID), (nsCycleCollectionISupports::kIID)) && (LowWordEquals (aIID, (nsXPCOMCycleCollectionParticipant::kIID)) || LowWordEquals (aIID, (nsCycleCollectionISupports::kIID)))) { if (LowWordEquals (aIID, (nsXPCOMCycleCollectionParticipant::kIID))) { *aInstancePtr = TextEditor::cycleCollection::GetParticipant(); return NS_OK ; } if (LowWordEquals(aIID, (nsCycleCollectionISupports::kIID ))) { *aInstancePtr = TextEditor::cycleCollection::Upcast(this ); return NS_OK; } foundInterface = nullptr; } else |
115 | NS_INTERFACE_MAP_ENTRY(nsITimerCallback)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t <decltype(*this)>, nsITimerCallback>)) foundInterface = static_cast<nsITimerCallback*>(this); else |
116 | NS_INTERFACE_MAP_ENTRY(nsINamed)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t <decltype(*this)>, nsINamed>)) foundInterface = static_cast <nsINamed*>(this); else |
117 | NS_INTERFACE_MAP_END_INHERITING(EditorBase)foundInterface = 0; nsresult status; if (!foundInterface) status = EditorBase::QueryInterface(aIID, (void**)&foundInterface ); else { (foundInterface)->AddRef(); status = NS_OK; } *aInstancePtr = foundInterface; return status; } |
118 | |
119 | NS_IMETHODIMPnsresult TextEditor::EndOfDocument() { |
120 | AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing); |
121 | if (NS_WARN_IF(!editActionData.CanHandle())NS_warn_if_impl(!editActionData.CanHandle(), "!editActionData.CanHandle()" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 121)) { |
122 | return NS_ERROR_NOT_INITIALIZED; |
123 | } |
124 | nsresult rv = CollapseSelectionToEndOfTextNode(); |
125 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::CollapseSelectionToEndOfTextNode() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 126); } } while (false) |
126 | "TextEditor::CollapseSelectionToEndOfTextNode() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::CollapseSelectionToEndOfTextNode() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 126); } } while (false); |
127 | // This is low level API for embedders and chrome script so that we can return |
128 | // raw error code here. |
129 | return rv; |
130 | } |
131 | |
132 | nsresult TextEditor::CollapseSelectionToEndOfTextNode() { |
133 | MOZ_ASSERT(IsEditActionDataAvailable())do { static_assert( mozilla::detail::AssertionConditionType< decltype(IsEditActionDataAvailable())>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(IsEditActionDataAvailable()) )), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsEditActionDataAvailable()" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 133) ; AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()" ")"); do { MOZ_CrashSequence(__null, 133); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
134 | |
135 | Element* anonymousDivElement = GetRoot(); |
136 | if (NS_WARN_IF(!anonymousDivElement)NS_warn_if_impl(!anonymousDivElement, "!anonymousDivElement", "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 136)) { |
137 | return NS_ERROR_NULL_POINTER; |
138 | } |
139 | |
140 | RefPtr<Text> textNode = |
141 | Text::FromNodeOrNull(anonymousDivElement->GetFirstChild()); |
142 | MOZ_ASSERT(textNode)do { static_assert( mozilla::detail::AssertionConditionType< decltype(textNode)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(textNode))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("textNode", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 142); AnnotateMozCrashReason("MOZ_ASSERT" "(" "textNode" ")" ); do { MOZ_CrashSequence(__null, 142); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
143 | nsresult rv = CollapseSelectionToEndOf(*textNode); |
144 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::CollapseSelectionToEndOf() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 145); } } while (false) |
145 | "EditorBase::CollapseSelectionToEndOf() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::CollapseSelectionToEndOf() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 145); } } while (false); |
146 | return rv; |
147 | } |
148 | |
149 | nsresult TextEditor::Init(Document& aDocument, Element& aAnonymousDivElement, |
150 | nsISelectionController& aSelectionController, |
151 | uint32_t aFlags, |
152 | UniquePtr<PasswordMaskData>&& aPasswordMaskData) { |
153 | MOZ_ASSERT(!mInitSucceeded,do { static_assert( mozilla::detail::AssertionConditionType< decltype(!mInitSucceeded)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(!mInitSucceeded))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!mInitSucceeded" " (" "TextEditor::Init() called again without calling PreDestroy()?" ")", "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 154 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mInitSucceeded" ") (" "TextEditor::Init() called again without calling PreDestroy()?" ")"); do { MOZ_CrashSequence(__null, 154); __attribute__((nomerge )) ::abort(); } while (false); } } while (false) |
154 | "TextEditor::Init() called again without calling PreDestroy()?")do { static_assert( mozilla::detail::AssertionConditionType< decltype(!mInitSucceeded)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(!mInitSucceeded))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!mInitSucceeded" " (" "TextEditor::Init() called again without calling PreDestroy()?" ")", "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 154 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mInitSucceeded" ") (" "TextEditor::Init() called again without calling PreDestroy()?" ")"); do { MOZ_CrashSequence(__null, 154); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
155 | MOZ_ASSERT(!(aFlags & nsIEditor::eEditorPasswordMask) == !aPasswordMaskData)do { static_assert( mozilla::detail::AssertionConditionType< decltype(!(aFlags & nsIEditor::eEditorPasswordMask) == !aPasswordMaskData )>::isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(!(aFlags & nsIEditor::eEditorPasswordMask) == !aPasswordMaskData ))), 0))) { do { } while (false); MOZ_ReportAssertionFailure( "!(aFlags & nsIEditor::eEditorPasswordMask) == !aPasswordMaskData" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 155) ; AnnotateMozCrashReason("MOZ_ASSERT" "(" "!(aFlags & nsIEditor::eEditorPasswordMask) == !aPasswordMaskData" ")"); do { MOZ_CrashSequence(__null, 155); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
156 | mPasswordMaskData = std::move(aPasswordMaskData); |
157 | |
158 | // Init the base editor |
159 | nsresult rv = InitInternal(aDocument, &aAnonymousDivElement, |
160 | aSelectionController, aFlags); |
161 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
162 | NS_WARNING("EditorBase::InitInternal() failed")NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::InitInternal() failed" , nullptr, "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 162); |
163 | return rv; |
164 | } |
165 | |
166 | AutoEditActionDataSetter editActionData(*this, EditAction::eInitializing); |
167 | if (NS_WARN_IF(!editActionData.CanHandle())NS_warn_if_impl(!editActionData.CanHandle(), "!editActionData.CanHandle()" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 167)) { |
168 | return NS_ERROR_FAILURE; |
169 | } |
170 | |
171 | // We set mInitSucceeded here rather than at the end of the function, |
172 | // since InitEditorContentAndSelection() can perform some transactions |
173 | // and can warn if mInitSucceeded is still false. |
174 | MOZ_ASSERT(!mInitSucceeded, "TextEditor::Init() shouldn't be nested")do { static_assert( mozilla::detail::AssertionConditionType< decltype(!mInitSucceeded)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(!mInitSucceeded))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!mInitSucceeded" " (" "TextEditor::Init() shouldn't be nested" ")", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 174); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mInitSucceeded" ") (" "TextEditor::Init() shouldn't be nested" ")"); do { MOZ_CrashSequence (__null, 174); __attribute__((nomerge)) ::abort(); } while (false ); } } while (false); |
175 | mInitSucceeded = true; |
176 | |
177 | rv = InitEditorContentAndSelection(); |
178 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
179 | NS_WARNING("TextEditor::InitEditorContentAndSelection() failed")NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::InitEditorContentAndSelection() failed" , nullptr, "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 179); |
180 | // XXX Shouldn't we expose `NS_ERROR_EDITOR_DESTROYED` even though this |
181 | // is a public method? |
182 | mInitSucceeded = false; |
183 | return EditorBase::ToGenericNSResult(rv); |
184 | } |
185 | |
186 | // Throw away the old transaction manager if this is not the first time that |
187 | // we're initializing the editor. |
188 | ClearUndoRedo(); |
189 | EnableUndoRedo(); |
190 | return NS_OK; |
191 | } |
192 | |
193 | nsresult TextEditor::InitEditorContentAndSelection() { |
194 | MOZ_ASSERT(IsEditActionDataAvailable())do { static_assert( mozilla::detail::AssertionConditionType< decltype(IsEditActionDataAvailable())>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(IsEditActionDataAvailable()) )), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsEditActionDataAvailable()" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 194) ; AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()" ")"); do { MOZ_CrashSequence(__null, 194); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
195 | |
196 | MOZ_TRY(EnsureEmptyTextFirstChild())__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult (EnsureEmptyTextFirstChild()); if ((__builtin_expect(!!(mozTryVarTempResult .isErr()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult.unwrap(); }); |
197 | |
198 | // If the selection hasn't been set up yet, set it up collapsed to the end of |
199 | // our editable content. |
200 | if (!SelectionRef().RangeCount()) { |
201 | nsresult rv = CollapseSelectionToEndOfTextNode(); |
202 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
203 | NS_WARNING("EditorBase::CollapseSelectionToEndOfTextNode() failed")NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::CollapseSelectionToEndOfTextNode() failed" , nullptr, "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 203); |
204 | return rv; |
205 | } |
206 | } |
207 | |
208 | if (!IsSingleLineEditor()) { |
209 | nsresult rv = EnsurePaddingBRElementInMultilineEditor(); |
210 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
211 | NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::EnsurePaddingBRElementInMultilineEditor() failed" , nullptr, "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 212) |
212 | "EditorBase::EnsurePaddingBRElementInMultilineEditor() failed")NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::EnsurePaddingBRElementInMultilineEditor() failed" , nullptr, "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 212); |
213 | return rv; |
214 | } |
215 | } |
216 | |
217 | return NS_OK; |
218 | } |
219 | |
220 | nsresult TextEditor::PostCreate() { |
221 | AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing); |
222 | if (NS_WARN_IF(!editActionData.CanHandle())NS_warn_if_impl(!editActionData.CanHandle(), "!editActionData.CanHandle()" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 222)) { |
223 | return NS_ERROR_NOT_INITIALIZED; |
224 | } |
225 | |
226 | nsresult rv = PostCreateInternal(); |
227 | |
228 | // Restore unmasked range if there is. |
229 | if (IsPasswordEditor() && !IsAllMasked()) { |
230 | DebugOnly<nsresult> rvIgnored = |
231 | SetUnmaskRangeAndNotify(UnmaskedStart(), UnmaskedLength()); |
232 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed to " "restore unmasked range, but ignored", "NS_SUCCEEDED(rvIgnored)" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 234) ; } } while (false) |
233 | "TextEditor::SetUnmaskRangeAndNotify() failed to "do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed to " "restore unmasked range, but ignored", "NS_SUCCEEDED(rvIgnored)" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 234) ; } } while (false) |
234 | "restore unmasked range, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed to " "restore unmasked range, but ignored", "NS_SUCCEEDED(rvIgnored)" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 234) ; } } while (false); |
235 | } |
236 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::PostCreateInternal() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 237); } } while (false) |
237 | "EditorBase::PostCreateInternal() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::PostCreateInternal() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 237); } } while (false); |
238 | return rv; |
239 | } |
240 | |
241 | UniquePtr<PasswordMaskData> TextEditor::PreDestroy() { |
242 | if (mDidPreDestroy) { |
243 | return nullptr; |
244 | } |
245 | |
246 | UniquePtr<PasswordMaskData> passwordMaskData = std::move(mPasswordMaskData); |
247 | if (passwordMaskData) { |
248 | // Disable auto-masking timer since nobody can catch the notification |
249 | // from the timer and canceling the unmasking. |
250 | passwordMaskData->CancelTimer(PasswordMaskData::ReleaseTimer::Yes); |
251 | // Similary, keeping preventing echoing password temporarily across |
252 | // TextEditor instances is hard. So, we should forget it. |
253 | passwordMaskData->mEchoingPasswordPrevented = false; |
254 | } |
255 | |
256 | PreDestroyInternal(); |
257 | |
258 | return passwordMaskData; |
259 | } |
260 | |
261 | nsresult TextEditor::HandleKeyPressEvent(WidgetKeyboardEvent* aKeyboardEvent) { |
262 | // NOTE: When you change this method, you should also change: |
263 | // * editor/libeditor/tests/test_texteditor_keyevent_handling.html |
264 | // * editor/libeditor/tests/test_htmleditor_keyevent_handling.html |
265 | // |
266 | // And also when you add new key handling, you need to change the subclass's |
267 | // HandleKeyPressEvent()'s switch statement. |
268 | |
269 | if (NS_WARN_IF(!aKeyboardEvent)NS_warn_if_impl(!aKeyboardEvent, "!aKeyboardEvent", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 269)) { |
270 | return NS_ERROR_UNEXPECTED; |
271 | } |
272 | |
273 | if (IsReadonly()) { |
274 | HandleKeyPressEventInReadOnlyMode(*aKeyboardEvent); |
275 | return NS_OK; |
276 | } |
277 | |
278 | MOZ_ASSERT(aKeyboardEvent->mMessage == eKeyPress,do { static_assert( mozilla::detail::AssertionConditionType< decltype(aKeyboardEvent->mMessage == eKeyPress)>::isValid , "invalid assertion condition"); if ((__builtin_expect(!!(!( !!(aKeyboardEvent->mMessage == eKeyPress))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("aKeyboardEvent->mMessage == eKeyPress" " (" "HandleKeyPressEvent gets non-keypress event" ")", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 279); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aKeyboardEvent->mMessage == eKeyPress" ") (" "HandleKeyPressEvent gets non-keypress event" ")"); do { MOZ_CrashSequence(__null, 279); __attribute__((nomerge)) :: abort(); } while (false); } } while (false) |
279 | "HandleKeyPressEvent gets non-keypress event")do { static_assert( mozilla::detail::AssertionConditionType< decltype(aKeyboardEvent->mMessage == eKeyPress)>::isValid , "invalid assertion condition"); if ((__builtin_expect(!!(!( !!(aKeyboardEvent->mMessage == eKeyPress))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("aKeyboardEvent->mMessage == eKeyPress" " (" "HandleKeyPressEvent gets non-keypress event" ")", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 279); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aKeyboardEvent->mMessage == eKeyPress" ") (" "HandleKeyPressEvent gets non-keypress event" ")"); do { MOZ_CrashSequence(__null, 279); __attribute__((nomerge)) :: abort(); } while (false); } } while (false); |
280 | |
281 | switch (aKeyboardEvent->mKeyCode) { |
282 | case NS_VK_META: |
283 | case NS_VK_WIN: |
284 | case NS_VK_SHIFT: |
285 | case NS_VK_CONTROL: |
286 | case NS_VK_ALT: |
287 | // FYI: This shouldn't occur since modifier key shouldn't cause eKeyPress |
288 | // event. |
289 | aKeyboardEvent->PreventDefault(); |
290 | return NS_OK; |
291 | |
292 | case NS_VK_BACK: |
293 | case NS_VK_DELETE: |
294 | case NS_VK_TAB: { |
295 | nsresult rv = EditorBase::HandleKeyPressEvent(aKeyboardEvent); |
296 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::HandleKeyPressEvent() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 297); } } while (false) |
297 | "EditorBase::HandleKeyPressEvent() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::HandleKeyPressEvent() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 297); } } while (false); |
298 | return rv; |
299 | } |
300 | case NS_VK_RETURN: { |
301 | if (!aKeyboardEvent->IsInputtingLineBreak()) { |
302 | return NS_OK; |
303 | } |
304 | if (!IsSingleLineEditor()) { |
305 | aKeyboardEvent->PreventDefault(); |
306 | } |
307 | // We need to dispatch "beforeinput" event at least even if we're a |
308 | // single line text editor. |
309 | nsresult rv = InsertLineBreakAsAction(); |
310 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::InsertLineBreakAsAction() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 311); } } while (false) |
311 | "TextEditor::InsertLineBreakAsAction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::InsertLineBreakAsAction() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 311); } } while (false); |
312 | return rv; |
313 | } |
314 | } |
315 | |
316 | if (!aKeyboardEvent->IsInputtingText()) { |
317 | // we don't PreventDefault() here or keybindings like control-x won't work |
318 | return NS_OK; |
319 | } |
320 | aKeyboardEvent->PreventDefault(); |
321 | // If we dispatch 2 keypress events for a surrogate pair and we set only |
322 | // first `.key` value to the surrogate pair, the preceding one has it and the |
323 | // other has empty string. In this case, we should handle only the first one |
324 | // with the key value. |
325 | if (!StaticPrefs::dom_event_keypress_dispatch_once_per_surrogate_pair() && |
326 | !StaticPrefs::dom_event_keypress_key_allow_lone_surrogate() && |
327 | aKeyboardEvent->mKeyValue.IsEmpty() && |
328 | IS_SURROGATE(aKeyboardEvent->mCharCode)((uint32_t(aKeyboardEvent->mCharCode) & 0xFFFFF800) == 0xD800)) { |
329 | return NS_OK; |
330 | } |
331 | // Our widget shouldn't set `\r` to `mKeyValue`, but it may be synthesized |
332 | // keyboard event and its value may be `\r`. In such case, we should treat |
333 | // it as `\n` for the backward compatibility because we stopped converting |
334 | // `\r` and `\r\n` to `\n` at getting `HTMLInputElement.value` and |
335 | // `HTMLTextAreaElement.value` for the performance (i.e., we don't need to |
336 | // take care in `HTMLEditor`). |
337 | nsAutoString str(aKeyboardEvent->mKeyValue); |
338 | if (str.IsEmpty()) { |
339 | MOZ_ASSERT(aKeyboardEvent->mCharCode <= 0xFFFF,do { static_assert( mozilla::detail::AssertionConditionType< decltype(aKeyboardEvent->mCharCode <= 0xFFFF)>::isValid , "invalid assertion condition"); if ((__builtin_expect(!!(!( !!(aKeyboardEvent->mCharCode <= 0xFFFF))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("aKeyboardEvent->mCharCode <= 0xFFFF" " (" "Non-BMP character needs special handling" ")", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 340); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aKeyboardEvent->mCharCode <= 0xFFFF" ") (" "Non-BMP character needs special handling" ")"); do { MOZ_CrashSequence (__null, 340); __attribute__((nomerge)) ::abort(); } while (false ); } } while (false) |
340 | "Non-BMP character needs special handling")do { static_assert( mozilla::detail::AssertionConditionType< decltype(aKeyboardEvent->mCharCode <= 0xFFFF)>::isValid , "invalid assertion condition"); if ((__builtin_expect(!!(!( !!(aKeyboardEvent->mCharCode <= 0xFFFF))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("aKeyboardEvent->mCharCode <= 0xFFFF" " (" "Non-BMP character needs special handling" ")", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 340); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aKeyboardEvent->mCharCode <= 0xFFFF" ") (" "Non-BMP character needs special handling" ")"); do { MOZ_CrashSequence (__null, 340); __attribute__((nomerge)) ::abort(); } while (false ); } } while (false); |
341 | str.Assign(aKeyboardEvent->mCharCode == nsCRT::CR |
342 | ? static_cast<char16_t>(nsCRT::LF) |
343 | : static_cast<char16_t>(aKeyboardEvent->mCharCode)); |
344 | } else { |
345 | MOZ_ASSERT(str.Find(u"\r\n"_ns) == kNotFound,do { static_assert( mozilla::detail::AssertionConditionType< decltype(str.Find(u"\r\n"_ns) == kNotFound)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(str.Find(u"\r\n"_ns) == kNotFound ))), 0))) { do { } while (false); MOZ_ReportAssertionFailure( "str.Find(u\"\\r\\n\"_ns) == kNotFound" " (" "This assumes that typed text does not include CRLF" ")", "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 346 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "str.Find(u\"\\r\\n\"_ns) == kNotFound" ") (" "This assumes that typed text does not include CRLF" ")" ); do { MOZ_CrashSequence(__null, 346); __attribute__((nomerge )) ::abort(); } while (false); } } while (false) |
346 | "This assumes that typed text does not include CRLF")do { static_assert( mozilla::detail::AssertionConditionType< decltype(str.Find(u"\r\n"_ns) == kNotFound)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(str.Find(u"\r\n"_ns) == kNotFound ))), 0))) { do { } while (false); MOZ_ReportAssertionFailure( "str.Find(u\"\\r\\n\"_ns) == kNotFound" " (" "This assumes that typed text does not include CRLF" ")", "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 346 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "str.Find(u\"\\r\\n\"_ns) == kNotFound" ") (" "This assumes that typed text does not include CRLF" ")" ); do { MOZ_CrashSequence(__null, 346); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
347 | str.ReplaceChar('\r', '\n'); |
348 | } |
349 | nsresult rv = OnInputText(str); |
350 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "EditorBase::OnInputText() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::OnInputText() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 350); } } while (false); |
351 | return rv; |
352 | } |
353 | |
354 | NS_IMETHODIMPnsresult TextEditor::InsertLineBreak() { |
355 | AutoEditActionDataSetter editActionData(*this, EditAction::eInsertLineBreak); |
356 | nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent(); |
357 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
358 | NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak (NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed" , "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 359); } } while (false) |
359 | "CanHandleAndMaybeDispatchBeforeInputEvent() failed")do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak (NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed" , "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 359); } } while (false); |
360 | return EditorBase::ToGenericNSResult(rv); |
361 | } |
362 | |
363 | if (NS_WARN_IF(IsSingleLineEditor())NS_warn_if_impl(IsSingleLineEditor(), "IsSingleLineEditor()", "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 363)) { |
364 | return NS_ERROR_FAILURE; |
365 | } |
366 | |
367 | AutoPlaceholderBatch treatAsOneTransaction( |
368 | *this, ScrollSelectionIntoView::Yes, __FUNCTION__); |
369 | rv = InsertLineBreakAsSubAction(); |
370 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::InsertLineBreakAsSubAction() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 371); } } while (false) |
371 | "TextEditor::InsertLineBreakAsSubAction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::InsertLineBreakAsSubAction() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 371); } } while (false); |
372 | return EditorBase::ToGenericNSResult(rv); |
373 | } |
374 | |
375 | nsresult TextEditor::InsertLineBreakAsAction(nsIPrincipal* aPrincipal) { |
376 | AutoEditActionDataSetter editActionData(*this, EditAction::eInsertLineBreak, |
377 | aPrincipal); |
378 | nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent(); |
379 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
380 | NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak (NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed" , "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 381); } } while (false) |
381 | "CanHandleAndMaybeDispatchBeforeInputEvent() failed")do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak (NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed" , "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 381); } } while (false); |
382 | return EditorBase::ToGenericNSResult(rv); |
383 | } |
384 | |
385 | if (IsSingleLineEditor()) { |
386 | return NS_OK; |
387 | } |
388 | |
389 | // XXX This may be called by execCommand() with "insertParagraph". |
390 | // In such case, naming the transaction "TypingTxnName" is odd. |
391 | AutoPlaceholderBatch treatAsOneTransaction(*this, *nsGkAtoms::TypingTxnName, |
392 | ScrollSelectionIntoView::Yes, |
393 | __FUNCTION__); |
394 | rv = InsertLineBreakAsSubAction(); |
395 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::InsertLineBreakAsSubAction() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 396); } } while (false) |
396 | "EditorBase::InsertLineBreakAsSubAction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::InsertLineBreakAsSubAction() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 396); } } while (false); |
397 | return EditorBase::ToGenericNSResult(rv); |
398 | } |
399 | |
400 | nsresult TextEditor::SetTextAsAction( |
401 | const nsAString& aString, |
402 | AllowBeforeInputEventCancelable aAllowBeforeInputEventCancelable, |
403 | nsIPrincipal* aPrincipal) { |
404 | MOZ_ASSERT(aString.FindChar(nsCRT::CR) == kNotFound)do { static_assert( mozilla::detail::AssertionConditionType< decltype(aString.FindChar(nsCRT::CR) == kNotFound)>::isValid , "invalid assertion condition"); if ((__builtin_expect(!!(!( !!(aString.FindChar(nsCRT::CR) == kNotFound))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("aString.FindChar(nsCRT::CR) == kNotFound" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 404) ; AnnotateMozCrashReason("MOZ_ASSERT" "(" "aString.FindChar(nsCRT::CR) == kNotFound" ")"); do { MOZ_CrashSequence(__null, 404); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
405 | |
406 | AutoEditActionDataSetter editActionData(*this, EditAction::eSetText, |
407 | aPrincipal); |
408 | if (aAllowBeforeInputEventCancelable == AllowBeforeInputEventCancelable::No) { |
409 | editActionData.MakeBeforeInputEventNonCancelable(); |
410 | } |
411 | nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent(); |
412 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
413 | NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak (NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed" , "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 414); } } while (false) |
414 | "CanHandleAndMaybeDispatchBeforeInputEvent() failed")do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak (NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed" , "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 414); } } while (false); |
415 | return EditorBase::ToGenericNSResult(rv); |
416 | } |
417 | |
418 | AutoPlaceholderBatch treatAsOneTransaction( |
419 | *this, ScrollSelectionIntoView::Yes, __FUNCTION__); |
420 | rv = SetTextAsSubAction(aString); |
421 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetTextAsSubAction() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 422); } } while (false) |
422 | "TextEditor::SetTextAsSubAction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetTextAsSubAction() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 422); } } while (false); |
423 | return EditorBase::ToGenericNSResult(rv); |
424 | } |
425 | |
426 | nsresult TextEditor::SetTextAsSubAction(const nsAString& aString) { |
427 | MOZ_ASSERT(IsEditActionDataAvailable())do { static_assert( mozilla::detail::AssertionConditionType< decltype(IsEditActionDataAvailable())>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(IsEditActionDataAvailable()) )), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsEditActionDataAvailable()" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 427) ; AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()" ")"); do { MOZ_CrashSequence(__null, 427); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
428 | MOZ_ASSERT(mPlaceholderBatch)do { static_assert( mozilla::detail::AssertionConditionType< decltype(mPlaceholderBatch)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(mPlaceholderBatch))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("mPlaceholderBatch" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 428) ; AnnotateMozCrashReason("MOZ_ASSERT" "(" "mPlaceholderBatch" ")"); do { MOZ_CrashSequence(__null, 428); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
429 | |
430 | if (NS_WARN_IF(!mInitSucceeded)NS_warn_if_impl(!mInitSucceeded, "!mInitSucceeded", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 430)) { |
431 | return NS_ERROR_NOT_INITIALIZED; |
432 | } |
433 | |
434 | IgnoredErrorResult ignoredError; |
435 | AutoEditSubActionNotifier startToHandleEditSubAction( |
436 | *this, EditSubAction::eSetText, nsIEditor::eNext, ignoredError); |
437 | if (NS_WARN_IF(ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED))NS_warn_if_impl(ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED ), "ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 437)) { |
438 | return ignoredError.StealNSResult(); |
439 | } |
440 | NS_WARNING_ASSERTION(do { if (!(!ignoredError.Failed())) { NS_DebugBreak(NS_DEBUG_WARNING , "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored" , "!ignoredError.Failed()", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 442); } } while (false) |
441 | !ignoredError.Failed(),do { if (!(!ignoredError.Failed())) { NS_DebugBreak(NS_DEBUG_WARNING , "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored" , "!ignoredError.Failed()", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 442); } } while (false) |
442 | "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored")do { if (!(!ignoredError.Failed())) { NS_DebugBreak(NS_DEBUG_WARNING , "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored" , "!ignoredError.Failed()", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 442); } } while (false); |
443 | |
444 | if (!IsIMEComposing() && !IsUndoRedoEnabled() && |
445 | GetEditAction() != EditAction::eReplaceText && mMaxTextLength < 0) { |
446 | Result<EditActionResult, nsresult> result = |
447 | SetTextWithoutTransaction(aString); |
448 | if (MOZ_UNLIKELY(result.isErr())(__builtin_expect(!!(result.isErr()), 0))) { |
449 | NS_WARNING("TextEditor::SetTextWithoutTransaction() failed")NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetTextWithoutTransaction() failed" , nullptr, "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 449); |
450 | return result.unwrapErr(); |
451 | } |
452 | if (!result.inspect().Ignored()) { |
453 | return NS_OK; |
454 | } |
455 | } |
456 | |
457 | { |
458 | // Note that do not notify selectionchange caused by selecting all text |
459 | // because it's preparation of our delete implementation so web apps |
460 | // shouldn't receive such selectionchange before the first mutation. |
461 | AutoUpdateViewBatch preventSelectionChangeEvent(*this, __FUNCTION__); |
462 | |
463 | // XXX We should make ReplaceSelectionAsSubAction() take range. Then, |
464 | // we can saving the expensive cost of modifying `Selection` here. |
465 | if (NS_SUCCEEDED(SelectEntireDocument())((bool)(__builtin_expect(!!(!NS_FAILED_impl(SelectEntireDocument ())), 1)))) { |
466 | DebugOnly<nsresult> rvIgnored = ReplaceSelectionAsSubAction(aString); |
467 | NS_WARNING_ASSERTION(do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::ReplaceSelectionAsSubAction() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 469); } } while (false) |
468 | NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::ReplaceSelectionAsSubAction() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 469); } } while (false) |
469 | "EditorBase::ReplaceSelectionAsSubAction() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::ReplaceSelectionAsSubAction() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 469); } } while (false); |
470 | } |
471 | } |
472 | |
473 | // Destroying AutoUpdateViewBatch may cause destroying us. |
474 | return NS_WARN_IF(Destroyed())NS_warn_if_impl(Destroyed(), "Destroyed()", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 474) ? NS_ERROR_EDITOR_DESTROYED : NS_OK; |
475 | } |
476 | |
477 | already_AddRefed<Element> TextEditor::GetInputEventTargetElement() const { |
478 | RefPtr<Element> target = Element::FromEventTargetOrNull(mEventTarget); |
479 | return target.forget(); |
480 | } |
481 | |
482 | bool TextEditor::IsEmpty() const { |
483 | // This is a public method. Therefore, it might have not been initialized yet |
484 | // when this is called. Let's return true in such case, but warn it because |
485 | // it may return different value than actual value which is stored by the |
486 | // text control element. |
487 | MOZ_ASSERT_IF(mInitSucceeded, GetRoot())do { if (mInitSucceeded) { do { static_assert( mozilla::detail ::AssertionConditionType<decltype(GetRoot())>::isValid, "invalid assertion condition"); if ((__builtin_expect(!!(!(! !(GetRoot()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure ("GetRoot()", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 487); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetRoot()" ")" ); do { MOZ_CrashSequence(__null, 487); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); } } while ( false); |
488 | if (NS_WARN_IF(!GetRoot())NS_warn_if_impl(!GetRoot(), "!GetRoot()", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 488)) { |
489 | NS_ASSERTION(false,do { if (!(false)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Make the root caller stop doing that before initializing or " "after destroying the TextEditor", "false", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 491); MOZ_PretendNoReturn(); } } while (0) |
490 | "Make the root caller stop doing that before initializing or "do { if (!(false)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Make the root caller stop doing that before initializing or " "after destroying the TextEditor", "false", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 491); MOZ_PretendNoReturn(); } } while (0) |
491 | "after destroying the TextEditor")do { if (!(false)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Make the root caller stop doing that before initializing or " "after destroying the TextEditor", "false", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 491); MOZ_PretendNoReturn(); } } while (0); |
492 | return true; |
493 | } |
494 | const Text* const textNode = GetTextNode(); |
495 | MOZ_DIAGNOSTIC_ASSERT_IF(textNode,do { if (textNode) { do { static_assert( mozilla::detail::AssertionConditionType <decltype(!Text::FromNodeOrNull(textNode->GetNextSibling ()))>::isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(!Text::FromNodeOrNull(textNode->GetNextSibling()) ))), 0))) { do { } while (false); MOZ_ReportAssertionFailure( "!Text::FromNodeOrNull(textNode->GetNextSibling())", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 496); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!Text::FromNodeOrNull(textNode->GetNextSibling())" ")"); do { MOZ_CrashSequence(__null, 496); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); } } while ( false) |
496 | !Text::FromNodeOrNull(textNode->GetNextSibling()))do { if (textNode) { do { static_assert( mozilla::detail::AssertionConditionType <decltype(!Text::FromNodeOrNull(textNode->GetNextSibling ()))>::isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(!Text::FromNodeOrNull(textNode->GetNextSibling()) ))), 0))) { do { } while (false); MOZ_ReportAssertionFailure( "!Text::FromNodeOrNull(textNode->GetNextSibling())", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 496); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!Text::FromNodeOrNull(textNode->GetNextSibling())" ")"); do { MOZ_CrashSequence(__null, 496); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); } } while ( false); |
497 | return !textNode || !textNode->TextDataLength(); |
498 | } |
499 | |
500 | NS_IMETHODIMPnsresult TextEditor::GetTextLength(uint32_t* aCount) { |
501 | MOZ_ASSERT(aCount)do { static_assert( mozilla::detail::AssertionConditionType< decltype(aCount)>::isValid, "invalid assertion condition") ; if ((__builtin_expect(!!(!(!!(aCount))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("aCount", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 501); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aCount" ")") ; do { MOZ_CrashSequence(__null, 501); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
502 | |
503 | if (NS_WARN_IF(!GetRoot())NS_warn_if_impl(!GetRoot(), "!GetRoot()", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 503)) { |
504 | return NS_ERROR_FAILURE; |
505 | } |
506 | |
507 | const Text* const textNode = GetTextNode(); |
508 | MOZ_DIAGNOSTIC_ASSERT_IF(textNode,do { if (textNode) { do { static_assert( mozilla::detail::AssertionConditionType <decltype(!Text::FromNodeOrNull(textNode->GetNextSibling ()))>::isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(!Text::FromNodeOrNull(textNode->GetNextSibling()) ))), 0))) { do { } while (false); MOZ_ReportAssertionFailure( "!Text::FromNodeOrNull(textNode->GetNextSibling())", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 509); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!Text::FromNodeOrNull(textNode->GetNextSibling())" ")"); do { MOZ_CrashSequence(__null, 509); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); } } while ( false) |
509 | !Text::FromNodeOrNull(textNode->GetNextSibling()))do { if (textNode) { do { static_assert( mozilla::detail::AssertionConditionType <decltype(!Text::FromNodeOrNull(textNode->GetNextSibling ()))>::isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(!Text::FromNodeOrNull(textNode->GetNextSibling()) ))), 0))) { do { } while (false); MOZ_ReportAssertionFailure( "!Text::FromNodeOrNull(textNode->GetNextSibling())", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 509); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!Text::FromNodeOrNull(textNode->GetNextSibling())" ")"); do { MOZ_CrashSequence(__null, 509); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); } } while ( false); |
510 | *aCount = textNode ? textNode->TextDataLength() : 0u; |
511 | return NS_OK; |
512 | } |
513 | |
514 | bool TextEditor::IsCopyToClipboardAllowedInternal() const { |
515 | MOZ_ASSERT(IsEditActionDataAvailable())do { static_assert( mozilla::detail::AssertionConditionType< decltype(IsEditActionDataAvailable())>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(IsEditActionDataAvailable()) )), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsEditActionDataAvailable()" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 515) ; AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()" ")"); do { MOZ_CrashSequence(__null, 515); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
516 | if (!EditorBase::IsCopyToClipboardAllowedInternal()) { |
517 | return false; |
518 | } |
519 | |
520 | if (!IsSingleLineEditor() || !IsPasswordEditor() || |
521 | NS_WARN_IF(!mPasswordMaskData)NS_warn_if_impl(!mPasswordMaskData, "!mPasswordMaskData", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 521)) { |
522 | return true; |
523 | } |
524 | |
525 | // If we're a password editor, we should allow selected text to be copied |
526 | // to the clipboard only when selection range is in unmasked range. |
527 | if (IsAllMasked() || IsMaskingPassword() || !UnmaskedLength()) { |
528 | return false; |
529 | } |
530 | |
531 | // If there are 2 or more ranges, we don't allow to copy/cut for now since |
532 | // we need to check whether all ranges are in unmasked range or not. |
533 | // Anyway, such operation in password field does not make sense. |
534 | if (SelectionRef().RangeCount() > 1) { |
535 | return false; |
536 | } |
537 | |
538 | uint32_t selectionStart = 0, selectionEnd = 0; |
539 | nsContentUtils::GetSelectionInTextControl(&SelectionRef(), mRootElement, |
540 | selectionStart, selectionEnd); |
541 | return UnmaskedStart() <= selectionStart && UnmaskedEnd() >= selectionEnd; |
542 | } |
543 | |
544 | nsresult TextEditor::HandlePasteAsQuotation( |
545 | AutoEditActionDataSetter& aEditActionData, |
546 | nsIClipboard::ClipboardType aClipboardType, DataTransfer* aDataTransfer) { |
547 | MOZ_ASSERT(aClipboardType == nsIClipboard::kGlobalClipboard ||do { static_assert( mozilla::detail::AssertionConditionType< decltype(aClipboardType == nsIClipboard::kGlobalClipboard || aClipboardType == nsIClipboard::kSelectionClipboard)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(aClipboardType == nsIClipboard ::kGlobalClipboard || aClipboardType == nsIClipboard::kSelectionClipboard ))), 0))) { do { } while (false); MOZ_ReportAssertionFailure( "aClipboardType == nsIClipboard::kGlobalClipboard || aClipboardType == nsIClipboard::kSelectionClipboard" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 548) ; AnnotateMozCrashReason("MOZ_ASSERT" "(" "aClipboardType == nsIClipboard::kGlobalClipboard || aClipboardType == nsIClipboard::kSelectionClipboard" ")"); do { MOZ_CrashSequence(__null, 548); __attribute__((nomerge )) ::abort(); } while (false); } } while (false) |
548 | aClipboardType == nsIClipboard::kSelectionClipboard)do { static_assert( mozilla::detail::AssertionConditionType< decltype(aClipboardType == nsIClipboard::kGlobalClipboard || aClipboardType == nsIClipboard::kSelectionClipboard)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(aClipboardType == nsIClipboard ::kGlobalClipboard || aClipboardType == nsIClipboard::kSelectionClipboard ))), 0))) { do { } while (false); MOZ_ReportAssertionFailure( "aClipboardType == nsIClipboard::kGlobalClipboard || aClipboardType == nsIClipboard::kSelectionClipboard" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 548) ; AnnotateMozCrashReason("MOZ_ASSERT" "(" "aClipboardType == nsIClipboard::kGlobalClipboard || aClipboardType == nsIClipboard::kSelectionClipboard" ")"); do { MOZ_CrashSequence(__null, 548); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
549 | if (NS_WARN_IF(!GetDocument())NS_warn_if_impl(!GetDocument(), "!GetDocument()", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 549)) { |
550 | return NS_OK; |
551 | } |
552 | |
553 | // XXX Why don't we dispatch ePaste event here? |
554 | |
555 | // Get the nsITransferable interface for getting the data from the clipboard |
556 | Result<nsCOMPtr<nsITransferable>, nsresult> maybeTransferable = |
557 | EditorUtils::CreateTransferableForPlainText(*GetDocument()); |
558 | if (maybeTransferable.isErr()) { |
559 | NS_WARNING("EditorUtils::CreateTransferableForPlainText() failed")NS_DebugBreak(NS_DEBUG_WARNING, "EditorUtils::CreateTransferableForPlainText() failed" , nullptr, "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 559); |
560 | return maybeTransferable.unwrapErr(); |
561 | } |
562 | nsCOMPtr<nsITransferable> trans(maybeTransferable.unwrap()); |
563 | if (!trans) { |
564 | NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "EditorUtils::CreateTransferableForPlainText() returned nullptr, but " "ignored", nullptr, "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 566) |
565 | "EditorUtils::CreateTransferableForPlainText() returned nullptr, but "NS_DebugBreak(NS_DEBUG_WARNING, "EditorUtils::CreateTransferableForPlainText() returned nullptr, but " "ignored", nullptr, "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 566) |
566 | "ignored")NS_DebugBreak(NS_DEBUG_WARNING, "EditorUtils::CreateTransferableForPlainText() returned nullptr, but " "ignored", nullptr, "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 566); |
567 | return NS_OK; |
568 | } |
569 | |
570 | // Get the Data from the clipboard |
571 | nsresult rv = |
Value stored to 'rv' during its initialization is never read | |
572 | GetDataFromDataTransferOrClipboard(aDataTransfer, trans, aClipboardType); |
573 | |
574 | // Now we ask the transferable for the data |
575 | // it still owns the data, we just have a pointer to it. |
576 | // If it can't support a "text" output of the data the call will fail |
577 | nsCOMPtr<nsISupports> genericDataObj; |
578 | nsAutoCString flavor; |
579 | rv = trans->GetAnyTransferData(flavor, getter_AddRefs(genericDataObj)); |
580 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
581 | NS_WARNING("nsITransferable::GetAnyTransferData() failed")NS_DebugBreak(NS_DEBUG_WARNING, "nsITransferable::GetAnyTransferData() failed" , nullptr, "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 581); |
582 | return rv; |
583 | } |
584 | |
585 | if (!flavor.EqualsLiteral(kTextMime"text/plain") && |
586 | !flavor.EqualsLiteral(kMozTextInternal"text/x-moz-text-internal")) { |
587 | return NS_OK; |
588 | } |
589 | |
590 | nsCOMPtr<nsISupportsString> text = do_QueryInterface(genericDataObj); |
591 | if (!text) { |
592 | return NS_OK; |
593 | } |
594 | |
595 | nsString stuffToPaste; |
596 | DebugOnly<nsresult> rvIgnored = text->GetData(stuffToPaste); |
597 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "nsISupportsString::GetData() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 598); } } while (false) |
598 | "nsISupportsString::GetData() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "nsISupportsString::GetData() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 598); } } while (false); |
599 | if (stuffToPaste.IsEmpty()) { |
600 | return NS_OK; |
601 | } |
602 | |
603 | aEditActionData.SetData(stuffToPaste); |
604 | if (!stuffToPaste.IsEmpty()) { |
605 | nsContentUtils::PlatformToDOMLineBreaks(stuffToPaste); |
606 | } |
607 | rv = aEditActionData.MaybeDispatchBeforeInputEvent(); |
608 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
609 | NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak (NS_DEBUG_WARNING, "MaybeDispatchBeforeInputEvent() failed", "rv == NS_ERROR_EDITOR_ACTION_CANCELED" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 610) ; } } while (false) |
610 | "MaybeDispatchBeforeInputEvent() failed")do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak (NS_DEBUG_WARNING, "MaybeDispatchBeforeInputEvent() failed", "rv == NS_ERROR_EDITOR_ACTION_CANCELED" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 610) ; } } while (false); |
611 | return rv; |
612 | } |
613 | |
614 | AutoPlaceholderBatch treatAsOneTransaction( |
615 | *this, ScrollSelectionIntoView::Yes, __FUNCTION__); |
616 | rv = InsertWithQuotationsAsSubAction(stuffToPaste); |
617 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::InsertWithQuotationsAsSubAction() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 618); } } while (false) |
618 | "TextEditor::InsertWithQuotationsAsSubAction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::InsertWithQuotationsAsSubAction() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 618); } } while (false); |
619 | return rv; |
620 | } |
621 | |
622 | nsresult TextEditor::InsertWithQuotationsAsSubAction( |
623 | const nsAString& aQuotedText) { |
624 | MOZ_ASSERT(IsEditActionDataAvailable())do { static_assert( mozilla::detail::AssertionConditionType< decltype(IsEditActionDataAvailable())>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(IsEditActionDataAvailable()) )), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsEditActionDataAvailable()" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 624) ; AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()" ")"); do { MOZ_CrashSequence(__null, 624); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
625 | |
626 | if (IsReadonly()) { |
627 | return NS_OK; |
628 | } |
629 | |
630 | // Let the citer quote it for us: |
631 | nsString quotedStuff; |
632 | InternetCiter::GetCiteString(aQuotedText, quotedStuff); |
633 | |
634 | // It's best to put a blank line after the quoted text so that mails |
635 | // written without thinking won't be so ugly. |
636 | if (!aQuotedText.IsEmpty() && (aQuotedText.Last() != char16_t('\n'))) { |
637 | quotedStuff.Append(char16_t('\n')); |
638 | } |
639 | |
640 | IgnoredErrorResult ignoredError; |
641 | AutoEditSubActionNotifier startToHandleEditSubAction( |
642 | *this, EditSubAction::eInsertText, nsIEditor::eNext, ignoredError); |
643 | if (NS_WARN_IF(ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED))NS_warn_if_impl(ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED ), "ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 643)) { |
644 | return ignoredError.StealNSResult(); |
645 | } |
646 | NS_WARNING_ASSERTION(do { if (!(!ignoredError.Failed())) { NS_DebugBreak(NS_DEBUG_WARNING , "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored" , "!ignoredError.Failed()", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 648); } } while (false) |
647 | !ignoredError.Failed(),do { if (!(!ignoredError.Failed())) { NS_DebugBreak(NS_DEBUG_WARNING , "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored" , "!ignoredError.Failed()", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 648); } } while (false) |
648 | "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored")do { if (!(!ignoredError.Failed())) { NS_DebugBreak(NS_DEBUG_WARNING , "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored" , "!ignoredError.Failed()", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 648); } } while (false); |
649 | |
650 | // XXX Do we need to support paste-as-quotation in password editor (and |
651 | // also in single line editor)? |
652 | MaybeDoAutoPasswordMasking(); |
653 | |
654 | nsresult rv = InsertTextAsSubAction(quotedStuff, InsertTextFor::NormalText); |
655 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::InsertTextAsSubAction() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 656); } } while (false) |
656 | "EditorBase::InsertTextAsSubAction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::InsertTextAsSubAction() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 656); } } while (false); |
657 | return rv; |
658 | } |
659 | |
660 | nsresult TextEditor::SelectEntireDocument() { |
661 | MOZ_ASSERT(IsEditActionDataAvailable())do { static_assert( mozilla::detail::AssertionConditionType< decltype(IsEditActionDataAvailable())>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(IsEditActionDataAvailable()) )), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsEditActionDataAvailable()" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 661) ; AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()" ")"); do { MOZ_CrashSequence(__null, 661); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
662 | |
663 | if (NS_WARN_IF(!mInitSucceeded)NS_warn_if_impl(!mInitSucceeded, "!mInitSucceeded", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 663)) { |
664 | return NS_ERROR_NOT_INITIALIZED; |
665 | } |
666 | |
667 | RefPtr<Element> anonymousDivElement = GetRoot(); |
668 | if (NS_WARN_IF(!anonymousDivElement)NS_warn_if_impl(!anonymousDivElement, "!anonymousDivElement", "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 668)) { |
669 | return NS_ERROR_NOT_INITIALIZED; |
670 | } |
671 | |
672 | RefPtr<Text> text = |
673 | Text::FromNodeOrNull(anonymousDivElement->GetFirstChild()); |
674 | MOZ_ASSERT(text)do { static_assert( mozilla::detail::AssertionConditionType< decltype(text)>::isValid, "invalid assertion condition"); if ((__builtin_expect(!!(!(!!(text))), 0))) { do { } while (false ); MOZ_ReportAssertionFailure("text", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 674); AnnotateMozCrashReason("MOZ_ASSERT" "(" "text" ")"); do { MOZ_CrashSequence(__null, 674); __attribute__((nomerge)) :: abort(); } while (false); } } while (false); |
675 | |
676 | MOZ_TRY(SelectionRef().SetStartAndEndInLimiter(__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult (SelectionRef().SetStartAndEndInLimiter( *text, 0, *text, text ->TextDataLength(), eDirNext, nsISelectionListener::SELECTALL_REASON )); if ((__builtin_expect(!!(mozTryVarTempResult.isErr()), 0) )) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult .unwrap(); }) |
677 | *text, 0, *text, text->TextDataLength(), eDirNext,__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult (SelectionRef().SetStartAndEndInLimiter( *text, 0, *text, text ->TextDataLength(), eDirNext, nsISelectionListener::SELECTALL_REASON )); if ((__builtin_expect(!!(mozTryVarTempResult.isErr()), 0) )) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult .unwrap(); }) |
678 | nsISelectionListener::SELECTALL_REASON))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult (SelectionRef().SetStartAndEndInLimiter( *text, 0, *text, text ->TextDataLength(), eDirNext, nsISelectionListener::SELECTALL_REASON )); if ((__builtin_expect(!!(mozTryVarTempResult.isErr()), 0) )) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult .unwrap(); }); |
679 | |
680 | return NS_OK; |
681 | } |
682 | |
683 | EventTarget* TextEditor::GetDOMEventTarget() const { return mEventTarget; } |
684 | |
685 | void TextEditor::ReinitializeSelection(Element& aElement) { |
686 | if (NS_WARN_IF(Destroyed())NS_warn_if_impl(Destroyed(), "Destroyed()", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 686)) { |
687 | return; |
688 | } |
689 | |
690 | AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing); |
691 | if (NS_WARN_IF(!editActionData.CanHandle())NS_warn_if_impl(!editActionData.CanHandle(), "!editActionData.CanHandle()" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 691)) { |
692 | return; |
693 | } |
694 | |
695 | // We don't need to flush pending notifications here and we don't need to |
696 | // handle spellcheck at first focus. Therefore, we don't need to call |
697 | // `TextEditor::OnFocus` here. |
698 | EditorBase::OnFocus(aElement); |
699 | |
700 | // If previous focused editor turn on spellcheck and this editor doesn't |
701 | // turn on it, spellcheck state is mismatched. So we need to re-sync it. |
702 | SyncRealTimeSpell(); |
703 | } |
704 | |
705 | nsresult TextEditor::OnFocus(const nsINode& aOriginalEventTargetNode) { |
706 | RefPtr<PresShell> presShell = GetPresShell(); |
707 | if (NS_WARN_IF(!presShell)NS_warn_if_impl(!presShell, "!presShell", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 707)) { |
708 | return NS_ERROR_FAILURE; |
709 | } |
710 | // Let's update the layout information right now because there are some |
711 | // pending notifications and flushing them may cause destroying the editor. |
712 | presShell->FlushPendingNotifications(FlushType::Layout); |
713 | if (MOZ_UNLIKELY(!CanKeepHandlingFocusEvent(aOriginalEventTargetNode))(__builtin_expect(!!(!CanKeepHandlingFocusEvent(aOriginalEventTargetNode )), 0))) { |
714 | return NS_OK; |
715 | } |
716 | |
717 | AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing); |
718 | if (NS_WARN_IF(!editActionData.CanHandle())NS_warn_if_impl(!editActionData.CanHandle(), "!editActionData.CanHandle()" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 718)) { |
719 | return NS_ERROR_FAILURE; |
720 | } |
721 | |
722 | // Spell check a textarea the first time that it is focused. |
723 | nsresult rv = FlushPendingSpellCheck(); |
724 | if (MOZ_UNLIKELY(rv == NS_ERROR_EDITOR_DESTROYED)(__builtin_expect(!!(rv == NS_ERROR_EDITOR_DESTROYED), 0))) { |
725 | NS_WARNING("EditorBase::FlushPendingSpellCheck() failed")NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::FlushPendingSpellCheck() failed" , nullptr, "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 725); |
726 | return NS_ERROR_EDITOR_DESTROYED; |
727 | } |
728 | NS_WARNING_ASSERTION(do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::FlushPendingSpellCheck() failed, but ignored" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 730); } } while (false) |
729 | NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::FlushPendingSpellCheck() failed, but ignored" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 730); } } while (false) |
730 | "EditorBase::FlushPendingSpellCheck() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::FlushPendingSpellCheck() failed, but ignored" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 730); } } while (false); |
731 | if (MOZ_UNLIKELY(!CanKeepHandlingFocusEvent(aOriginalEventTargetNode))(__builtin_expect(!!(!CanKeepHandlingFocusEvent(aOriginalEventTargetNode )), 0))) { |
732 | return NS_OK; |
733 | } |
734 | |
735 | return EditorBase::OnFocus(aOriginalEventTargetNode); |
736 | } |
737 | |
738 | nsresult TextEditor::OnBlur(const EventTarget* aEventTarget) { |
739 | // check if something else is focused. If another element is focused, then |
740 | // we should not change the selection. If another element already has focus, |
741 | // we should not maintain the selection because we may not have the rights |
742 | // doing it. |
743 | if (nsFocusManager::GetFocusedElementStatic()) { |
744 | return NS_OK; |
745 | } |
746 | |
747 | nsresult rv = FinalizeSelection(); |
748 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::FinalizeSelection() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 749); } } while (false) |
749 | "EditorBase::FinalizeSelection() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::FinalizeSelection() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 749); } } while (false); |
750 | return rv; |
751 | } |
752 | |
753 | nsresult TextEditor::SetAttributeOrEquivalent(Element* aElement, |
754 | nsAtom* aAttribute, |
755 | const nsAString& aValue, |
756 | bool aSuppressTransaction) { |
757 | if (NS_WARN_IF(!aElement)NS_warn_if_impl(!aElement, "!aElement", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 757) || NS_WARN_IF(!aAttribute)NS_warn_if_impl(!aAttribute, "!aAttribute", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 757)) { |
758 | return NS_ERROR_INVALID_ARG; |
759 | } |
760 | |
761 | AutoEditActionDataSetter editActionData(*this, EditAction::eSetAttribute); |
762 | nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent(); |
763 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
764 | NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak (NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed" , "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 765); } } while (false) |
765 | "CanHandleAndMaybeDispatchBeforeInputEvent() failed")do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak (NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed" , "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 765); } } while (false); |
766 | return EditorBase::ToGenericNSResult(rv); |
767 | } |
768 | |
769 | rv = SetAttributeWithTransaction(*aElement, *aAttribute, aValue); |
770 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::SetAttributeWithTransaction() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 771); } } while (false) |
771 | "EditorBase::SetAttributeWithTransaction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::SetAttributeWithTransaction() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 771); } } while (false); |
772 | return EditorBase::ToGenericNSResult(rv); |
773 | } |
774 | |
775 | nsresult TextEditor::RemoveAttributeOrEquivalent(Element* aElement, |
776 | nsAtom* aAttribute, |
777 | bool aSuppressTransaction) { |
778 | if (NS_WARN_IF(!aElement)NS_warn_if_impl(!aElement, "!aElement", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 778) || NS_WARN_IF(!aAttribute)NS_warn_if_impl(!aAttribute, "!aAttribute", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 778)) { |
779 | return NS_ERROR_INVALID_ARG; |
780 | } |
781 | |
782 | AutoEditActionDataSetter editActionData(*this, EditAction::eRemoveAttribute); |
783 | nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent(); |
784 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
785 | NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak (NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed" , "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 786); } } while (false) |
786 | "CanHandleAndMaybeDispatchBeforeInputEvent() failed")do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak (NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed" , "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 786); } } while (false); |
787 | return EditorBase::ToGenericNSResult(rv); |
788 | } |
789 | |
790 | rv = RemoveAttributeWithTransaction(*aElement, *aAttribute); |
791 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::RemoveAttributeWithTransaction() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 792); } } while (false) |
792 | "EditorBase::RemoveAttributeWithTransaction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::RemoveAttributeWithTransaction() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 792); } } while (false); |
793 | return EditorBase::ToGenericNSResult(rv); |
794 | } |
795 | |
796 | template <typename EditorDOMPointType> |
797 | EditorDOMPointType TextEditor::FindBetterInsertionPoint( |
798 | const EditorDOMPointType& aPoint) const { |
799 | if (MOZ_UNLIKELY(NS_WARN_IF(!aPoint.IsInContentNode()))(__builtin_expect(!!(NS_warn_if_impl(!aPoint.IsInContentNode( ), "!aPoint.IsInContentNode()", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 799)), 0))) { |
800 | return aPoint; |
801 | } |
802 | |
803 | MOZ_ASSERT(aPoint.IsSetAndValid())do { static_assert( mozilla::detail::AssertionConditionType< decltype(aPoint.IsSetAndValid())>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(aPoint.IsSetAndValid()))), 0 ))) { do { } while (false); MOZ_ReportAssertionFailure("aPoint.IsSetAndValid()" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 803) ; AnnotateMozCrashReason("MOZ_ASSERT" "(" "aPoint.IsSetAndValid()" ")"); do { MOZ_CrashSequence(__null, 803); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
804 | |
805 | Element* const anonymousDivElement = GetRoot(); |
806 | if (aPoint.GetContainer() == anonymousDivElement) { |
807 | // In some cases, aPoint points start of the anonymous <div>. To avoid |
808 | // injecting unneeded text nodes, we first look to see if we have one |
809 | // available. In that case, we'll just adjust node and offset accordingly. |
810 | if (aPoint.IsStartOfContainer()) { |
811 | if (aPoint.GetContainer()->HasChildren() && |
812 | aPoint.GetContainer()->GetFirstChild()->IsText()) { |
813 | return EditorDOMPointType(aPoint.GetContainer()->GetFirstChild(), 0u); |
814 | } |
815 | } |
816 | // In some other cases, aPoint points the terminating padding <br> element |
817 | // for empty last line in the anonymous <div>. In that case, we'll adjust |
818 | // aInOutNode and aInOutOffset to the preceding text node, if any. |
819 | else { |
820 | nsIContent* child = aPoint.GetContainer()->GetLastChild(); |
821 | while (child) { |
822 | if (child->IsText()) { |
823 | return EditorDOMPointType::AtEndOf(*child); |
824 | } |
825 | child = child->GetPreviousSibling(); |
826 | } |
827 | } |
828 | } |
829 | |
830 | // Sometimes, aPoint points the padding <br> element. In that case, we'll |
831 | // adjust the insertion point to the previous text node, if one exists, or to |
832 | // the parent anonymous DIV. |
833 | if (EditorUtils::IsPaddingBRElementForEmptyLastLine( |
834 | *aPoint.template ContainerAs<nsIContent>()) && |
835 | aPoint.IsStartOfContainer()) { |
836 | nsIContent* previousSibling = aPoint.GetContainer()->GetPreviousSibling(); |
837 | if (previousSibling && previousSibling->IsText()) { |
838 | return EditorDOMPointType::AtEndOf(*previousSibling); |
839 | } |
840 | |
841 | nsINode* parentOfContainer = aPoint.GetContainerParent(); |
842 | if (parentOfContainer && parentOfContainer == anonymousDivElement) { |
843 | return EditorDOMPointType(parentOfContainer, |
844 | aPoint.template ContainerAs<nsIContent>(), 0u); |
845 | } |
846 | } |
847 | |
848 | return aPoint; |
849 | } |
850 | |
851 | // static |
852 | void TextEditor::MaskString(nsString& aString, const Text& aTextNode, |
853 | uint32_t aStartOffsetInString, |
854 | uint32_t aStartOffsetInText) { |
855 | MOZ_ASSERT(aTextNode.HasFlag(NS_MAYBE_MASKED))do { static_assert( mozilla::detail::AssertionConditionType< decltype(aTextNode.HasFlag(NS_MAYBE_MASKED))>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(aTextNode.HasFlag(NS_MAYBE_MASKED )))), 0))) { do { } while (false); MOZ_ReportAssertionFailure ("aTextNode.HasFlag(NS_MAYBE_MASKED)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 855); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aTextNode.HasFlag(NS_MAYBE_MASKED)" ")"); do { MOZ_CrashSequence(__null, 855); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
856 | MOZ_ASSERT(aStartOffsetInString == 0 || aStartOffsetInText == 0)do { static_assert( mozilla::detail::AssertionConditionType< decltype(aStartOffsetInString == 0 || aStartOffsetInText == 0 )>::isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(aStartOffsetInString == 0 || aStartOffsetInText == 0 ))), 0))) { do { } while (false); MOZ_ReportAssertionFailure( "aStartOffsetInString == 0 || aStartOffsetInText == 0", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 856); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aStartOffsetInString == 0 || aStartOffsetInText == 0" ")"); do { MOZ_CrashSequence(__null, 856); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
857 | |
858 | uint32_t unmaskStart = UINT32_MAX(4294967295U), unmaskLength = 0; |
859 | const TextEditor* const textEditor = |
860 | nsContentUtils::GetExtantTextEditorFromAnonymousNode(&aTextNode); |
861 | if (textEditor && textEditor->UnmaskedLength() > 0) { |
862 | unmaskStart = textEditor->UnmaskedStart(); |
863 | unmaskLength = textEditor->UnmaskedLength(); |
864 | // If text is copied from after unmasked range, we can treat this case |
865 | // as mask all. |
866 | if (aStartOffsetInText >= unmaskStart + unmaskLength) { |
867 | unmaskLength = 0; |
868 | unmaskStart = UINT32_MAX(4294967295U); |
869 | } else { |
870 | // If text is copied from middle of unmasked range, reduce the length |
871 | // and adjust start offset. |
872 | if (aStartOffsetInText > unmaskStart) { |
873 | unmaskLength = unmaskStart + unmaskLength - aStartOffsetInText; |
874 | unmaskStart = 0; |
875 | } |
876 | // If text is copied from before start of unmasked range, just adjust |
877 | // the start offset. |
878 | else { |
879 | unmaskStart -= aStartOffsetInText; |
880 | } |
881 | // Make the range is in the string. |
882 | unmaskStart += aStartOffsetInString; |
883 | } |
884 | } |
885 | |
886 | const char16_t kPasswordMask = TextEditor::PasswordMask(); |
887 | for (uint32_t i = aStartOffsetInString; i < aString.Length(); ++i) { |
888 | bool isSurrogatePair = NS_IS_HIGH_SURROGATE(aString.CharAt(i))((uint32_t(aString.CharAt(i)) & 0xFFFFFC00) == 0xD800) && |
889 | i < aString.Length() - 1 && |
890 | NS_IS_LOW_SURROGATE(aString.CharAt(i + 1))((uint32_t(aString.CharAt(i + 1)) & 0xFFFFFC00) == 0xDC00 ); |
891 | if (i < unmaskStart || i >= unmaskStart + unmaskLength) { |
892 | if (isSurrogatePair) { |
893 | aString.SetCharAt(kPasswordMask, i); |
894 | aString.SetCharAt(kPasswordMask, i + 1); |
895 | } else { |
896 | aString.SetCharAt(kPasswordMask, i); |
897 | } |
898 | } |
899 | |
900 | // Skip the following low surrogate. |
901 | if (isSurrogatePair) { |
902 | ++i; |
903 | } |
904 | } |
905 | } |
906 | |
907 | nsresult TextEditor::SetUnmaskRangeInternal(uint32_t aStart, uint32_t aLength, |
908 | uint32_t aTimeout, bool aNotify, |
909 | bool aForceStartMasking) { |
910 | if (mPasswordMaskData) { |
911 | mPasswordMaskData->mIsMaskingPassword = aForceStartMasking || aTimeout != 0; |
912 | |
913 | // We cannot manage multiple unmasked ranges so that shrink the previous |
914 | // range first. |
915 | if (!IsAllMasked()) { |
916 | mPasswordMaskData->mUnmaskedLength = 0; |
917 | mPasswordMaskData->CancelTimer(PasswordMaskData::ReleaseTimer::No); |
918 | } |
919 | } |
920 | |
921 | // If we're not a password editor, return error since this call does not |
922 | // make sense. |
923 | if (!IsPasswordEditor() || NS_WARN_IF(!mPasswordMaskData)NS_warn_if_impl(!mPasswordMaskData, "!mPasswordMaskData", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 923)) { |
924 | mPasswordMaskData->CancelTimer(PasswordMaskData::ReleaseTimer::Yes); |
925 | return NS_ERROR_NOT_AVAILABLE; |
926 | } |
927 | |
928 | if (NS_WARN_IF(!GetRoot())NS_warn_if_impl(!GetRoot(), "!GetRoot()", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 928)) { |
929 | return NS_ERROR_NOT_INITIALIZED; |
930 | } |
931 | Text* const text = GetTextNode(); |
932 | if (!text || !text->Length()) { |
933 | // There is no anonymous text node in the editor. |
934 | return aStart > 0 && aStart != UINT32_MAX(4294967295U) ? NS_ERROR_INVALID_ARG : NS_OK; |
935 | } |
936 | |
937 | if (aStart < UINT32_MAX(4294967295U)) { |
938 | uint32_t valueLength = text->Length(); |
939 | if (aStart >= valueLength) { |
940 | return NS_ERROR_INVALID_ARG; // There is no character can be masked. |
941 | } |
942 | // If aStart is middle of a surrogate pair, expand it to include the |
943 | // preceding high surrogate because the caller may want to show a |
944 | // character before the character at `aStart + 1`. |
945 | const nsTextFragment& textFragment = text->TextFragment(); |
946 | if (textFragment.IsLowSurrogateFollowingHighSurrogateAt(aStart)) { |
947 | mPasswordMaskData->mUnmaskedStart = aStart - 1; |
948 | // If caller collapses the range, keep it. Otherwise, expand the length. |
949 | if (aLength > 0) { |
950 | ++aLength; |
951 | } |
952 | } else { |
953 | mPasswordMaskData->mUnmaskedStart = aStart; |
954 | } |
955 | mPasswordMaskData->mUnmaskedLength = |
956 | std::min(valueLength - UnmaskedStart(), aLength); |
957 | // If unmasked end is middle of a surrogate pair, expand it to include |
958 | // the following low surrogate because the caller may want to show a |
959 | // character after the character at `aStart + aLength`. |
960 | if (UnmaskedEnd() < valueLength && |
961 | textFragment.IsLowSurrogateFollowingHighSurrogateAt(UnmaskedEnd())) { |
962 | mPasswordMaskData->mUnmaskedLength++; |
963 | } |
964 | // If it's first time to mask the unmasking characters with timer, create |
965 | // the timer now. Then, we'll keep using it for saving the creation cost. |
966 | if (!HasAutoMaskingTimer() && aLength && aTimeout && UnmaskedLength()) { |
967 | mPasswordMaskData->mTimer = NS_NewTimer(); |
968 | } |
969 | } else { |
970 | if (NS_WARN_IF(aLength != 0)NS_warn_if_impl(aLength != 0, "aLength != 0", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 970)) { |
971 | return NS_ERROR_INVALID_ARG; |
972 | } |
973 | mPasswordMaskData->MaskAll(); |
974 | } |
975 | |
976 | // Notify nsTextFrame of this update if the caller wants this to do it. |
977 | // Only in this case, script may run. |
978 | if (aNotify) { |
979 | MOZ_ASSERT(IsEditActionDataAvailable())do { static_assert( mozilla::detail::AssertionConditionType< decltype(IsEditActionDataAvailable())>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(IsEditActionDataAvailable()) )), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsEditActionDataAvailable()" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 979) ; AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()" ")"); do { MOZ_CrashSequence(__null, 979); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
980 | |
981 | RefPtr<Document> document = GetDocument(); |
982 | if (NS_WARN_IF(!document)NS_warn_if_impl(!document, "!document", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 982)) { |
983 | return NS_ERROR_NOT_INITIALIZED; |
984 | } |
985 | // Notify nsTextFrame of masking range change. |
986 | if (RefPtr<PresShell> presShell = document->GetObservingPresShell()) { |
987 | nsAutoScriptBlocker blockRunningScript; |
988 | uint32_t valueLength = text->Length(); |
989 | CharacterDataChangeInfo changeInfo = {false, 0, valueLength, valueLength, |
990 | nullptr}; |
991 | presShell->CharacterDataChanged(text, changeInfo); |
992 | } |
993 | |
994 | // Scroll caret into the view since masking or unmasking character may |
995 | // move caret to outside of the view. |
996 | nsresult rv = ScrollSelectionFocusIntoView(); |
997 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
998 | NS_WARNING("EditorBase::ScrollSelectionFocusIntoView() failed")NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::ScrollSelectionFocusIntoView() failed" , nullptr, "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 998); |
999 | return rv; |
1000 | } |
1001 | } |
1002 | |
1003 | if (!IsAllMasked() && aTimeout != 0) { |
1004 | // Initialize the timer to mask the range automatically. |
1005 | MOZ_ASSERT(HasAutoMaskingTimer())do { static_assert( mozilla::detail::AssertionConditionType< decltype(HasAutoMaskingTimer())>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(HasAutoMaskingTimer()))), 0) )) { do { } while (false); MOZ_ReportAssertionFailure("HasAutoMaskingTimer()" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 1005 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "HasAutoMaskingTimer()" ")"); do { MOZ_CrashSequence(__null, 1005); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
1006 | DebugOnly<nsresult> rvIgnored = mPasswordMaskData->mTimer->InitWithCallback( |
1007 | this, aTimeout, nsITimer::TYPE_ONE_SHOT); |
1008 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "nsITimer::InitWithCallback() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1009); } } while (false) |
1009 | "nsITimer::InitWithCallback() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "nsITimer::InitWithCallback() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1009); } } while (false); |
1010 | } |
1011 | |
1012 | return NS_OK; |
1013 | } |
1014 | |
1015 | // static |
1016 | char16_t TextEditor::PasswordMask() { |
1017 | char16_t ret = LookAndFeel::GetPasswordCharacter(); |
1018 | if (!ret) { |
1019 | ret = '*'; |
1020 | } |
1021 | return ret; |
1022 | } |
1023 | |
1024 | MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMPnsresult TextEditor::Notify(nsITimer* aTimer) { |
1025 | // Check whether our text editor's password flag was changed before this |
1026 | // "hide password character" timer actually fires. |
1027 | if (!IsPasswordEditor() || NS_WARN_IF(!mPasswordMaskData)NS_warn_if_impl(!mPasswordMaskData, "!mPasswordMaskData", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1027)) { |
1028 | return NS_OK; |
1029 | } |
1030 | |
1031 | if (IsAllMasked()) { |
1032 | return NS_OK; |
1033 | } |
1034 | |
1035 | AutoEditActionDataSetter editActionData(*this, EditAction::eHidePassword); |
1036 | if (NS_WARN_IF(!editActionData.CanHandle())NS_warn_if_impl(!editActionData.CanHandle(), "!editActionData.CanHandle()" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 1036 )) { |
1037 | return NS_ERROR_NOT_INITIALIZED; |
1038 | } |
1039 | |
1040 | // Mask all characters. |
1041 | nsresult rv = MaskAllCharactersAndNotify(); |
1042 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::MaskAllCharactersAndNotify() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1043); } } while (false) |
1043 | "TextEditor::MaskAllCharactersAndNotify() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::MaskAllCharactersAndNotify() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1043); } } while (false); |
1044 | |
1045 | if (StaticPrefs::editor_password_testing_mask_delay()) { |
1046 | if (RefPtr<Element> target = GetInputEventTargetElement()) { |
1047 | RefPtr<Document> document = target->OwnerDoc(); |
1048 | DebugOnly<nsresult> rvIgnored = nsContentUtils::DispatchTrustedEvent( |
1049 | document, target, u"MozLastInputMasked"_ns, CanBubble::eYes, |
1050 | Cancelable::eNo); |
1051 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "nsContentUtils::DispatchTrustedEvent(" "MozLastInputMasked) failed, but ignored", "NS_SUCCEEDED(rvIgnored)" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 1053 ); } } while (false) |
1052 | "nsContentUtils::DispatchTrustedEvent("do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "nsContentUtils::DispatchTrustedEvent(" "MozLastInputMasked) failed, but ignored", "NS_SUCCEEDED(rvIgnored)" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 1053 ); } } while (false) |
1053 | "MozLastInputMasked) failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "nsContentUtils::DispatchTrustedEvent(" "MozLastInputMasked) failed, but ignored", "NS_SUCCEEDED(rvIgnored)" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 1053 ); } } while (false); |
1054 | } |
1055 | } |
1056 | |
1057 | return EditorBase::ToGenericNSResult(rv); |
1058 | } |
1059 | |
1060 | NS_IMETHODIMPnsresult TextEditor::GetName(nsACString& aName) { |
1061 | aName.AssignLiteral("TextEditor"); |
1062 | return NS_OK; |
1063 | } |
1064 | |
1065 | void TextEditor::WillDeleteText(uint32_t aCurrentLength, |
1066 | uint32_t aRemoveStartOffset, |
1067 | uint32_t aRemoveLength) { |
1068 | MOZ_ASSERT(IsEditActionDataAvailable())do { static_assert( mozilla::detail::AssertionConditionType< decltype(IsEditActionDataAvailable())>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(IsEditActionDataAvailable()) )), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsEditActionDataAvailable()" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 1068 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()" ")"); do { MOZ_CrashSequence(__null, 1068); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
1069 | |
1070 | if (!IsPasswordEditor() || NS_WARN_IF(!mPasswordMaskData)NS_warn_if_impl(!mPasswordMaskData, "!mPasswordMaskData", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1070) || IsAllMasked()) { |
1071 | return; |
1072 | } |
1073 | |
1074 | // Adjust unmasked range before deletion since DOM mutation may cause |
1075 | // layout referring the range in old text. |
1076 | |
1077 | // If we need to mask automatically, mask all now. |
1078 | if (IsMaskingPassword()) { |
1079 | DebugOnly<nsresult> rvIgnored = MaskAllCharacters(); |
1080 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::MaskAllCharacters() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1081); } } while (false) |
1081 | "TextEditor::MaskAllCharacters() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::MaskAllCharacters() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1081); } } while (false); |
1082 | return; |
1083 | } |
1084 | |
1085 | if (aRemoveStartOffset < UnmaskedStart()) { |
1086 | // If removing range is before the unmasked range, move it. |
1087 | if (aRemoveStartOffset + aRemoveLength <= UnmaskedStart()) { |
1088 | DebugOnly<nsresult> rvIgnored = |
1089 | SetUnmaskRange(UnmaskedStart() - aRemoveLength, UnmaskedLength()); |
1090 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1091); } } while (false) |
1091 | "TextEditor::SetUnmaskRange() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1091); } } while (false); |
1092 | return; |
1093 | } |
1094 | |
1095 | // If removing range starts before unmasked range, and ends in unmasked |
1096 | // range, move and shrink the range. |
1097 | if (aRemoveStartOffset + aRemoveLength < UnmaskedEnd()) { |
1098 | uint32_t unmaskedLengthInRemovingRange = |
1099 | aRemoveStartOffset + aRemoveLength - UnmaskedStart(); |
1100 | DebugOnly<nsresult> rvIgnored = SetUnmaskRange( |
1101 | aRemoveStartOffset, UnmaskedLength() - unmaskedLengthInRemovingRange); |
1102 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1103); } } while (false) |
1103 | "TextEditor::SetUnmaskRange() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1103); } } while (false); |
1104 | return; |
1105 | } |
1106 | |
1107 | // If removing range includes all unmasked range, collapse it to the |
1108 | // remove offset. |
1109 | DebugOnly<nsresult> rvIgnored = SetUnmaskRange(aRemoveStartOffset, 0); |
1110 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1111); } } while (false) |
1111 | "TextEditor::SetUnmaskRange() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1111); } } while (false); |
1112 | return; |
1113 | } |
1114 | |
1115 | if (aRemoveStartOffset < UnmaskedEnd()) { |
1116 | // If removing range is in unmasked range, shrink the range. |
1117 | if (aRemoveStartOffset + aRemoveLength <= UnmaskedEnd()) { |
1118 | DebugOnly<nsresult> rvIgnored = |
1119 | SetUnmaskRange(UnmaskedStart(), UnmaskedLength() - aRemoveLength); |
1120 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1121); } } while (false) |
1121 | "TextEditor::SetUnmaskRange() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1121); } } while (false); |
1122 | return; |
1123 | } |
1124 | |
1125 | // If removing range starts from unmasked range, and ends after it, |
1126 | // shrink it. |
1127 | DebugOnly<nsresult> rvIgnored = |
1128 | SetUnmaskRange(UnmaskedStart(), aRemoveStartOffset - UnmaskedStart()); |
1129 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1130); } } while (false) |
1130 | "TextEditor::SetUnmaskRange() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1130); } } while (false); |
1131 | return; |
1132 | } |
1133 | |
1134 | // If removing range is after the unmasked range, keep it. |
1135 | } |
1136 | |
1137 | nsresult TextEditor::DidInsertText(uint32_t aNewLength, |
1138 | uint32_t aInsertedOffset, |
1139 | uint32_t aInsertedLength) { |
1140 | MOZ_ASSERT(IsEditActionDataAvailable())do { static_assert( mozilla::detail::AssertionConditionType< decltype(IsEditActionDataAvailable())>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(IsEditActionDataAvailable()) )), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsEditActionDataAvailable()" , "/root/firefox-clang/editor/libeditor/TextEditor.cpp", 1140 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()" ")"); do { MOZ_CrashSequence(__null, 1140); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
1141 | |
1142 | if (!IsPasswordEditor() || NS_WARN_IF(!mPasswordMaskData)NS_warn_if_impl(!mPasswordMaskData, "!mPasswordMaskData", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1142) || IsAllMasked()) { |
1143 | return NS_OK; |
1144 | } |
1145 | |
1146 | if (IsMaskingPassword()) { |
1147 | // If we need to mask password, mask all right now. |
1148 | nsresult rv = MaskAllCharactersAndNotify(); |
1149 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::MaskAllCharacters() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1150); } } while (false) |
1150 | "TextEditor::MaskAllCharacters() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::MaskAllCharacters() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1150); } } while (false); |
1151 | return rv; |
1152 | } |
1153 | |
1154 | if (aInsertedOffset < UnmaskedStart()) { |
1155 | // If insertion point is before unmasked range, expand the unmasked range |
1156 | // to include the new text. |
1157 | nsresult rv = SetUnmaskRangeAndNotify( |
1158 | aInsertedOffset, UnmaskedEnd() + aInsertedLength - aInsertedOffset); |
1159 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1160); } } while (false) |
1160 | "TextEditor::SetUnmaskRangeAndNotify() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1160); } } while (false); |
1161 | return rv; |
1162 | } |
1163 | |
1164 | if (aInsertedOffset <= UnmaskedEnd()) { |
1165 | // If insertion point is in unmasked range, unmask new text. |
1166 | nsresult rv = SetUnmaskRangeAndNotify(UnmaskedStart(), |
1167 | UnmaskedLength() + aInsertedLength); |
1168 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1169); } } while (false) |
1169 | "TextEditor::SetUnmaskRangeAndNotify() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1169); } } while (false); |
1170 | return rv; |
1171 | } |
1172 | |
1173 | // If insertion point is after unmasked range, extend the unmask range to |
1174 | // include the new text. |
1175 | nsresult rv = SetUnmaskRangeAndNotify( |
1176 | UnmaskedStart(), aInsertedOffset + aInsertedLength - UnmaskedStart()); |
1177 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1178); } } while (false) |
1178 | "TextEditor::SetUnmaskRangeAndNotify() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed" , "NS_SUCCEEDED(rv)", "/root/firefox-clang/editor/libeditor/TextEditor.cpp" , 1178); } } while (false); |
1179 | return rv; |
1180 | } |
1181 | |
1182 | } // namespace mozilla |