File: textfield.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (979 lines) | stat: -rw-r--r-- 39,176 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_H_
#define UI_VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_H_

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <utility>

#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/ime/text_edit_commands.h"
#include "ui/base/ime/text_input_client.h"
#include "ui/base/ime/text_input_type.h"
#include "ui/base/mojom/menu_source_type.mojom-forward.h"
#include "ui/compositor/layer_tree_owner.h"
#include "ui/events/gesture_event_details.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/gfx/font_list.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/range/range.h"
#include "ui/gfx/selection_model.h"
#include "ui/gfx/text_constants.h"
#include "ui/menus/simple_menu_model.h"
#include "ui/touch_selection/touch_editing_controller.h"
#include "ui/touch_selection/touch_selection_metrics.h"
#include "ui/views/buildflags.h"
#include "ui/views/context_menu_controller.h"
#include "ui/views/controls/textfield/textfield_model.h"
#include "ui/views/drag_controller.h"
#include "ui/views/metadata/view_factory.h"
#include "ui/views/selection_controller.h"
#include "ui/views/selection_controller_delegate.h"
#include "ui/views/touchui/touch_selection_controller.h"
#include "ui/views/view.h"
#include "ui/views/view_observer.h"
#include "ui/views/word_lookup_client.h"

#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#include <vector>
#endif

namespace base {
class TimeDelta;
}

#if BUILDFLAG(IS_MAC)
namespace ui {
class ScopedPasswordInputEnabler;
}
#endif  // BUILDFLAG(IS_MAC)

namespace views {

class MenuRunner;
class TextfieldController;
class ViewsTextServicesContextMenu;

// A views/skia textfield implementation. No platform-specific code is used.
class VIEWS_EXPORT Textfield : public View,
                               public TextfieldModel::Delegate,
                               public ContextMenuController,
                               public DragController,
                               public WordLookupClient,
                               public SelectionControllerDelegate,
                               public ui::TouchEditable,
                               public ui::TextInputClient,
                               public views::ViewObserver {
  METADATA_HEADER(Textfield, View)

 public:
  enum MenuCommands {
    kUndo = kLastTouchEditableCommandId + 1,
    kDelete,
    kLastCommandId = kDelete,
  };

#if BUILDFLAG(IS_MAC)
  static constexpr gfx::SelectionBehavior kLineSelectionBehavior =
      gfx::SELECTION_EXTEND;
  static constexpr gfx::SelectionBehavior kWordSelectionBehavior =
      gfx::SELECTION_CARET;
  static constexpr gfx::SelectionBehavior kMoveParagraphSelectionBehavior =
      gfx::SELECTION_CARET;
  static constexpr gfx::SelectionBehavior kPageSelectionBehavior =
      gfx::SELECTION_EXTEND;
#else
  static constexpr gfx::SelectionBehavior kLineSelectionBehavior =
      gfx::SELECTION_RETAIN;
  static constexpr gfx::SelectionBehavior kWordSelectionBehavior =
      gfx::SELECTION_RETAIN;
  static constexpr gfx::SelectionBehavior kMoveParagraphSelectionBehavior =
      gfx::SELECTION_RETAIN;
  static constexpr gfx::SelectionBehavior kPageSelectionBehavior =
      gfx::SELECTION_RETAIN;
#endif

  // Pair of |text_changed|, |cursor_changed|.
  using EditCommandResult = std::pair<bool, bool>;

  // Returns the text cursor blink time, or 0 for no blinking.
  static base::TimeDelta GetCaretBlinkInterval();

  // Returns the default FontList used by all textfields.
  static const gfx::FontList& GetDefaultFontList();

  Textfield();
  Textfield(const Textfield&) = delete;
  Textfield& operator=(const Textfield&) = delete;
  ~Textfield() override;

  // Set the controller for this textfield.
  void set_controller(TextfieldController* controller) {
    controller_ = controller;
  }

  // TODD (kylixrd): Remove set_controller and refactor codebase.
  void SetController(TextfieldController* controller);

  // Gets/Sets whether or not the Textfield is read-only.
  bool GetReadOnly() const;
  void SetReadOnly(bool read_only);

  // Sets the input type; displays only asterisks for TEXT_INPUT_TYPE_PASSWORD.
  // Other types are not no-op.
  // TODO(crbug.com/419034676): restrict inputs appropriately for the type.
  // e.g. TEXT_INPUT_TYPE_NUMBER should take only numbers.
  void SetTextInputType(ui::TextInputType type);

  // Sets the input flags so that the system input methods can turn on/off some
  // features. The flags is the bit map of ui::TextInputFlags.
  void SetTextInputFlags(int flags);

  // Gets the text for the Textfield.
  // NOTE: Call sites should take care to not reveal the text for a password
  // textfield.
  std::u16string_view GetText() const;

  // Sets the text currently displayed in the Textfield.
  void SetText(std::u16string_view new_text);

  // Sets the text currently displayed in the Textfield and the cursor position.
  // Does not fire notifications about the caret bounds changing. This is
  // intended for low-level use, where callers need precise control over what
  // notifications are fired when, e.g. to avoid firing duplicate accessibility
  // notifications, which can cause issues for accessibility tools. Updating the
  // selection or cursor separately afterwards does not update the edit history,
  // i.e. the cursor position after redoing this change will be determined by
  // |cursor_position| and not by subsequent calls to e.g. SetSelectedRange().
  void SetTextWithoutCaretBoundsChangeNotification(std::u16string_view text,
                                                   size_t cursor_position);

  // Scrolls all of |scroll_positions| into view, if possible. For each
  // position, the minimum scrolling change necessary to just bring the position
  // into view is applied. |scroll_positions| are applied in order, so later
  // positions will have priority over earlier positions if not all can be
  // visible simultaneously.
  // NOTE: Unlike MoveCursorTo(), this will not fire any accessibility
  // notifications.
  void Scroll(const std::vector<size_t>& scroll_positions);

  // Appends the given string to the previously-existing text in the field.
  void AppendText(const std::u16string& new_text);

  // Inserts |new_text| at the cursor position, replacing any selected text.
  // This method is used to handle user input via paths Textfield doesn't
  // normally handle, so it calls UpdateAfterChange() and notifies observers of
  // changes.
  void InsertOrReplaceText(const std::u16string& new_text);

  // Returns the text that is currently selected.
  // NOTE: Call sites should take care to not reveal the text for a password
  // textfield.
  std::u16string_view GetSelectedText() const;

  // Select the entire text range. If |reversed| is true, the range will end at
  // the logical beginning of the text; this generally shows the leading portion
  // of text that overflows its display area.
  void SelectAll(bool reversed);

  // Selects the word at which the cursor is currently positioned. If there is a
  // non-empty selection, the selection bounds are extended to their nearest
  // word boundaries.
  void SelectWord();

  // A convenience method to select the word closest to |point|.
  void SelectWordAt(const gfx::Point& point);

  // Clears the selection within the edit field and sets the caret to the end.
  void ClearSelection();

  // Checks if there is any selected text. |primary_only| indicates whether
  // secondary selections should also be considered.
  bool HasSelection(bool primary_only = false) const;

  // Gets/sets the text color to be used when painting the Textfield.
  SkColor GetTextColor() const;
  void SetTextColor(SkColor color);

  // Gets/sets the background color to be used when painting the Textfield.
  SkColor GetBackgroundColor() const;
  void SetBackgroundColor(SkColor color);

  // Getter/Setter methods for `is_background_enabled_` which controls
  // whether a background is drawn for this view.
  bool GetBackgroundEnabled() const;
  void SetBackgroundEnabled(bool enabled);

  // Gets/sets the selection text color to be used when painting the Textfield.
  SkColor GetSelectionTextColor() const;
  void SetSelectionTextColor(SkColor color);

  // Gets/sets the selection background color to be used when painting the
  // Textfield.
  SkColor GetSelectionBackgroundColor() const;
  void SetSelectionBackgroundColor(SkColor color);

  // Gets/Sets whether or not the cursor is enabled.
  bool GetCursorEnabled() const;
  void SetCursorEnabled(bool enabled);

  // Gets/Sets the fonts used when rendering the text within the Textfield.
  const gfx::FontList& GetFontList() const;
  void SetFontList(const gfx::FontList& font_list);

  // Sets the default width of the text control. See default_width_in_chars_.
  void SetDefaultWidthInChars(int default_width);

  // Sets the minimum width of the text control. See minimum_width_in_chars_.
  void SetMinimumWidthInChars(int minimum_width);

  // Gets/Sets the text to display when empty.
  std::u16string_view GetPlaceholderText() const;
  void SetPlaceholderText(std::u16string_view text);

  void set_placeholder_text_color(SkColor color) {
    placeholder_text_color_ = color;
  }

  void set_placeholder_font_list(const gfx::FontList& font_list) {
    placeholder_font_list_ = font_list;
  }

  int placeholder_text_draw_flags() const {
    return placeholder_text_draw_flags_;
  }
  void set_placeholder_text_draw_flags(int flags) {
    placeholder_text_draw_flags_ = flags;
  }

  bool force_text_directionality() const { return force_text_directionality_; }
  void set_force_text_directionality(bool force) {
    force_text_directionality_ = force;
  }

  bool drop_cursor_visible() const { return drop_cursor_visible_; }

  // Gets/Sets whether to indicate the textfield has invalid content.
  bool GetInvalid() const;
  void SetInvalid(bool invalid);

  // Get or set the horizontal alignment used for the button from the underlying
  // RenderText object.
  gfx::HorizontalAlignment GetHorizontalAlignment() const;
  void SetHorizontalAlignment(gfx::HorizontalAlignment alignment);

  // Displays a virtual keyboard or alternate input view if enabled.
  void ShowVirtualKeyboardIfEnabled();

  // Returns whether or not an IME is composing text.
  bool IsIMEComposing() const;

  // Gets the selected logical text range.
  const gfx::Range& GetSelectedRange() const;

  // Selects the specified logical text range.
  void SetSelectedRange(const gfx::Range& range);

  // Without clearing the current selected range, adds |range| as an additional
  // selection.
  // NOTE: Unlike SetSelectedRange(), this will not fire any accessibility
  // notifications.
  void AddSecondarySelectedRange(const gfx::Range& range);

  // Gets the text selection model.
  const gfx::SelectionModel& GetSelectionModel() const;

  // Sets the specified text selection model.
  void SelectSelectionModel(const gfx::SelectionModel& sel);

  // Returns the current cursor position.
  size_t GetCursorPosition() const;

  // Set the text color over the entire text or a logical character range.
  // Empty and invalid ranges are ignored.
  void SetColor(SkColor value);
  void ApplyColor(SkColor value, const gfx::Range& range);

  // Set various text styles over the entire text or a logical character range.
  // The respective |style| is applied if |value| is true, or removed if false.
  // Empty and invalid ranges are ignored.
  void SetStyle(gfx::TextStyle style, bool value);
  void ApplyStyle(gfx::TextStyle style, bool value, const gfx::Range& range);

  // Clears Edit history.
  void ClearEditHistory();

  // Set extra spacing placed between glyphs; used for obscured text styling.
  void SetObscuredGlyphSpacing(int spacing);

  std::optional<size_t> GetPasswordCharRevealIndex() const {
    return password_char_reveal_index_;
  }

  void SetExtraInsets(const gfx::Insets& insets);

  // Fits the textfield to the local bounds, applying internal padding and
  // updating the cursor position and visibility.
  void FitToLocalBounds();

  // Getter/Setter methods for `use_default_border_`.
  bool GetUseDefaultBorder() const;
  void SetUseDefaultBorder(bool use_default_border);

  // Removes the Inkdrop hover effect.
  void RemoveHoverEffect();

  // View overrides:
  int GetBaseline() const override;
  gfx::Size CalculatePreferredSize(
      const SizeBounds& available_size) const override;
  gfx::Size GetMinimumSize() const override;
  void SetBorder(std::unique_ptr<Border> b) override;
  ui::Cursor GetCursor(const ui::MouseEvent& event) override;
  bool OnMousePressed(const ui::MouseEvent& event) override;
  bool OnMouseDragged(const ui::MouseEvent& event) override;
  void OnMouseReleased(const ui::MouseEvent& event) override;
  void OnMouseCaptureLost() override;
  bool OnMouseWheel(const ui::MouseWheelEvent& event) override;
  WordLookupClient* GetWordLookupClient() override;
  void OnGestureEvent(ui::GestureEvent* event) override;
  bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
  bool CanHandleAccelerators() const override;
  void AboutToRequestFocusFromTabTraversal(bool reverse) override;
  bool SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) override;
  bool GetDropFormats(int* formats,
                      std::set<ui::ClipboardFormatType>* format_types) override;
  bool CanDrop(const ui::OSExchangeData& data) override;
  int OnDragUpdated(const ui::DropTargetEvent& event) override;
  void OnDragExited() override;
  views::View::DropCallback GetDropCallback(
      const ui::DropTargetEvent& event) override;
  void OnDragDone() override;
  // We don't want to compute the accessible text offsets unless accessibility
  // is enabled. We need to override this function to make sure that when
  // accessibility turns on, we compute the current accessible text offsets.
  void OnAccessibilityInitializing(ui::AXNodeData* node_data) override;
  bool HandleAccessibleAction(const ui::AXActionData& action_data) override;
  void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
  bool GetNeedsNotificationWhenVisibleBoundsChange() const override;
  void OnVisibleBoundsChanged() override;
  void OnPaint(gfx::Canvas* canvas) override;
  void OnFocus() override;
  void OnBlur() override;
  gfx::Point GetKeyboardContextMenuLocation() override;
  void OnThemeChanged() override;

  // TextfieldModel::Delegate overrides:
  void OnCompositionTextConfirmedOrCleared() override;
  void OnTextChanged() override;

  // ContextMenuController overrides:
  void ShowContextMenuForViewImpl(
      View* source,
      const gfx::Point& point,
      ui::mojom::MenuSourceType source_type) override;

  // DragController overrides:
  void WriteDragDataForView(View* sender,
                            const gfx::Point& press_pt,
                            ui::OSExchangeData* data) override;
  int GetDragOperationsForView(View* sender, const gfx::Point& p) override;
  bool CanStartDragForView(View* sender,
                           const gfx::Point& press_pt,
                           const gfx::Point& p) override;

  // WordLookupClient overrides:
  bool GetWordLookupDataAtPoint(const gfx::Point& point,
                                gfx::DecoratedText* decorated_word,
                                gfx::Rect* rect) override;
  bool GetWordLookupDataFromSelection(gfx::DecoratedText* decorated_text,
                                      gfx::Rect* rect) override;

  // SelectionControllerDelegate overrides:
  bool HasTextBeingDragged() const override;

  // ui::TouchEditable overrides:
  void MoveCaret(const gfx::Point& position) override;
  void MoveRangeSelectionExtent(const gfx::Point& extent) override;
  void SelectBetweenCoordinates(const gfx::Point& base,
                                const gfx::Point& extent) override;
  void GetSelectionEndPoints(gfx::SelectionBound* anchor,
                             gfx::SelectionBound* focus) override;
  gfx::Rect GetBounds() override;
  gfx::NativeView GetNativeView() const override;
  bool IsSelectionDragging() const override;
  void ConvertPointToScreen(gfx::Point* point) override;
  void ConvertPointFromScreen(gfx::Point* point) override;
  void OpenContextMenu(const gfx::Point& anchor) override;
  void DestroyTouchSelection() override;

