Chromium Code Reviews| Index: chrome/browser/autocomplete/autocomplete_edit.cc |
| diff --git a/chrome/browser/autocomplete/autocomplete_edit.cc b/chrome/browser/autocomplete/autocomplete_edit.cc |
| index 5bf0c210624ae1931b8c222cbb7203299318f558..18b0c291a649a2737af5c0b9d381aa485c2fd52f 100644 |
| --- a/chrome/browser/autocomplete/autocomplete_edit.cc |
| +++ b/chrome/browser/autocomplete/autocomplete_edit.cc |
| @@ -45,13 +45,11 @@ AutocompleteEditController::~AutocompleteEditController() { |
| AutocompleteEditModel::State::State(bool user_input_in_progress, |
| const std::wstring& user_text, |
| const std::wstring& keyword, |
| - bool is_keyword_hint, |
| - KeywordUIState keyword_ui_state) |
| + bool is_keyword_hint) |
| : user_input_in_progress(user_input_in_progress), |
| user_text(user_text), |
| keyword(keyword), |
| - is_keyword_hint(is_keyword_hint), |
| - keyword_ui_state(keyword_ui_state) { |
| + is_keyword_hint(is_keyword_hint) { |
| } |
| AutocompleteEditModel::State::~State() { |
| @@ -71,11 +69,9 @@ AutocompleteEditModel::AutocompleteEditModel( |
| user_input_in_progress_(false), |
| just_deleted_text_(false), |
| has_temporary_text_(false), |
| - original_keyword_ui_state_(NORMAL), |
| paste_state_(NONE), |
| control_key_state_(UP), |
| is_keyword_hint_(false), |
| - keyword_ui_state_(NORMAL), |
| paste_and_go_transition_(PageTransition::TYPED), |
| profile_(profile) { |
| } |
| @@ -114,8 +110,7 @@ const AutocompleteEditModel::State |
| } |
| } |
| - return State(user_input_in_progress_, user_text_, keyword_, is_keyword_hint_, |
| - keyword_ui_state_); |
| + return State(user_input_in_progress_, user_text_, keyword_, is_keyword_hint_); |
| } |
| void AutocompleteEditModel::RestoreState(const State& state) { |
| @@ -125,7 +120,6 @@ void AutocompleteEditModel::RestoreState(const State& state) { |
| // DisplayTextFromUserText(), as its result depends upon this state. |
| keyword_ = state.keyword; |
| is_keyword_hint_ = state.is_keyword_hint; |
| - keyword_ui_state_ = state.keyword_ui_state; |
| view_->SetUserText(state.user_text, |
| DisplayTextFromUserText(state.user_text), false); |
| } |
| @@ -296,7 +290,6 @@ void AutocompleteEditModel::Revert() { |
| InternalSetUserText(std::wstring()); |
| keyword_.clear(); |
| is_keyword_hint_ = false; |
| - keyword_ui_state_ = NORMAL; |
| has_temporary_text_ = false; |
| view_->SetWindowTextAndCaretPos(permanent_text_, |
| has_focus_ ? permanent_text_.length() : 0); |
| @@ -305,11 +298,11 @@ void AutocompleteEditModel::Revert() { |
| void AutocompleteEditModel::StartAutocomplete( |
| bool has_selected_text, |
| bool prevent_inline_autocomplete) const { |
| + bool keyword_is_selected = KeywordIsSelected(); |
| popup_->StartAutocomplete(user_text_, GetDesiredTLD(), |
| prevent_inline_autocomplete || just_deleted_text_ || |
| (has_selected_text && inline_autocomplete_text_.empty()) || |
| - (paste_state_ != NONE), keyword_ui_state_ == KEYWORD, |
| - keyword_ui_state_ != NO_KEYWORD); |
| + (paste_state_ == REPLACED_ALL), keyword_is_selected, keyword_is_selected); |
| } |
| bool AutocompleteEditModel::CanPasteAndGo(const std::wstring& text) const { |
| @@ -356,7 +349,7 @@ void AutocompleteEditModel::AcceptInput(WindowOpenDisposition disposition, |
| // (e.g. manually retyping the same search query), and it seems wrong to |
| // treat this as a reload. |
| match.transition = PageTransition::RELOAD; |
| - } else if (for_drop || ((paste_state_ != NONE) && |
| + } else if (for_drop || ((paste_state_ == REPLACED_ALL) && |
| match.is_history_what_you_typed_match)) { |
| // When the user pasted in a URL and hit enter, score it like a link click |
| // rather than a normal typed URL, so it doesn't get inline autocompleted |
| @@ -439,10 +432,11 @@ void AutocompleteEditModel::OpenURL(const GURL& url, |
| } |
| void AutocompleteEditModel::AcceptKeyword() { |
| + DCHECK(is_keyword_hint_ && !keyword_.empty()); |
| + |
| view_->OnBeforePossibleChange(); |
| view_->SetWindowTextAndCaretPos(std::wstring(), 0); |
| is_keyword_hint_ = false; |
| - keyword_ui_state_ = KEYWORD; |
| view_->OnAfterPossibleChange(); |
| just_deleted_text_ = false; // OnAfterPossibleChange() erroneously sets this |
| // since the edit contents have disappeared. It |
| @@ -456,7 +450,7 @@ void AutocompleteEditModel::ClearKeyword(const std::wstring& visible_text) { |
| const std::wstring window_text(keyword_ + visible_text); |
| view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length()); |
| keyword_.clear(); |
| - keyword_ui_state_ = NORMAL; |
| + is_keyword_hint_ = false; |
| view_->OnAfterPossibleChange(); |
| just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this |
| // since the edit contents have actually grown |
| @@ -502,7 +496,6 @@ bool AutocompleteEditModel::OnEscapeKeyPressed() { |
| // NOTE: This purposefully does not reset paste_state_. |
| just_deleted_text_ = false; |
| has_temporary_text_ = false; |
| - keyword_ui_state_ = original_keyword_ui_state_; |
| popup_->ResetToDefaultMatch(); |
| view_->OnRevertTemporaryText(); |
| return true; |
| @@ -544,6 +537,10 @@ void AutocompleteEditModel::OnControlKeyChanged(bool pressed) { |
| } |
| } |
| +void AutocompleteEditModel::OnPaste(bool replacing_all) { |
| + paste_state_ = replacing_all ? REPLACING_ALL : PASTING; |
| +} |
| + |
| void AutocompleteEditModel::OnUpOrDownKeyPressed(int count) { |
| // NOTE: This purposefully don't trigger any code that resets paste_state_. |
| @@ -576,21 +573,15 @@ void AutocompleteEditModel::OnPopupDataChanged( |
| GURL* destination_for_temporary_text_change, |
| const std::wstring& keyword, |
| bool is_keyword_hint) { |
| - KeywordUIState old_keyword_ui_state = keyword_ui_state_; |
| - |
| // Update keyword/hint-related local state. |
| bool keyword_state_changed = (keyword_ != keyword) || |
| ((is_keyword_hint_ != is_keyword_hint) && !keyword.empty()); |
| if (keyword_state_changed) { |
| keyword_ = keyword; |
| is_keyword_hint_ = is_keyword_hint; |
| - } |
| - // Update |keyword_ui_state_| only when necessary. It may be changed even if |
| - // |keyword_state_changed| is false. |
| - if (keyword_ui_state_ != NO_KEYWORD) { |
| - keyword_ui_state_ = (is_keyword_hint_ || keyword_.empty()) ? |
| - NORMAL : KEYWORD; |
| + // |is_keyword_hint_| should always be false if |keyword_| is empty. |
| + DCHECK(!keyword_.empty() || !is_keyword_hint_); |
| } |
| // Handle changes to temporary text. |
| @@ -600,7 +591,6 @@ void AutocompleteEditModel::OnPopupDataChanged( |
| // Save the original selection and URL so it can be reverted later. |
| has_temporary_text_ = true; |
| original_url_ = *destination_for_temporary_text_change; |
| - original_keyword_ui_state_ = old_keyword_ui_state; |
| inline_autocomplete_text_.clear(); |
| } |
| if (control_key_state_ == DOWN_WITHOUT_CHANGE) { |
| @@ -645,6 +635,8 @@ bool AutocompleteEditModel::OnAfterPossibleChange( |
| // made some other edit, clear paste tracking. |
| if (paste_state_ == REPLACING_ALL) |
| paste_state_ = REPLACED_ALL; |
| + else if (paste_state_ == PASTING) |
| + paste_state_ = PASTED; |
| else if (text_differs) |
| paste_state_ = NONE; |
| @@ -664,13 +656,20 @@ bool AutocompleteEditModel::OnAfterPossibleChange( |
| return false; |
| } |
| - const bool had_keyword = KeywordIsSelected(); |
| - |
| // 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 |
| // where the autocompleted text unexpectedly reappears, e.g. crbug.com/55983 |
| 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)) |
|
Peter Kasting
2011/01/14 00:43:31
I think that rather than trying to detect this cas
James Su
2011/01/14 01:03:54
The difference between Tab and Space is that Tab d
Peter Kasting
2011/01/14 01:20:01
This is part of why I suggested changing the under
James Su
2011/01/14 02:02:46
The problem is, the IME will handle the space key
Peter Kasting
2011/01/14 02:30:36
It seems like I don't understand how IMEs work wel
James Su
2011/01/14 03:26:22
There is no way on Windows to intercept a key even
Peter Kasting
2011/01/14 17:31:33
I've been reading a few MSDN docs and I don't thin
James Su
2011/01/14 18:04:12
Yes exactly. But if the user uses an IME and enabl
Peter Kasting
2011/01/19 19:24:42
It seems like acting directly on VK_SPACE might be
James Su
2011/01/19 19:57:15
One possible case is that an IME may use a differe
Peter Kasting
2011/01/19 20:07:05
We should not trigger keyword mode for this case.
|
| + return false; |
| + |
| + InternalSetUserText(new_user_text); |
| has_temporary_text_ = false; |
| // Track when the user has deleted text so we won't allow inline |
| @@ -678,17 +677,6 @@ bool AutocompleteEditModel::OnAfterPossibleChange( |
| 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(); |
| return true; |
| } |
| @@ -762,7 +750,7 @@ void AutocompleteEditModel::InternalSetUserText(const std::wstring& text) { |
| } |
| bool AutocompleteEditModel::KeywordIsSelected() const { |
| - return keyword_ui_state_ == KEYWORD; |
| + return !is_keyword_hint_ && !keyword_.empty(); |
| } |
| std::wstring AutocompleteEditModel::DisplayTextFromUserText( |
| @@ -834,3 +822,21 @@ void AutocompleteEditModel::UpdateSuggestedSearchText() { |
| } |
| controller_->OnSetSuggestedSearchText(suggested_text); |
| } |
| + |
| +bool AutocompleteEditModel::MaybeAcceptKeywordBySpace( |
| + const std::wstring& new_user_text) { |
| + if (paste_state_ != NONE || !is_keyword_hint_ || keyword_.empty() || |
| + !controller_->IsKeywordHintVisible()) |
| + return false; |
| + |
| + const size_t old_length = user_text_.length(); |
| + const size_t new_length = new_user_text.length(); |
| + if (old_length && old_length + 1 == new_length && |
| + user_text_ == new_user_text.substr(0, old_length) && |
| + IsWhitespace(new_user_text[old_length]) && |
| + !IsWhitespace(user_text_[old_length - 1])) { |
| + AcceptKeyword(); |
| + return true; |
| + } |
| + return false; |
| +} |