OLD | NEW |
---|---|
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/omnibox/browser/omnibox_edit_model.h" | 5 #include "components/omnibox/browser/omnibox_edit_model.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
196 } | 196 } |
197 | 197 |
198 const OmniboxEditModel::State OmniboxEditModel::GetStateForTabSwitch() { | 198 const OmniboxEditModel::State OmniboxEditModel::GetStateForTabSwitch() { |
199 // Like typing, switching tabs "accepts" the temporary text as the user | 199 // Like typing, switching tabs "accepts" the temporary text as the user |
200 // text, because it makes little sense to have temporary text when the | 200 // text, because it makes little sense to have temporary text when the |
201 // popup is closed. | 201 // popup is closed. |
202 if (user_input_in_progress_) { | 202 if (user_input_in_progress_) { |
203 // Weird edge case to match other browsers: if the edit is empty, revert to | 203 // Weird edge case to match other browsers: if the edit is empty, revert to |
204 // the permanent text (so the user can get it back easily) but select it (so | 204 // the permanent text (so the user can get it back easily) but select it (so |
205 // on switching back, typing will "just work"). | 205 // on switching back, typing will "just work"). |
206 const base::string16 user_text(UserTextFromDisplayText(view_->GetText())); | 206 const base::string16 display_text = view_->GetText(); |
207 if (user_text.empty()) { | 207 if (MaybePrependKeyword(display_text).empty()) { |
208 base::AutoReset<bool> tmp(&in_revert_, true); | 208 base::AutoReset<bool> tmp(&in_revert_, true); |
209 view_->RevertAll(); | 209 view_->RevertAll(); |
210 view_->SelectAll(true); | 210 view_->SelectAll(true); |
211 } else { | 211 } else { |
212 InternalSetUserText(user_text); | 212 InternalSetUserText(display_text); |
213 } | 213 } |
214 } | 214 } |
215 | 215 |
216 UMA_HISTOGRAM_BOOLEAN("Omnibox.SaveStateForTabSwitch.UserInputInProgress", | 216 UMA_HISTOGRAM_BOOLEAN("Omnibox.SaveStateForTabSwitch.UserInputInProgress", |
217 user_input_in_progress_); | 217 user_input_in_progress_); |
218 return State( | 218 return State( |
219 user_input_in_progress_, user_text_, view_->GetGrayTextAutocompletion(), | 219 user_input_in_progress_, user_text_, view_->GetGrayTextAutocompletion(), |
220 keyword_, is_keyword_hint_, | 220 keyword_, is_keyword_hint_, |
221 controller_->GetToolbarModel()->url_replacement_enabled(), | 221 controller_->GetToolbarModel()->url_replacement_enabled(), |
222 focus_state_, focus_source_, input_); | 222 focus_state_, focus_source_, input_); |
(...skipping 12 matching lines...) Expand all Loading... | |
235 // Restore the autocomplete controller's input, or clear it if this is a new | 235 // Restore the autocomplete controller's input, or clear it if this is a new |
236 // tab. | 236 // tab. |
237 input_ = state ? state->autocomplete_input : AutocompleteInput(); | 237 input_ = state ? state->autocomplete_input : AutocompleteInput(); |
238 if (!state) | 238 if (!state) |
239 return; | 239 return; |
240 | 240 |
241 SetFocusState(state->focus_state, OMNIBOX_FOCUS_CHANGE_TAB_SWITCH); | 241 SetFocusState(state->focus_state, OMNIBOX_FOCUS_CHANGE_TAB_SWITCH); |
242 focus_source_ = state->focus_source; | 242 focus_source_ = state->focus_source; |
243 // Restore any user editing. | 243 // Restore any user editing. |
244 if (state->user_input_in_progress) { | 244 if (state->user_input_in_progress) { |
245 // NOTE: Be sure and set keyword-related state BEFORE invoking | 245 // NOTE: Be sure and set keyword-related state AFTER invoking |
246 // DisplayTextFromUserText(), as its result depends upon this state. | 246 // SetUserText(), as SetUserText() clears the keyword state. |
247 view_->SetUserText(state->user_text, false); | |
247 keyword_ = state->keyword; | 248 keyword_ = state->keyword; |
248 is_keyword_hint_ = state->is_keyword_hint; | 249 is_keyword_hint_ = state->is_keyword_hint; |
249 view_->SetUserText(state->user_text, | |
250 DisplayTextFromUserText(state->user_text), false); | |
251 view_->SetGrayTextAutocompletion(state->gray_text); | 250 view_->SetGrayTextAutocompletion(state->gray_text); |
252 } | 251 } |
253 } | 252 } |
254 | 253 |
255 AutocompleteMatch OmniboxEditModel::CurrentMatch( | 254 AutocompleteMatch OmniboxEditModel::CurrentMatch( |
256 GURL* alternate_nav_url) const { | 255 GURL* alternate_nav_url) const { |
257 // If we have a valid match use it. Otherwise get one for the current text. | 256 // If we have a valid match use it. Otherwise get one for the current text. |
258 AutocompleteMatch match = omnibox_controller_->current_match(); | 257 AutocompleteMatch match = omnibox_controller_->current_match(); |
259 | 258 |
260 if (!match.destination_url.is_valid()) { | 259 if (!match.destination_url.is_valid()) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
301 return visibly_changed_permanent_text; | 300 return visibly_changed_permanent_text; |
302 } | 301 } |
303 | 302 |
304 GURL OmniboxEditModel::PermanentURL() { | 303 GURL OmniboxEditModel::PermanentURL() { |
305 return url_formatter::FixupURL(base::UTF16ToUTF8(permanent_text_), | 304 return url_formatter::FixupURL(base::UTF16ToUTF8(permanent_text_), |
306 std::string()); | 305 std::string()); |
307 } | 306 } |
308 | 307 |
309 void OmniboxEditModel::SetUserText(const base::string16& text) { | 308 void OmniboxEditModel::SetUserText(const base::string16& text) { |
310 SetInputInProgress(true); | 309 SetInputInProgress(true); |
310 keyword_.clear(); | |
311 is_keyword_hint_ = false; | |
Peter Kasting
2016/05/18 03:32:22
What caller(s) of this function require that we cl
Tom (Use chromium acct)
2016/05/18 19:15:35
There were some browser tests that called SetUserT
| |
311 InternalSetUserText(text); | 312 InternalSetUserText(text); |
312 omnibox_controller_->InvalidateCurrentMatch(); | 313 omnibox_controller_->InvalidateCurrentMatch(); |
313 paste_state_ = NONE; | 314 paste_state_ = NONE; |
314 has_temporary_text_ = false; | 315 has_temporary_text_ = false; |
315 } | 316 } |
316 | 317 |
317 bool OmniboxEditModel::CommitSuggestedText() { | 318 bool OmniboxEditModel::CommitSuggestedText() { |
318 const base::string16 suggestion = view_->GetGrayTextAutocompletion(); | 319 const base::string16 suggestion = view_->GetGrayTextAutocompletion(); |
319 if (suggestion.empty()) | 320 if (suggestion.empty()) |
320 return false; | 321 return false; |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
472 view_->SetWindowTextAndCaretPos(permanent_text_, | 473 view_->SetWindowTextAndCaretPos(permanent_text_, |
473 has_focus() ? permanent_text_.length() : 0, | 474 has_focus() ? permanent_text_.length() : 0, |
474 false, true); | 475 false, true); |
475 client_->OnRevert(); | 476 client_->OnRevert(); |
476 } | 477 } |
477 | 478 |
478 void OmniboxEditModel::StartAutocomplete( | 479 void OmniboxEditModel::StartAutocomplete( |
479 bool has_selected_text, | 480 bool has_selected_text, |
480 bool prevent_inline_autocomplete, | 481 bool prevent_inline_autocomplete, |
481 bool entering_keyword_mode) { | 482 bool entering_keyword_mode) { |
482 size_t cursor_position; | 483 size_t cursor_position; |
Peter Kasting
2016/05/18 03:32:22
Nit: Perhaps if up here you added a temp:
const
Tom (Use chromium acct)
2016/05/18 19:15:36
Done.
| |
483 if (inline_autocomplete_text_.empty()) { | 484 if (inline_autocomplete_text_.empty()) { |
484 // Cursor position is equivalent to the current selection's end. | 485 // Cursor position is equivalent to the current selection's end. |
485 size_t start; | 486 size_t start; |
486 view_->GetSelectionBounds(&start, &cursor_position); | 487 view_->GetSelectionBounds(&start, &cursor_position); |
487 // If we're in keyword mode, we're not displaying the full |user_text_|, so | 488 // The text that AutocompleteInput expects is of the form |
Peter Kasting
2016/05/18 03:32:22
Nit: Maybe start this whole comment with "For keyw
Tom (Use chromium acct)
2016/05/18 19:15:35
Done.
| |
488 // the cursor position we got from the view has to be adjusted later by the | 489 // "<keyword><SpaceChar><query>", where our query is |user_text_|. So if |
Peter Kasting
2016/05/18 03:32:22
Nit: I'd just use an actual space in place of "<Sp
Tom (Use chromium acct)
2016/05/18 19:15:35
Done.
| |
489 // length of the undisplayed text. If we're just entering keyword mode, | 490 // we're in keyword mode, we need to adjust the cursor position forward by |
490 // though, we have to avoid making this adjustment, because we haven't | 491 // the length of "<keyword><SpaceChar>". If we're just entering keyword |
491 // actually hidden any text yet, but the caller has already cleared | 492 // mode, though, we have to avoid making this adjustment, because we haven't |
492 // |is_keyword_hint_|, so DisplayTextFromUserText() will believe we are | 493 // actually updated |user_text_| yet, but the caller has already cleared |
493 // already in keyword mode, and will thus mis-adjust the cursor position. | 494 // |is_keyword_hint_|, so MaybeStripKeyword() will believe we are already in |
Peter Kasting
2016/05/18 03:32:22
Nit: Did you mean to say MaybePrependKeyword() her
Tom (Use chromium acct)
2016/05/18 19:15:35
Yes & done
| |
495 // keyword mode, and will thus mis-adjust the cursor position. | |
494 if (!entering_keyword_mode) { | 496 if (!entering_keyword_mode) { |
495 cursor_position += | 497 cursor_position += |
496 user_text_.length() - DisplayTextFromUserText(user_text_).length(); | 498 MaybePrependKeyword(user_text_).length() - user_text_.length(); |
497 } | 499 } |
498 } else { | 500 } else { |
499 // There are some cases where StartAutocomplete() may be called | 501 // There are some cases where StartAutocomplete() may be called |
500 // with non-empty |inline_autocomplete_text_|. In such cases, we cannot | 502 // with non-empty |inline_autocomplete_text_|. In such cases, we cannot |
501 // use the current selection, because it could result with the cursor | 503 // use the current selection, because it could result with the cursor |
502 // position past the last character from the user text. Instead, | 504 // position past the last character from the user text. Instead, |
503 // we assume that the cursor is simply at the end of input. | 505 // we assume that the cursor is simply at the end of input. |
504 // One example is when user presses Ctrl key while having a highlighted | 506 // One example is when user presses Ctrl key while having a highlighted |
505 // inline autocomplete text. | 507 // inline autocomplete text. |
506 // TODO: Rethink how we are going to handle this case to avoid | 508 // TODO: Rethink how we are going to handle this case to avoid |
507 // inconsistent behavior when user presses Ctrl key. | 509 // inconsistent behavior when user presses Ctrl key. |
508 // See http://crbug.com/165961 and http://crbug.com/165968 for more details. | 510 // See http://crbug.com/165961 and http://crbug.com/165968 for more details. |
509 cursor_position = user_text_.length(); | 511 cursor_position = MaybePrependKeyword(user_text_).length(); |
510 } | 512 } |
511 | 513 |
512 GURL current_url; | 514 GURL current_url; |
513 if (client_->CurrentPageExists()) | 515 if (client_->CurrentPageExists()) |
514 current_url = client_->GetURL(); | 516 current_url = client_->GetURL(); |
515 input_ = AutocompleteInput( | 517 input_ = AutocompleteInput( |
516 user_text_, cursor_position, std::string(), current_url, ClassifyPage(), | 518 MaybePrependKeyword(user_text_), cursor_position, std::string(), |
519 current_url, ClassifyPage(), | |
517 prevent_inline_autocomplete || just_deleted_text_ || | 520 prevent_inline_autocomplete || just_deleted_text_ || |
518 (has_selected_text && inline_autocomplete_text_.empty()) || | 521 (has_selected_text && inline_autocomplete_text_.empty()) || |
519 (paste_state_ != NONE), | 522 (paste_state_ != NONE), |
520 is_keyword_selected(), | 523 is_keyword_selected(), |
521 is_keyword_selected() || allow_exact_keyword_match_, true, false, | 524 is_keyword_selected() || allow_exact_keyword_match_, true, false, |
522 client_->GetSchemeClassifier()); | 525 client_->GetSchemeClassifier()); |
523 | 526 |
524 omnibox_controller_->StartAutocomplete(input_); | 527 omnibox_controller_->StartAutocomplete(input_); |
525 } | 528 } |
526 | 529 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
569 autocomplete_controller()->history_url_provider()) { | 572 autocomplete_controller()->history_url_provider()) { |
570 // Generate a new AutocompleteInput, copying the latest one but using "com" | 573 // Generate a new AutocompleteInput, copying the latest one but using "com" |
571 // as the desired TLD. Then use this autocomplete input to generate a | 574 // as the desired TLD. Then use this autocomplete input to generate a |
572 // URL_WHAT_YOU_TYPED AutocompleteMatch. Note that using the most recent | 575 // URL_WHAT_YOU_TYPED AutocompleteMatch. Note that using the most recent |
573 // input instead of the currently visible text means we'll ignore any | 576 // input instead of the currently visible text means we'll ignore any |
574 // visible inline autocompletion: if a user types "foo" and is autocompleted | 577 // visible inline autocompletion: if a user types "foo" and is autocompleted |
575 // to "foodnetwork.com", ctrl-enter will navigate to "foo.com", not | 578 // to "foodnetwork.com", ctrl-enter will navigate to "foo.com", not |
576 // "foodnetwork.com". At the time of writing, this behavior matches | 579 // "foodnetwork.com". At the time of writing, this behavior matches |
577 // Internet Explorer, but not Firefox. | 580 // Internet Explorer, but not Firefox. |
578 input_ = AutocompleteInput( | 581 input_ = AutocompleteInput( |
579 has_temporary_text_ ? UserTextFromDisplayText(view_->GetText()) | 582 has_temporary_text_ ? view_->GetText() : input_.text(), |
580 : input_.text(), | |
581 input_.cursor_position(), "com", GURL(), | 583 input_.cursor_position(), "com", GURL(), |
582 input_.current_page_classification(), | 584 input_.current_page_classification(), |
583 input_.prevent_inline_autocomplete(), input_.prefer_keyword(), | 585 input_.prevent_inline_autocomplete(), input_.prefer_keyword(), |
584 input_.allow_exact_keyword_match(), input_.want_asynchronous_matches(), | 586 input_.allow_exact_keyword_match(), input_.want_asynchronous_matches(), |
585 input_.from_omnibox_focus(), client_->GetSchemeClassifier()); | 587 input_.from_omnibox_focus(), client_->GetSchemeClassifier()); |
586 AutocompleteMatch url_match( | 588 AutocompleteMatch url_match( |
587 autocomplete_controller()->history_url_provider()->SuggestExactInput( | 589 autocomplete_controller()->history_url_provider()->SuggestExactInput( |
588 input_, input_.canonicalized_url(), false)); | 590 input_, input_.canonicalized_url(), false)); |
589 | 591 |
590 if (url_match.destination_url.is_valid()) { | 592 if (url_match.destination_url.is_valid()) { |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
782 if (bookmark_model && bookmark_model->IsBookmarked(match.destination_url)) | 784 if (bookmark_model && bookmark_model->IsBookmarked(match.destination_url)) |
783 client_->OnBookmarkLaunched(); | 785 client_->OnBookmarkLaunched(); |
784 } | 786 } |
785 | 787 |
786 bool OmniboxEditModel::AcceptKeyword(EnteredKeywordModeMethod entered_method) { | 788 bool OmniboxEditModel::AcceptKeyword(EnteredKeywordModeMethod entered_method) { |
787 DCHECK(is_keyword_hint_ && !keyword_.empty()); | 789 DCHECK(is_keyword_hint_ && !keyword_.empty()); |
788 | 790 |
789 autocomplete_controller()->Stop(false); | 791 autocomplete_controller()->Stop(false); |
790 is_keyword_hint_ = false; | 792 is_keyword_hint_ = false; |
791 | 793 |
794 user_text_ = MaybeStripKeyword(user_text_); | |
795 | |
792 if (popup_model() && popup_model()->IsOpen()) | 796 if (popup_model() && popup_model()->IsOpen()) |
793 popup_model()->SetSelectedLineState(OmniboxPopupModel::KEYWORD); | 797 popup_model()->SetSelectedLineState(OmniboxPopupModel::KEYWORD); |
794 else | 798 else |
795 StartAutocomplete(false, true, true); | 799 StartAutocomplete(false, true, true); |
796 | 800 |
797 // When entering keyword mode via tab, the new text to show is whatever the | 801 // When entering keyword mode via tab, the new text to show is whatever the |
798 // newly-selected match in the dropdown is. When entering via space, however, | 802 // newly-selected match in the dropdown is. When entering via space, however, |
799 // we should make sure to use the actual |user_text_| as the basis for the new | 803 // we should make sure to use the actual |user_text_| as the basis for the new |
800 // text. This ensures that if the user types "<keyword><space>" and the | 804 // text. This ensures that if the user types "<keyword><space>" and the |
801 // default match would have inline autocompleted a further string (e.g. | 805 // default match would have inline autocompleted a further string (e.g. |
(...skipping 11 matching lines...) Expand all Loading... | |
813 // comments in ClearKeyword(). | 817 // comments in ClearKeyword(). |
814 if (entered_method == ENTERED_KEYWORD_MODE_VIA_TAB) { | 818 if (entered_method == ENTERED_KEYWORD_MODE_VIA_TAB) { |
815 // Ensure the current selection is saved before showing keyword mode | 819 // Ensure the current selection is saved before showing keyword mode |
816 // so that moving to another line and then reverting the text will restore | 820 // so that moving to another line and then reverting the text will restore |
817 // the current state properly. | 821 // the current state properly. |
818 bool save_original_selection = !has_temporary_text_; | 822 bool save_original_selection = !has_temporary_text_; |
819 has_temporary_text_ = true; | 823 has_temporary_text_ = true; |
820 const AutocompleteMatch& match = CurrentMatch(NULL); | 824 const AutocompleteMatch& match = CurrentMatch(NULL); |
821 original_url_ = match.destination_url; | 825 original_url_ = match.destination_url; |
822 view_->OnTemporaryTextMaybeChanged( | 826 view_->OnTemporaryTextMaybeChanged( |
823 DisplayTextFromUserText(match.fill_into_edit), | 827 MaybeStripKeyword(match.fill_into_edit), save_original_selection, |
824 save_original_selection, true); | 828 true); |
825 } else { | 829 } else { |
826 view_->OnTemporaryTextMaybeChanged(DisplayTextFromUserText(user_text_), | 830 view_->OnTemporaryTextMaybeChanged(user_text_, false, true); |
827 false, true); | |
828 } | 831 } |
829 | 832 |
830 base::RecordAction(base::UserMetricsAction("AcceptedKeywordHint")); | 833 base::RecordAction(base::UserMetricsAction("AcceptedKeywordHint")); |
831 UMA_HISTOGRAM_ENUMERATION(kEnteredKeywordModeHistogram, entered_method, | 834 UMA_HISTOGRAM_ENUMERATION(kEnteredKeywordModeHistogram, entered_method, |
832 ENTERED_KEYWORD_MODE_NUM_ITEMS); | 835 ENTERED_KEYWORD_MODE_NUM_ITEMS); |
833 | 836 |
834 return true; | 837 return true; |
835 } | 838 } |
836 | 839 |
837 void OmniboxEditModel::AcceptTemporaryTextAsUserText() { | 840 void OmniboxEditModel::AcceptTemporaryTextAsUserText() { |
838 InternalSetUserText(UserTextFromDisplayText(view_->GetText())); | 841 InternalSetUserText(view_->GetText()); |
Peter Kasting
2016/05/18 03:32:22
Don't we need to call MaybePrependKeyword() here?
Tom (Use chromium acct)
2016/05/18 19:15:36
InternalSetUserText will not change the keyword (t
| |
839 has_temporary_text_ = false; | 842 has_temporary_text_ = false; |
840 | 843 |
841 if (user_input_in_progress_ || !in_revert_) | 844 if (user_input_in_progress_ || !in_revert_) |
842 client_->OnInputStateChanged(); | 845 client_->OnInputStateChanged(); |
843 } | 846 } |
844 | 847 |
845 void OmniboxEditModel::ClearKeyword() { | 848 void OmniboxEditModel::ClearKeyword() { |
846 autocomplete_controller()->Stop(false); | 849 autocomplete_controller()->Stop(false); |
847 | 850 |
848 // While we're always in keyword mode upon reaching here, sometimes we've just | 851 // While we're always in keyword mode upon reaching here, sometimes we've just |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1063 GURL* destination_for_temporary_text_change, | 1066 GURL* destination_for_temporary_text_change, |
1064 const base::string16& keyword, | 1067 const base::string16& keyword, |
1065 bool is_keyword_hint) { | 1068 bool is_keyword_hint) { |
1066 // The popup changed its data, the match in the controller is no longer valid. | 1069 // The popup changed its data, the match in the controller is no longer valid. |
1067 omnibox_controller_->InvalidateCurrentMatch(); | 1070 omnibox_controller_->InvalidateCurrentMatch(); |
1068 | 1071 |
1069 // Update keyword/hint-related local state. | 1072 // Update keyword/hint-related local state. |
1070 bool keyword_state_changed = (keyword_ != keyword) || | 1073 bool keyword_state_changed = (keyword_ != keyword) || |
1071 ((is_keyword_hint_ != is_keyword_hint) && !keyword.empty()); | 1074 ((is_keyword_hint_ != is_keyword_hint) && !keyword.empty()); |
1072 if (keyword_state_changed) { | 1075 if (keyword_state_changed) { |
1076 bool keyword_was_selected = is_keyword_selected(); | |
1073 keyword_ = keyword; | 1077 keyword_ = keyword; |
1074 is_keyword_hint_ = is_keyword_hint; | 1078 is_keyword_hint_ = is_keyword_hint; |
1079 if(!keyword_was_selected && is_keyword_selected()) { | |
Peter Kasting
2016/05/18 03:32:22
Nit: Space after if
Tom (Use chromium acct)
2016/05/18 19:15:35
Done.
| |
1080 // We just entered keyword mode, so remove the keyword from the query. | |
Peter Kasting
2016/05/18 03:32:22
Nit: query -> input
Tom (Use chromium acct)
2016/05/18 19:15:35
Done.
| |
1081 user_text_ = MaybeStripKeyword(user_text_); | |
1082 } | |
1075 | 1083 |
1076 // |is_keyword_hint_| should always be false if |keyword_| is empty. | 1084 // |is_keyword_hint_| should always be false if |keyword_| is empty. |
1077 DCHECK(!keyword_.empty() || !is_keyword_hint_); | 1085 DCHECK(!keyword_.empty() || !is_keyword_hint_); |
1078 } | 1086 } |
1079 | 1087 |
1080 // Handle changes to temporary text. | 1088 // Handle changes to temporary text. |
1081 if (destination_for_temporary_text_change != NULL) { | 1089 if (destination_for_temporary_text_change != NULL) { |
1082 const bool save_original_selection = !has_temporary_text_; | 1090 const bool save_original_selection = !has_temporary_text_; |
1083 if (save_original_selection) { | 1091 if (save_original_selection) { |
1084 // Save the original selection and URL so it can be reverted later. | 1092 // Save the original selection and URL so it can be reverted later. |
1085 has_temporary_text_ = true; | 1093 has_temporary_text_ = true; |
1086 original_url_ = *destination_for_temporary_text_change; | 1094 original_url_ = *destination_for_temporary_text_change; |
1087 inline_autocomplete_text_.clear(); | 1095 inline_autocomplete_text_.clear(); |
1088 view_->OnInlineAutocompleteTextCleared(); | 1096 view_->OnInlineAutocompleteTextCleared(); |
1089 } | 1097 } |
1090 if (control_key_state_ == DOWN_WITHOUT_CHANGE) { | 1098 if (control_key_state_ == DOWN_WITHOUT_CHANGE) { |
1091 // Arrowing around the popup cancels control-enter. | 1099 // Arrowing around the popup cancels control-enter. |
1092 control_key_state_ = DOWN_WITH_CHANGE; | 1100 control_key_state_ = DOWN_WITH_CHANGE; |
1093 // Now things are a bit screwy: the desired_tld has changed, but if we | 1101 // Now things are a bit screwy: the desired_tld has changed, but if we |
1094 // update the popup, the new order of entries won't match the old, so the | 1102 // update the popup, the new order of entries won't match the old, so the |
1095 // user's selection gets screwy; and if we don't update the popup, and the | 1103 // user's selection gets screwy; and if we don't update the popup, and the |
1096 // user reverts, then the selected item will be as if control is still | 1104 // user reverts, then the selected item will be as if control is still |
1097 // pressed, even though maybe it isn't any more. There is no obvious | 1105 // pressed, even though maybe it isn't any more. There is no obvious |
1098 // right answer here :( | 1106 // right answer here :( |
1099 } | 1107 } |
1100 view_->OnTemporaryTextMaybeChanged(DisplayTextFromUserText(text), | 1108 view_->OnTemporaryTextMaybeChanged(MaybeStripKeyword(text), |
1101 save_original_selection, true); | 1109 save_original_selection, true); |
1102 return; | 1110 return; |
1103 } | 1111 } |
1104 | 1112 |
1105 bool call_controller_onchanged = true; | 1113 bool call_controller_onchanged = true; |
1106 inline_autocomplete_text_ = text; | 1114 inline_autocomplete_text_ = text; |
1107 if (inline_autocomplete_text_.empty()) | 1115 if (inline_autocomplete_text_.empty()) |
1108 view_->OnInlineAutocompleteTextCleared(); | 1116 view_->OnInlineAutocompleteTextCleared(); |
1109 | 1117 |
1110 const base::string16& user_text = | 1118 const base::string16& user_text = |
1111 user_input_in_progress_ ? user_text_ : permanent_text_; | 1119 user_input_in_progress_ ? user_text_ : permanent_text_; |
1112 if (keyword_state_changed && is_keyword_selected()) { | 1120 if (keyword_state_changed && is_keyword_selected()) { |
1113 // If we reach here, the user most likely entered keyword mode by inserting | 1121 // If we reach here, the user most likely entered keyword mode by inserting |
1114 // a space between a keyword name and a search string (as pressing space or | 1122 // a space between a keyword name and a search string (as pressing space or |
1115 // tab after the keyword name alone would have been be handled in | 1123 // tab after the keyword name alone would have been be handled in |
1116 // MaybeAcceptKeywordBySpace() by calling AcceptKeyword(), which won't reach | 1124 // MaybeAcceptKeywordBySpace() by calling AcceptKeyword(), which won't reach |
1117 // here). In this case, we don't want to call | 1125 // here). In this case, we don't want to call |
1118 // OnInlineAutocompleteTextMaybeChanged() as normal, because that will | 1126 // OnInlineAutocompleteTextMaybeChanged() as normal, because that will |
1119 // correctly change the text (to the search string alone) but move the caret | 1127 // correctly change the text (to the search string alone) but move the caret |
1120 // to the end of the string; instead we want the caret at the start of the | 1128 // to the end of the string; instead we want the caret at the start of the |
1121 // search string since that's where it was in the original input. So we set | 1129 // search string since that's where it was in the original input. So we set |
1122 // the text and caret position directly. | 1130 // the text and caret position directly. |
1123 // | 1131 // |
1124 // It may also be possible to reach here if we're reverting from having | 1132 // It may also be possible to reach here if we're reverting from having |
1125 // temporary text back to a default match that's a keyword search, but in | 1133 // temporary text back to a default match that's a keyword search, but in |
1126 // that case the RevertTemporaryText() call below will reset the caret or | 1134 // that case the RevertTemporaryText() call below will reset the caret or |
1127 // selection correctly so the caret positioning we do here won't matter. | 1135 // selection correctly so the caret positioning we do here won't matter. |
1128 view_->SetWindowTextAndCaretPos(DisplayTextFromUserText(user_text), 0, | 1136 view_->SetWindowTextAndCaretPos(user_text, 0, false, false); |
1129 false, false); | |
1130 } else if (view_->OnInlineAutocompleteTextMaybeChanged( | 1137 } else if (view_->OnInlineAutocompleteTextMaybeChanged( |
1131 DisplayTextFromUserText(user_text + inline_autocomplete_text_), | 1138 user_text + inline_autocomplete_text_, user_text.length())) { |
1132 DisplayTextFromUserText(user_text).length())) { | |
1133 call_controller_onchanged = false; | 1139 call_controller_onchanged = false; |
1134 } | 1140 } |
1135 | 1141 |
1136 // If |has_temporary_text_| is true, then we previously had a manual selection | 1142 // If |has_temporary_text_| is true, then we previously had a manual selection |
1137 // but now don't (or |destination_for_temporary_text_change| would have been | 1143 // but now don't (or |destination_for_temporary_text_change| would have been |
1138 // non-NULL). This can happen when deleting the selected item in the popup. | 1144 // non-NULL). This can happen when deleting the selected item in the popup. |
1139 // In this case, we've already reverted the popup to the default match, so we | 1145 // In this case, we've already reverted the popup to the default match, so we |
1140 // need to revert ourselves as well. | 1146 // need to revert ourselves as well. |
1141 if (has_temporary_text_) { | 1147 if (has_temporary_text_) { |
1142 RevertTemporaryText(false); | 1148 RevertTemporaryText(false); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1192 if ((text_differs || selection_differs) && | 1198 if ((text_differs || selection_differs) && |
1193 (control_key_state_ == DOWN_WITHOUT_CHANGE)) | 1199 (control_key_state_ == DOWN_WITHOUT_CHANGE)) |
1194 control_key_state_ = DOWN_WITH_CHANGE; | 1200 control_key_state_ = DOWN_WITH_CHANGE; |
1195 | 1201 |
1196 if (!user_text_changed) | 1202 if (!user_text_changed) |
1197 return false; | 1203 return false; |
1198 | 1204 |
1199 // If the user text has not changed, we do not want to change the model's | 1205 // If the user text has not changed, we do not want to change the model's |
1200 // state associated with the text. Otherwise, we can get surprising behavior | 1206 // state associated with the text. Otherwise, we can get surprising behavior |
1201 // where the autocompleted text unexpectedly reappears, e.g. crbug.com/55983 | 1207 // where the autocompleted text unexpectedly reappears, e.g. crbug.com/55983 |
1202 InternalSetUserText(UserTextFromDisplayText(new_text)); | 1208 InternalSetUserText(new_text); |
1203 has_temporary_text_ = false; | 1209 has_temporary_text_ = false; |
1204 | 1210 |
1205 // Track when the user has deleted text so we won't allow inline | 1211 // Track when the user has deleted text so we won't allow inline |
1206 // autocomplete. | 1212 // autocomplete. |
1207 just_deleted_text_ = just_deleted_text; | 1213 just_deleted_text_ = just_deleted_text; |
1208 | 1214 |
1209 if (user_input_in_progress_ && user_text_.empty()) { | 1215 if (user_input_in_progress_ && user_text_.empty()) { |
1210 // Log cases where the user started editing and then subsequently cleared | 1216 // Log cases where the user started editing and then subsequently cleared |
1211 // all the text. Note that this explicitly doesn't catch cases like | 1217 // all the text. Note that this explicitly doesn't catch cases like |
1212 // "hit ctrl-l to select whole edit contents, then hit backspace", because | 1218 // "hit ctrl-l to select whole edit contents, then hit backspace", because |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1287 user_text_ = text; | 1293 user_text_ = text; |
1288 just_deleted_text_ = false; | 1294 just_deleted_text_ = false; |
1289 inline_autocomplete_text_.clear(); | 1295 inline_autocomplete_text_.clear(); |
1290 view_->OnInlineAutocompleteTextCleared(); | 1296 view_->OnInlineAutocompleteTextCleared(); |
1291 } | 1297 } |
1292 | 1298 |
1293 void OmniboxEditModel::ClearPopupKeywordMode() const { | 1299 void OmniboxEditModel::ClearPopupKeywordMode() const { |
1294 omnibox_controller_->ClearPopupKeywordMode(); | 1300 omnibox_controller_->ClearPopupKeywordMode(); |
1295 } | 1301 } |
1296 | 1302 |
1297 base::string16 OmniboxEditModel::DisplayTextFromUserText( | 1303 base::string16 OmniboxEditModel::MaybeStripKeyword( |
1298 const base::string16& text) const { | 1304 const base::string16& text) const { |
1299 return is_keyword_selected() ? | 1305 return is_keyword_selected() ? |
1300 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; | 1306 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; |
1301 } | 1307 } |
1302 | 1308 |
1303 base::string16 OmniboxEditModel::UserTextFromDisplayText( | 1309 base::string16 OmniboxEditModel::MaybePrependKeyword( |
1304 const base::string16& text) const { | 1310 const base::string16& text) const { |
1305 return is_keyword_selected() ? (keyword_ + base::char16(' ') + text) : text; | 1311 return is_keyword_selected() ? (keyword_ + base::char16(' ') + text) : text; |
1306 } | 1312 } |
1307 | 1313 |
1308 void OmniboxEditModel::GetInfoForCurrentText(AutocompleteMatch* match, | 1314 void OmniboxEditModel::GetInfoForCurrentText(AutocompleteMatch* match, |
1309 GURL* alternate_nav_url) const { | 1315 GURL* alternate_nav_url) const { |
1310 DCHECK(match != NULL); | 1316 DCHECK(match != NULL); |
1311 | 1317 |
1312 if (controller_->GetToolbarModel()->WouldPerformSearchTermReplacement( | 1318 if (controller_->GetToolbarModel()->WouldPerformSearchTermReplacement( |
1313 false)) { | 1319 false)) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1345 result().match_at(popup_model()->selected_line()); | 1351 result().match_at(popup_model()->selected_line()); |
1346 *match = | 1352 *match = |
1347 (popup_model()->selected_line_state() == OmniboxPopupModel::KEYWORD) ? | 1353 (popup_model()->selected_line_state() == OmniboxPopupModel::KEYWORD) ? |
1348 *selected_match.associated_keyword : selected_match; | 1354 *selected_match.associated_keyword : selected_match; |
1349 } | 1355 } |
1350 if (alternate_nav_url && | 1356 if (alternate_nav_url && |
1351 (!popup_model() || popup_model()->manually_selected_match().empty())) | 1357 (!popup_model() || popup_model()->manually_selected_match().empty())) |
1352 *alternate_nav_url = result().alternate_nav_url(); | 1358 *alternate_nav_url = result().alternate_nav_url(); |
1353 } else { | 1359 } else { |
1354 client_->GetAutocompleteClassifier()->Classify( | 1360 client_->GetAutocompleteClassifier()->Classify( |
1355 UserTextFromDisplayText(view_->GetText()), is_keyword_selected(), true, | 1361 MaybePrependKeyword(view_->GetText()), is_keyword_selected(), true, |
1356 ClassifyPage(), match, alternate_nav_url); | 1362 ClassifyPage(), match, alternate_nav_url); |
1357 } | 1363 } |
1358 } | 1364 } |
1359 | 1365 |
1360 void OmniboxEditModel::RevertTemporaryText(bool revert_popup) { | 1366 void OmniboxEditModel::RevertTemporaryText(bool revert_popup) { |
1361 // The user typed something, then selected a different item. Restore the | 1367 // The user typed something, then selected a different item. Restore the |
1362 // text they typed and change back to the default item. | 1368 // text they typed and change back to the default item. |
1363 // NOTE: This purposefully does not reset paste_state_. | 1369 // NOTE: This purposefully does not reset paste_state_. |
1364 just_deleted_text_ = false; | 1370 just_deleted_text_ = false; |
1365 has_temporary_text_ = false; | 1371 has_temporary_text_ = false; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1463 // Update state and notify view if the omnibox has focus and the caret | 1469 // Update state and notify view if the omnibox has focus and the caret |
1464 // visibility changed. | 1470 // visibility changed. |
1465 const bool was_caret_visible = is_caret_visible(); | 1471 const bool was_caret_visible = is_caret_visible(); |
1466 focus_state_ = state; | 1472 focus_state_ = state; |
1467 if (focus_state_ != OMNIBOX_FOCUS_NONE && | 1473 if (focus_state_ != OMNIBOX_FOCUS_NONE && |
1468 is_caret_visible() != was_caret_visible) | 1474 is_caret_visible() != was_caret_visible) |
1469 view_->ApplyCaretVisibility(); | 1475 view_->ApplyCaretVisibility(); |
1470 | 1476 |
1471 client_->OnFocusChanged(focus_state_, reason); | 1477 client_->OnFocusChanged(focus_state_, reason); |
1472 } | 1478 } |
OLD | NEW |