  // ui::SimpleMenuModel::Delegate overrides:
  bool IsCommandIdChecked(int command_id) const override;
  bool IsCommandIdEnabled(int command_id) const override;
  bool GetAcceleratorForCommandId(int command_id,
                                  ui::Accelerator* accelerator) const override;
  void ExecuteCommand(int command_id, int event_flags) override;

  // ui::TextInputClient overrides:
  base::WeakPtr<ui::TextInputClient> AsWeakPtr() override;
  void SetCompositionText(const ui::CompositionText& composition) override;
  size_t ConfirmCompositionText(bool keep_selection) override;
  void ClearCompositionText() override;
  void InsertText(const std::u16string& text,
                  InsertTextCursorBehavior cursor_behavior) override;
  void InsertChar(const ui::KeyEvent& event) override;
  ui::TextInputType GetTextInputType() const override;
  ui::TextInputMode GetTextInputMode() const override;
  base::i18n::TextDirection GetTextDirection() const override;
  int GetTextInputFlags() const override;
  bool CanComposeInline() const override;
  gfx::Rect GetCaretBounds() const override;
  gfx::Rect GetSelectionBoundingBox() const override;
#if BUILDFLAG(IS_WIN)
  std::optional<gfx::Rect> GetProximateCharacterBounds(
      const gfx::Range& range) const override;
  std::optional<size_t> GetProximateCharacterIndexFromPoint(
      const gfx::Point& screen_point_in_dips,
      ui::IndexFromPointFlags flags) const override;
#endif  // BUILDFLAG(IS_WIN)
  bool GetCompositionCharacterBounds(size_t index,
                                     gfx::Rect* rect) const override;
  bool HasCompositionText() const override;
  FocusReason GetFocusReason() const override;
  bool GetTextRange(gfx::Range* range) const override;
  bool GetCompositionTextRange(gfx::Range* range) const override;
  bool GetEditableSelectionRange(gfx::Range* range) const override;
  bool SetEditableSelectionRange(const gfx::Range& range) override;
#if BUILDFLAG(IS_MAC)
  bool DeleteRange(const gfx::Range& range) override;
#else
  bool DeleteRange(const gfx::Range& range);
#endif
  bool GetTextFromRange(const gfx::Range& range,
                        std::u16string* text) const override;
  void OnInputMethodChanged() override;
  bool ChangeTextDirectionAndLayoutAlignment(
      base::i18n::TextDirection direction) override;
  void ExtendSelectionAndDelete(size_t before, size_t after) override;
  void EnsureCaretNotInRect(const gfx::Rect& rect) override;
  bool IsTextEditCommandEnabled(ui::TextEditCommand command) const override;
  void SetTextEditCommandForNextKeyEvent(ui::TextEditCommand command) override;
  ukm::SourceId GetClientSourceForMetrics() const override;
  bool ShouldDoLearning() override;

  // Set whether the text should be used to improve typing suggestions.
  void SetShouldDoLearning(bool value) { should_do_learning_ = value; }

#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  bool SetCompositionFromExistingText(
      const gfx::Range& range,
      const std::vector<ui::ImeTextSpan>& ui_ime_text_spans) override;
#endif

#if BUILDFLAG(IS_CHROMEOS)
  gfx::Range GetAutocorrectRange() const override;
  gfx::Rect GetAutocorrectCharacterBounds() const override;
  bool SetAutocorrectRange(const gfx::Range& range) override;
  bool AddGrammarFragments(
      const std::vector<ui::GrammarFragment>& fragments) override;
