Commit 96ed237d authored by suzhe@google.com's avatar suzhe@google.com

Accept keyword by pressing space.

This CL disables implicit keyword accepting completely. The user can only
accept a keyword by pressing Tab or space explicitly while the keyword hint
UI is visible.

BUG=60972
TEST=interactive_ui_tests --gtest_filter=AutocompleteEditViewTest.AcceptKeywordBySpace

Review URL: http://codereview.chromium.org/6252003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@72003 0039d316-1c4b-4281-b951-d872f2087c98
parent e9f57506
...@@ -45,13 +45,11 @@ AutocompleteEditController::~AutocompleteEditController() { ...@@ -45,13 +45,11 @@ AutocompleteEditController::~AutocompleteEditController() {
AutocompleteEditModel::State::State(bool user_input_in_progress, AutocompleteEditModel::State::State(bool user_input_in_progress,
const std::wstring& user_text, const std::wstring& user_text,
const std::wstring& keyword, const std::wstring& keyword,
bool is_keyword_hint, bool is_keyword_hint)
KeywordUIState keyword_ui_state)
: user_input_in_progress(user_input_in_progress), : user_input_in_progress(user_input_in_progress),
user_text(user_text), user_text(user_text),
keyword(keyword), keyword(keyword),
is_keyword_hint(is_keyword_hint), is_keyword_hint(is_keyword_hint) {
keyword_ui_state(keyword_ui_state) {
} }
AutocompleteEditModel::State::~State() { AutocompleteEditModel::State::~State() {
...@@ -71,11 +69,9 @@ AutocompleteEditModel::AutocompleteEditModel( ...@@ -71,11 +69,9 @@ AutocompleteEditModel::AutocompleteEditModel(
user_input_in_progress_(false), user_input_in_progress_(false),
just_deleted_text_(false), just_deleted_text_(false),
has_temporary_text_(false), has_temporary_text_(false),
original_keyword_ui_state_(NORMAL),
paste_state_(NONE), paste_state_(NONE),
control_key_state_(UP), control_key_state_(UP),
is_keyword_hint_(false), is_keyword_hint_(false),
keyword_ui_state_(NORMAL),
paste_and_go_transition_(PageTransition::TYPED), paste_and_go_transition_(PageTransition::TYPED),
profile_(profile) { profile_(profile) {
} }
...@@ -114,8 +110,7 @@ const AutocompleteEditModel::State ...@@ -114,8 +110,7 @@ const AutocompleteEditModel::State
} }
} }
return State(user_input_in_progress_, user_text_, keyword_, is_keyword_hint_, return State(user_input_in_progress_, user_text_, keyword_, is_keyword_hint_);
keyword_ui_state_);
} }
void AutocompleteEditModel::RestoreState(const State& state) { void AutocompleteEditModel::RestoreState(const State& state) {
...@@ -125,7 +120,6 @@ void AutocompleteEditModel::RestoreState(const State& state) { ...@@ -125,7 +120,6 @@ void AutocompleteEditModel::RestoreState(const State& state) {
// DisplayTextFromUserText(), as its result depends upon this state. // DisplayTextFromUserText(), as its result depends upon this state.
keyword_ = state.keyword; keyword_ = state.keyword;
is_keyword_hint_ = state.is_keyword_hint; is_keyword_hint_ = state.is_keyword_hint;
keyword_ui_state_ = state.keyword_ui_state;
view_->SetUserText(state.user_text, view_->SetUserText(state.user_text,
DisplayTextFromUserText(state.user_text), false); DisplayTextFromUserText(state.user_text), false);
} }
...@@ -296,7 +290,6 @@ void AutocompleteEditModel::Revert() { ...@@ -296,7 +290,6 @@ void AutocompleteEditModel::Revert() {
InternalSetUserText(std::wstring()); InternalSetUserText(std::wstring());
keyword_.clear(); keyword_.clear();
is_keyword_hint_ = false; is_keyword_hint_ = false;
keyword_ui_state_ = NORMAL;
has_temporary_text_ = false; has_temporary_text_ = false;
view_->SetWindowTextAndCaretPos(permanent_text_, view_->SetWindowTextAndCaretPos(permanent_text_,
has_focus_ ? permanent_text_.length() : 0); has_focus_ ? permanent_text_.length() : 0);
...@@ -305,11 +298,11 @@ void AutocompleteEditModel::Revert() { ...@@ -305,11 +298,11 @@ void AutocompleteEditModel::Revert() {
void AutocompleteEditModel::StartAutocomplete( void AutocompleteEditModel::StartAutocomplete(
bool has_selected_text, bool has_selected_text,
bool prevent_inline_autocomplete) const { bool prevent_inline_autocomplete) const {
bool keyword_is_selected = KeywordIsSelected();
popup_->StartAutocomplete(user_text_, GetDesiredTLD(), popup_->StartAutocomplete(user_text_, GetDesiredTLD(),
prevent_inline_autocomplete || just_deleted_text_ || prevent_inline_autocomplete || just_deleted_text_ ||
(has_selected_text && inline_autocomplete_text_.empty()) || (has_selected_text && inline_autocomplete_text_.empty()) ||
(paste_state_ != NONE), keyword_ui_state_ == KEYWORD, (paste_state_ != NONE), keyword_is_selected, keyword_is_selected);
keyword_ui_state_ != NO_KEYWORD);
} }
bool AutocompleteEditModel::CanPasteAndGo(const std::wstring& text) const { bool AutocompleteEditModel::CanPasteAndGo(const std::wstring& text) const {
...@@ -438,17 +431,19 @@ void AutocompleteEditModel::OpenURL(const GURL& url, ...@@ -438,17 +431,19 @@ void AutocompleteEditModel::OpenURL(const GURL& url,
alternate_nav_url); alternate_nav_url);
} }
void AutocompleteEditModel::AcceptKeyword() { bool AutocompleteEditModel::AcceptKeyword() {
DCHECK(is_keyword_hint_ && !keyword_.empty());
view_->OnBeforePossibleChange(); view_->OnBeforePossibleChange();
view_->SetWindowTextAndCaretPos(std::wstring(), 0); view_->SetWindowTextAndCaretPos(std::wstring(), 0);
is_keyword_hint_ = false; is_keyword_hint_ = false;
keyword_ui_state_ = KEYWORD;
view_->OnAfterPossibleChange(); view_->OnAfterPossibleChange();
just_deleted_text_ = false; // OnAfterPossibleChange() erroneously sets this just_deleted_text_ = false; // OnAfterPossibleChange() erroneously sets this
// since the edit contents have disappeared. It // since the edit contents have disappeared. It
// doesn't really matter, but we clear it to be // doesn't really matter, but we clear it to be
// consistent. // consistent.
UserMetrics::RecordAction(UserMetricsAction("AcceptedKeywordHint"), profile_); UserMetrics::RecordAction(UserMetricsAction("AcceptedKeywordHint"), profile_);
return true;
} }
void AutocompleteEditModel::ClearKeyword(const std::wstring& visible_text) { void AutocompleteEditModel::ClearKeyword(const std::wstring& visible_text) {
...@@ -456,7 +451,7 @@ void AutocompleteEditModel::ClearKeyword(const std::wstring& visible_text) { ...@@ -456,7 +451,7 @@ void AutocompleteEditModel::ClearKeyword(const std::wstring& visible_text) {
const std::wstring window_text(keyword_ + visible_text); const std::wstring window_text(keyword_ + visible_text);
view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length()); view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length());
keyword_.clear(); keyword_.clear();
keyword_ui_state_ = NORMAL; is_keyword_hint_ = false;
view_->OnAfterPossibleChange(); view_->OnAfterPossibleChange();
just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this
// since the edit contents have actually grown // since the edit contents have actually grown
...@@ -502,7 +497,6 @@ bool AutocompleteEditModel::OnEscapeKeyPressed() { ...@@ -502,7 +497,6 @@ bool AutocompleteEditModel::OnEscapeKeyPressed() {
// NOTE: This purposefully does not reset paste_state_. // NOTE: This purposefully does not reset paste_state_.
just_deleted_text_ = false; just_deleted_text_ = false;
has_temporary_text_ = false; has_temporary_text_ = false;
keyword_ui_state_ = original_keyword_ui_state_;
popup_->ResetToDefaultMatch(); popup_->ResetToDefaultMatch();
view_->OnRevertTemporaryText(); view_->OnRevertTemporaryText();
return true; return true;
...@@ -576,21 +570,15 @@ void AutocompleteEditModel::OnPopupDataChanged( ...@@ -576,21 +570,15 @@ void AutocompleteEditModel::OnPopupDataChanged(
GURL* destination_for_temporary_text_change, GURL* destination_for_temporary_text_change,
const std::wstring& keyword, const std::wstring& keyword,
bool is_keyword_hint) { bool is_keyword_hint) {
KeywordUIState old_keyword_ui_state = keyword_ui_state_;
// Update keyword/hint-related local state. // Update keyword/hint-related local state.
bool keyword_state_changed = (keyword_ != keyword) || bool keyword_state_changed = (keyword_ != keyword) ||
((is_keyword_hint_ != is_keyword_hint) && !keyword.empty()); ((is_keyword_hint_ != is_keyword_hint) && !keyword.empty());
if (keyword_state_changed) { if (keyword_state_changed) {
keyword_ = keyword; keyword_ = keyword;
is_keyword_hint_ = is_keyword_hint; is_keyword_hint_ = is_keyword_hint;
}
// Update |keyword_ui_state_| only when necessary. It may be changed even if // |is_keyword_hint_| should always be false if |keyword_| is empty.
// |keyword_state_changed| is false. DCHECK(!keyword_.empty() || !is_keyword_hint_);
if (keyword_ui_state_ != NO_KEYWORD) {
keyword_ui_state_ = (is_keyword_hint_ || keyword_.empty()) ?
NORMAL : KEYWORD;
} }
// Handle changes to temporary text. // Handle changes to temporary text.
...@@ -600,7 +588,6 @@ void AutocompleteEditModel::OnPopupDataChanged( ...@@ -600,7 +588,6 @@ void AutocompleteEditModel::OnPopupDataChanged(
// Save the original selection and URL so it can be reverted later. // Save the original selection and URL so it can be reverted later.
has_temporary_text_ = true; has_temporary_text_ = true;
original_url_ = *destination_for_temporary_text_change; original_url_ = *destination_for_temporary_text_change;
original_keyword_ui_state_ = old_keyword_ui_state;
inline_autocomplete_text_.clear(); inline_autocomplete_text_.clear();
} }
if (control_key_state_ == DOWN_WITHOUT_CHANGE) { if (control_key_state_ == DOWN_WITHOUT_CHANGE) {
...@@ -643,8 +630,8 @@ bool AutocompleteEditModel::OnAfterPossibleChange( ...@@ -643,8 +630,8 @@ bool AutocompleteEditModel::OnAfterPossibleChange(
// Update the paste state as appropriate: if we're just finishing a paste // Update the paste state as appropriate: if we're just finishing a paste
// that replaced all the text, preserve that information; otherwise, if we've // that replaced all the text, preserve that information; otherwise, if we've
// made some other edit, clear paste tracking. // made some other edit, clear paste tracking.
if (paste_state_ == REPLACING_ALL) if (paste_state_ == PASTING)
paste_state_ = REPLACED_ALL; paste_state_ = PASTED;
else if (text_differs) else if (text_differs)
paste_state_ = NONE; paste_state_ = NONE;
...@@ -664,13 +651,20 @@ bool AutocompleteEditModel::OnAfterPossibleChange( ...@@ -664,13 +651,20 @@ bool AutocompleteEditModel::OnAfterPossibleChange(
return false; return false;
} }
const bool had_keyword = KeywordIsSelected();
// If the user text has not changed, we do not want to change the model's // If the user text has not changed, we do not want to change the model's
// state associated with the text. Otherwise, we can get surprising behavior // state associated with the text. Otherwise, we can get surprising behavior
// where the autocompleted text unexpectedly reappears, e.g. crbug.com/55983 // where the autocompleted text unexpectedly reappears, e.g. crbug.com/55983
if (user_text_changed) { if (user_text_changed) {
InternalSetUserText(UserTextFromDisplayText(new_text)); const std::wstring new_user_text = UserTextFromDisplayText(new_text);
// Try to accept the current keyword if the user only typed a space at the
// end of content. Model's state and popup will be updated when the keyword
// is accepted. So we just need to return false here.
if (allow_keyword_ui_change && !selection_differs &&
MaybeAcceptKeywordBySpace(new_user_text))
return false;
InternalSetUserText(new_user_text);
has_temporary_text_ = false; has_temporary_text_ = false;
// Track when the user has deleted text so we won't allow inline // Track when the user has deleted text so we won't allow inline
...@@ -678,17 +672,6 @@ bool AutocompleteEditModel::OnAfterPossibleChange( ...@@ -678,17 +672,6 @@ bool AutocompleteEditModel::OnAfterPossibleChange(
just_deleted_text_ = just_deleted_text; just_deleted_text_ = just_deleted_text;
} }
// Disable the fancy keyword UI if the user didn't already have a visible
// keyword and the view doesn't want us to change the keyword UI state.
// This prevents us from showing the fancy UI and interrupting the user's
// editing if, for example, the user happens to have a keyword for 'a',
// types 'ab' then puts a space between the 'a' and the 'b'.
// If |keyword_ui_state_| is set to NORMAL here, then it will be updated
// to a proper value in OnPopupDataChanged() method according to the new
// match result.
if (!had_keyword)
keyword_ui_state_ = allow_keyword_ui_change ? NORMAL : NO_KEYWORD;
view_->UpdatePopup(); view_->UpdatePopup();
return true; return true;
} }
...@@ -758,7 +741,7 @@ void AutocompleteEditModel::InternalSetUserText(const std::wstring& text) { ...@@ -758,7 +741,7 @@ void AutocompleteEditModel::InternalSetUserText(const std::wstring& text) {
} }
bool AutocompleteEditModel::KeywordIsSelected() const { bool AutocompleteEditModel::KeywordIsSelected() const {
return keyword_ui_state_ == KEYWORD; return !is_keyword_hint_ && !keyword_.empty();
} }
std::wstring AutocompleteEditModel::DisplayTextFromUserText( std::wstring AutocompleteEditModel::DisplayTextFromUserText(
...@@ -795,3 +778,25 @@ bool AutocompleteEditModel::GetURLForText(const std::wstring& text, ...@@ -795,3 +778,25 @@ bool AutocompleteEditModel::GetURLForText(const std::wstring& text,
*url = parsed_url; *url = parsed_url;
return true; return true;
} }
bool AutocompleteEditModel::MaybeAcceptKeywordBySpace(
const std::wstring& new_user_text) {
return (paste_state_ == NONE) && is_keyword_hint_ && !keyword_.empty() &&
inline_autocomplete_text_.empty() && !user_text_.empty() &&
(new_user_text.length() == user_text_.length() + 1) &&
!new_user_text.compare(0, user_text_.length(), user_text_) &&
IsSpaceCharForAcceptingKeyword(new_user_text[user_text_.length()]) &&
!IsWhitespace(user_text_[user_text_.length() - 1]) &&
AcceptKeyword();
}
// static
bool AutocompleteEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) {
switch (c) {
case 0x0020: // Space
case 0x3000: // Ideographic Space
return true;
default:
return false;
}
}
...@@ -102,32 +102,17 @@ class AutocompleteEditController { ...@@ -102,32 +102,17 @@ class AutocompleteEditController {
class AutocompleteEditModel : public NotificationObserver { class AutocompleteEditModel : public NotificationObserver {
public: public:
enum KeywordUIState {
// The user is typing normally.
NORMAL,
// The user is editing in the middle of the input string. Even if the
// input looks like a keyword, don't display the keyword UI, as to not
// interfere with the user's editing.
NO_KEYWORD,
// The user has triggered the keyword UI. Until it disappears, bias
// autocomplete results so that input strings of the keyword alone default
// to the keyword provider, not a normal navigation or search.
KEYWORD,
};
struct State { struct State {
State(bool user_input_in_progress, State(bool user_input_in_progress,
const std::wstring& user_text, const std::wstring& user_text,
const std::wstring& keyword, const std::wstring& keyword,
bool is_keyword_hint, bool is_keyword_hint);
KeywordUIState keyword_ui_state);
~State(); ~State();
bool user_input_in_progress; bool user_input_in_progress;
const std::wstring user_text; const std::wstring user_text;
const std::wstring keyword; const std::wstring keyword;
const bool is_keyword_hint; const bool is_keyword_hint;
const KeywordUIState keyword_ui_state;
}; };
AutocompleteEditModel(AutocompleteEditView* view, AutocompleteEditModel(AutocompleteEditView* view,
...@@ -255,14 +240,12 @@ class AutocompleteEditModel : public NotificationObserver { ...@@ -255,14 +240,12 @@ class AutocompleteEditModel : public NotificationObserver {
// Accessors for keyword-related state (see comments on keyword_ and // Accessors for keyword-related state (see comments on keyword_ and
// is_keyword_hint_). // is_keyword_hint_).
std::wstring keyword() const { const std::wstring& keyword() const { return keyword_; }
return (is_keyword_hint_ || (keyword_ui_state_ != NO_KEYWORD)) ?
keyword_ : std::wstring();
}
bool is_keyword_hint() const { return is_keyword_hint_; } bool is_keyword_hint() const { return is_keyword_hint_; }
// Accepts the current keyword hint as a keyword. // Accepts the current keyword hint as a keyword. It always returns true for
void AcceptKeyword(); // caller convenience.
bool AcceptKeyword();
// Clears the current keyword. |visible_text| is the (non-keyword) text // Clears the current keyword. |visible_text| is the (non-keyword) text
// currently visible in the edit. // currently visible in the edit.
...@@ -294,8 +277,8 @@ class AutocompleteEditModel : public NotificationObserver { ...@@ -294,8 +277,8 @@ class AutocompleteEditModel : public NotificationObserver {
// necessary. // necessary.
void OnControlKeyChanged(bool pressed); void OnControlKeyChanged(bool pressed);
// Called when the user pastes in text that replaces the entire edit contents. // Called when the user pastes in text.
void on_paste_replacing_all() { paste_state_ = REPLACING_ALL; } void on_paste() { paste_state_ = PASTING; }
// Called when the user presses up or down. |count| is a repeat count, // Called when the user presses up or down. |count| is a repeat count,
// negative for moving up, positive for moving down. // negative for moving up, positive for moving down.
...@@ -338,15 +321,14 @@ class AutocompleteEditModel : public NotificationObserver { ...@@ -338,15 +321,14 @@ class AutocompleteEditModel : public NotificationObserver {
private: private:
enum PasteState { enum PasteState {
NONE, // Most recent edit was not a paste that replaced all text. NONE, // Most recent edit was not a paste.
REPLACED_ALL, // Most recent edit was a paste that replaced all text. PASTING, // In the middle of doing a paste. We need this intermediate
REPLACING_ALL, // In the middle of doing a paste that replaces all // state because OnPaste() does the actual detection of
// text. We need this intermediate state because OnPaste() // paste, but OnAfterPossibleChange() has to update the
// does the actual detection of such pastes, but // paste state for every edit. If OnPaste() set the state
// OnAfterPossibleChange() has to update the paste state // directly to PASTED, OnAfterPossibleChange() wouldn't know
// for every edit. If OnPaste() set the state directly to
// REPLACED_ALL, OnAfterPossibleChange() wouldn't know
// whether that represented the current edit or a past one. // whether that represented the current edit or a past one.
PASTED, // Most recent edit was a paste.
}; };
enum ControlKeyState { enum ControlKeyState {
...@@ -393,6 +375,14 @@ class AutocompleteEditModel : public NotificationObserver { ...@@ -393,6 +375,14 @@ class AutocompleteEditModel : public NotificationObserver {
// copy. // copy.
bool GetURLForText(const std::wstring& text, GURL* url) const; bool GetURLForText(const std::wstring& text, GURL* url) const;
// Accepts current keyword if the user only typed a space at the end of
// |new_user_text|. Returns true if the current keyword is accepted.
bool MaybeAcceptKeywordBySpace(const std::wstring& new_user_text);
// Checks if a given character is a valid space character for accepting
// keyword.
static bool IsSpaceCharForAcceptingKeyword(wchar_t c);
AutocompleteEditView* view_; AutocompleteEditView* view_;
AutocompletePopupModel* popup_; AutocompletePopupModel* popup_;
...@@ -461,12 +451,10 @@ class AutocompleteEditModel : public NotificationObserver { ...@@ -461,12 +451,10 @@ class AutocompleteEditModel : public NotificationObserver {
// them and not revert all the way to the permanent_text_. // them and not revert all the way to the permanent_text_.
bool has_temporary_text_; bool has_temporary_text_;
GURL original_url_; GURL original_url_;
KeywordUIState original_keyword_ui_state_;
// When the user's last action was to paste and replace all the text, we // When the user's last action was to paste, we disallow inline autocomplete
// disallow inline autocomplete (on the theory that the user is trying to // (on the theory that the user is trying to paste in a new URL or part of
// paste in a new URL or part of one, and in either case inline autocomplete // one, and in either case inline autocomplete would get in the way).
// would get in the way).
PasteState paste_state_; PasteState paste_state_;
// Whether the control key is depressed. We track this to avoid calling // Whether the control key is depressed. We track this to avoid calling
...@@ -485,9 +473,6 @@ class AutocompleteEditModel : public NotificationObserver { ...@@ -485,9 +473,6 @@ class AutocompleteEditModel : public NotificationObserver {
// keyword_ to show a "Press <tab> to search" sort of hint. // keyword_ to show a "Press <tab> to search" sort of hint.
bool is_keyword_hint_; bool is_keyword_hint_;
// See KeywordUIState enum.
KeywordUIState keyword_ui_state_;
// Paste And Go-related state. See CanPasteAndGo(). // Paste And Go-related state. See CanPasteAndGo().
mutable GURL paste_and_go_url_; mutable GURL paste_and_go_url_;
mutable PageTransition::Type paste_and_go_transition_; mutable PageTransition::Type paste_and_go_transition_;
......
...@@ -184,7 +184,6 @@ AutocompleteEditViewGtk::AutocompleteEditViewGtk( ...@@ -184,7 +184,6 @@ AutocompleteEditViewGtk::AutocompleteEditViewGtk(
tab_was_pressed_(false), tab_was_pressed_(false),
paste_clipboard_requested_(false), paste_clipboard_requested_(false),
enter_was_inserted_(false), enter_was_inserted_(false),
enable_tab_to_search_(true),
selection_suggested_(false), selection_suggested_(false),
delete_was_pressed_(false), delete_was_pressed_(false),
delete_at_end_pressed_(false), delete_at_end_pressed_(false),
...@@ -650,13 +649,10 @@ void AutocompleteEditViewGtk::OnRevertTemporaryText() { ...@@ -650,13 +649,10 @@ void AutocompleteEditViewGtk::OnRevertTemporaryText() {
} }
void AutocompleteEditViewGtk::OnBeforePossibleChange() { void AutocompleteEditViewGtk::OnBeforePossibleChange() {
// If this change is caused by a paste clipboard action and all text is // Record this paste, so we can do different behavior.
// selected, then call model_->on_paste_replacing_all() to prevent inline
// autocomplete.
if (paste_clipboard_requested_) { if (paste_clipboard_requested_) {
paste_clipboard_requested_ = false; paste_clipboard_requested_ = false;
if (IsSelectAll()) model_->on_paste();
model_->on_paste_replacing_all();
} }
// This method will be called in HandleKeyPress() method just before // This method will be called in HandleKeyPress() method just before
...@@ -696,8 +692,11 @@ bool AutocompleteEditViewGtk::OnAfterPossibleChange() { ...@@ -696,8 +692,11 @@ bool AutocompleteEditViewGtk::OnAfterPossibleChange() {
CharRange new_sel = GetSelection(); CharRange new_sel = GetSelection();
int length = GetTextLength(); int length = GetTextLength();
bool selection_differs = (new_sel.cp_min != sel_before_change_.cp_min) || bool selection_differs =
(new_sel.cp_max != sel_before_change_.cp_max); ((new_sel.cp_min != new_sel.cp_max) ||
(sel_before_change_.cp_min != sel_before_change_.cp_max)) &&
((new_sel.cp_min != sel_before_change_.cp_min) ||
(new_sel.cp_max != sel_before_change_.cp_max));
bool at_end_of_edit = (new_sel.cp_min == length && new_sel.cp_max == length); bool at_end_of_edit = (new_sel.cp_min == length && new_sel.cp_max == length);
// See if the text or selection have changed since OnBeforePossibleChange(). // See if the text or selection have changed since OnBeforePossibleChange().
...@@ -1626,18 +1625,13 @@ void AutocompleteEditViewGtk::HandleViewMoveFocus(GtkWidget* widget, ...@@ -1626,18 +1625,13 @@ void AutocompleteEditViewGtk::HandleViewMoveFocus(GtkWidget* widget,
bool handled = false; bool handled = false;
// Trigger Tab to search behavior only when Tab key is pressed. // Trigger Tab to search behavior only when Tab key is pressed.
if (model_->is_keyword_hint() && !model_->keyword().empty()) { if (model_->is_keyword_hint()) {
if (enable_tab_to_search_) { handled = model_->AcceptKeyword();
model_->AcceptKeyword(); } else if (GTK_WIDGET_VISIBLE(instant_view_)) {
handled = true; controller_->OnCommitSuggestedText(GetText());
} handled = true;
} else { } else {
if (GTK_WIDGET_VISIBLE(instant_view_)) { handled = controller_->AcceptCurrentInstantPreview();
controller_->OnCommitSuggestedText(GetText());
handled = true;
} else {
handled = controller_->AcceptCurrentInstantPreview();
}
} }
if (handled) { if (handled) {
......
...@@ -185,13 +185,6 @@ class AutocompleteEditViewGtk : public AutocompleteEditView, ...@@ -185,13 +185,6 @@ class AutocompleteEditViewGtk : public AutocompleteEditView,
bool CommitInstantSuggestion(); bool CommitInstantSuggestion();
// Used by LocationBarViewGtk to inform AutocompleteEditViewGtk if the tab to
// search should be enabled or not. See the comment of |enable_tab_to_search_|
// for details.
void set_enable_tab_to_search(bool enable) {
enable_tab_to_search_ = enable;
}
GtkWidget* text_view() { GtkWidget* text_view() {
return text_view_; return text_view_;
} }
...@@ -495,11 +488,6 @@ class AutocompleteEditViewGtk : public AutocompleteEditView, ...@@ -495,11 +488,6 @@ class AutocompleteEditViewGtk : public AutocompleteEditView,
// is needed. // is needed.
CharRange strikethrough_; CharRange strikethrough_;
// Indicate if the tab to search should be enabled or not. It's true by
// default and will only be set to false if the location bar view is not able
// to show the tab to search hint.
bool enable_tab_to_search_;
// Indicates if the selected text is suggested text or not. If the selection // Indicates if the selected text is suggested text or not. If the selection
// is not suggested text, that means the user manually made the selection. // is not suggested text, that means the user manually made the selection.
bool selection_suggested_; bool selection_suggested_;
......
...@@ -648,8 +648,9 @@ bool AutocompleteEditViewMac::OnAfterPossibleChange() { ...@@ -648,8 +648,9 @@ bool AutocompleteEditViewMac::OnAfterPossibleChange() {
const std::wstring new_text(GetText()); const std::wstring new_text(GetText());
const size_t length = new_text.length(); const size_t length = new_text.length();
const bool selection_differs = !NSEqualRanges(new_selection, const bool selection_differs =
selection_before_change_); (new_selection.length || selection_before_change_.length) &&
!NSEqualRanges(new_selection, selection_before_change_);
const bool at_end_of_edit = (length == new_selection.location); const bool at_end_of_edit = (length == new_selection.location);
const bool text_differs = (new_text != text_before_change_) || const bool text_differs = (new_text != text_before_change_) ||
!NSEqualRanges(marked_range_before_change_, GetMarkedRange()); !NSEqualRanges(marked_range_before_change_, GetMarkedRange());
...@@ -810,10 +811,8 @@ bool AutocompleteEditViewMac::OnDoCommandBySelector(SEL cmd) { ...@@ -810,10 +811,8 @@ bool AutocompleteEditViewMac::OnDoCommandBySelector(SEL cmd) {
if (cmd == @selector(insertTab:) || if (cmd == @selector(insertTab:) ||
cmd == @selector(insertTabIgnoringFieldEditor:)) { cmd == @selector(insertTabIgnoringFieldEditor:)) {
if (model_->is_keyword_hint() && !model_->keyword().empty()) { if (model_->is_keyword_hint())
model_->AcceptKeyword(); return model_->AcceptKeyword();
return true;
}
if (suggest_text_length_ > 0) { if (suggest_text_length_ > 0) {
controller_->OnCommitSuggestedText(GetText()); controller_->OnCommitSuggestedText(GetText());
...@@ -939,10 +938,8 @@ void AutocompleteEditViewMac::OnPaste() { ...@@ -939,10 +938,8 @@ void AutocompleteEditViewMac::OnPaste() {
NSTextView* editor = static_cast<NSTextView*>([field_ currentEditor]); NSTextView* editor = static_cast<NSTextView*>([field_ currentEditor]);
const NSRange selectedRange = GetSelectedRange(); const NSRange selectedRange = GetSelectedRange();
if ([editor shouldChangeTextInRange:selectedRange replacementString:s]) { if ([editor shouldChangeTextInRange:selectedRange replacementString:s]) {
// If this paste will be replacing all the text, record that, so // Record this paste, so we can do different behavior.
// we can do different behaviors in such a case. model_->on_paste();
if (IsSelectAll())
model_->on_paste_replacing_all();
// Force a Paste operation to trigger the text_changed code in // Force a Paste operation to trigger the text_changed code in
// OnAfterPossibleChange(), even if identical contents are pasted // OnAfterPossibleChange(), even if identical contents are pasted
......
...@@ -861,8 +861,11 @@ bool AutocompleteEditViewWin::OnAfterPossibleChangeInternal( ...@@ -861,8 +861,11 @@ bool AutocompleteEditViewWin::OnAfterPossibleChangeInternal(
new_sel.cpMax = length; new_sel.cpMax = length;
SetSelectionRange(new_sel); SetSelectionRange(new_sel);
} }
const bool selection_differs = (new_sel.cpMin != sel_before_change_.cpMin) || const bool selection_differs =
(new_sel.cpMax != sel_before_change_.cpMax); ((new_sel.cpMin != new_sel.cpMax) ||
(sel_before_change_.cpMin != sel_before_change_.cpMax)) &&
((new_sel.cpMin != sel_before_change_.cpMin) ||
(new_sel.cpMax != sel_before_change_.cpMax));
const bool at_end_of_edit = const bool at_end_of_edit =
(new_sel.cpMin == length) && (new_sel.cpMax == length); (new_sel.cpMin == length) && (new_sel.cpMax == length);
...@@ -1690,10 +1693,8 @@ void AutocompleteEditViewWin::OnPaste() { ...@@ -1690,10 +1693,8 @@ void AutocompleteEditViewWin::OnPaste() {
// Replace the selection if we have something to paste. // Replace the selection if we have something to paste.
const std::wstring text(GetClipboardText()); const std::wstring text(GetClipboardText());
if (!text.empty()) { if (!text.empty()) {
// If this paste will be replacing all the text, record that, so we can do // Record this paste, so we can do different behavior.
// different behaviors in such a case. model_->on_paste();
if (IsSelectAll())
model_->on_paste_replacing_all();
// Force a Paste operation to trigger the text_changed code in // Force a Paste operation to trigger the text_changed code in
// OnAfterPossibleChange(), even if identical contents are pasted into the // OnAfterPossibleChange(), even if identical contents are pasted into the
// text box. // text box.
...@@ -1972,7 +1973,7 @@ bool AutocompleteEditViewWin::OnKeyDownOnlyWritable(TCHAR key, ...@@ -1972,7 +1973,7 @@ bool AutocompleteEditViewWin::OnKeyDownOnlyWritable(TCHAR key,
} }
case VK_TAB: { case VK_TAB: {
if (model_->is_keyword_hint() && !model_->keyword().empty()) { if (model_->is_keyword_hint()) {
// Accept the keyword. // Accept the keyword.
ScopedFreeze freeze(this, GetTextObjectModel()); ScopedFreeze freeze(this, GetTextObjectModel());
model_->AcceptKeyword(); model_->AcceptKeyword();
......
...@@ -1198,12 +1198,10 @@ void LocationBarViewGtk::AdjustChildrenVisibility() { ...@@ -1198,12 +1198,10 @@ void LocationBarViewGtk::AdjustChildrenVisibility() {
// Only one of |tab_to_search_box_| and |tab_to_search_hint_| can be visible // Only one of |tab_to_search_box_| and |tab_to_search_hint_| can be visible
// at the same time. // at the same time.
if (!show_selected_keyword_ && GTK_WIDGET_VISIBLE(tab_to_search_box_)) { if (!show_selected_keyword_ && GTK_WIDGET_VISIBLE(tab_to_search_box_))
gtk_widget_hide(tab_to_search_box_); gtk_widget_hide(tab_to_search_box_);
} else if (!show_keyword_hint_ && GTK_WIDGET_VISIBLE(tab_to_search_hint_)) { else if (!show_keyword_hint_ && GTK_WIDGET_VISIBLE(tab_to_search_hint_))
gtk_widget_hide(tab_to_search_hint_); gtk_widget_hide(tab_to_search_hint_);
location_entry_->set_enable_tab_to_search(false);
}
if (show_selected_keyword_) { if (show_selected_keyword_) {
GtkRequisition box, full_label, partial_label; GtkRequisition box, full_label, partial_label;
...@@ -1241,17 +1239,14 @@ void LocationBarViewGtk::AdjustChildrenVisibility() { ...@@ -1241,17 +1239,14 @@ void LocationBarViewGtk::AdjustChildrenVisibility() {
if (icon.width >= entry_box_width_ - kInnerPadding) { if (icon.width >= entry_box_width_ - kInnerPadding) {
gtk_widget_hide(tab_to_search_hint_); gtk_widget_hide(tab_to_search_hint_);
location_entry_->set_enable_tab_to_search(false);
} else if (full_width >= available_width) { } else if (full_width >= available_width) {
gtk_widget_hide(tab_to_search_hint_leading_label_); gtk_widget_hide(tab_to_search_hint_leading_label_);
gtk_widget_hide(tab_to_search_hint_trailing_label_); gtk_widget_hide(tab_to_search_hint_trailing_label_);
gtk_widget_show(tab_to_search_hint_); gtk_widget_show(tab_to_search_hint_);
location_entry_->set_enable_tab_to_search(true);
} else if (full_width < available_width) { } else if (full_width < available_width) {
gtk_widget_show(tab_to_search_hint_leading_label_); gtk_widget_show(tab_to_search_hint_leading_label_);
gtk_widget_show(tab_to_search_hint_trailing_label_); gtk_widget_show(tab_to_search_hint_trailing_label_);
gtk_widget_show(tab_to_search_hint_); gtk_widget_show(tab_to_search_hint_);
location_entry_->set_enable_tab_to_search(true);
} }
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment