#include "ui/views/controls/textfield/textfield.h"
#include <algorithm>
#include <set>
#include <string>
#include <utility>
#include "base/auto_reset.h"
#include "base/command_line.h"
#include "base/functional/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/ranges/algorithm.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "ui/accessibility/ax_action_data.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/platform/ax_platform.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/data_transfer_policy/data_transfer_endpoint.h"
#include "ui/base/default_style.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h"
#include "ui/base/ime/constants.h"
#include "ui/base/ime/input_method.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_features.h"
#include "ui/base/ui_base_switches.h"
#include "ui/base/ui_base_switches_util.h"
#include "ui/color/color_id.h"
#include "ui/color/color_provider.h"
#include "ui/compositor/canvas_painter.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_tree_owner.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/events/gesture_event_details.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/selection_bound.h"
#include "ui/native_theme/native_theme.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/touch_selection/touch_selection_metrics.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/accessibility/views_utilities_aura.h"
#include "ui/views/animation/ink_drop.h"
#include "ui/views/animation/ink_drop_highlight.h"
#include "ui/views/animation/ink_drop_impl.h"
#include "ui/views/background.h"
#include "ui/views/controls/focus_ring.h"
#include "ui/views/controls/focusable_border.h"
#include "ui/views/controls/highlight_path_generator.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/controls/textfield/textfield_controller.h"
#include "ui/views/controls/views_text_services_context_menu.h"
#include "ui/views/drag_utils.h"
#include "ui/views/layout/layout_provider.h"
#include "ui/views/painter.h"
#include "ui/views/style/platform_style.h"
#include "ui/views/style/typography.h"
#include "ui/views/style/typography_provider.h"
#include "ui/views/touchui/touch_selection_controller.h"
#include "ui/views/views_delegate.h"
#include "ui/views/views_features.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/coordinate_conversion.h"
#if BUILDFLAG(IS_WIN)
#include "base/win/win_util.h"
#endif
#if BUILDFLAG(IS_LINUX)
#include "ui/base/ime/linux/text_edit_command_auralinux.h"
#include "ui/base/ime/text_input_flags.h"
#include "ui/linux/linux_ui.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ui/aura/window.h"
#include "ui/wm/core/ime_util_chromeos.h"
#endif
#if BUILDFLAG(IS_MAC)
#include "ui/base/cocoa/secure_password_input.h"
#endif
#if BUILDFLAG(IS_OZONE)
#include "ui/ozone/public/ozone_platform.h"
#include "ui/ozone/public/platform_gl_egl_utility.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ui/base/ime/ash/extension_ime_util.h"
#include "ui/base/ime/ash/input_method_manager.h"
#endif
#if defined(USE_AURA)
#include "ui/views/touchui/touch_selection_controller_impl.h"
#endif
namespace views {
namespace {
DragOperation;
enum TextfieldPropertyKey { … };
ui::TextEditCommand GetTextEditCommandFromMenuCommand(int command_id,
bool has_selection) { … }
base::TimeDelta GetPasswordRevealDuration(const ui::KeyEvent& event) { … }
bool IsControlKeyModifier(int flags) { … }
bool IsValidCharToInsert(const char16_t& ch) { … }
#if BUILDFLAG(IS_MAC)
const float kAlmostTransparent = 1.0 / 255.0;
const float kOpaque = 1.0;
#endif
}
base::TimeDelta Textfield::GetCaretBlinkInterval() { … }
const gfx::FontList& Textfield::GetDefaultFontList() { … }
Textfield::Textfield()
: … { … }
Textfield::~Textfield() { … }
void Textfield::SetController(TextfieldController* controller) { … }
void Textfield::AddedToWidget() { … }
bool Textfield::GetReadOnly() const { … }
void Textfield::SetReadOnly(bool read_only) { … }
void Textfield::SetTextInputType(ui::TextInputType type) { … }
void Textfield::SetTextInputFlags(int flags) { … }
const std::u16string& Textfield::GetText() const { … }
void Textfield::SetText(const std::u16string& new_text) { … }
void Textfield::SetTextWithoutCaretBoundsChangeNotification(
const std::u16string& text,
size_t cursor_position) { … }
void Textfield::Scroll(const std::vector<size_t>& positions) { … }
void Textfield::AppendText(const std::u16string& new_text) { … }
void Textfield::InsertOrReplaceText(const std::u16string& new_text) { … }
std::u16string Textfield::GetSelectedText() const { … }
void Textfield::SelectAll(bool reversed) { … }
void Textfield::SelectWord() { … }
void Textfield::SelectWordAt(const gfx::Point& point) { … }
void Textfield::ClearSelection() { … }
bool Textfield::HasSelection(bool primary_only) const { … }
SkColor Textfield::GetTextColor() const { … }
void Textfield::SetTextColor(SkColor color) { … }
SkColor Textfield::GetBackgroundColor() const { … }
void Textfield::SetBackgroundColor(SkColor color) { … }
bool Textfield::GetBackgroundEnabled() const { … }
void Textfield::SetBackgroundEnabled(bool enabled) { … }
SkColor Textfield::GetSelectionTextColor() const { … }
void Textfield::SetSelectionTextColor(SkColor color) { … }
SkColor Textfield::GetSelectionBackgroundColor() const { … }
void Textfield::SetSelectionBackgroundColor(SkColor color) { … }
bool Textfield::GetCursorEnabled() const { … }
void Textfield::SetCursorEnabled(bool enabled) { … }
const gfx::FontList& Textfield::GetFontList() const { … }
void Textfield::SetFontList(const gfx::FontList& font_list) { … }
void Textfield::SetDefaultWidthInChars(int default_width) { … }
void Textfield::SetMinimumWidthInChars(int minimum_width) { … }
const std::u16string& Textfield::GetPlaceholderText() const { … }
void Textfield::SetPlaceholderText(const std::u16string& text) { … }
gfx::HorizontalAlignment Textfield::GetHorizontalAlignment() const { … }
void Textfield::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) { … }
void Textfield::ShowVirtualKeyboardIfEnabled() { … }
bool Textfield::IsIMEComposing() const { … }
const gfx::Range& Textfield::GetSelectedRange() const { … }
void Textfield::SetSelectedRange(const gfx::Range& range) { … }
void Textfield::AddSecondarySelectedRange(const gfx::Range& range) { … }
const gfx::SelectionModel& Textfield::GetSelectionModel() const { … }
void Textfield::SelectSelectionModel(const gfx::SelectionModel& sel) { … }
size_t Textfield::GetCursorPosition() const { … }
void Textfield::SetColor(SkColor value) { … }
void Textfield::ApplyColor(SkColor value, const gfx::Range& range) { … }
void Textfield::SetStyle(gfx::TextStyle style, bool value) { … }
void Textfield::ApplyStyle(gfx::TextStyle style,
bool value,
const gfx::Range& range) { … }
bool Textfield::GetInvalid() const { … }
void Textfield::SetInvalid(bool invalid) { … }
void Textfield::ClearEditHistory() { … }
void Textfield::SetObscuredGlyphSpacing(int spacing) { … }
void Textfield::SetExtraInsets(const gfx::Insets& insets) { … }
void Textfield::FitToLocalBounds() { … }
bool Textfield::GetUseDefaultBorder() const { … }
void Textfield::SetUseDefaultBorder(bool use_default_border) { … }
void Textfield::RemoveHoverEffect() { … }
int Textfield::GetBaseline() const { … }
gfx::Size Textfield::CalculatePreferredSize(
const SizeBounds& available_size) const { … }
gfx::Size Textfield::GetMinimumSize() const { … }
void Textfield::SetBorder(std::unique_ptr<Border> b) { … }
ui::Cursor Textfield::GetCursor(const ui::MouseEvent& event) { … }
bool Textfield::OnMousePressed(const ui::MouseEvent& event) { … }
bool Textfield::OnMouseDragged(const ui::MouseEvent& event) { … }
void Textfield::OnMouseReleased(const ui::MouseEvent& event) { … }
void Textfield::OnMouseCaptureLost() { … }
bool Textfield::OnMouseWheel(const ui::MouseWheelEvent& event) { … }
WordLookupClient* Textfield::GetWordLookupClient() { … }
bool Textfield::OnKeyPressed(const ui::KeyEvent& event) { … }
bool Textfield::OnKeyReleased(const ui::KeyEvent& event) { … }
void Textfield::OnGestureEvent(ui::GestureEvent* event) { … }
bool Textfield::AcceleratorPressed(const ui::Accelerator& accelerator) { … }
bool Textfield::CanHandleAccelerators() const { … }
void Textfield::AboutToRequestFocusFromTabTraversal(bool reverse) { … }
bool Textfield::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) { … }
bool Textfield::GetDropFormats(
int* formats,
std::set<ui::ClipboardFormatType>* format_types) { … }
bool Textfield::CanDrop(const OSExchangeData& data) { … }
int Textfield::OnDragUpdated(const ui::DropTargetEvent& event) { … }
void Textfield::OnDragExited() { … }
views::View::DropCallback Textfield::GetDropCallback(
const ui::DropTargetEvent& event) { … }
void Textfield::OnDragDone() { … }
void Textfield::UpdateAccessibleTextSelection() { … }
void Textfield::GetAccessibleNodeData(ui::AXNodeData* node_data) { … }
#if BUILDFLAG(SUPPORTS_AX_TEXT_OFFSETS)
void Textfield::RefreshAccessibleTextOffsets() {
if (GetRenderText()->multiline()) {
return;
}
GetViewAccessibility().SetCharacterOffsets(
ComputeTextOffsets(GetRenderText()));
WordBoundaries boundaries = ComputeWordBoundaries(GetText());
GetViewAccessibility().SetWordStarts(boundaries.starts);
GetViewAccessibility().SetWordEnds(boundaries.ends);
}
#endif
bool Textfield::HandleAccessibleAction(const ui::AXActionData& action_data) { … }
void Textfield::OnBoundsChanged(const gfx::Rect& previous_bounds) { … }
bool Textfield::GetNeedsNotificationWhenVisibleBoundsChange() const { … }
void Textfield::OnVisibleBoundsChanged() { … }
void Textfield::OnPaint(gfx::Canvas* canvas) { … }
void Textfield::OnFocus() { … }
void Textfield::OnBlur() { … }
gfx::Point Textfield::GetKeyboardContextMenuLocation() { … }
void Textfield::OnThemeChanged() { … }
void Textfield::OnCompositionTextConfirmedOrCleared() { … }
void Textfield::OnTextChanged() { … }
void Textfield::ShowContextMenuForViewImpl(View* source,
const gfx::Point& point,
ui::MenuSourceType source_type) { … }
void Textfield::WriteDragDataForView(View* sender,
const gfx::Point& press_pt,
OSExchangeData* data) { … }
int Textfield::GetDragOperationsForView(View* sender, const gfx::Point& p) { … }
bool Textfield::CanStartDragForView(View* sender,
const gfx::Point& press_pt,
const gfx::Point& p) { … }
bool Textfield::GetWordLookupDataAtPoint(const gfx::Point& point,
gfx::DecoratedText* decorated_word,
gfx::Rect* rect) { … }
bool Textfield::GetWordLookupDataFromSelection(
gfx::DecoratedText* decorated_text,
gfx::Rect* rect) { … }
bool Textfield::HasTextBeingDragged() const { … }
void Textfield::MoveCaret(const gfx::Point& position) { … }
void Textfield::MoveRangeSelectionExtent(const gfx::Point& extent) { … }
void Textfield::SelectBetweenCoordinates(const gfx::Point& base,
const gfx::Point& extent) { … }
void Textfield::GetSelectionEndPoints(gfx::SelectionBound* anchor,
gfx::SelectionBound* focus) { … }
gfx::Rect Textfield::GetBounds() { … }
gfx::NativeView Textfield::GetNativeView() const { … }
bool Textfield::IsSelectionDragging() const { … }
void Textfield::ConvertPointToScreen(gfx::Point* point) { … }
void Textfield::ConvertPointFromScreen(gfx::Point* point) { … }
void Textfield::OpenContextMenu(const gfx::Point& anchor) { … }
void Textfield::DestroyTouchSelection() { … }
bool Textfield::IsCommandIdChecked(int command_id) const { … }
bool Textfield::IsCommandIdEnabled(int command_id) const { … }
bool Textfield::GetAcceleratorForCommandId(int command_id,
ui::Accelerator* accelerator) const { … }
void Textfield::ExecuteCommand(int command_id, int event_flags) { … }
base::WeakPtr<ui::TextInputClient> Textfield::AsWeakPtr() { … }
void Textfield::SetCompositionText(const ui::CompositionText& composition) { … }
size_t Textfield::ConfirmCompositionText(bool keep_selection) { … }
void Textfield::ClearCompositionText() { … }
void Textfield::InsertText(const std::u16string& new_text,
InsertTextCursorBehavior cursor_behavior) { … }
void Textfield::InsertChar(const ui::KeyEvent& event) { … }
ui::TextInputType Textfield::GetTextInputType() const { … }
ui::TextInputMode Textfield::GetTextInputMode() const { … }
base::i18n::TextDirection Textfield::GetTextDirection() const { … }
int Textfield::GetTextInputFlags() const { … }
bool Textfield::CanComposeInline() const { … }
gfx::Rect Textfield::GetCaretBounds() const { … }
gfx::Rect Textfield::GetSelectionBoundingBox() const { … }
bool Textfield::GetCompositionCharacterBounds(size_t index,
gfx::Rect* rect) const { … }
bool Textfield::HasCompositionText() const { … }
ui::TextInputClient::FocusReason Textfield::GetFocusReason() const { … }
bool Textfield::GetTextRange(gfx::Range* range) const { … }
bool Textfield::GetCompositionTextRange(gfx::Range* range) const { … }
bool Textfield::GetEditableSelectionRange(gfx::Range* range) const { … }
bool Textfield::SetEditableSelectionRange(const gfx::Range& range) { … }
bool Textfield::DeleteRange(const gfx::Range& range) { … }
bool Textfield::GetTextFromRange(const gfx::Range& range,
std::u16string* range_text) const { … }
void Textfield::OnInputMethodChanged() { … }
bool Textfield::ChangeTextDirectionAndLayoutAlignment(
base::i18n::TextDirection direction) { … }
void Textfield::ExtendSelectionAndDelete(size_t before, size_t after) { … }
void Textfield::EnsureCaretNotInRect(const gfx::Rect& rect_in_screen) { … }
bool Textfield::IsTextEditCommandEnabled(ui::TextEditCommand command) const { … }
void Textfield::SetTextEditCommandForNextKeyEvent(ui::TextEditCommand command) { … }
ukm::SourceId Textfield::GetClientSourceForMetrics() const { … }
bool Textfield::ShouldDoLearning() { … }
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
bool Textfield::SetCompositionFromExistingText(
const gfx::Range& range,
const std::vector<ui::ImeTextSpan>& ui_ime_text_spans) { … }
#endif
#if BUILDFLAG(IS_CHROMEOS)
gfx::Range Textfield::GetAutocorrectRange() const {
NOTIMPLEMENTED_LOG_ONCE();
return gfx::Range();
}
gfx::Rect Textfield::GetAutocorrectCharacterBounds() const {
NOTIMPLEMENTED_LOG_ONCE();
return gfx::Rect();
}
bool Textfield::SetAutocorrectRange(const gfx::Range& range) {
if (!range.is_empty()) {
base::UmaHistogramEnumeration("InputMethod.Assistive.Autocorrect.Count",
TextInputClient::SubClass::kTextField);
}
NOTIMPLEMENTED_LOG_ONCE();
return false;
}
bool Textfield::AddGrammarFragments(
const std::vector<ui::GrammarFragment>& fragments) {
if (!fragments.empty()) {
base::UmaHistogramEnumeration("InputMethod.Assistive.Grammar.Count",
TextInputClient::SubClass::kTextField);
}
NOTIMPLEMENTED_LOG_ONCE();
return false;
}
#endif
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS)
void Textfield::GetActiveTextInputControlLayoutBounds(
std::optional<gfx::Rect>* control_bounds,
std::optional<gfx::Rect>* selection_bounds) {
gfx::Rect origin = GetContentsBounds();
ConvertRectToScreen(this, &origin);
*control_bounds = origin;
}
#endif
#if BUILDFLAG(IS_WIN)
void Textfield::SetActiveCompositionForAccessibility(
const gfx::Range& range,
const std::u16string& active_composition_text,
bool is_composition_committed) {}
#endif
void Textfield::OnViewFocused(views::View* observed_view) { … }
void Textfield::DoInsertChar(char16_t ch) { … }
gfx::RenderText* Textfield::GetRenderText() const { … }
gfx::Point Textfield::GetLastClickRootLocation() const { … }
std::u16string Textfield::GetSelectionClipboardText() const { … }
void Textfield::ExecuteTextEditCommand(ui::TextEditCommand command) { … }
Textfield::EditCommandResult Textfield::DoExecuteTextEditCommand(
ui::TextEditCommand command) { … }
void Textfield::OffsetDoubleClickWord(size_t offset) { … }
bool Textfield::IsDropCursorForInsertion() const { … }
bool Textfield::ShouldShowPlaceholderText() const { … }
void Textfield::RequestFocusWithPointer(ui::EventPointerType pointer_type) { … }
void Textfield::RequestFocusForGesture(const ui::GestureEventDetails& details) { … }
base::CallbackListSubscription Textfield::AddTextChangedCallback(
views::PropertyChangedCallback callback) { … }
bool Textfield::PreHandleKeyPressed(const ui::KeyEvent& event) { … }
ui::TextEditCommand Textfield::GetCommandForKeyEvent(
const ui::KeyEvent& event) { … }
#if BUILDFLAG(SUPPORTS_AX_TEXT_OFFSETS)
void Textfield::SetNeedsAccessibleTextOffsetsUpdate() {
needs_ax_text_offsets_update_ = true;
}
#endif
gfx::RenderText* Textfield::GetRenderTextForSelectionController() { … }
bool Textfield::IsReadOnly() const { … }
bool Textfield::SupportsDrag() const { … }
void Textfield::SetTextBeingDragged(bool value) { … }
int Textfield::GetViewHeight() const { … }
int Textfield::GetViewWidth() const { … }
int Textfield::GetDragSelectionDelay() const { … }
void Textfield::OnBeforePointerAction() { … }
void Textfield::OnAfterPointerAction(bool text_changed,
bool selection_changed) { … }
bool Textfield::PasteSelectionClipboard() { … }
void Textfield::UpdateSelectionClipboard() { … }
void Textfield::UpdateBackgroundColor() { … }
void Textfield::UpdateDefaultBorder() { … }
void Textfield::UpdateSelectionTextColor() { … }
void Textfield::UpdateSelectionBackgroundColor() { … }
void Textfield::UpdateAfterChange(
TextChangeType text_change_type,
bool cursor_changed,
std::optional<bool> notify_caret_bounds_changed) { … }
void Textfield::UpdateAccessibilityTextDirection() { … }
void Textfield::UpdateAccessibleValue() { … }
void Textfield::UpdateCursorVisibility() { … }
bool Textfield::IsMenuShowing() const { … }
gfx::Rect Textfield::CalculateCursorViewBounds() const { … }
void Textfield::UpdateCursorViewPosition() { … }
int Textfield::GetTextStyle() const { … }
void Textfield::PaintTextAndCursor(gfx::Canvas* canvas) { … }
void Textfield::MoveCursorTo(const gfx::Point& point, bool select) { … }
void Textfield::OnCaretBoundsChanged() { … }
void Textfield::OnBeforeUserAction() { … }
void Textfield::OnAfterUserAction() { … }
bool Textfield::Cut() { … }
bool Textfield::Copy() { … }
bool Textfield::Paste() { … }
void Textfield::UpdateContextMenu() { … }
bool Textfield::ImeEditingAllowed() const { … }
void Textfield::RevealPasswordChar(std::optional<size_t> index,
base::TimeDelta duration) { … }
void Textfield::CreateTouchSelectionControllerAndNotifyIt() { … }
void Textfield::OnEditFailed() { … }
bool Textfield::ShouldShowCursor() const { … }
int Textfield::CharsToDips(int width_in_chars) const { … }
bool Textfield::ShouldBlinkCursor() const { … }
void Textfield::StartBlinkingCursor() { … }
void Textfield::StopBlinkingCursor() { … }
void Textfield::OnCursorBlinkTimerFired() { … }
void Textfield::OnEnabledChanged() { … }
void Textfield::DropDraggedText(
const ui::DropTargetEvent& event,
ui::mojom::DragOperation& output_drag_op,
std::unique_ptr<ui::LayerTreeOwner> drag_image_layer_owner) { … }
float Textfield::GetCornerRadius() { … }
void Textfield::OnGestureScrollBegin(int drag_start_location_x) { … }
void Textfield::GestureScroll(int drag_location_x) { … }
bool Textfield::HandleGestureForSelectionDragging(ui::GestureEvent* event) { … }
bool Textfield::StartSelectionDragging(const ui::GestureEvent& event) { … }
void Textfield::StopSelectionDragging() { … }
void Textfield::UpdateAccessibleDefaultActionVerb() { … }
BEGIN_METADATA(…)
}