#endif

#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS)
  void GetActiveTextInputControlLayoutBounds(
      std::optional<gfx::Rect>* control_bounds,
      std::optional<gfx::Rect>* selection_bounds) override;
#endif

#if BUILDFLAG(IS_WIN)
  void SetActiveCompositionForAccessibility(
      const gfx::Range& range,
      const std::u16string& active_composition_text,
      bool is_composition_committed) override;
#endif

  // ViewObserver overrides:
  void OnViewFocused(views::View* observed_view) override;

  [[nodiscard]] base::CallbackListSubscription AddTextChangedCallback(
      views::PropertyChangedCallback callback);

 protected:
  TextfieldModel* textfield_model() { return model_.get(); }

  // Inserts or appends a character in response to an IME operation.
  virtual void DoInsertChar(char16_t ch);

  // Returns the TextfieldModel's text/cursor/selection rendering model.
  gfx::RenderText* GetRenderText() const;

  // Returns the last click root location (relative to the root window).
  gfx::Point GetLastClickRootLocation() const;

  // Get the text from the selection clipboard.
  virtual std::u16string GetSelectionClipboardText() const;

  // Executes the given |command|.
  virtual void ExecuteTextEditCommand(ui::TextEditCommand command);

  // Offsets the double-clicked word's range. This is only used in the unusual
  // case where the text changes on the second mousedown of a double-click.
  // This is harmless if there is not a currently double-clicked word.
  void OffsetDoubleClickWord(size_t offset);

  // Returns true if the drop cursor is for insertion at a target text location,
  // the standard behavior/style. Returns false when drop will do something
  // else (like replace the text entirely).
  virtual bool IsDropCursorForInsertion() const;

  // Returns true if the placeholder text should be shown. Subclasses may
  // override this to customize when the placeholder text is shown.
  virtual bool ShouldShowPlaceholderText() const;

  // Like RequestFocus, but explicitly states that the focus is triggered by
  // a pointer event.
  void RequestFocusWithPointer(ui::EventPointerType pointer_type);

  // Like RequestFocus, but explicitly states that the focus is triggered by a
  // gesture event.
  void RequestFocusForGesture(const ui::GestureEventDetails& details);

  virtual Textfield::EditCommandResult DoExecuteTextEditCommand(
      ui::TextEditCommand command);

  // Handles key press event ahead of OnKeyPressed(). This is used for Textarea
  // to handle the return key. Use TextfieldController::HandleKeyEvent to
  // intercept the key event in other cases.
  virtual bool PreHandleKeyPressed(const ui::KeyEvent& event);

  // Get the default command for a given key |event|.
  virtual ui::TextEditCommand GetCommandForKeyEvent(const ui::KeyEvent& event);

  // Update the cursor position in the text field.
  void UpdateCursorViewPosition();

  // A callback function to periodically update the cursor node_data.
  void UpdateCursorVisibility();

  // Returns true if a context menu for this view is showing.
  bool IsMenuShowing() const;

  void AddedToWidget() override;

#if BUILDFLAG(SUPPORTS_AX_TEXT_OFFSETS)
  void UpdateAccessibleTextOffsetsIfNeeded();
