File: | var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp |
Warning: | line 593, 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", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 114); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface ; if (TopThreeWordsEquals( aIID, (nsXPCOMCycleCollectionParticipant ::COMTypeInfo<nsXPCOMCycleCollectionParticipant, void>:: kIID), (nsCycleCollectionISupports::COMTypeInfo<nsCycleCollectionISupports , void>::kIID)) && (LowWordEquals(aIID, (nsXPCOMCycleCollectionParticipant ::COMTypeInfo<nsXPCOMCycleCollectionParticipant, void>:: kIID)) || LowWordEquals(aIID, (nsCycleCollectionISupports::COMTypeInfo <nsCycleCollectionISupports, void>::kIID)))) { if (LowWordEquals (aIID, (nsXPCOMCycleCollectionParticipant::COMTypeInfo<nsXPCOMCycleCollectionParticipant , void>::kIID))) { *aInstancePtr = TextEditor::cycleCollection ::GetParticipant(); return NS_OK; } if (LowWordEquals(aIID, ( nsCycleCollectionISupports::COMTypeInfo<nsCycleCollectionISupports , void>::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()" , "/var/lib/jenkins/workspace/firefox-scan-build/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)", "/var/lib/jenkins/workspace/firefox-scan-build/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)", "/var/lib/jenkins/workspace/firefox-scan-build/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()" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 133); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()" ")"); do { *((volatile int*)__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", "/var/lib/jenkins/workspace/firefox-scan-build/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", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 142); AnnotateMozCrashReason("MOZ_ASSERT" "(" "textNode" ")" ); do { *((volatile int*)__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)", "/var/lib/jenkins/workspace/firefox-scan-build/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)", "/var/lib/jenkins/workspace/firefox-scan-build/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()?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 154); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mInitSucceeded" ") (" "TextEditor::Init() called again without calling PreDestroy()?" ")"); do { *((volatile int*)__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()?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 154); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mInitSucceeded" ") (" "TextEditor::Init() called again without calling PreDestroy()?" ")"); do { *((volatile int*)__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" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 155); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!(aFlags & nsIEditor::eEditorPasswordMask) == !aPasswordMaskData" ")"); do { *((volatile int*)__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, "/var/lib/jenkins/workspace/firefox-scan-build/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()" , "/var/lib/jenkins/workspace/firefox-scan-build/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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 174); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mInitSucceeded" ") (" "TextEditor::Init() shouldn't be nested" ")"); do { *( (volatile int*)__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, "/var/lib/jenkins/workspace/firefox-scan-build/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()" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 194); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()" ")"); do { *((volatile int*)__null) = 194; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
195 | |
196 | MOZ_TRY(EnsureEmptyTextFirstChild())do { auto mozTryTempResult_ = ::mozilla::ToResult(EnsureEmptyTextFirstChild ()); if ((__builtin_expect(!!(mozTryTempResult_.isErr()), 0)) ) { return mozTryTempResult_.propagateErr(); } } while (0); |
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, "/var/lib/jenkins/workspace/firefox-scan-build/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, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 212) |
212 | "EditorBase::EnsurePaddingBRElementInMultilineEditor() failed")NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::EnsurePaddingBRElementInMultilineEditor() failed" , nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/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()" , "/var/lib/jenkins/workspace/firefox-scan-build/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)" , "/var/lib/jenkins/workspace/firefox-scan-build/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)" , "/var/lib/jenkins/workspace/firefox-scan-build/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)" , "/var/lib/jenkins/workspace/firefox-scan-build/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)", "/var/lib/jenkins/workspace/firefox-scan-build/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)", "/var/lib/jenkins/workspace/firefox-scan-build/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", "/var/lib/jenkins/workspace/firefox-scan-build/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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 279); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aKeyboardEvent->mMessage == eKeyPress" ") (" "HandleKeyPressEvent gets non-keypress event" ")"); do { *((volatile int*)__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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 279); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aKeyboardEvent->mMessage == eKeyPress" ") (" "HandleKeyPressEvent gets non-keypress event" ")"); do { *((volatile int*)__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)", "/var/lib/jenkins/workspace/firefox-scan-build/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)", "/var/lib/jenkins/workspace/firefox-scan-build/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)", "/var/lib/jenkins/workspace/firefox-scan-build/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)", "/var/lib/jenkins/workspace/firefox-scan-build/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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 340); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aKeyboardEvent->mCharCode <= 0xFFFF" ") (" "Non-BMP character needs special handling" ")"); do { * ((volatile int*)__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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 340); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aKeyboardEvent->mCharCode <= 0xFFFF" ") (" "Non-BMP character needs special handling" ")"); do { * ((volatile int*)__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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/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 { *((volatile int*)__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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/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 { *((volatile int*)__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)", "/var/lib/jenkins/workspace/firefox-scan-build/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", "/var/lib/jenkins/workspace/firefox-scan-build/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", "/var/lib/jenkins/workspace/firefox-scan-build/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()", "/var/lib/jenkins/workspace/firefox-scan-build/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)", "/var/lib/jenkins/workspace/firefox-scan-build/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)", "/var/lib/jenkins/workspace/firefox-scan-build/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", "/var/lib/jenkins/workspace/firefox-scan-build/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", "/var/lib/jenkins/workspace/firefox-scan-build/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)", "/var/lib/jenkins/workspace/firefox-scan-build/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)", "/var/lib/jenkins/workspace/firefox-scan-build/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" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 404); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aString.FindChar(nsCRT::CR) == kNotFound" ")"); do { *((volatile int*)__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", "/var/lib/jenkins/workspace/firefox-scan-build/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", "/var/lib/jenkins/workspace/firefox-scan-build/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)", "/var/lib/jenkins/workspace/firefox-scan-build/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)", "/var/lib/jenkins/workspace/firefox-scan-build/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()" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 427); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()" ")"); do { *((volatile int*)__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" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 428); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mPlaceholderBatch" ")"); do { *((volatile int*)__null) = 428; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
429 | |
430 | if (NS_WARN_IF(!mInitSucceeded)NS_warn_if_impl(!mInitSucceeded, "!mInitSucceeded", "/var/lib/jenkins/workspace/firefox-scan-build/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)", "/var/lib/jenkins/workspace/firefox-scan-build/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()", "/var/lib/jenkins/workspace/firefox-scan-build/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()", "/var/lib/jenkins/workspace/firefox-scan-build/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()", "/var/lib/jenkins/workspace/firefox-scan-build/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, "/var/lib/jenkins/workspace/firefox-scan-build/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)", "/var/lib/jenkins/workspace/firefox-scan-build/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)", "/var/lib/jenkins/workspace/firefox-scan-build/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)", "/var/lib/jenkins/workspace/firefox-scan-build/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()", "/var/lib/jenkins/workspace/firefox-scan-build/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 | // Even if there is no padding <br> element for empty editor, we should be |
484 | // detected as empty editor if all the children are text nodes and these |
485 | // have no content. |
486 | Element* anonymousDivElement = GetRoot(); |
487 | if (!anonymousDivElement) { |
488 | return true; // Don't warn it, this is possible, e.g., 997805.html |
489 | } |
490 | |
491 | MOZ_ASSERT(anonymousDivElement->GetFirstChild() &&do { static_assert( mozilla::detail::AssertionConditionType< decltype(anonymousDivElement->GetFirstChild() && anonymousDivElement ->GetFirstChild()->IsText())>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(anonymousDivElement->GetFirstChild () && anonymousDivElement->GetFirstChild()->IsText ()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure ("anonymousDivElement->GetFirstChild() && anonymousDivElement->GetFirstChild()->IsText()" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 492); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anonymousDivElement->GetFirstChild() && anonymousDivElement->GetFirstChild()->IsText()" ")"); do { *((volatile int*)__null) = 492; __attribute__((nomerge )) ::abort(); } while (false); } } while (false) |
492 | anonymousDivElement->GetFirstChild()->IsText())do { static_assert( mozilla::detail::AssertionConditionType< decltype(anonymousDivElement->GetFirstChild() && anonymousDivElement ->GetFirstChild()->IsText())>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(anonymousDivElement->GetFirstChild () && anonymousDivElement->GetFirstChild()->IsText ()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure ("anonymousDivElement->GetFirstChild() && anonymousDivElement->GetFirstChild()->IsText()" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 492); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anonymousDivElement->GetFirstChild() && anonymousDivElement->GetFirstChild()->IsText()" ")"); do { *((volatile int*)__null) = 492; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
493 | |
494 | // Only when there is non-empty text node, we are not empty. |
495 | return !anonymousDivElement->GetFirstChild()->Length(); |
496 | } |
497 | |
498 | NS_IMETHODIMPnsresult TextEditor::GetTextLength(uint32_t* aCount) { |
499 | 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", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 499); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aCount" ")") ; do { *((volatile int*)__null) = 499; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
500 | |
501 | // initialize out params |
502 | *aCount = 0; |
503 | |
504 | // special-case for empty document, to account for the padding <br> element |
505 | // for empty editor. |
506 | // XXX This should be overridden by `HTMLEditor` and we should return the |
507 | // first text node's length from `TextEditor` instead. The following |
508 | // code is too expensive. |
509 | if (IsEmpty()) { |
510 | return NS_OK; |
511 | } |
512 | |
513 | Element* rootElement = GetRoot(); |
514 | if (NS_WARN_IF(!rootElement)NS_warn_if_impl(!rootElement, "!rootElement", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 514)) { |
515 | return NS_ERROR_FAILURE; |
516 | } |
517 | |
518 | uint32_t totalLength = 0; |
519 | PostContentIterator postOrderIter; |
520 | DebugOnly<nsresult> rvIgnored = postOrderIter.Init(rootElement); |
521 | NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "PostContentIterator::Init() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 522); } } while (false) |
522 | "PostContentIterator::Init() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored )), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "PostContentIterator::Init() failed, but ignored" , "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 522); } } while (false); |
523 | EditorType editorType = GetEditorType(); |
524 | for (; !postOrderIter.IsDone(); postOrderIter.Next()) { |
525 | nsINode* currentNode = postOrderIter.GetCurrentNode(); |
526 | if (currentNode && currentNode->IsText() && |
527 | EditorUtils::IsEditableContent(*currentNode->AsText(), editorType)) { |
528 | totalLength += currentNode->Length(); |
529 | } |
530 | } |
531 | |
532 | *aCount = totalLength; |
533 | return NS_OK; |
534 | } |
535 | |
536 | bool TextEditor::IsCopyToClipboardAllowedInternal() const { |
537 | 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()" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 537); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()" ")"); do { *((volatile int*)__null) = 537; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
538 | if (!EditorBase::IsCopyToClipboardAllowedInternal()) { |
539 | return false; |
540 | } |
541 | |
542 | if (!IsSingleLineEditor() || !IsPasswordEditor() || |
543 | NS_WARN_IF(!mPasswordMaskData)NS_warn_if_impl(!mPasswordMaskData, "!mPasswordMaskData", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 543)) { |
544 | return true; |
545 | } |
546 | |
547 | // If we're a password editor, we should allow selected text to be copied |
548 | // to the clipboard only when selection range is in unmasked range. |
549 | if (IsAllMasked() || IsMaskingPassword() || !UnmaskedLength()) { |
550 | return false; |
551 | } |
552 | |
553 | // If there are 2 or more ranges, we don't allow to copy/cut for now since |
554 | // we need to check whether all ranges are in unmasked range or not. |
555 | // Anyway, such operation in password field does not make sense. |
556 | if (SelectionRef().RangeCount() > 1) { |
557 | return false; |
558 | } |
559 | |
560 | uint32_t selectionStart = 0, selectionEnd = 0; |
561 | nsContentUtils::GetSelectionInTextControl(&SelectionRef(), mRootElement, |
562 | selectionStart, selectionEnd); |
563 | return UnmaskedStart() <= selectionStart && UnmaskedEnd() >= selectionEnd; |
564 | } |
565 | |
566 | nsresult TextEditor::HandlePasteAsQuotation( |
567 | AutoEditActionDataSetter& aEditActionData, |
568 | nsIClipboard::ClipboardType aClipboardType, DataTransfer* aDataTransfer) { |
569 | 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" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 570); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aClipboardType == nsIClipboard::kGlobalClipboard || aClipboardType == nsIClipboard::kSelectionClipboard" ")"); do { *((volatile int*)__null) = 570; __attribute__((nomerge )) ::abort(); } while (false); } } while (false) |
570 | 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" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 570); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aClipboardType == nsIClipboard::kGlobalClipboard || aClipboardType == nsIClipboard::kSelectionClipboard" ")"); do { *((volatile int*)__null) = 570; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
571 | if (NS_WARN_IF(!GetDocument())NS_warn_if_impl(!GetDocument(), "!GetDocument()", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 571)) { |
572 | return NS_OK; |
573 | } |
574 | |
575 | // XXX Why don't we dispatch ePaste event here? |
576 | |
577 | // Get the nsITransferable interface for getting the data from the clipboard |
578 | Result<nsCOMPtr<nsITransferable>, nsresult> maybeTransferable = |
579 | EditorUtils::CreateTransferableForPlainText(*GetDocument()); |
580 | if (maybeTransferable.isErr()) { |
581 | NS_WARNING("EditorUtils::CreateTransferableForPlainText() failed")NS_DebugBreak(NS_DEBUG_WARNING, "EditorUtils::CreateTransferableForPlainText() failed" , nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 581); |
582 | return maybeTransferable.unwrapErr(); |
583 | } |
584 | nsCOMPtr<nsITransferable> trans(maybeTransferable.unwrap()); |
585 | if (!trans) { |
586 | NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "EditorUtils::CreateTransferableForPlainText() returned nullptr, but " "ignored", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 588) |
587 | "EditorUtils::CreateTransferableForPlainText() returned nullptr, but "NS_DebugBreak(NS_DEBUG_WARNING, "EditorUtils::CreateTransferableForPlainText() returned nullptr, but " "ignored", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 588) |
588 | "ignored")NS_DebugBreak(NS_DEBUG_WARNING, "EditorUtils::CreateTransferableForPlainText() returned nullptr, but " "ignored", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 588); |
589 | return NS_OK; |
590 | } |
591 | |
592 | // Get the Data from the clipboard |
593 | nsresult rv = |
Value stored to 'rv' during its initialization is never read | |
594 | GetDataFromDataTransferOrClipboard(aDataTransfer, trans, aClipboardType); |
595 | |
596 | // Now we ask the transferable for the data |
597 | // it still owns the data, we just have a pointer to it. |
598 | // If it can't support a "text" output of the data the call will fail |
599 | nsCOMPtr<nsISupports> genericDataObj; |
600 | nsAutoCString flavor; |
601 | rv = trans->GetAnyTransferData(flavor, getter_AddRefs(genericDataObj)); |
602 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
603 | NS_WARNING("nsITransferable::GetAnyTransferData() failed")NS_DebugBreak(NS_DEBUG_WARNING, "nsITransferable::GetAnyTransferData() failed" , nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 603); |
604 | return rv; |
605 | } |
606 | |
607 | if (!flavor.EqualsLiteral(kTextMime"text/plain") && |
608 | !flavor.EqualsLiteral(kMozTextInternal"text/x-moz-text-internal")) { |
609 | return NS_OK; |
610 | } |
611 | |
612 | nsCOMPtr<nsISupportsString> text = do_QueryInterface(genericDataObj); |
613 | if (!text) { |
614 | return NS_OK; |
615 | } |
616 | |
617 | nsString stuffToPaste; |
618 | DebugOnly<nsresult> rvIgnored = text->GetData(stuffToPaste); |
619 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 620); } } while (false) |
620 | "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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 620); } } while (false); |
621 | if (stuffToPaste.IsEmpty()) { |
622 | return NS_OK; |
623 | } |
624 | |
625 | aEditActionData.SetData(stuffToPaste); |
626 | if (!stuffToPaste.IsEmpty()) { |
627 | nsContentUtils::PlatformToDOMLineBreaks(stuffToPaste); |
628 | } |
629 | rv = aEditActionData.MaybeDispatchBeforeInputEvent(); |
630 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
631 | 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" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 632); } } while (false) |
632 | "MaybeDispatchBeforeInputEvent() failed")do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak (NS_DEBUG_WARNING, "MaybeDispatchBeforeInputEvent() failed", "rv == NS_ERROR_EDITOR_ACTION_CANCELED" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 632); } } while (false); |
633 | return rv; |
634 | } |
635 | |
636 | AutoPlaceholderBatch treatAsOneTransaction( |
637 | *this, ScrollSelectionIntoView::Yes, __FUNCTION__); |
638 | rv = InsertWithQuotationsAsSubAction(stuffToPaste); |
639 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 640); } } while (false) |
640 | "TextEditor::InsertWithQuotationsAsSubAction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::InsertWithQuotationsAsSubAction() failed" , "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 640); } } while (false); |
641 | return rv; |
642 | } |
643 | |
644 | nsresult TextEditor::InsertWithQuotationsAsSubAction( |
645 | const nsAString& aQuotedText) { |
646 | 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()" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 646); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()" ")"); do { *((volatile int*)__null) = 646; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
647 | |
648 | if (IsReadonly()) { |
649 | return NS_OK; |
650 | } |
651 | |
652 | // Let the citer quote it for us: |
653 | nsString quotedStuff; |
654 | InternetCiter::GetCiteString(aQuotedText, quotedStuff); |
655 | |
656 | // It's best to put a blank line after the quoted text so that mails |
657 | // written without thinking won't be so ugly. |
658 | if (!aQuotedText.IsEmpty() && (aQuotedText.Last() != char16_t('\n'))) { |
659 | quotedStuff.Append(char16_t('\n')); |
660 | } |
661 | |
662 | IgnoredErrorResult ignoredError; |
663 | AutoEditSubActionNotifier startToHandleEditSubAction( |
664 | *this, EditSubAction::eInsertText, nsIEditor::eNext, ignoredError); |
665 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 665)) { |
666 | return ignoredError.StealNSResult(); |
667 | } |
668 | NS_WARNING_ASSERTION(do { if (!(!ignoredError.Failed())) { NS_DebugBreak(NS_DEBUG_WARNING , "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored" , "!ignoredError.Failed()", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 670); } } while (false) |
669 | !ignoredError.Failed(),do { if (!(!ignoredError.Failed())) { NS_DebugBreak(NS_DEBUG_WARNING , "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored" , "!ignoredError.Failed()", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 670); } } while (false) |
670 | "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored")do { if (!(!ignoredError.Failed())) { NS_DebugBreak(NS_DEBUG_WARNING , "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored" , "!ignoredError.Failed()", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 670); } } while (false); |
671 | |
672 | // XXX Do we need to support paste-as-quotation in password editor (and |
673 | // also in single line editor)? |
674 | MaybeDoAutoPasswordMasking(); |
675 | |
676 | nsresult rv = InsertTextAsSubAction(quotedStuff, SelectionHandling::Delete); |
677 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 678); } } while (false) |
678 | "EditorBase::InsertTextAsSubAction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::InsertTextAsSubAction() failed" , "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 678); } } while (false); |
679 | return rv; |
680 | } |
681 | |
682 | nsresult TextEditor::SelectEntireDocument() { |
683 | 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()" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 683); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()" ")"); do { *((volatile int*)__null) = 683; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
684 | |
685 | if (NS_WARN_IF(!mInitSucceeded)NS_warn_if_impl(!mInitSucceeded, "!mInitSucceeded", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 685)) { |
686 | return NS_ERROR_NOT_INITIALIZED; |
687 | } |
688 | |
689 | RefPtr<Element> anonymousDivElement = GetRoot(); |
690 | if (NS_WARN_IF(!anonymousDivElement)NS_warn_if_impl(!anonymousDivElement, "!anonymousDivElement", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 690)) { |
691 | return NS_ERROR_NOT_INITIALIZED; |
692 | } |
693 | |
694 | RefPtr<Text> text = |
695 | Text::FromNodeOrNull(anonymousDivElement->GetFirstChild()); |
696 | 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", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 696); AnnotateMozCrashReason("MOZ_ASSERT" "(" "text" ")"); do { *((volatile int*)__null) = 696; __attribute__((nomerge)) :: abort(); } while (false); } } while (false); |
697 | |
698 | MOZ_TRY(SelectionRef().SetStartAndEndInLimiter(do { auto mozTryTempResult_ = ::mozilla::ToResult(SelectionRef ().SetStartAndEndInLimiter( *text, 0, *text, text->TextDataLength (), eDirNext, nsISelectionListener::SELECTALL_REASON)); if (( __builtin_expect(!!(mozTryTempResult_.isErr()), 0))) { return mozTryTempResult_.propagateErr(); } } while (0) |
699 | *text, 0, *text, text->TextDataLength(), eDirNext,do { auto mozTryTempResult_ = ::mozilla::ToResult(SelectionRef ().SetStartAndEndInLimiter( *text, 0, *text, text->TextDataLength (), eDirNext, nsISelectionListener::SELECTALL_REASON)); if (( __builtin_expect(!!(mozTryTempResult_.isErr()), 0))) { return mozTryTempResult_.propagateErr(); } } while (0) |
700 | nsISelectionListener::SELECTALL_REASON))do { auto mozTryTempResult_ = ::mozilla::ToResult(SelectionRef ().SetStartAndEndInLimiter( *text, 0, *text, text->TextDataLength (), eDirNext, nsISelectionListener::SELECTALL_REASON)); if (( __builtin_expect(!!(mozTryTempResult_.isErr()), 0))) { return mozTryTempResult_.propagateErr(); } } while (0); |
701 | |
702 | return NS_OK; |
703 | } |
704 | |
705 | EventTarget* TextEditor::GetDOMEventTarget() const { return mEventTarget; } |
706 | |
707 | void TextEditor::ReinitializeSelection(Element& aElement) { |
708 | if (NS_WARN_IF(Destroyed())NS_warn_if_impl(Destroyed(), "Destroyed()", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 708)) { |
709 | return; |
710 | } |
711 | |
712 | AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing); |
713 | if (NS_WARN_IF(!editActionData.CanHandle())NS_warn_if_impl(!editActionData.CanHandle(), "!editActionData.CanHandle()" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 713)) { |
714 | return; |
715 | } |
716 | |
717 | // We don't need to flush pending notifications here and we don't need to |
718 | // handle spellcheck at first focus. Therefore, we don't need to call |
719 | // `TextEditor::OnFocus` here. |
720 | EditorBase::OnFocus(aElement); |
721 | |
722 | // If previous focused editor turn on spellcheck and this editor doesn't |
723 | // turn on it, spellcheck state is mismatched. So we need to re-sync it. |
724 | SyncRealTimeSpell(); |
725 | } |
726 | |
727 | nsresult TextEditor::OnFocus(const nsINode& aOriginalEventTargetNode) { |
728 | RefPtr<PresShell> presShell = GetPresShell(); |
729 | if (NS_WARN_IF(!presShell)NS_warn_if_impl(!presShell, "!presShell", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 729)) { |
730 | return NS_ERROR_FAILURE; |
731 | } |
732 | // Let's update the layout information right now because there are some |
733 | // pending notifications and flushing them may cause destroying the editor. |
734 | presShell->FlushPendingNotifications(FlushType::Layout); |
735 | if (MOZ_UNLIKELY(!CanKeepHandlingFocusEvent(aOriginalEventTargetNode))(__builtin_expect(!!(!CanKeepHandlingFocusEvent(aOriginalEventTargetNode )), 0))) { |
736 | return NS_OK; |
737 | } |
738 | |
739 | AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing); |
740 | if (NS_WARN_IF(!editActionData.CanHandle())NS_warn_if_impl(!editActionData.CanHandle(), "!editActionData.CanHandle()" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 740)) { |
741 | return NS_ERROR_FAILURE; |
742 | } |
743 | |
744 | // Spell check a textarea the first time that it is focused. |
745 | nsresult rv = FlushPendingSpellCheck(); |
746 | if (MOZ_UNLIKELY(rv == NS_ERROR_EDITOR_DESTROYED)(__builtin_expect(!!(rv == NS_ERROR_EDITOR_DESTROYED), 0))) { |
747 | NS_WARNING("EditorBase::FlushPendingSpellCheck() failed")NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::FlushPendingSpellCheck() failed" , nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 747); |
748 | return NS_ERROR_EDITOR_DESTROYED; |
749 | } |
750 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 752); } } while (false) |
751 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 752); } } while (false) |
752 | "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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 752); } } while (false); |
753 | if (MOZ_UNLIKELY(!CanKeepHandlingFocusEvent(aOriginalEventTargetNode))(__builtin_expect(!!(!CanKeepHandlingFocusEvent(aOriginalEventTargetNode )), 0))) { |
754 | return NS_OK; |
755 | } |
756 | |
757 | return EditorBase::OnFocus(aOriginalEventTargetNode); |
758 | } |
759 | |
760 | nsresult TextEditor::OnBlur(const EventTarget* aEventTarget) { |
761 | // check if something else is focused. If another element is focused, then |
762 | // we should not change the selection. If another element already has focus, |
763 | // we should not maintain the selection because we may not have the rights |
764 | // doing it. |
765 | if (nsFocusManager::GetFocusedElementStatic()) { |
766 | return NS_OK; |
767 | } |
768 | |
769 | nsresult rv = FinalizeSelection(); |
770 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 771); } } while (false) |
771 | "EditorBase::FinalizeSelection() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::FinalizeSelection() failed" , "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 771); } } while (false); |
772 | return rv; |
773 | } |
774 | |
775 | nsresult TextEditor::SetAttributeOrEquivalent(Element* aElement, |
776 | nsAtom* aAttribute, |
777 | const nsAString& aValue, |
778 | bool aSuppressTransaction) { |
779 | if (NS_WARN_IF(!aElement)NS_warn_if_impl(!aElement, "!aElement", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 779) || NS_WARN_IF(!aAttribute)NS_warn_if_impl(!aAttribute, "!aAttribute", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 779)) { |
780 | return NS_ERROR_INVALID_ARG; |
781 | } |
782 | |
783 | AutoEditActionDataSetter editActionData(*this, EditAction::eSetAttribute); |
784 | nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent(); |
785 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
786 | 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", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 787); } } while (false) |
787 | "CanHandleAndMaybeDispatchBeforeInputEvent() failed")do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak (NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed" , "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 787); } } while (false); |
788 | return EditorBase::ToGenericNSResult(rv); |
789 | } |
790 | |
791 | rv = SetAttributeWithTransaction(*aElement, *aAttribute, aValue); |
792 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 793); } } while (false) |
793 | "EditorBase::SetAttributeWithTransaction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::SetAttributeWithTransaction() failed" , "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 793); } } while (false); |
794 | return EditorBase::ToGenericNSResult(rv); |
795 | } |
796 | |
797 | nsresult TextEditor::RemoveAttributeOrEquivalent(Element* aElement, |
798 | nsAtom* aAttribute, |
799 | bool aSuppressTransaction) { |
800 | if (NS_WARN_IF(!aElement)NS_warn_if_impl(!aElement, "!aElement", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 800) || NS_WARN_IF(!aAttribute)NS_warn_if_impl(!aAttribute, "!aAttribute", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 800)) { |
801 | return NS_ERROR_INVALID_ARG; |
802 | } |
803 | |
804 | AutoEditActionDataSetter editActionData(*this, EditAction::eRemoveAttribute); |
805 | nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent(); |
806 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
807 | 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", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 808); } } while (false) |
808 | "CanHandleAndMaybeDispatchBeforeInputEvent() failed")do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak (NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed" , "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 808); } } while (false); |
809 | return EditorBase::ToGenericNSResult(rv); |
810 | } |
811 | |
812 | rv = RemoveAttributeWithTransaction(*aElement, *aAttribute); |
813 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 814); } } while (false) |
814 | "EditorBase::RemoveAttributeWithTransaction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::RemoveAttributeWithTransaction() failed" , "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 814); } } while (false); |
815 | return EditorBase::ToGenericNSResult(rv); |
816 | } |
817 | |
818 | template <typename EditorDOMPointType> |
819 | EditorDOMPointType TextEditor::FindBetterInsertionPoint( |
820 | const EditorDOMPointType& aPoint) const { |
821 | if (MOZ_UNLIKELY(NS_WARN_IF(!aPoint.IsInContentNode()))(__builtin_expect(!!(NS_warn_if_impl(!aPoint.IsInContentNode( ), "!aPoint.IsInContentNode()", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 821)), 0))) { |
822 | return aPoint; |
823 | } |
824 | |
825 | 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()" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 825); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aPoint.IsSetAndValid()" ")"); do { *((volatile int*)__null) = 825; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
826 | |
827 | Element* const anonymousDivElement = GetRoot(); |
828 | if (aPoint.GetContainer() == anonymousDivElement) { |
829 | // In some cases, aPoint points start of the anonymous <div>. To avoid |
830 | // injecting unneeded text nodes, we first look to see if we have one |
831 | // available. In that case, we'll just adjust node and offset accordingly. |
832 | if (aPoint.IsStartOfContainer()) { |
833 | if (aPoint.GetContainer()->HasChildren() && |
834 | aPoint.GetContainer()->GetFirstChild()->IsText()) { |
835 | return EditorDOMPointType(aPoint.GetContainer()->GetFirstChild(), 0u); |
836 | } |
837 | } |
838 | // In some other cases, aPoint points the terminating padding <br> element |
839 | // for empty last line in the anonymous <div>. In that case, we'll adjust |
840 | // aInOutNode and aInOutOffset to the preceding text node, if any. |
841 | else { |
842 | nsIContent* child = aPoint.GetContainer()->GetLastChild(); |
843 | while (child) { |
844 | if (child->IsText()) { |
845 | return EditorDOMPointType::AtEndOf(*child); |
846 | } |
847 | child = child->GetPreviousSibling(); |
848 | } |
849 | } |
850 | } |
851 | |
852 | // Sometimes, aPoint points the padding <br> element. In that case, we'll |
853 | // adjust the insertion point to the previous text node, if one exists, or to |
854 | // the parent anonymous DIV. |
855 | if (EditorUtils::IsPaddingBRElementForEmptyLastLine( |
856 | *aPoint.template ContainerAs<nsIContent>()) && |
857 | aPoint.IsStartOfContainer()) { |
858 | nsIContent* previousSibling = aPoint.GetContainer()->GetPreviousSibling(); |
859 | if (previousSibling && previousSibling->IsText()) { |
860 | return EditorDOMPointType::AtEndOf(*previousSibling); |
861 | } |
862 | |
863 | nsINode* parentOfContainer = aPoint.GetContainerParent(); |
864 | if (parentOfContainer && parentOfContainer == anonymousDivElement) { |
865 | return EditorDOMPointType(parentOfContainer, |
866 | aPoint.template ContainerAs<nsIContent>(), 0u); |
867 | } |
868 | } |
869 | |
870 | return aPoint; |
871 | } |
872 | |
873 | // static |
874 | void TextEditor::MaskString(nsString& aString, const Text& aTextNode, |
875 | uint32_t aStartOffsetInString, |
876 | uint32_t aStartOffsetInText) { |
877 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 877); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aTextNode.HasFlag(NS_MAYBE_MASKED)" ")"); do { *((volatile int*)__null) = 877; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
878 | 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", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 878); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aStartOffsetInString == 0 || aStartOffsetInText == 0" ")"); do { *((volatile int*)__null) = 878; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
879 | |
880 | uint32_t unmaskStart = UINT32_MAX(4294967295U), unmaskLength = 0; |
881 | TextEditor* textEditor = |
882 | nsContentUtils::GetTextEditorFromAnonymousNodeWithoutCreation(&aTextNode); |
883 | if (textEditor && textEditor->UnmaskedLength() > 0) { |
884 | unmaskStart = textEditor->UnmaskedStart(); |
885 | unmaskLength = textEditor->UnmaskedLength(); |
886 | // If text is copied from after unmasked range, we can treat this case |
887 | // as mask all. |
888 | if (aStartOffsetInText >= unmaskStart + unmaskLength) { |
889 | unmaskLength = 0; |
890 | unmaskStart = UINT32_MAX(4294967295U); |
891 | } else { |
892 | // If text is copied from middle of unmasked range, reduce the length |
893 | // and adjust start offset. |
894 | if (aStartOffsetInText > unmaskStart) { |
895 | unmaskLength = unmaskStart + unmaskLength - aStartOffsetInText; |
896 | unmaskStart = 0; |
897 | } |
898 | // If text is copied from before start of unmasked range, just adjust |
899 | // the start offset. |
900 | else { |
901 | unmaskStart -= aStartOffsetInText; |
902 | } |
903 | // Make the range is in the string. |
904 | unmaskStart += aStartOffsetInString; |
905 | } |
906 | } |
907 | |
908 | const char16_t kPasswordMask = TextEditor::PasswordMask(); |
909 | for (uint32_t i = aStartOffsetInString; i < aString.Length(); ++i) { |
910 | bool isSurrogatePair = NS_IS_HIGH_SURROGATE(aString.CharAt(i))((uint32_t(aString.CharAt(i)) & 0xFFFFFC00) == 0xD800) && |
911 | i < aString.Length() - 1 && |
912 | NS_IS_LOW_SURROGATE(aString.CharAt(i + 1))((uint32_t(aString.CharAt(i + 1)) & 0xFFFFFC00) == 0xDC00 ); |
913 | if (i < unmaskStart || i >= unmaskStart + unmaskLength) { |
914 | if (isSurrogatePair) { |
915 | aString.SetCharAt(kPasswordMask, i); |
916 | aString.SetCharAt(kPasswordMask, i + 1); |
917 | } else { |
918 | aString.SetCharAt(kPasswordMask, i); |
919 | } |
920 | } |
921 | |
922 | // Skip the following low surrogate. |
923 | if (isSurrogatePair) { |
924 | ++i; |
925 | } |
926 | } |
927 | } |
928 | |
929 | nsresult TextEditor::SetUnmaskRangeInternal(uint32_t aStart, uint32_t aLength, |
930 | uint32_t aTimeout, bool aNotify, |
931 | bool aForceStartMasking) { |
932 | if (mPasswordMaskData) { |
933 | mPasswordMaskData->mIsMaskingPassword = aForceStartMasking || aTimeout != 0; |
934 | |
935 | // We cannot manage multiple unmasked ranges so that shrink the previous |
936 | // range first. |
937 | if (!IsAllMasked()) { |
938 | mPasswordMaskData->mUnmaskedLength = 0; |
939 | mPasswordMaskData->CancelTimer(PasswordMaskData::ReleaseTimer::No); |
940 | } |
941 | } |
942 | |
943 | // If we're not a password editor, return error since this call does not |
944 | // make sense. |
945 | if (!IsPasswordEditor() || NS_WARN_IF(!mPasswordMaskData)NS_warn_if_impl(!mPasswordMaskData, "!mPasswordMaskData", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 945)) { |
946 | mPasswordMaskData->CancelTimer(PasswordMaskData::ReleaseTimer::Yes); |
947 | return NS_ERROR_NOT_AVAILABLE; |
948 | } |
949 | |
950 | Element* rootElement = GetRoot(); |
951 | if (NS_WARN_IF(!rootElement)NS_warn_if_impl(!rootElement, "!rootElement", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 951)) { |
952 | return NS_ERROR_NOT_INITIALIZED; |
953 | } |
954 | Text* text = Text::FromNodeOrNull(rootElement->GetFirstChild()); |
955 | if (!text || !text->Length()) { |
956 | // There is no anonymous text node in the editor. |
957 | return aStart > 0 && aStart != UINT32_MAX(4294967295U) ? NS_ERROR_INVALID_ARG : NS_OK; |
958 | } |
959 | |
960 | if (aStart < UINT32_MAX(4294967295U)) { |
961 | uint32_t valueLength = text->Length(); |
962 | if (aStart >= valueLength) { |
963 | return NS_ERROR_INVALID_ARG; // There is no character can be masked. |
964 | } |
965 | // If aStart is middle of a surrogate pair, expand it to include the |
966 | // preceding high surrogate because the caller may want to show a |
967 | // character before the character at `aStart + 1`. |
968 | const nsTextFragment* textFragment = text->GetText(); |
969 | if (textFragment->IsLowSurrogateFollowingHighSurrogateAt(aStart)) { |
970 | mPasswordMaskData->mUnmaskedStart = aStart - 1; |
971 | // If caller collapses the range, keep it. Otherwise, expand the length. |
972 | if (aLength > 0) { |
973 | ++aLength; |
974 | } |
975 | } else { |
976 | mPasswordMaskData->mUnmaskedStart = aStart; |
977 | } |
978 | mPasswordMaskData->mUnmaskedLength = |
979 | std::min(valueLength - UnmaskedStart(), aLength); |
980 | // If unmasked end is middle of a surrogate pair, expand it to include |
981 | // the following low surrogate because the caller may want to show a |
982 | // character after the character at `aStart + aLength`. |
983 | if (UnmaskedEnd() < valueLength && |
984 | textFragment->IsLowSurrogateFollowingHighSurrogateAt(UnmaskedEnd())) { |
985 | mPasswordMaskData->mUnmaskedLength++; |
986 | } |
987 | // If it's first time to mask the unmasking characters with timer, create |
988 | // the timer now. Then, we'll keep using it for saving the creation cost. |
989 | if (!HasAutoMaskingTimer() && aLength && aTimeout && UnmaskedLength()) { |
990 | mPasswordMaskData->mTimer = NS_NewTimer(); |
991 | } |
992 | } else { |
993 | if (NS_WARN_IF(aLength != 0)NS_warn_if_impl(aLength != 0, "aLength != 0", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 993)) { |
994 | return NS_ERROR_INVALID_ARG; |
995 | } |
996 | mPasswordMaskData->MaskAll(); |
997 | } |
998 | |
999 | // Notify nsTextFrame of this update if the caller wants this to do it. |
1000 | // Only in this case, script may run. |
1001 | if (aNotify) { |
1002 | 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()" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1002); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()" ")"); do { *((volatile int*)__null) = 1002; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
1003 | |
1004 | RefPtr<Document> document = GetDocument(); |
1005 | if (NS_WARN_IF(!document)NS_warn_if_impl(!document, "!document", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1005)) { |
1006 | return NS_ERROR_NOT_INITIALIZED; |
1007 | } |
1008 | // Notify nsTextFrame of masking range change. |
1009 | if (RefPtr<PresShell> presShell = document->GetObservingPresShell()) { |
1010 | nsAutoScriptBlocker blockRunningScript; |
1011 | uint32_t valueLength = text->Length(); |
1012 | CharacterDataChangeInfo changeInfo = {false, 0, valueLength, valueLength, |
1013 | nullptr}; |
1014 | presShell->CharacterDataChanged(text, changeInfo); |
1015 | } |
1016 | |
1017 | // Scroll caret into the view since masking or unmasking character may |
1018 | // move caret to outside of the view. |
1019 | nsresult rv = ScrollSelectionFocusIntoView(); |
1020 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
1021 | NS_WARNING("EditorBase::ScrollSelectionFocusIntoView() failed")NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::ScrollSelectionFocusIntoView() failed" , nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1021); |
1022 | return rv; |
1023 | } |
1024 | } |
1025 | |
1026 | if (!IsAllMasked() && aTimeout != 0) { |
1027 | // Initialize the timer to mask the range automatically. |
1028 | 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()" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1028); AnnotateMozCrashReason("MOZ_ASSERT" "(" "HasAutoMaskingTimer()" ")"); do { *((volatile int*)__null) = 1028; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
1029 | DebugOnly<nsresult> rvIgnored = mPasswordMaskData->mTimer->InitWithCallback( |
1030 | this, aTimeout, nsITimer::TYPE_ONE_SHOT); |
1031 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1032); } } while (false) |
1032 | "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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1032); } } while (false); |
1033 | } |
1034 | |
1035 | return NS_OK; |
1036 | } |
1037 | |
1038 | // static |
1039 | char16_t TextEditor::PasswordMask() { |
1040 | char16_t ret = LookAndFeel::GetPasswordCharacter(); |
1041 | if (!ret) { |
1042 | ret = '*'; |
1043 | } |
1044 | return ret; |
1045 | } |
1046 | |
1047 | MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMPnsresult TextEditor::Notify(nsITimer* aTimer) { |
1048 | // Check whether our text editor's password flag was changed before this |
1049 | // "hide password character" timer actually fires. |
1050 | if (!IsPasswordEditor() || NS_WARN_IF(!mPasswordMaskData)NS_warn_if_impl(!mPasswordMaskData, "!mPasswordMaskData", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1050)) { |
1051 | return NS_OK; |
1052 | } |
1053 | |
1054 | if (IsAllMasked()) { |
1055 | return NS_OK; |
1056 | } |
1057 | |
1058 | AutoEditActionDataSetter editActionData(*this, EditAction::eHidePassword); |
1059 | if (NS_WARN_IF(!editActionData.CanHandle())NS_warn_if_impl(!editActionData.CanHandle(), "!editActionData.CanHandle()" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1059)) { |
1060 | return NS_ERROR_NOT_INITIALIZED; |
1061 | } |
1062 | |
1063 | // Mask all characters. |
1064 | nsresult rv = MaskAllCharactersAndNotify(); |
1065 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1066); } } while (false) |
1066 | "TextEditor::MaskAllCharactersAndNotify() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::MaskAllCharactersAndNotify() failed" , "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1066); } } while (false); |
1067 | |
1068 | if (StaticPrefs::editor_password_testing_mask_delay()) { |
1069 | if (RefPtr<Element> target = GetInputEventTargetElement()) { |
1070 | RefPtr<Document> document = target->OwnerDoc(); |
1071 | DebugOnly<nsresult> rvIgnored = nsContentUtils::DispatchTrustedEvent( |
1072 | document, target, u"MozLastInputMasked"_ns, CanBubble::eYes, |
1073 | Cancelable::eNo); |
1074 | 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)" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1076); } } while (false) |
1075 | "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)" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1076); } } while (false) |
1076 | "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)" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1076); } } while (false); |
1077 | } |
1078 | } |
1079 | |
1080 | return EditorBase::ToGenericNSResult(rv); |
1081 | } |
1082 | |
1083 | NS_IMETHODIMPnsresult TextEditor::GetName(nsACString& aName) { |
1084 | aName.AssignLiteral("TextEditor"); |
1085 | return NS_OK; |
1086 | } |
1087 | |
1088 | void TextEditor::WillDeleteText(uint32_t aCurrentLength, |
1089 | uint32_t aRemoveStartOffset, |
1090 | uint32_t aRemoveLength) { |
1091 | 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()" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1091); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()" ")"); do { *((volatile int*)__null) = 1091; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
1092 | |
1093 | if (!IsPasswordEditor() || NS_WARN_IF(!mPasswordMaskData)NS_warn_if_impl(!mPasswordMaskData, "!mPasswordMaskData", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1093) || IsAllMasked()) { |
1094 | return; |
1095 | } |
1096 | |
1097 | // Adjust unmasked range before deletion since DOM mutation may cause |
1098 | // layout referring the range in old text. |
1099 | |
1100 | // If we need to mask automatically, mask all now. |
1101 | if (IsMaskingPassword()) { |
1102 | DebugOnly<nsresult> rvIgnored = MaskAllCharacters(); |
1103 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1104); } } while (false) |
1104 | "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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1104); } } while (false); |
1105 | return; |
1106 | } |
1107 | |
1108 | if (aRemoveStartOffset < UnmaskedStart()) { |
1109 | // If removing range is before the unmasked range, move it. |
1110 | if (aRemoveStartOffset + aRemoveLength <= UnmaskedStart()) { |
1111 | DebugOnly<nsresult> rvIgnored = |
1112 | SetUnmaskRange(UnmaskedStart() - aRemoveLength, UnmaskedLength()); |
1113 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1114); } } while (false) |
1114 | "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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1114); } } while (false); |
1115 | return; |
1116 | } |
1117 | |
1118 | // If removing range starts before unmasked range, and ends in unmasked |
1119 | // range, move and shrink the range. |
1120 | if (aRemoveStartOffset + aRemoveLength < UnmaskedEnd()) { |
1121 | uint32_t unmaskedLengthInRemovingRange = |
1122 | aRemoveStartOffset + aRemoveLength - UnmaskedStart(); |
1123 | DebugOnly<nsresult> rvIgnored = SetUnmaskRange( |
1124 | aRemoveStartOffset, UnmaskedLength() - unmaskedLengthInRemovingRange); |
1125 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1126); } } while (false) |
1126 | "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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1126); } } while (false); |
1127 | return; |
1128 | } |
1129 | |
1130 | // If removing range includes all unmasked range, collapse it to the |
1131 | // remove offset. |
1132 | DebugOnly<nsresult> rvIgnored = SetUnmaskRange(aRemoveStartOffset, 0); |
1133 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1134); } } while (false) |
1134 | "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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1134); } } while (false); |
1135 | return; |
1136 | } |
1137 | |
1138 | if (aRemoveStartOffset < UnmaskedEnd()) { |
1139 | // If removing range is in unmasked range, shrink the range. |
1140 | if (aRemoveStartOffset + aRemoveLength <= UnmaskedEnd()) { |
1141 | DebugOnly<nsresult> rvIgnored = |
1142 | SetUnmaskRange(UnmaskedStart(), UnmaskedLength() - aRemoveLength); |
1143 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1144); } } while (false) |
1144 | "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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1144); } } while (false); |
1145 | return; |
1146 | } |
1147 | |
1148 | // If removing range starts from unmasked range, and ends after it, |
1149 | // shrink it. |
1150 | DebugOnly<nsresult> rvIgnored = |
1151 | SetUnmaskRange(UnmaskedStart(), aRemoveStartOffset - UnmaskedStart()); |
1152 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1153); } } while (false) |
1153 | "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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1153); } } while (false); |
1154 | return; |
1155 | } |
1156 | |
1157 | // If removing range is after the unmasked range, keep it. |
1158 | } |
1159 | |
1160 | nsresult TextEditor::DidInsertText(uint32_t aNewLength, |
1161 | uint32_t aInsertedOffset, |
1162 | uint32_t aInsertedLength) { |
1163 | 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()" , "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1163); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()" ")"); do { *((volatile int*)__null) = 1163; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
1164 | |
1165 | if (!IsPasswordEditor() || NS_WARN_IF(!mPasswordMaskData)NS_warn_if_impl(!mPasswordMaskData, "!mPasswordMaskData", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1165) || IsAllMasked()) { |
1166 | return NS_OK; |
1167 | } |
1168 | |
1169 | if (IsMaskingPassword()) { |
1170 | // If we need to mask password, mask all right now. |
1171 | nsresult rv = MaskAllCharactersAndNotify(); |
1172 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1173); } } while (false) |
1173 | "TextEditor::MaskAllCharacters() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::MaskAllCharacters() failed" , "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1173); } } while (false); |
1174 | return rv; |
1175 | } |
1176 | |
1177 | if (aInsertedOffset < UnmaskedStart()) { |
1178 | // If insertion point is before unmasked range, expand the unmasked range |
1179 | // to include the new text. |
1180 | nsresult rv = SetUnmaskRangeAndNotify( |
1181 | aInsertedOffset, UnmaskedEnd() + aInsertedLength - aInsertedOffset); |
1182 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1183); } } while (false) |
1183 | "TextEditor::SetUnmaskRangeAndNotify() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed" , "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1183); } } while (false); |
1184 | return rv; |
1185 | } |
1186 | |
1187 | if (aInsertedOffset <= UnmaskedEnd()) { |
1188 | // If insertion point is in unmasked range, unmask new text. |
1189 | nsresult rv = SetUnmaskRangeAndNotify(UnmaskedStart(), |
1190 | UnmaskedLength() + aInsertedLength); |
1191 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1192); } } while (false) |
1192 | "TextEditor::SetUnmaskRangeAndNotify() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed" , "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1192); } } while (false); |
1193 | return rv; |
1194 | } |
1195 | |
1196 | // If insertion point is after unmasked range, extend the unmask range to |
1197 | // include the new text. |
1198 | nsresult rv = SetUnmaskRangeAndNotify( |
1199 | UnmaskedStart(), aInsertedOffset + aInsertedLength - UnmaskedStart()); |
1200 | 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)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1201); } } while (false) |
1201 | "TextEditor::SetUnmaskRangeAndNotify() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1 ))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed" , "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp" , 1201); } } while (false); |
1202 | return rv; |
1203 | } |
1204 | |
1205 | } // namespace mozilla |