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