#endif  // BUILDFLAG(SUPPORTS_AX_TEXT_OFFSETS)

 private:
  friend class TextfieldTestApi;

  enum class TextChangeType { kNone, kInternal, kUserTriggered };

  // View overrides:
  // Declared final since overriding by subclasses would interfere with the
  // accounting related to the scheduled text edit command. Subclasses should
  // use TextfieldController::HandleKeyEvent, to intercept the key event.
  bool OnKeyPressed(const ui::KeyEvent& event) final;
  bool OnKeyReleased(const ui::KeyEvent& event) final;

  // SelectionControllerDelegate overrides:
  gfx::RenderText* GetRenderTextForSelectionController() override;
  bool IsReadOnly() const override;
  bool SupportsDrag() const override;
  void SetTextBeingDragged(bool value) override;
  int GetViewHeight() const override;
  int GetViewWidth() const override;
  int GetDragSelectionDelay() const override;
  void OnBeforePointerAction() override;
  void OnAfterPointerAction(bool text_changed, bool selection_changed) override;
  // Callers within Textfield should call UpdateAfterChange depending on the
  // return value.
  bool PasteSelectionClipboard() override;
  void UpdateSelectionClipboard() override;

  // Updates the painted background color.
  void UpdateBackgroundColor();

  // Updates the border per the state of the textfield (i.e. Normal, Invalid,
  // Readonly, Disabled). This will not do anything if a custom border has been
  // set by SetBorder().
  void UpdateDefaultBorder();

  // Updates the selection text color.
  void UpdateSelectionTextColor();

  // Updates the selection background color.
  void UpdateSelectionBackgroundColor();

  virtual void UpdateAccessibleTextSelection();

  // Does necessary updates when the text and/or cursor position changes.
  // If |notify_caret_bounds_changed| is not explicitly set, it will be computed
  // based on whether either of the other arguments is set.
  void UpdateAfterChange(
      TextChangeType text_change_type,
      bool cursor_changed,
      std::optional<bool> notify_caret_bounds_changed = std::nullopt);

  virtual void UpdateAccessibilityTextDirection();

  // Subclass OmniboxViewViews is overriding this method to update the
  // accessible value.
  virtual void UpdateAccessibleValue();

  // Updates cursor visibility and blinks the cursor if needed.
  void ShowCursor();

  // Gets the style::TextStyle that should be used.
  int GetTextStyle() const;

  void PaintTextAndCursor(gfx::Canvas* canvas);

  // Helper function to call MoveCursorTo on the TextfieldModel.
  void MoveCursorTo(const gfx::Point& point, bool select);

  // Recalculates cursor view bounds based on model_.
  gfx::Rect CalculateCursorViewBounds() const;

  // Convenience method to notify the InputMethod and TouchSelectionController.
  void OnCaretBoundsChanged();

  // Convenience method to call TextfieldController::OnBeforeUserAction();
  void OnBeforeUserAction();

  // Convenience method to call TextfieldController::OnAfterUserAction();
  void OnAfterUserAction();

  // Calls |model_->Cut()| and notifies TextfieldController on success.
  bool Cut();

  // Calls |model_->Copy()| and notifies TextfieldController on success.
  bool Copy();

  // Calls |model_->Paste()| and calls TextfieldController::ContentsChanged()
  // explicitly if paste succeeded.
  bool Paste();

  // Utility function to prepare the context menu.
  void UpdateContextMenu();

  // Returns true if the current text input type allows access by the IME.
  bool ImeEditingAllowed() const;

  // Reveals the password character at |index| for a set duration.
  // If |index| is nullopt, the existing revealed character will be reset.
  // |duration| is the time to remain the password char to be visible.
  void RevealPasswordChar(std::optional<size_t> index,
                          base::TimeDelta duration);

  void CreateTouchSelectionControllerAndNotifyIt();

  // Called when editing a textfield fails because the textfield is readonly.
  void OnEditFailed();

  // Returns true if an insertion cursor should be visible (a vertical bar,
  // placed at the point new text will be inserted).
  bool ShouldShowCursor() const;

  // Converts a textfield width in "average characters" to the required number
  // of DIPs, accounting for insets and cursor.
  int CharsToDips(int width_in_chars) const;

  // Returns true if an insertion cursor should be visible and blinking.
  bool ShouldBlinkCursor() const;

  // Starts and stops blinking the cursor, respectively. These are both
  // idempotent if the cursor is already blinking/not blinking.
  void StartBlinkingCursor();
  void StopBlinkingCursor();

  // Callback for the cursor blink timer. Called every
  // Textfield::GetCaretBlinkMs().
  void OnCursorBlinkTimerFired();

  void OnEnabledChanged();

  // Drops the dragged text.
  void DropDraggedText(
      const ui::DropTargetEvent& event,
      ui::mojom::DragOperation& output_drag_op,
      std::unique_ptr<ui::LayerTreeOwner> drag_image_layer_owner);

  // Returns the corner radius of the text field.
  float GetCornerRadius();

  // Prepares the Textfield for gesture scrolling by setting the drag start
  // state.
  void OnGestureScrollBegin(int drag_start_location_x);

  // Performs gesture scrolling.
  void GestureScroll(int drag_location_x);

  // Performs gesture handling needed for touch selection dragging. Sets `event`
  // as handled and returns true if the event should not be processed further.
  bool HandleGestureForSelectionDragging(ui::GestureEvent* event);

  // Determines whether touch selection dragging should start and updates the
  // selection dragging state if needed. Returns true if selection dragging
  // starts.
  bool StartSelectionDragging(const ui::GestureEvent& event);

  void StopSelectionDragging();

  void UpdateAccessibleDefaultActionVerb();

#if BUILDFLAG(SUPPORTS_AX_TEXT_OFFSETS)
  // Calculate widths for each grapheme and word starts and ends. Used for
  // accessibility. Currently only on Windows when UIA is enabled.
  void RefreshAccessibleTextOffsets();
