summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_views.cc71
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_views.h104
-rw-r--r--views/controls/textfield/native_textfield_views.cc157
-rw-r--r--views/controls/textfield/native_textfield_views.h14
-rw-r--r--views/controls/textfield/textfield.cc7
-rw-r--r--views/controls/textfield/textfield.h3
-rw-r--r--views/controls/textfield/textfield_controller.h11
7 files changed, 134 insertions, 233 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_views.cc b/chrome/browser/autocomplete/autocomplete_edit_view_views.cc
index e3626b7..76a22d4 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view_views.cc
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_views.cc
@@ -121,7 +121,7 @@ AutocompleteEditViewViews::AutocompleteEditViewViews(
command_updater_(command_updater),
popup_window_mode_(popup_window_mode),
security_level_(ToolbarModel::NONE),
- delete_was_pressed_(false),
+ ime_composing_before_change_(false),
delete_at_end_pressed_(false) {
set_border(views::Border::CreateEmptyBorder(kAutocompleteVerticalMargin, 0,
kAutocompleteVerticalMargin, 0));
@@ -164,10 +164,6 @@ void AutocompleteEditViewViews::SetBaseColor() {
bool AutocompleteEditViewViews::HandleAfterKeyEvent(
const views::KeyEvent& event,
bool handled) {
- handling_key_press_ = false;
- if (content_maybe_changed_by_key_press_)
- OnAfterPossibleChange();
-
if (event.key_code() == ui::VKEY_RETURN) {
bool alt_held = event.IsAltDown();
model_->AcceptInput(alt_held ? NEW_FOREGROUND_TAB : CURRENT_TAB, false);
@@ -182,7 +178,7 @@ bool AutocompleteEditViewViews::HandleAfterKeyEvent(
// the contents of omnibox2, we notify the AutocompleteEditModel class when
// the control-key state is changed.
model_->OnControlKeyChanged(true);
- } else if (!text_changed_ && event.key_code() == ui::VKEY_DELETE &&
+ } else if (!handled && event.key_code() == ui::VKEY_DELETE &&
event.IsShiftDown()) {
// If shift+del didn't change the text, we let this delete an entry from
// the popup. We can't check to see if the IME handled it because even if
@@ -255,18 +251,6 @@ void AutocompleteEditViewViews::HandleFocusOut() {
////////////////////////////////////////////////////////////////////////////////
// AutocompleteEditViewViews, views::View implementation:
-
-bool AutocompleteEditViewViews::OnMousePressed(
- const views::MouseEvent& event) {
- if (event.IsLeftMouseButton()) {
- // Button press event may change the selection, we need to record the change
- // and report it to |model_| later when button is released.
- OnBeforePossibleChange();
- }
- // Pass the event through to TextfieldViews.
- return false;
-}
-
void AutocompleteEditViewViews::Layout() {
gfx::Insets insets = GetInsets();
textfield_->SetBounds(insets.left(), insets.top(),
@@ -478,17 +462,10 @@ void AutocompleteEditViewViews::OnBeforePossibleChange() {
// Record our state.
text_before_change_ = GetText();
textfield_->GetSelectedRange(&sel_before_change_);
+ ime_composing_before_change_ = textfield_->IsIMEComposing();
}
bool AutocompleteEditViewViews::OnAfterPossibleChange() {
- // OnAfterPossibleChange should be called once per modification,
- // and we should ignore if this is called while a key event is being handled
- // because OnAfterPossibleChagne will be called after the key event is
- // actually handled.
- if (handling_key_press_) {
- content_maybe_changed_by_key_press_ = true;
- return false;
- }
ui::Range new_sel;
textfield_->GetSelectedRange(&new_sel);
@@ -497,7 +474,8 @@ bool AutocompleteEditViewViews::OnAfterPossibleChange() {
// See if the text or selection have changed since OnBeforePossibleChange().
string16 new_text = GetText();
- text_changed_ = (new_text != text_before_change_);
+ bool text_changed = (new_text != text_before_change_) ||
+ (ime_composing_before_change_ != textfield_->IsIMEComposing());
bool selection_differs =
!((sel_before_change_.is_empty() && new_sel.is_empty()) ||
sel_before_change_.EqualsIgnoringDirection(new_sel));
@@ -511,24 +489,19 @@ bool AutocompleteEditViewViews::OnAfterPossibleChange() {
(text_before_change_.length() > new_text.length()) &&
(new_sel.start() <= sel_before_change_.GetMin());
- delete_at_end_pressed_ = false;
-
bool something_changed = model_->OnAfterPossibleChange(new_text,
- selection_differs, text_changed_, just_deleted_text, at_end_of_edit);
+ selection_differs, text_changed, just_deleted_text, at_end_of_edit);
// If only selection was changed, we don't need to call |model_|'s
// OnChanged() method, which is called in TextChanged().
// But we still need to call EmphasizeURLComponents() to make sure the text
// attributes are updated correctly.
- if (something_changed && text_changed_) {
+ if (something_changed && text_changed)
TextChanged();
- } else if (selection_differs) {
+ else if (selection_differs)
EmphasizeURLComponents();
- } else if (delete_was_pressed_ && at_end_of_edit) {
- delete_at_end_pressed_ = true;
+ else if (delete_at_end_pressed_)
model_->OnChanged();
- }
- delete_was_pressed_ = false;
return something_changed;
}
@@ -587,27 +560,19 @@ void AutocompleteEditViewViews::Observe(NotificationType type,
void AutocompleteEditViewViews::ContentsChanged(views::Textfield* sender,
const string16& new_contents) {
- if (handling_key_press_)
- content_maybe_changed_by_key_press_ = true;
}
bool AutocompleteEditViewViews::HandleKeyEvent(
views::Textfield* textfield,
const views::KeyEvent& event) {
- delete_was_pressed_ = event.key_code() == ui::VKEY_DELETE;
-
- // Reset |text_changed_| before passing the key event on to the text view.
- text_changed_ = false;
- OnBeforePossibleChange();
- handling_key_press_ = true;
- content_maybe_changed_by_key_press_ = false;
+ delete_at_end_pressed_ = false;
if (event.key_code() == ui::VKEY_BACK) {
// Checks if it's currently in keyword search mode.
if (model_->is_keyword_hint() || model_->keyword().empty())
return false;
// If there is selection, let textfield handle the backspace.
- if (!textfield_->GetSelectedText().empty())
+ if (textfield_->HasSelection())
return false;
// If not at the begining of the text, let textfield handle the backspace.
if (textfield_->GetCursorPosition())
@@ -616,9 +581,23 @@ bool AutocompleteEditViewViews::HandleKeyEvent(
return true;
}
+ if (event.key_code() == ui::VKEY_DELETE && !event.IsAltDown()) {
+ delete_at_end_pressed_ =
+ (!textfield_->HasSelection() &&
+ textfield_->GetCursorPosition() == textfield_->text().length());
+ }
+
return false;
}
+void AutocompleteEditViewViews::OnBeforeUserAction(views::Textfield* sender) {
+ OnBeforePossibleChange();
+}
+
+void AutocompleteEditViewViews::OnAfterUserAction(views::Textfield* sender) {
+ OnAfterPossibleChange();
+}
+
////////////////////////////////////////////////////////////////////////////////
// AutocompleteEditViewViews, private:
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_views.h b/chrome/browser/autocomplete/autocomplete_edit_view_views.h
index 4f32ed9..92fb4b1 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view_views.h
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_views.h
@@ -66,72 +66,74 @@ class AutocompleteEditViewViews : public views::View,
void HandleFocusOut();
// Implements views::View
- virtual bool OnMousePressed(const views::MouseEvent& event);
- virtual void Layout();
+ virtual void Layout() OVERRIDE;
virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
// Implement the AutocompleteEditView interface.
- virtual AutocompleteEditModel* model();
- virtual const AutocompleteEditModel* model() const;
+ virtual AutocompleteEditModel* model() OVERRIDE;
+ virtual const AutocompleteEditModel* model() const OVERRIDE;
- virtual void SaveStateToTab(TabContents* tab);
+ virtual void SaveStateToTab(TabContents* tab) OVERRIDE;
- virtual void Update(const TabContents* tab_for_state_restoring);
+ virtual void Update(const TabContents* tab_for_state_restoring) OVERRIDE;
virtual void OpenURL(const GURL& url,
WindowOpenDisposition disposition,
PageTransition::Type transition,
const GURL& alternate_nav_url,
size_t selected_line,
- const string16& keyword);
+ const string16& keyword) OVERRIDE;
- virtual string16 GetText() const;
+ virtual string16 GetText() const OVERRIDE;
- virtual bool IsEditingOrEmpty() const;
- virtual int GetIcon() const;
- virtual void SetUserText(const string16& text);
+ virtual bool IsEditingOrEmpty() const OVERRIDE;
+ virtual int GetIcon() const OVERRIDE;
+ virtual void SetUserText(const string16& text) OVERRIDE;
virtual void SetUserText(const string16& text,
const string16& display_text,
- bool update_popup);
+ bool update_popup) OVERRIDE;
virtual void SetWindowTextAndCaretPos(const string16& text,
- size_t caret_pos);
- virtual void SetForcedQuery();
- virtual bool IsSelectAll();
- virtual bool DeleteAtEndPressed();
+ size_t caret_pos) OVERRIDE;
+ virtual void SetForcedQuery() OVERRIDE;
+ virtual bool IsSelectAll() OVERRIDE;
+ virtual bool DeleteAtEndPressed() OVERRIDE;
virtual void GetSelectionBounds(string16::size_type* start,
- string16::size_type* end);
- virtual void SelectAll(bool reversed);
- virtual void RevertAll();
- virtual void UpdatePopup();
- virtual void ClosePopup();
- virtual void SetFocus();
- virtual void OnTemporaryTextMaybeChanged(const string16& display_text,
- bool save_original_selection);
+ string16::size_type* end) OVERRIDE;
+ virtual void SelectAll(bool reversed) OVERRIDE;
+ virtual void RevertAll() OVERRIDE;
+ virtual void UpdatePopup() OVERRIDE;
+ virtual void ClosePopup() OVERRIDE;
+ virtual void SetFocus() OVERRIDE;
+ virtual void OnTemporaryTextMaybeChanged(
+ const string16& display_text,
+ bool save_original_selection) OVERRIDE;
virtual bool OnInlineAutocompleteTextMaybeChanged(
- const string16& display_text, size_t user_text_length);
- virtual void OnRevertTemporaryText();
- virtual void OnBeforePossibleChange();
- virtual bool OnAfterPossibleChange();
- virtual gfx::NativeView GetNativeView() const;
- virtual CommandUpdater* GetCommandUpdater();
+ const string16& display_text, size_t user_text_length) OVERRIDE;
+ virtual void OnRevertTemporaryText() OVERRIDE;
+ virtual void OnBeforePossibleChange() OVERRIDE;
+ virtual bool OnAfterPossibleChange() OVERRIDE;
+ virtual gfx::NativeView GetNativeView() const OVERRIDE;
+ virtual CommandUpdater* GetCommandUpdater() OVERRIDE;
virtual void SetInstantSuggestion(const string16& input,
- bool animate_to_complete);
- virtual string16 GetInstantSuggestion() const;
- virtual int TextWidth() const;
- virtual bool IsImeComposing() const;
- virtual views::View* AddToView(views::View* parent);
- virtual int OnPerformDrop(const views::DropTargetEvent& event);
+ bool animate_to_complete) OVERRIDE;
+ virtual string16 GetInstantSuggestion() const OVERRIDE;
+ virtual int TextWidth() const OVERRIDE;
+ virtual bool IsImeComposing() const OVERRIDE;
+ virtual views::View* AddToView(views::View* parent) OVERRIDE;
+ virtual int OnPerformDrop(const views::DropTargetEvent& event) OVERRIDE;
// NotificationObserver:
virtual void Observe(NotificationType type,
const NotificationSource& source,
- const NotificationDetails& details);
+ const NotificationDetails& details) OVERRIDE;
// views::TextfieldController:
virtual void ContentsChanged(views::Textfield* sender,
- const string16& new_contents);
+ const string16& new_contents) OVERRIDE;
virtual bool HandleKeyEvent(views::Textfield* sender,
- const views::KeyEvent& key_event);
+ const views::KeyEvent& key_event) OVERRIDE;
+ virtual void OnBeforeUserAction(views::Textfield* sender) OVERRIDE;
+ virtual void OnAfterUserAction(views::Textfield* sender) OVERRIDE;
private:
// Return the number of characers in the current buffer.
@@ -180,33 +182,11 @@ class AutocompleteEditViewViews : public views::View,
// Tracking state before and after a possible change.
string16 text_before_change_;
ui::Range sel_before_change_;
-
- // TODO(oshima): following flags are copied from gtk implementation.
- // It should be possible to refactor this class to simplify flags and
- // logic. I'll work on this refactoring once all features are completed.
-
- // Indicates whether the IME changed the text. It's possible for the IME to
- // handle a key event but not change the text contents (e.g., when pressing
- // shift+del with no selection).
- bool text_changed_;
-
- // Was delete pressed?
- bool delete_was_pressed_;
+ bool ime_composing_before_change_;
// Was the delete key pressed with an empty selection at the end of the edit?
bool delete_at_end_pressed_;
- // Indicates if we are handling a key press event.
- bool handling_key_press_;
-
- // Indicates if omnibox's content maybe changed by a key press event, so that
- // we need to call OnAfterPossibleChange() after handling the event.
- // This flag should be set for changes directly caused by a key press event,
- // including changes to content text, selection range and preedit string.
- // Changes caused by function calls like SetUserText() should not affect this
- // flag.
- bool content_maybe_changed_by_key_press_;
-
DISALLOW_COPY_AND_ASSIGN(AutocompleteEditViewViews);
};
diff --git a/views/controls/textfield/native_textfield_views.cc b/views/controls/textfield/native_textfield_views.cc
index f935193..17885ba 100644
--- a/views/controls/textfield/native_textfield_views.cc
+++ b/views/controls/textfield/native_textfield_views.cc
@@ -86,17 +86,21 @@ NativeTextfieldViews::~NativeTextfieldViews() {
// NativeTextfieldViews, View overrides:
bool NativeTextfieldViews::OnMousePressed(const views::MouseEvent& e) {
+ OnBeforeUserAction();
if (HandleMousePressed(e))
SchedulePaint();
+ OnAfterUserAction();
return true;
}
bool NativeTextfieldViews::OnMouseDragged(const views::MouseEvent& e) {
+ OnBeforeUserAction();
size_t pos = FindCursorPosition(e.location());
if (model_->MoveCursorTo(pos, true)) {
UpdateCursorBoundsAndTextOffset();
SchedulePaint();
}
+ OnAfterUserAction();
return true;
}
@@ -360,6 +364,7 @@ bool NativeTextfieldViews::GetAcceleratorForCommandId(int command_id,
void NativeTextfieldViews::ExecuteCommand(int command_id) {
bool text_changed = false;
bool editable = !textfield_->read_only();
+ OnBeforeUserAction();
switch (command_id) {
case IDS_APP_CUT:
if (editable)
@@ -386,6 +391,7 @@ void NativeTextfieldViews::ExecuteCommand(int command_id) {
// The cursor must have changed if text changed during cut/paste/delete.
UpdateAfterChange(text_changed, text_changed);
+ OnAfterUserAction();
}
// static
@@ -531,6 +537,8 @@ bool NativeTextfieldViews::HandleKeyEvent(const KeyEvent& key_event) {
// TODO(oshima): shift-tab does not work. Figure out why and fix.
if (key_code == ui::VKEY_TAB)
return false;
+
+ OnBeforeUserAction();
bool editable = !textfield_->read_only();
bool selection = key_event.IsShiftDown();
bool control = key_event.IsControlDown();
@@ -619,138 +627,22 @@ bool NativeTextfieldViews::HandleKeyEvent(const KeyEvent& key_event) {
default:
break;
}
- char16 print_char = GetPrintableChar(key_event);
- if (!control && print_char && editable) {
+ char16 ch = key_event.GetCharacter();
+ if (editable && ShouldInsertChar(ch, key_event.flags())) {
if (insert_)
- model_->Insert(print_char);
+ model_->Insert(ch);
else
- model_->Replace(print_char);
+ model_->Replace(ch);
text_changed = true;
}
UpdateAfterChange(text_changed, cursor_changed);
+ OnAfterUserAction();
return (text_changed || cursor_changed);
}
return false;
}
-char16 NativeTextfieldViews::GetPrintableChar(const KeyEvent& key_event) {
- // TODO(oshima): IME, i18n support.
- // This only works for UCS-2 characters.
- ui::KeyboardCode key_code = key_event.key_code();
- bool shift = key_event.IsShiftDown();
- bool upper = shift ^ key_event.IsCapsLockDown();
- // TODO(oshima): We should have a utility function
- // under app to convert a KeyboardCode to a printable character,
- // probably in keyboard_code_conversion{.h, _x
- switch (key_code) {
- case ui::VKEY_NUMPAD0:
- return '0';
- case ui::VKEY_NUMPAD1:
- return '1';
- case ui::VKEY_NUMPAD2:
- return '2';
- case ui::VKEY_NUMPAD3:
- return '3';
- case ui::VKEY_NUMPAD4:
- return '4';
- case ui::VKEY_NUMPAD5:
- return '5';
- case ui::VKEY_NUMPAD6:
- return '6';
- case ui::VKEY_NUMPAD7:
- return '7';
- case ui::VKEY_NUMPAD8:
- return '8';
- case ui::VKEY_NUMPAD9:
- return '9';
- case ui::VKEY_MULTIPLY:
- return '*';
- case ui::VKEY_ADD:
- return '+';
- case ui::VKEY_SUBTRACT:
- return '-';
- case ui::VKEY_DECIMAL:
- return '.';
- case ui::VKEY_DIVIDE:
- return '/';
- case ui::VKEY_SPACE:
- return ' ';
- case ui::VKEY_0:
- return shift ? ')' : '0';
- case ui::VKEY_1:
- return shift ? '!' : '1';
- case ui::VKEY_2:
- return shift ? '@' : '2';
- case ui::VKEY_3:
- return shift ? '#' : '3';
- case ui::VKEY_4:
- return shift ? '$' : '4';
- case ui::VKEY_5:
- return shift ? '%' : '5';
- case ui::VKEY_6:
- return shift ? '^' : '6';
- case ui::VKEY_7:
- return shift ? '&' : '7';
- case ui::VKEY_8:
- return shift ? '*' : '8';
- case ui::VKEY_9:
- return shift ? '(' : '9';
-
- case ui::VKEY_A:
- case ui::VKEY_B:
- case ui::VKEY_C:
- case ui::VKEY_D:
- case ui::VKEY_E:
- case ui::VKEY_F:
- case ui::VKEY_G:
- case ui::VKEY_H:
- case ui::VKEY_I:
- case ui::VKEY_J:
- case ui::VKEY_K:
- case ui::VKEY_L:
- case ui::VKEY_M:
- case ui::VKEY_N:
- case ui::VKEY_O:
- case ui::VKEY_P:
- case ui::VKEY_Q:
- case ui::VKEY_R:
- case ui::VKEY_S:
- case ui::VKEY_T:
- case ui::VKEY_U:
- case ui::VKEY_V:
- case ui::VKEY_W:
- case ui::VKEY_X:
- case ui::VKEY_Y:
- case ui::VKEY_Z:
- return (upper ? 'A' : 'a') + (key_code - ui::VKEY_A);
- case ui::VKEY_OEM_1:
- return shift ? ':' : ';';
- case ui::VKEY_OEM_PLUS:
- return shift ? '+' : '=';
- case ui::VKEY_OEM_COMMA:
- return shift ? '<' : ',';
- case ui::VKEY_OEM_MINUS:
- return shift ? '_' : '-';
- case ui::VKEY_OEM_PERIOD:
- return shift ? '>' : '.';
- case ui::VKEY_OEM_2:
- return shift ? '?' : '/';
- case ui::VKEY_OEM_3:
- return shift ? '~' : '`';
- case ui::VKEY_OEM_4:
- return shift ? '}' : ']';
- case ui::VKEY_OEM_5:
- return shift ? '|' : '\\';
- case ui::VKEY_OEM_6:
- return shift ? '{' : '[';
- case ui::VKEY_OEM_7:
- return shift ? '"' : '\'';
- default:
- return 0;
- }
-}
-
size_t NativeTextfieldViews::FindCursorPosition(const gfx::Point& point) const {
// TODO(oshima): BIDI/i18n support.
gfx::Font font = GetFont();
@@ -859,6 +751,29 @@ void NativeTextfieldViews::InitContextMenuIfRequired() {
context_menu_menu_.reset(new Menu2(context_menu_contents_.get()));
}
+void NativeTextfieldViews::OnBeforeUserAction() {
+ TextfieldController* controller = textfield_->GetController();
+ if (controller)
+ controller->OnBeforeUserAction(textfield_);
+}
+
+void NativeTextfieldViews::OnAfterUserAction() {
+ TextfieldController* controller = textfield_->GetController();
+ if (controller)
+ controller->OnAfterUserAction(textfield_);
+}
+
+// static
+bool NativeTextfieldViews::ShouldInsertChar(char16 ch, int flags) {
+ // Filter out all control characters, including tab and new line characters,
+ // and all characters with Alt modifier. But we need to allow characters with
+ // AltGr modifier.
+ // On Windows AltGr is represented by Alt+Ctrl, and on Linux it's a different
+ // flag that we don't care about.
+ return ((ch >= 0x20 && ch < 0x7F) || ch > 0x9F) &&
+ (flags & ~(ui::EF_SHIFT_DOWN | ui::EF_CAPS_LOCK_DOWN)) != ui::EF_ALT_DOWN;
+}
+
///////////////////////////////////////////////////////////////////////////////
//
// TextifieldBorder
diff --git a/views/controls/textfield/native_textfield_views.h b/views/controls/textfield/native_textfield_views.h
index 1f80147..7cc8317f 100644
--- a/views/controls/textfield/native_textfield_views.h
+++ b/views/controls/textfield/native_textfield_views.h
@@ -169,10 +169,6 @@ class NativeTextfieldViews : public views::View,
// Handle the keyevent.
bool HandleKeyEvent(const KeyEvent& key_event);
- // Utility function. Gets the character corresponding to a keyevent.
- // Returns 0 if the character is not printable.
- char16 GetPrintableChar(const KeyEvent& key_event);
-
// Find a cusor position for given |point| in this views coordinates.
size_t FindCursorPosition(const gfx::Point& point) const;
@@ -194,6 +190,16 @@ class NativeTextfieldViews : public views::View,
// Utility function to create the context menu if one does not already exist.
void InitContextMenuIfRequired();
+ // Convenience method to call TextfieldController::OnBeforeUserAction();
+ void OnBeforeUserAction();
+
+ // Convenience method to call TextfieldController::OnAfterUserAction();
+ void OnAfterUserAction();
+
+ // Checks if a char is ok to be inserted into the textfield. The |ch| is a
+ // modified character, i.e., modifiers took effect when generating this char.
+ static bool ShouldInsertChar(char16 ch, int flags);
+
// The parent textfield, the owner of this object.
Textfield* textfield_;
diff --git a/views/controls/textfield/textfield.cc b/views/controls/textfield/textfield.cc
index ec99e77..7dfa4da 100644
--- a/views/controls/textfield/textfield.cc
+++ b/views/controls/textfield/textfield.cc
@@ -141,6 +141,13 @@ void Textfield::ClearSelection() const {
native_wrapper_->ClearSelection();
}
+bool Textfield::HasSelection() const {
+ ui::Range range;
+ if (native_wrapper_)
+ native_wrapper_->GetSelectedRange(&range);
+ return !range.is_empty();
+}
+
void Textfield::SetTextColor(SkColor color) {
text_color_ = color;
use_default_text_color_ = false;
diff --git a/views/controls/textfield/textfield.h b/views/controls/textfield/textfield.h
index ca87bdf..bbea47d 100644
--- a/views/controls/textfield/textfield.h
+++ b/views/controls/textfield/textfield.h
@@ -89,6 +89,9 @@ class Textfield : public View {
// Clears the selection within the edit field and sets the caret to the end.
void ClearSelection() const;
+ // Checks if there is any selected text.
+ bool HasSelection() const;
+
// Accessor for |style_|.
StyleFlags style() const { return style_; }
diff --git a/views/controls/textfield/textfield_controller.h b/views/controls/textfield/textfield_controller.h
index 53fe97c..ee8df1b 100644
--- a/views/controls/textfield/textfield_controller.h
+++ b/views/controls/textfield/textfield_controller.h
@@ -26,6 +26,17 @@ class TextfieldController {
// further. If it returns false the processing continues.
virtual bool HandleKeyEvent(Textfield* sender,
const KeyEvent& key_event) = 0;
+
+ // Called before performing a user action that may change the textfield.
+ // It's currently only supported by Views implementation.
+ virtual void OnBeforeUserAction(Textfield* sender) {}
+
+ // Called after performing a user action that may change the textfield.
+ // It's currently only supported by Views implementation.
+ virtual void OnAfterUserAction(Textfield* sender) {}
+
+ protected:
+ virtual ~TextfieldController() {}
};
} // namespace views