Bug Summary

File:root/firefox-clang/editor/libeditor/TextEditor.cpp
Warning:line 571, column 12
Value stored to 'rv' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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