#endif  // BUILDFLAG(SUPPORTS_AX_TEXT_OFFSETS)

  // The text model.
  std::unique_ptr<TextfieldModel> model_;

  // This is the current listener for events from this Textfield.
  raw_ptr<TextfieldController> controller_ = nullptr;

  // An edit command to execute on the next key event. When set to a valid
  // value, the key event is still passed to |controller_|, but otherwise
  // ignored in favor of the edit command. Set via
  // SetTextEditCommandForNextKeyEvent() during dispatch of that key event (see
  // comment in TextInputClient).
  ui::TextEditCommand scheduled_text_edit_command_ =
      ui::TextEditCommand::INVALID_COMMAND;

  // True if this Textfield cannot accept input and is read-only.
  bool read_only_ = false;

  // The default number of average characters for the width of this text field.
  // This will be reported as the "desired size". Must be set to >=
  // minimum_width_in_chars_. Defaults to 0.
  int default_width_in_chars_ = 0;

  // The minimum allowed width of this text field in average characters. This
  // will be reported as the minimum size. Must be set to <=
  // default_width_in_chars_. Setting this to -1 will cause GetMinimumSize() to
  // return View::GetMinimumSize(). Defaults to -1.
  int minimum_width_in_chars_ = -1;

  // Colors which override default system colors.
  // TODO(tluk): These should be updated to be ColorIds instead of SkColors.
  std::optional<SkColor> text_color_;
  std::optional<SkColor> background_color_;
  std::optional<SkColor> selection_text_color_;
  std::optional<SkColor> selection_background_color_;

  // Text to display when empty.
  std::u16string placeholder_text_;

  // Placeholder text color.
  // TODO(newcomer): Use NativeTheme to define different default placeholder
  // text colors for chrome/CrOS when harmony is enabled by default
  // (https://crbug.com/803279).
  std::optional<SkColor> placeholder_text_color_;

  // The draw flags specified for |placeholder_text_|.
  int placeholder_text_draw_flags_;

  // The font used for the placeholder text. If this value is null, the
  // placeholder text uses the same font list as the underlying RenderText.
  std::optional<gfx::FontList> placeholder_font_list_;

  // True when the contents are deemed unacceptable and should be indicated as
  // such.
  bool invalid_ = false;

  // The input type of this text field.
  ui::TextInputType text_input_type_ = ui::TEXT_INPUT_TYPE_TEXT;

  // The input flags of this text field.
  int text_input_flags_ = 0;

  // The timer to reveal the last typed password character.
  base::OneShotTimer password_reveal_timer_;

  // Tracks whether a user action is being performed which may change the
  // textfield; i.e. OnBeforeUserAction() has been called, but
  // OnAfterUserAction() has not yet been called.
  bool performing_user_action_ = false;

  // True if InputMethod::CancelComposition() should not be called.
  bool skip_input_method_cancel_composition_ = false;

  // Insertion cursor repaint timer and visibility.
  base::RepeatingTimer cursor_blink_timer_;

  // The drop cursor is a visual cue for where dragged text will be dropped.
  bool drop_cursor_visible_ = false;
  gfx::SelectionModel drop_cursor_position_;

  // Is the user potentially dragging and dropping from this view?
  bool initiating_drag_ = false;

  std::unique_ptr<TouchSelectionController> touch_selection_controller_;

  SelectionController selection_controller_;

  // Tracks the touch selection dragging state which is used when determining
  // whether a dragging movement should be used for scrolling, cursor placement
  // or adjusting the text selection.
  enum class SelectionDraggingState {
    // Default state, i.e. no selection dragging gestures being handled.
    kNone,
    // A gesture has used to select all text (e.g. triple press), but dragging
    // has not started yet.
    kSelectedAll,
    // A gesture has used to select word (e.g. long press or double press), but
    // dragging has not started yet.
    kSelectedWord,
    // Dragging gesture is being handled to move the cursor. This state is
    // reached if a dragging gesture begins while the cursor is present (roughly
    // corresponds to the case where no text was selected by a prior gesture).
    kDraggingCursor,
    // Dragging gesture is being handled to adjust the selection. This state is
    // reached if a dragging gesture begins after a word was selected by a prior
    // gesture.
    kDraggingSelectionExtent
  };
  SelectionDraggingState selection_dragging_state_ =
      SelectionDraggingState::kNone;

  // Tracks the type of the current or pending selection drag gesture.
  std::optional<ui::TouchSelectionDragType> selection_drag_type_;

  // The offset applied to the touch drag location when determining selection
  // updates.
  gfx::Vector2d selection_dragging_offset_;

  // Used to track touch drag starting location and offset to enable touch
  // scrolling.
  int drag_start_location_x_;
  int drag_start_display_offset_ = 0;

  // Tracks the selection extent, which is used to determine the logical end of
  // the selection. Roughly, this corresponds to the last drag position of the
  // touch handle or scroll gesture used to update the selection range.
  gfx::Point selection_extent_;

  // Specifies granularity of selection extent updates, i.e. the break type
  // where we can place the end of the selection when the extent is moved. For
  // "expand by word, shrink by character" behaviour, the break type is set to
  // WORD_BREAK if the selection has expanded past the current word boundary and
  // back to CHARACTER_BREAK if the selection is shrinking.
  gfx::BreakType break_type_ = gfx::CHARACTER_BREAK;

  // The horizontal offset applied to selection extent when adjusting the
  // selection. We apply this offset to smoothen the movement of the end of the
  // selection after switching between word and character granularity.
  int extent_offset_x_ = 0;

  // Whether touch selection handles should be shown once the current scroll
  // sequence ends. Handles should be shown if touch editing handles were hidden
  // while scrolling or if part of the scroll sequence was used for cursor
  // placement or adjusting the text selection.
  bool show_touch_handles_after_scroll_ = false;

  // Whether the user should be notified if the clipboard is restricted.
  bool show_rejection_ui_if_any_ = false;

  // Whether the text should be used to improve typing suggestions.
  std::optional<bool> should_do_learning_;

