TextEditor.h (25170B)
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 #ifndef mozilla_TextEditor_h 7 #define mozilla_TextEditor_h 8 9 #include "mozilla/EditorBase.h" 10 #include "mozilla/EditorForwards.h" 11 #include "mozilla/TextControlState.h" 12 #include "mozilla/UniquePtr.h" 13 14 #include "nsCOMPtr.h" 15 #include "nsCycleCollectionParticipant.h" 16 #include "nsIClipboard.h" 17 #include "nsINamed.h" 18 #include "nsISupportsImpl.h" 19 #include "nsITimer.h" 20 #include "nscore.h" 21 22 class nsIContent; 23 class nsIDocumentEncoder; 24 class nsIOutputStream; 25 class nsIPrincipal; 26 class nsISelectionController; 27 class nsITransferable; 28 29 namespace mozilla { 30 namespace dom { 31 class Selection; 32 } // namespace dom 33 34 /** 35 * The text editor implementation. 36 * Use to edit text document represented as a DOM tree. 37 */ 38 class TextEditor final : public EditorBase, 39 public nsITimerCallback, 40 public nsINamed { 41 public: 42 /**************************************************************************** 43 * NOTE: DO NOT MAKE YOUR NEW METHODS PUBLIC IF they are called by other 44 * classes under libeditor except EditorEventListener and 45 * HTMLEditorEventListener because each public method which may fire 46 * eEditorInput event will need to instantiate new stack class for 47 * managing input type value of eEditorInput and cache some objects 48 * for smarter handling. In other words, when you add new root 49 * method to edit the DOM tree, you can make your new method public. 50 ****************************************************************************/ 51 52 NS_DECL_ISUPPORTS_INHERITED 53 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TextEditor, EditorBase) 54 55 TextEditor(); 56 57 /** 58 * Note that TextEditor::Init() shouldn't cause running script synchronously. 59 * So, `MOZ_CAN_RUN_SCRIPT_BOUNDARY` is safe here. 60 * 61 * @param aDocument The document which aAnonymousDivElement belongs to. 62 * @param aAnonymousDivElement 63 * The root editable element for this editor. 64 * @param aSelectionController 65 * The selection controller for independent selections 66 * in the `<input>` or `<textarea>` element. 67 * @param aFlags Some of nsIEditor::eEditor*Mask flags. 68 * @param aPasswordMaskData 69 * Set to an instance only when aFlags includes 70 * `nsIEditor::eEditorPasswordMask`. Otherwise, must be 71 * `nullptr`. 72 */ 73 MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult 74 Init(Document& aDocument, Element& aAnonymousDivElement, 75 nsISelectionController& aSelectionController, uint32_t aFlags, 76 UniquePtr<PasswordMaskData>&& aPasswordMaskData); 77 78 /** 79 * PostCreate() should be called after Init, and is the time that the editor 80 * tells its documentStateObservers that the document has been created. 81 * Note that TextEditor::PostCreate() shouldn't cause running script 82 * synchronously. So, `MOZ_CAN_RUN_SCRIPT_BOUNDARY` is safe here. 83 */ 84 MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult PostCreate(); 85 86 /** 87 * This method re-initializes the selection and caret state that are for 88 * current editor state. When editor session is destroyed, it always reset 89 * selection state even if this has no focus. So if destroying editor, 90 * we have to call this method for focused editor to set selection state. 91 */ 92 MOZ_CAN_RUN_SCRIPT void ReinitializeSelection(Element& aElement); 93 94 /** 95 * PreDestroy() is called before the editor goes away, and gives the editor a 96 * chance to tell its documentStateObservers that the document is going away. 97 * Note that TextEditor::PreDestroy() shouldn't cause running script 98 * synchronously. So, `MOZ_CAN_RUN_SCRIPT_BOUNDARY` is safe here. 99 */ 100 [[nodiscard]] MOZ_CAN_RUN_SCRIPT_BOUNDARY UniquePtr<PasswordMaskData> 101 PreDestroy(); 102 103 static TextEditor* GetFrom(nsIEditor* aEditor) { 104 return aEditor ? aEditor->GetAsTextEditor() : nullptr; 105 } 106 static const TextEditor* GetFrom(const nsIEditor* aEditor) { 107 return aEditor ? aEditor->GetAsTextEditor() : nullptr; 108 } 109 110 /** 111 * Helper method for `AppendString()` and `AppendSubString()`. This should 112 * be called only when `aText` is in a password field. This method masks 113 * A part of or all of `aText` (`aStartOffsetInText` and later) should've 114 * been copied (appended) to `aString`. `aStartOffsetInString` is where 115 * the password was appended into `aString`. 116 */ 117 static void MaskString(nsString& aString, const dom::Text& aTextNode, 118 uint32_t aStartOffsetInString, 119 uint32_t aStartOffsetInText); 120 121 NS_DECL_NSITIMERCALLBACK 122 NS_DECL_NSINAMED 123 124 // Overrides of nsIEditor 125 MOZ_CAN_RUN_SCRIPT NS_IMETHOD EndOfDocument() final; 126 MOZ_CAN_RUN_SCRIPT NS_IMETHOD InsertLineBreak() final; 127 NS_IMETHOD GetTextLength(uint32_t* aCount) final; 128 129 // Shouldn't be used internally, but we need these using declarations for 130 // avoiding warnings of clang. 131 using EditorBase::CanCopy; 132 using EditorBase::CanCut; 133 using EditorBase::CanPaste; 134 135 // Overrides of EditorBase 136 bool IsEmpty() const final; 137 138 bool CanPaste(nsIClipboard::ClipboardType aClipboardType) const final; 139 140 bool CanPasteTransferable(nsITransferable* aTransferable) final; 141 142 MOZ_CAN_RUN_SCRIPT nsresult 143 HandleKeyPressEvent(WidgetKeyboardEvent* aKeyboardEvent) final; 144 145 dom::EventTarget* GetDOMEventTarget() const final; 146 147 MOZ_CAN_RUN_SCRIPT nsresult 148 OnFocus(const nsINode& aOriginalEventTargetNode) final; 149 150 nsresult OnBlur(const dom::EventTarget* aEventTarget) final; 151 152 [[nodiscard]] Result<widget::IMEState, nsresult> GetPreferredIMEState() 153 const final; 154 155 /** 156 * The maximum number of characters allowed. 157 * default: -1 (unlimited). 158 */ 159 int32_t MaxTextLength() const { return mMaxTextLength; } 160 void SetMaxTextLength(int32_t aLength) { mMaxTextLength = aLength; } 161 162 /** 163 * This updates the wrap width used for initializing a document encoder within 164 * a call of EditorBase::GetAndInitDocEncoder(). 165 */ 166 void SetWrapColumn(int32_t aWrapColumn) { mWrapColumn = aWrapColumn; } 167 168 /** 169 * Replace existed string with a string. 170 * This is fast path to replace all string when using single line control. 171 * 172 * @param aString The string to be set 173 * @param aAllowBeforeInputEventCancelable 174 * Whether `beforeinput` event which will be 175 * dispatched for this can be cancelable or not. 176 * @param aPrincipal Set subject principal if it may be called by 177 * JS. If set to nullptr, will be treated as 178 * called by system. 179 */ 180 MOZ_CAN_RUN_SCRIPT nsresult SetTextAsAction( 181 const nsAString& aString, 182 AllowBeforeInputEventCancelable aAllowBeforeInputEventCancelable, 183 nsIPrincipal* aPrincipal = nullptr); 184 185 MOZ_CAN_RUN_SCRIPT nsresult 186 InsertLineBreakAsAction(nsIPrincipal* aPrincipal = nullptr) final; 187 188 /** 189 * ComputeTextValue() computes plaintext value of this editor. 190 */ 191 nsresult ComputeTextValue(nsAString&) const; 192 193 /** 194 * The following methods are available only when the instance is a password 195 * editor. They return whether there is unmasked range or not and range 196 * start and length. 197 */ 198 MOZ_ALWAYS_INLINE bool IsAllMasked() const { 199 MOZ_ASSERT(IsPasswordEditor()); 200 return !mPasswordMaskData || mPasswordMaskData->IsAllMasked(); 201 } 202 MOZ_ALWAYS_INLINE uint32_t UnmaskedStart() const { 203 MOZ_ASSERT(IsPasswordEditor()); 204 return mPasswordMaskData ? mPasswordMaskData->mUnmaskedStart : UINT32_MAX; 205 } 206 MOZ_ALWAYS_INLINE uint32_t UnmaskedLength() const { 207 MOZ_ASSERT(IsPasswordEditor()); 208 return mPasswordMaskData ? mPasswordMaskData->mUnmaskedLength : 0; 209 } 210 MOZ_ALWAYS_INLINE uint32_t UnmaskedEnd() const { 211 MOZ_ASSERT(IsPasswordEditor()); 212 return mPasswordMaskData ? mPasswordMaskData->UnmaskedEnd() : UINT32_MAX; 213 } 214 215 /** 216 * IsMaskingPassword() returns false when the last caller of `Unmask()` 217 * didn't want to mask again automatically. When this returns true, user 218 * input causes masking the password even before timed-out. 219 */ 220 bool IsMaskingPassword() const { 221 MOZ_ASSERT(IsPasswordEditor()); 222 return mPasswordMaskData && mPasswordMaskData->mIsMaskingPassword; 223 } 224 225 /** 226 * PasswordMask() returns a character which masks each character in password 227 * fields. 228 */ 229 static char16_t PasswordMask(); 230 231 /** 232 * If you want to prevent to echo password temporarily, use the following 233 * methods. 234 */ 235 bool EchoingPasswordPrevented() const { 236 return mPasswordMaskData && mPasswordMaskData->mEchoingPasswordPrevented; 237 } 238 void PreventToEchoPassword() { 239 if (mPasswordMaskData) { 240 mPasswordMaskData->mEchoingPasswordPrevented = true; 241 } 242 } 243 void AllowToEchoPassword() { 244 if (mPasswordMaskData) { 245 mPasswordMaskData->mEchoingPasswordPrevented = false; 246 } 247 } 248 249 /** 250 * Return the `Text` node in the anonymous <div>. Note that the anonymous 251 * <div> can have only one `Text` for the storage of the value of this editor. 252 */ 253 enum class IgnoreTextNodeCache : bool { No, Yes }; 254 dom::Text* GetTextNode( 255 IgnoreTextNodeCache aIgnoreTextNodeCache = IgnoreTextNodeCache::No) { 256 if (aIgnoreTextNodeCache == IgnoreTextNodeCache::No) { 257 if (Text* const cachedTextNode = GetCachedTextNode()) { 258 return cachedTextNode; 259 } 260 } 261 MOZ_DIAGNOSTIC_ASSERT(GetRoot()); 262 MOZ_DIAGNOSTIC_ASSERT(GetRoot()->GetFirstChild()); 263 MOZ_DIAGNOSTIC_ASSERT(GetRoot()->GetFirstChild()->IsText()); 264 if (MOZ_UNLIKELY(!GetRoot() || !GetRoot()->GetFirstChild())) { 265 return nullptr; 266 } 267 return GetRoot()->GetFirstChild()->GetAsText(); 268 } 269 const dom::Text* GetTextNode(IgnoreTextNodeCache aIgnoreTextNodeCache = 270 IgnoreTextNodeCache::No) const { 271 return const_cast<TextEditor*>(this)->GetTextNode(aIgnoreTextNodeCache); 272 } 273 274 protected: // May be called by friends. 275 /**************************************************************************** 276 * Some friend classes are allowed to call the following protected methods. 277 * However, those methods won't prepare caches of some objects which are 278 * necessary for them. So, if you call them from friend classes, you need 279 * to make sure that AutoEditActionDataSetter is created. 280 ****************************************************************************/ 281 282 // Overrides of EditorBase 283 MOZ_CAN_RUN_SCRIPT nsresult RemoveAttributeOrEquivalent( 284 Element* aElement, nsAtom* aAttribute, bool aSuppressTransaction) final; 285 MOZ_CAN_RUN_SCRIPT nsresult SetAttributeOrEquivalent( 286 Element* aElement, nsAtom* aAttribute, const nsAString& aValue, 287 bool aSuppressTransaction) final; 288 using EditorBase::RemoveAttributeOrEquivalent; 289 using EditorBase::SetAttributeOrEquivalent; 290 291 /** 292 * FindBetterInsertionPoint() tries to look for better insertion point which 293 * is typically the nearest text node and offset in it. 294 * 295 * @param aPoint Insertion point which the callers found. 296 * @return Better insertion point if there is. If not returns 297 * same point as aPoint. 298 */ 299 template <typename EditorDOMPointType> 300 EditorDOMPointType FindBetterInsertionPoint( 301 const EditorDOMPointType& aPoint) const; 302 303 /** 304 * InsertLineBreakAsSubAction() inserts a line break. 305 */ 306 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult InsertLineBreakAsSubAction(); 307 308 /** 309 * Replace existed string with aString. Caller must guarantee that there 310 * is a placeholder transaction which will have the transaction. 311 * 312 * @ param aString The string to be set. 313 */ 314 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult 315 SetTextAsSubAction(const nsAString& aString); 316 317 /** 318 * MaybeDoAutoPasswordMasking() may mask password if we're doing auto-masking. 319 */ 320 void MaybeDoAutoPasswordMasking() { 321 if (IsPasswordEditor() && IsMaskingPassword()) { 322 MaskAllCharacters(); 323 } 324 } 325 326 /** 327 * SetUnmaskRange() is available only when the instance is a password 328 * editor. This just updates unmask range. I.e., caller needs to 329 * guarantee to update the layout. 330 * 331 * @param aStart First index to show the character. 332 * If aLength is 0, this value is ignored. 333 * @param aLength Optional, Length to show characters. 334 * If UINT32_MAX, it means unmasking all characters after 335 * aStart. 336 * If 0, it means that masking all characters. 337 * @param aTimeout Optional, specify milliseconds to hide the unmasked 338 * characters after this call. 339 * If 0, it means this won't mask the characters 340 * automatically. 341 * If aLength is 0, this value is ignored. 342 */ 343 MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult SetUnmaskRange( 344 uint32_t aStart, uint32_t aLength = UINT32_MAX, uint32_t aTimeout = 0) { 345 return SetUnmaskRangeInternal(aStart, aLength, aTimeout, false, false); 346 } 347 348 /** 349 * SetUnmaskRangeAndNotify() is available only when the instance is a 350 * password editor. This updates unmask range and notifying the text frame 351 * to update the visible characters. 352 * 353 * @param aStart First index to show the character. 354 * If UINT32_MAX, it means masking all. 355 * @param aLength Optional, Length to show characters. 356 * If UINT32_MAX, it means unmasking all characters after 357 * aStart. 358 * @param aTimeout Optional, specify milliseconds to hide the unmasked 359 * characters after this call. 360 * If 0, it means this won't mask the characters 361 * automatically. 362 * If aLength is 0, this value is ignored. 363 */ 364 MOZ_CAN_RUN_SCRIPT nsresult SetUnmaskRangeAndNotify( 365 uint32_t aStart, uint32_t aLength = UINT32_MAX, uint32_t aTimeout = 0) { 366 return SetUnmaskRangeInternal(aStart, aLength, aTimeout, true, false); 367 } 368 369 /** 370 * MaskAllCharacters() is an alias of SetUnmaskRange() to mask all characters. 371 * In other words, this removes existing unmask range. 372 * After this is called, TextEditor starts masking password automatically. 373 */ 374 MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult MaskAllCharacters() { 375 if (!mPasswordMaskData) { 376 return NS_OK; // Already we don't have masked range data. 377 } 378 return SetUnmaskRangeInternal(UINT32_MAX, 0, 0, false, true); 379 } 380 381 /** 382 * MaskAllCharactersAndNotify() is an alias of SetUnmaskRangeAndNotify() to 383 * mask all characters and notifies the text frame. In other words, this 384 * removes existing unmask range. 385 * After this is called, TextEditor starts masking password automatically. 386 */ 387 MOZ_CAN_RUN_SCRIPT nsresult MaskAllCharactersAndNotify() { 388 return SetUnmaskRangeInternal(UINT32_MAX, 0, 0, true, true); 389 } 390 391 /** 392 * WillDeleteText() is called before `DeleteTextTransaction` or something 393 * removes text in a text node. Note that this won't be called if the 394 * instance is `HTMLEditor` since supporting it makes the code complicated 395 * due to mutation events. 396 * 397 * @param aCurrentLength Current text length of the node. 398 * @param aRemoveStartOffset Start offset of the range to be removed. 399 * @param aRemoveLength Length of the range to be removed. 400 */ 401 void WillDeleteText(uint32_t aCurrentLength, uint32_t aRemoveStartOffset, 402 uint32_t aRemoveLength); 403 404 /** 405 * DidInsertText() is called after `InsertTextTransaction` or something 406 * inserts text into a text node. Note that this won't be called if the 407 * instance is `HTMLEditor` since supporting it makes the code complicated 408 * due to mutatione events. 409 * 410 * @param aNewLength New text length after the insertion. 411 * @param aInsertedOffset Start offset of the inserted text. 412 * @param aInsertedLength Length of the inserted text. 413 * @return NS_OK or NS_ERROR_EDITOR_DESTROYED. 414 */ 415 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult DidInsertText( 416 uint32_t aNewLength, uint32_t aInsertedOffset, uint32_t aInsertedLength); 417 418 protected: // edit sub-action handler 419 /** 420 * MaybeTruncateInsertionStringForMaxLength() truncates aInsertionString to 421 * `maxlength` if it was not pasted in by the user. 422 * 423 * @param aInsertionString [in/out] New insertion string. This is 424 * truncated to `maxlength` if it was not pasted in 425 * by the user. 426 * @return If aInsertionString is truncated, it returns "as 427 * handled", else "as ignored." 428 */ 429 Result<EditActionResult, nsresult> MaybeTruncateInsertionStringForMaxLength( 430 nsAString& aInsertionString); 431 432 /** 433 * InsertLineFeedCharacterAtSelection() inserts a linefeed character at 434 * selection. 435 */ 436 [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<EditActionResult, nsresult> 437 InsertLineFeedCharacterAtSelection(); 438 439 /** 440 * Handles the newline characters according to the default system prefs 441 * (editor.singleLine.pasteNewlines). 442 * Each value means: 443 * nsIEditor::eNewlinesReplaceWithSpaces (2, Firefox default): 444 * replace newlines with spaces. 445 * nsIEditor::eNewlinesStrip (3): 446 * remove newlines from the string. 447 * nsIEditor::eNewlinesReplaceWithCommas (4, Thunderbird default): 448 * replace newlines with commas. 449 * nsIEditor::eNewlinesStripSurroundingWhitespace (5): 450 * collapse newlines and surrounding white-space characters and 451 * remove them from the string. 452 * nsIEditor::eNewlinesPasteIntact (0): 453 * only remove the leading and trailing newlines. 454 * nsIEditor::eNewlinesPasteToFirst (1) or any other value: 455 * remove the first newline and all characters following it. 456 * 457 * @param aString the string to be modified in place. 458 */ 459 void HandleNewLinesInStringForSingleLineEditor(nsString& aString) const; 460 461 [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<EditActionResult, nsresult> 462 HandleInsertText(const nsAString& aInsertionString, 463 InsertTextFor aPurpose) final; 464 465 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult InsertDroppedDataTransferAsAction( 466 AutoEditActionDataSetter& aEditActionData, DataTransfer& aDataTransfer, 467 const EditorDOMPoint& aDroppedAt, nsIPrincipal* aSourcePrincipal) final; 468 469 /** 470 * HandleDeleteSelectionInternal() is a helper method of 471 * HandleDeleteSelection(). Must be called only when the instance is 472 * TextEditor. 473 * NOTE: This method creates SelectionBatcher. Therefore, each caller 474 * needs to check if the editor is still available even if this returns 475 * NS_OK. 476 */ 477 [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<EditActionResult, nsresult> 478 HandleDeleteSelectionInternal(nsIEditor::EDirection aDirectionAndAmount, 479 nsIEditor::EStripWrappers aStripWrappers); 480 481 /** 482 * This method handles "delete selection" commands. 483 * 484 * @param aDirectionAndAmount Direction of the deletion. 485 * @param aStripWrappers Must be nsIEditor::eNoStrip. 486 */ 487 [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<EditActionResult, nsresult> 488 HandleDeleteSelection(nsIEditor::EDirection aDirectionAndAmount, 489 nsIEditor::EStripWrappers aStripWrappers) final; 490 491 /** 492 * ComputeValueFromTextNodeAndBRElement() tries to compute "value" of 493 * this editor content only with text nodes and `<br>` elements. 494 * If this succeeds to compute the value, it's returned with aValue and 495 * the result is marked as "handled". Otherwise, the caller needs to 496 * compute it with another way. 497 */ 498 Result<EditActionResult, nsresult> ComputeValueFromTextNodeAndBRElement( 499 nsAString& aValue) const; 500 501 /** 502 * SetTextWithoutTransaction() is optimized method to set `<input>.value` 503 * and `<textarea>.value` to aValue without transaction. This must be 504 * called only when it's not `HTMLEditor` and undo/redo is disabled. 505 */ 506 [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<EditActionResult, nsresult> 507 SetTextWithoutTransaction(const nsAString& aValue); 508 509 /** 510 * EnsureCaretNotAtEndOfTextNode() collapses selection at the padding `<br>` 511 * element (i.e., container becomes the anonymous `<div>` element) if 512 * `Selection` is at end of the text node. 513 */ 514 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult EnsureCaretNotAtEndOfTextNode(); 515 516 protected: // Called by helper classes. 517 MOZ_CAN_RUN_SCRIPT void OnStartToHandleTopLevelEditSubAction( 518 EditSubAction aTopLevelEditSubAction, 519 nsIEditor::EDirection aDirectionOfTopLevelEditSubAction, 520 ErrorResult& aRv) final; 521 MOZ_CAN_RUN_SCRIPT nsresult OnEndHandlingTopLevelEditSubAction() final; 522 523 /** 524 * HandleInlineSpellCheckAfterEdit() does spell-check after handling top level 525 * edit subaction. 526 */ 527 nsresult HandleInlineSpellCheckAfterEdit() { 528 MOZ_ASSERT(IsEditActionDataAvailable()); 529 if (!GetSpellCheckRestartPoint().IsSet()) { 530 return NS_OK; // Maybe being initialized. 531 } 532 nsresult rv = HandleInlineSpellCheck(GetSpellCheckRestartPoint()); 533 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to spellcheck"); 534 ClearSpellCheckRestartPoint(); 535 return rv; 536 } 537 538 protected: // Shouldn't be used by friend classes 539 virtual ~TextEditor(); 540 541 /** 542 * CanEchoPasswordNow() returns true if currently we can echo password. 543 * If it's direct user input such as pasting or dropping text, this 544 * returns false even if we may echo password. 545 */ 546 bool CanEchoPasswordNow() const; 547 548 /** 549 * InitEditorContentAndSelection() may insert a padding `<br>` element for 550 * if it's required in the anonymous `<div>` element or `<body>` element and 551 * collapse selection at the end if there is no selection ranges. 552 */ 553 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult InitEditorContentAndSelection(); 554 555 /** 556 * Collapse `Selection` to end of the text node in the anonymous <div> 557 * element. 558 */ 559 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult CollapseSelectionToEndOfTextNode(); 560 561 /** 562 * Make the given selection span the entire document. 563 */ 564 MOZ_CAN_RUN_SCRIPT nsresult SelectEntireDocument() final; 565 566 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult 567 HandlePaste(AutoEditActionDataSetter& aEditActionData, 568 nsIClipboard::ClipboardType aClipboardType, 569 DataTransfer* aDataTransfer) final; 570 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult 571 HandlePasteAsQuotation(AutoEditActionDataSetter& aEditActionData, 572 nsIClipboard::ClipboardType aClipboardType, 573 DataTransfer* aDataTransfer) final; 574 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult 575 HandlePasteTransferable(AutoEditActionDataSetter& aEditActionData, 576 nsITransferable& aTransferable) final; 577 578 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult 579 InsertWithQuotationsAsSubAction(const nsAString& aQuotedText) final; 580 581 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult 582 InsertTextFromTransferable(nsITransferable* transferable); 583 584 bool IsCopyToClipboardAllowedInternal() const final; 585 586 already_AddRefed<Element> GetInputEventTargetElement() const final; 587 588 /** 589 * See SetUnmaskRange() and SetUnmaskRangeAndNotify() for the detail. 590 * 591 * @param aForceStartMasking If true, forcibly starts masking. This should 592 * be used only when `nsIEditor::Mask()` is called. 593 */ 594 MOZ_CAN_RUN_SCRIPT nsresult SetUnmaskRangeInternal(uint32_t aStart, 595 uint32_t aLength, 596 uint32_t aTimeout, 597 bool aNotify, 598 bool aForceStartMasking); 599 600 MOZ_ALWAYS_INLINE bool HasAutoMaskingTimer() const { 601 return mPasswordMaskData && mPasswordMaskData->mTimer; 602 } 603 604 protected: 605 UniquePtr<PasswordMaskData> mPasswordMaskData; 606 607 int32_t mMaxTextLength = -1; 608 609 friend class AutoClonedSelectionRangeArray; // FindBetterInsertionPoint 610 friend class DeleteNodeTransaction; 611 friend class EditorBase; 612 friend class InsertNodeTransaction; 613 }; 614 615 } // namespace mozilla 616 617 mozilla::TextEditor* nsIEditor::AsTextEditor() { 618 MOZ_DIAGNOSTIC_ASSERT(IsTextEditor()); 619 return static_cast<mozilla::TextEditor*>(this); 620 } 621 622 const mozilla::TextEditor* nsIEditor::AsTextEditor() const { 623 MOZ_DIAGNOSTIC_ASSERT(IsTextEditor()); 624 return static_cast<const mozilla::TextEditor*>(this); 625 } 626 627 mozilla::TextEditor* nsIEditor::GetAsTextEditor() { 628 return AsEditorBase()->IsTextEditor() ? AsTextEditor() : nullptr; 629 } 630 631 const mozilla::TextEditor* nsIEditor::GetAsTextEditor() const { 632 return AsEditorBase()->IsTextEditor() ? AsTextEditor() : nullptr; 633 } 634 635 #endif // #ifndef mozilla_TextEditor_h