#if BUILDFLAG(SUPPORTS_AX_TEXT_OFFSETS)
  // The string used to compute the text offsets for accessibility. This is used
  // to determine if the offsets need to be recomputed.
  std::u16string ax_value_used_to_compute_offsets_;

  // Whether the last computed text offsets are still valid.
  bool needs_ax_text_offsets_update_;
#endif  // BUILDFLAG(SUPPORTS_AX_TEXT_OFFSETS)

  // Context menu related members.
  std::unique_ptr<ui::SimpleMenuModel> context_menu_contents_;
  std::unique_ptr<ViewsTextServicesContextMenu> text_services_context_menu_;
  std::unique_ptr<views::MenuRunner> context_menu_runner_;

  // View containing the text cursor.
  raw_ptr<View> cursor_view_ = nullptr;

#if BUILDFLAG(IS_MAC)
  // Used to track active password input sessions.
  std::unique_ptr<ui::ScopedPasswordInputEnabler> password_input_enabler_;
#endif  // BUILDFLAG(IS_MAC)

  // How this textfield was focused.
  ui::TextInputClient::FocusReason focus_reason_ =
      ui::TextInputClient::FOCUS_REASON_NONE;

  // The password char reveal index, for testing only.
  std::optional<size_t> password_char_reveal_index_;

  // Extra insets, useful to make room for a button for example.
  gfx::Insets extra_insets_ = gfx::Insets();

  // Whether the client forces a specific text directionality for this
  // textfield, which should inhibit the user's ability to control the
  // directionality.
  bool force_text_directionality_ = false;

  // Helper flag that tracks whether SetBorder was called with a custom
  // border.
  bool use_default_border_ = true;

  // Flag to set whether a background is created for this view.
  bool is_background_enabled_ = true;

  bool is_processing_focus_ = false;

  // Holds the subscription object for the enabled changed callback.
  base::CallbackListSubscription enabled_changed_subscription_ =
      AddEnabledChangedCallback(
          base::BindRepeating(&Textfield::OnEnabledChanged,
                              base::Unretained(this)));

  base::WeakPtrFactory<Textfield> weak_ptr_factory_{this};

  // Used to bind drop callback functions to this object.
  base::WeakPtrFactory<Textfield> drop_weak_ptr_factory_{this};
};

BEGIN_VIEW_BUILDER(VIEWS_EXPORT, Textfield, View)
VIEW_BUILDER_PROPERTY(SkColor, BackgroundColor)
VIEW_BUILDER_PROPERTY(bool, BackgroundEnabled)
VIEW_BUILDER_PROPERTY(TextfieldController*, Controller)
VIEW_BUILDER_PROPERTY(bool, CursorEnabled)
VIEW_BUILDER_PROPERTY(int, DefaultWidthInChars)
VIEW_BUILDER_PROPERTY(gfx::FontList, FontList)
VIEW_BUILDER_PROPERTY(gfx::HorizontalAlignment, HorizontalAlignment)
VIEW_BUILDER_PROPERTY(bool, Invalid)
VIEW_BUILDER_PROPERTY(int, MinimumWidthInChars)
VIEW_BUILDER_PROPERTY(std::u16string, PlaceholderText)
VIEW_BUILDER_PROPERTY(bool, ReadOnly)
VIEW_BUILDER_PROPERTY(gfx::Range, SelectedRange)
VIEW_BUILDER_PROPERTY(SkColor, SelectionBackgroundColor)
VIEW_BUILDER_PROPERTY(SkColor, SelectionTextColor)
VIEW_BUILDER_PROPERTY(std::u16string, Text)
VIEW_BUILDER_PROPERTY(SkColor, TextColor)
VIEW_BUILDER_PROPERTY(int, TextInputFlags)
VIEW_BUILDER_PROPERTY(ui::TextInputType, TextInputType)
VIEW_BUILDER_PROPERTY(bool, UseDefaultBorder)
END_VIEW_BUILDER

}  // namespace views

DEFINE_VIEW_BUILDER(VIEWS_EXPORT, Textfield)

#endif  // UI_VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_H_