Chromium Code Reviews| 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 user_text(user_text_); |
| 207 if (user_text.empty()) { | 207 if (user_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(user_text); |
| 213 } | 213 } |
| 214 } | 214 } |
| 215 | 215 |
| 216 UMA_HISTOGRAM_BOOLEAN("Omnibox.SaveStateForTabSwitch.UserInputInProgress", | 216 UMA_HISTOGRAM_BOOLEAN("Omnibox.SaveStateForTabSwitch.UserInputInProgress", |
| (...skipping 18 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 | |
| 246 // DisplayTextFromUserText(), as its result depends upon this state. | |
| 247 keyword_ = state->keyword; | 245 keyword_ = state->keyword; |
| 248 is_keyword_hint_ = state->is_keyword_hint; | 246 is_keyword_hint_ = state->is_keyword_hint; |
| 249 view_->SetUserText(state->user_text, | 247 view_->SetUserText(state->user_text, |
| 250 DisplayTextFromUserText(state->user_text), false); | 248 state->user_text, false); |
|
Peter Kasting
2016/05/07 01:42:39
Nit: Rewrap
Tom (Use chromium acct)
2016/05/09 18:53:48
Done.
| |
| 251 view_->SetGrayTextAutocompletion(state->gray_text); | 249 view_->SetGrayTextAutocompletion(state->gray_text); |
| 252 } | 250 } |
| 253 } | 251 } |
| 254 | 252 |
| 255 AutocompleteMatch OmniboxEditModel::CurrentMatch( | 253 AutocompleteMatch OmniboxEditModel::CurrentMatch( |
| 256 GURL* alternate_nav_url) const { | 254 GURL* alternate_nav_url) const { |
| 257 // If we have a valid match use it. Otherwise get one for the current text. | 255 // If we have a valid match use it. Otherwise get one for the current text. |
| 258 AutocompleteMatch match = omnibox_controller_->current_match(); | 256 AutocompleteMatch match = omnibox_controller_->current_match(); |
| 259 | 257 |
| 260 if (!match.destination_url.is_valid()) { | 258 if (!match.destination_url.is_valid()) { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 330 void OmniboxEditModel::OnChanged() { | 328 void OmniboxEditModel::OnChanged() { |
| 331 // Hide any suggestions we might be showing. | 329 // Hide any suggestions we might be showing. |
| 332 view_->SetGrayTextAutocompletion(base::string16()); | 330 view_->SetGrayTextAutocompletion(base::string16()); |
| 333 | 331 |
| 334 // Don't call CurrentMatch() when there's no editing, as in this case we'll | 332 // Don't call CurrentMatch() when there's no editing, as in this case we'll |
| 335 // never actually use it. This avoids running the autocomplete providers (and | 333 // never actually use it. This avoids running the autocomplete providers (and |
| 336 // any systems they then spin up) during startup. | 334 // any systems they then spin up) during startup. |
| 337 const AutocompleteMatch& current_match = user_input_in_progress_ ? | 335 const AutocompleteMatch& current_match = user_input_in_progress_ ? |
| 338 CurrentMatch(NULL) : AutocompleteMatch(); | 336 CurrentMatch(NULL) : AutocompleteMatch(); |
| 339 | 337 |
| 340 client_->OnTextChanged(current_match, user_input_in_progress_, user_text_, | 338 base::string16 temp(MaybePrependKeyword(user_text_)); |
| 341 result(), popup_model() && popup_model()->IsOpen(), | 339 |
| 342 has_focus()); | 340 client_->OnTextChanged(current_match, user_input_in_progress_, |
| 341 temp, result(), | |
| 342 popup_model() && popup_model()->IsOpen(), has_focus()); | |
| 343 user_text_ = MaybeStripKeyword(temp); | |
|
Peter Kasting
2016/05/07 01:42:39
(1) Why is this line necessary? If the call above
Tom (Use chromium acct)
2016/05/09 18:53:48
I wasn't 100% sure if the behavior of OmniboxClien
| |
| 343 controller_->OnChanged(); | 344 controller_->OnChanged(); |
| 344 } | 345 } |
| 345 | 346 |
| 346 void OmniboxEditModel::GetDataForURLExport(GURL* url, | 347 void OmniboxEditModel::GetDataForURLExport(GURL* url, |
| 347 base::string16* title, | 348 base::string16* title, |
| 348 gfx::Image* favicon) { | 349 gfx::Image* favicon) { |
| 349 *url = CurrentMatch(NULL).destination_url; | 350 *url = CurrentMatch(NULL).destination_url; |
| 350 if (*url == client_->GetURL()) { | 351 if (*url == client_->GetURL()) { |
| 351 *title = client_->GetTitle(); | 352 *title = client_->GetTitle(); |
| 352 *favicon = client_->GetFavicon(); | 353 *favicon = client_->GetFavicon(); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 482 size_t cursor_position; | 483 size_t cursor_position; |
| 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 // If we're in keyword mode, we're not displaying the full |user_text_|, so |
| 488 // the cursor position we got from the view has to be adjusted later by the | 489 // the cursor position we got from the view has to be adjusted later by the |
| 489 // length of the undisplayed text. If we're just entering keyword mode, | 490 // length of the undisplayed text. If we're just entering keyword mode, |
| 490 // though, we have to avoid making this adjustment, because we haven't | 491 // though, we have to avoid making this adjustment, because we haven't |
| 491 // actually hidden any text yet, but the caller has already cleared | 492 // actually hidden any text yet, but the caller has already cleared |
| 492 // |is_keyword_hint_|, so DisplayTextFromUserText() will believe we are | 493 // |is_keyword_hint_|, so MaybeStripKeyword() will believe we are |
| 493 // already in keyword mode, and will thus mis-adjust the cursor position. | 494 // already in keyword mode, and will thus mis-adjust the cursor position. |
| 494 if (!entering_keyword_mode) { | 495 if (!entering_keyword_mode) { |
| 495 cursor_position += | 496 cursor_position += |
| 496 user_text_.length() - DisplayTextFromUserText(user_text_).length(); | 497 user_text_.length() - user_text_.length(); |
|
Peter Kasting
2016/05/07 01:42:39
Nit: Rewrap
Tom (Use chromium acct)
2016/05/09 18:53:48
Done.
| |
| 497 } | 498 } |
| 498 } else { | 499 } else { |
| 499 // There are some cases where StartAutocomplete() may be called | 500 // There are some cases where StartAutocomplete() may be called |
| 500 // with non-empty |inline_autocomplete_text_|. In such cases, we cannot | 501 // with non-empty |inline_autocomplete_text_|. In such cases, we cannot |
| 501 // use the current selection, because it could result with the cursor | 502 // use the current selection, because it could result with the cursor |
| 502 // position past the last character from the user text. Instead, | 503 // position past the last character from the user text. Instead, |
| 503 // we assume that the cursor is simply at the end of input. | 504 // 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 | 505 // One example is when user presses Ctrl key while having a highlighted |
| 505 // inline autocomplete text. | 506 // inline autocomplete text. |
| 506 // TODO: Rethink how we are going to handle this case to avoid | 507 // TODO: Rethink how we are going to handle this case to avoid |
| 507 // inconsistent behavior when user presses Ctrl key. | 508 // inconsistent behavior when user presses Ctrl key. |
| 508 // See http://crbug.com/165961 and http://crbug.com/165968 for more details. | 509 // See http://crbug.com/165961 and http://crbug.com/165968 for more details. |
| 509 cursor_position = user_text_.length(); | 510 cursor_position = MaybePrependKeyword(user_text_).length(); |
| 510 } | 511 } |
| 511 | 512 |
| 512 GURL current_url; | 513 GURL current_url; |
| 513 if (client_->CurrentPageExists()) | 514 if (client_->CurrentPageExists()) |
| 514 current_url = client_->GetURL(); | 515 current_url = client_->GetURL(); |
| 515 input_ = AutocompleteInput( | 516 input_ = AutocompleteInput( |
| 516 user_text_, cursor_position, std::string(), current_url, ClassifyPage(), | 517 MaybePrependKeyword(user_text_), cursor_position, std::string(), |
| 518 current_url, ClassifyPage(), | |
| 517 prevent_inline_autocomplete || just_deleted_text_ || | 519 prevent_inline_autocomplete || just_deleted_text_ || |
| 518 (has_selected_text && inline_autocomplete_text_.empty()) || | 520 (has_selected_text && inline_autocomplete_text_.empty()) || |
| 519 (paste_state_ != NONE), | 521 (paste_state_ != NONE), |
| 520 is_keyword_selected(), | 522 is_keyword_selected(), |
| 521 is_keyword_selected() || allow_exact_keyword_match_, true, false, | 523 is_keyword_selected() || allow_exact_keyword_match_, true, false, |
| 522 client_->GetSchemeClassifier()); | 524 client_->GetSchemeClassifier()); |
| 523 | 525 |
| 524 omnibox_controller_->StartAutocomplete(input_); | 526 omnibox_controller_->StartAutocomplete(input_); |
| 525 } | 527 } |
| 526 | 528 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 569 autocomplete_controller()->history_url_provider()) { | 571 autocomplete_controller()->history_url_provider()) { |
| 570 // Generate a new AutocompleteInput, copying the latest one but using "com" | 572 // Generate a new AutocompleteInput, copying the latest one but using "com" |
| 571 // as the desired TLD. Then use this autocomplete input to generate a | 573 // as the desired TLD. Then use this autocomplete input to generate a |
| 572 // URL_WHAT_YOU_TYPED AutocompleteMatch. Note that using the most recent | 574 // URL_WHAT_YOU_TYPED AutocompleteMatch. Note that using the most recent |
| 573 // input instead of the currently visible text means we'll ignore any | 575 // input instead of the currently visible text means we'll ignore any |
| 574 // visible inline autocompletion: if a user types "foo" and is autocompleted | 576 // visible inline autocompletion: if a user types "foo" and is autocompleted |
| 575 // to "foodnetwork.com", ctrl-enter will navigate to "foo.com", not | 577 // to "foodnetwork.com", ctrl-enter will navigate to "foo.com", not |
| 576 // "foodnetwork.com". At the time of writing, this behavior matches | 578 // "foodnetwork.com". At the time of writing, this behavior matches |
| 577 // Internet Explorer, but not Firefox. | 579 // Internet Explorer, but not Firefox. |
| 578 input_ = AutocompleteInput( | 580 input_ = AutocompleteInput( |
| 579 has_temporary_text_ ? UserTextFromDisplayText(view_->GetText()) | 581 has_temporary_text_ ? MaybePrependKeyword(user_text_) : input_.text(), |
| 580 : input_.text(), | |
| 581 input_.cursor_position(), "com", GURL(), | 582 input_.cursor_position(), "com", GURL(), |
| 582 input_.current_page_classification(), | 583 input_.current_page_classification(), |
| 583 input_.prevent_inline_autocomplete(), input_.prefer_keyword(), | 584 input_.prevent_inline_autocomplete(), input_.prefer_keyword(), |
| 584 input_.allow_exact_keyword_match(), input_.want_asynchronous_matches(), | 585 input_.allow_exact_keyword_match(), input_.want_asynchronous_matches(), |
| 585 input_.from_omnibox_focus(), client_->GetSchemeClassifier()); | 586 input_.from_omnibox_focus(), client_->GetSchemeClassifier()); |
| 586 AutocompleteMatch url_match( | 587 AutocompleteMatch url_match( |
| 587 autocomplete_controller()->history_url_provider()->SuggestExactInput( | 588 autocomplete_controller()->history_url_provider()->SuggestExactInput( |
| 588 input_, input_.canonicalized_url(), false)); | 589 input_, input_.canonicalized_url(), false)); |
| 589 | 590 |
| 590 if (url_match.destination_url.is_valid()) { | 591 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)) | 783 if (bookmark_model && bookmark_model->IsBookmarked(match.destination_url)) |
| 783 client_->OnBookmarkLaunched(); | 784 client_->OnBookmarkLaunched(); |
| 784 } | 785 } |
| 785 | 786 |
| 786 bool OmniboxEditModel::AcceptKeyword(EnteredKeywordModeMethod entered_method) { | 787 bool OmniboxEditModel::AcceptKeyword(EnteredKeywordModeMethod entered_method) { |
| 787 DCHECK(is_keyword_hint_ && !keyword_.empty()); | 788 DCHECK(is_keyword_hint_ && !keyword_.empty()); |
| 788 | 789 |
| 789 autocomplete_controller()->Stop(false); | 790 autocomplete_controller()->Stop(false); |
| 790 is_keyword_hint_ = false; | 791 is_keyword_hint_ = false; |
| 791 | 792 |
| 793 user_text_ = MaybeStripKeyword(user_text_); | |
| 794 | |
| 792 if (popup_model() && popup_model()->IsOpen()) | 795 if (popup_model() && popup_model()->IsOpen()) |
| 793 popup_model()->SetSelectedLineState(OmniboxPopupModel::KEYWORD); | 796 popup_model()->SetSelectedLineState(OmniboxPopupModel::KEYWORD); |
| 794 else | 797 else |
| 795 StartAutocomplete(false, true, true); | 798 StartAutocomplete(false, true, true); |
| 796 | 799 |
| 797 // When entering keyword mode via tab, the new text to show is whatever the | 800 // 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, | 801 // 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 | 802 // 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 | 803 // text. This ensures that if the user types "<keyword><space>" and the |
| 801 // default match would have inline autocompleted a further string (e.g. | 804 // default match would have inline autocompleted a further string (e.g. |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 813 // comments in ClearKeyword(). | 816 // comments in ClearKeyword(). |
| 814 if (entered_method == ENTERED_KEYWORD_MODE_VIA_TAB) { | 817 if (entered_method == ENTERED_KEYWORD_MODE_VIA_TAB) { |
| 815 // Ensure the current selection is saved before showing keyword mode | 818 // Ensure the current selection is saved before showing keyword mode |
| 816 // so that moving to another line and then reverting the text will restore | 819 // so that moving to another line and then reverting the text will restore |
| 817 // the current state properly. | 820 // the current state properly. |
| 818 bool save_original_selection = !has_temporary_text_; | 821 bool save_original_selection = !has_temporary_text_; |
| 819 has_temporary_text_ = true; | 822 has_temporary_text_ = true; |
| 820 const AutocompleteMatch& match = CurrentMatch(NULL); | 823 const AutocompleteMatch& match = CurrentMatch(NULL); |
| 821 original_url_ = match.destination_url; | 824 original_url_ = match.destination_url; |
| 822 view_->OnTemporaryTextMaybeChanged( | 825 view_->OnTemporaryTextMaybeChanged( |
| 823 DisplayTextFromUserText(match.fill_into_edit), | 826 MaybeStripKeyword(match.fill_into_edit), save_original_selection, |
| 824 save_original_selection, true); | 827 true); |
| 825 } else { | 828 } else { |
| 826 view_->OnTemporaryTextMaybeChanged(DisplayTextFromUserText(user_text_), | 829 view_->OnTemporaryTextMaybeChanged(user_text_, false, true); |
| 827 false, true); | |
| 828 } | 830 } |
| 829 | 831 |
| 830 base::RecordAction(base::UserMetricsAction("AcceptedKeywordHint")); | 832 base::RecordAction(base::UserMetricsAction("AcceptedKeywordHint")); |
| 831 UMA_HISTOGRAM_ENUMERATION(kEnteredKeywordModeHistogram, entered_method, | 833 UMA_HISTOGRAM_ENUMERATION(kEnteredKeywordModeHistogram, entered_method, |
| 832 ENTERED_KEYWORD_MODE_NUM_ITEMS); | 834 ENTERED_KEYWORD_MODE_NUM_ITEMS); |
| 833 | 835 |
| 834 return true; | 836 return true; |
| 835 } | 837 } |
| 836 | 838 |
| 837 void OmniboxEditModel::AcceptTemporaryTextAsUserText() { | 839 void OmniboxEditModel::AcceptTemporaryTextAsUserText() { |
| 838 InternalSetUserText(UserTextFromDisplayText(view_->GetText())); | 840 InternalSetUserText(view_->GetText()); |
| 839 has_temporary_text_ = false; | 841 has_temporary_text_ = false; |
| 840 | 842 |
| 841 if (user_input_in_progress_ || !in_revert_) | 843 if (user_input_in_progress_ || !in_revert_) |
| 842 client_->OnInputStateChanged(); | 844 client_->OnInputStateChanged(); |
| 843 } | 845 } |
| 844 | 846 |
| 845 void OmniboxEditModel::ClearKeyword() { | 847 void OmniboxEditModel::ClearKeyword() { |
| 846 autocomplete_controller()->Stop(false); | 848 autocomplete_controller()->Stop(false); |
| 847 | 849 |
| 848 // While we're always in keyword mode upon reaching here, sometimes we've just | 850 // While we're always in keyword mode upon reaching here, sometimes we've just |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1065 bool is_keyword_hint) { | 1067 bool is_keyword_hint) { |
| 1066 // The popup changed its data, the match in the controller is no longer valid. | 1068 // The popup changed its data, the match in the controller is no longer valid. |
| 1067 omnibox_controller_->InvalidateCurrentMatch(); | 1069 omnibox_controller_->InvalidateCurrentMatch(); |
| 1068 | 1070 |
| 1069 // Update keyword/hint-related local state. | 1071 // Update keyword/hint-related local state. |
| 1070 bool keyword_state_changed = (keyword_ != keyword) || | 1072 bool keyword_state_changed = (keyword_ != keyword) || |
| 1071 ((is_keyword_hint_ != is_keyword_hint) && !keyword.empty()); | 1073 ((is_keyword_hint_ != is_keyword_hint) && !keyword.empty()); |
| 1072 if (keyword_state_changed) { | 1074 if (keyword_state_changed) { |
| 1073 keyword_ = keyword; | 1075 keyword_ = keyword; |
| 1074 is_keyword_hint_ = is_keyword_hint; | 1076 is_keyword_hint_ = is_keyword_hint; |
| 1077 user_text_ = MaybeStripKeyword(user_text_); | |
|
Peter Kasting
2016/05/07 01:42:39
When will this be needed? I'd think AcceptKeyword
Tom (Use chromium acct)
2016/05/09 18:53:48
CreatedKeywordSearchByInsertingSpaceInMiddle. I n
| |
| 1075 | 1078 |
| 1076 // |is_keyword_hint_| should always be false if |keyword_| is empty. | 1079 // |is_keyword_hint_| should always be false if |keyword_| is empty. |
| 1077 DCHECK(!keyword_.empty() || !is_keyword_hint_); | 1080 DCHECK(!keyword_.empty() || !is_keyword_hint_); |
| 1078 } | 1081 } |
| 1079 | 1082 |
| 1080 // Handle changes to temporary text. | 1083 // Handle changes to temporary text. |
| 1081 if (destination_for_temporary_text_change != NULL) { | 1084 if (destination_for_temporary_text_change != NULL) { |
| 1082 const bool save_original_selection = !has_temporary_text_; | 1085 const bool save_original_selection = !has_temporary_text_; |
| 1083 if (save_original_selection) { | 1086 if (save_original_selection) { |
| 1084 // Save the original selection and URL so it can be reverted later. | 1087 // Save the original selection and URL so it can be reverted later. |
| 1085 has_temporary_text_ = true; | 1088 has_temporary_text_ = true; |
| 1086 original_url_ = *destination_for_temporary_text_change; | 1089 original_url_ = *destination_for_temporary_text_change; |
| 1087 inline_autocomplete_text_.clear(); | 1090 inline_autocomplete_text_.clear(); |
| 1088 view_->OnInlineAutocompleteTextCleared(); | 1091 view_->OnInlineAutocompleteTextCleared(); |
| 1089 } | 1092 } |
| 1090 if (control_key_state_ == DOWN_WITHOUT_CHANGE) { | 1093 if (control_key_state_ == DOWN_WITHOUT_CHANGE) { |
| 1091 // Arrowing around the popup cancels control-enter. | 1094 // Arrowing around the popup cancels control-enter. |
| 1092 control_key_state_ = DOWN_WITH_CHANGE; | 1095 control_key_state_ = DOWN_WITH_CHANGE; |
| 1093 // Now things are a bit screwy: the desired_tld has changed, but if we | 1096 // 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 | 1097 // 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 | 1098 // 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 | 1099 // 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 | 1100 // pressed, even though maybe it isn't any more. There is no obvious |
| 1098 // right answer here :( | 1101 // right answer here :( |
| 1099 } | 1102 } |
| 1100 view_->OnTemporaryTextMaybeChanged(DisplayTextFromUserText(text), | 1103 view_->OnTemporaryTextMaybeChanged(MaybeStripKeyword(text), |
| 1101 save_original_selection, true); | 1104 save_original_selection, true); |
| 1102 return; | 1105 return; |
| 1103 } | 1106 } |
| 1104 | 1107 |
| 1105 bool call_controller_onchanged = true; | 1108 bool call_controller_onchanged = true; |
| 1106 inline_autocomplete_text_ = text; | 1109 inline_autocomplete_text_ = text; |
| 1107 if (inline_autocomplete_text_.empty()) | 1110 if (inline_autocomplete_text_.empty()) |
| 1108 view_->OnInlineAutocompleteTextCleared(); | 1111 view_->OnInlineAutocompleteTextCleared(); |
| 1109 | 1112 |
| 1110 const base::string16& user_text = | 1113 const base::string16& user_text = |
| 1111 user_input_in_progress_ ? user_text_ : permanent_text_; | 1114 user_input_in_progress_ ? user_text_ : permanent_text_; |
| 1112 if (keyword_state_changed && is_keyword_selected()) { | 1115 if (keyword_state_changed && is_keyword_selected()) { |
| 1113 // If we reach here, the user most likely entered keyword mode by inserting | 1116 // 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 | 1117 // 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 | 1118 // tab after the keyword name alone would have been be handled in |
| 1116 // MaybeAcceptKeywordBySpace() by calling AcceptKeyword(), which won't reach | 1119 // MaybeAcceptKeywordBySpace() by calling AcceptKeyword(), which won't reach |
| 1117 // here). In this case, we don't want to call | 1120 // here). In this case, we don't want to call |
| 1118 // OnInlineAutocompleteTextMaybeChanged() as normal, because that will | 1121 // OnInlineAutocompleteTextMaybeChanged() as normal, because that will |
| 1119 // correctly change the text (to the search string alone) but move the caret | 1122 // 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 | 1123 // 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 | 1124 // search string since that's where it was in the original input. So we set |
| 1122 // the text and caret position directly. | 1125 // the text and caret position directly. |
| 1123 // | 1126 // |
| 1124 // It may also be possible to reach here if we're reverting from having | 1127 // 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 | 1128 // 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 | 1129 // that case the RevertTemporaryText() call below will reset the caret or |
| 1127 // selection correctly so the caret positioning we do here won't matter. | 1130 // selection correctly so the caret positioning we do here won't matter. |
| 1128 view_->SetWindowTextAndCaretPos(DisplayTextFromUserText(user_text), 0, | 1131 view_->SetWindowTextAndCaretPos(user_text, 0, false, false); |
| 1129 false, false); | |
| 1130 } else if (view_->OnInlineAutocompleteTextMaybeChanged( | 1132 } else if (view_->OnInlineAutocompleteTextMaybeChanged( |
| 1131 DisplayTextFromUserText(user_text + inline_autocomplete_text_), | 1133 user_text + inline_autocomplete_text_, user_text.length())) { |
| 1132 DisplayTextFromUserText(user_text).length())) { | |
| 1133 call_controller_onchanged = false; | 1134 call_controller_onchanged = false; |
| 1134 } | 1135 } |
| 1135 | 1136 |
| 1136 // If |has_temporary_text_| is true, then we previously had a manual selection | 1137 // 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 | 1138 // 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. | 1139 // 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 | 1140 // In this case, we've already reverted the popup to the default match, so we |
| 1140 // need to revert ourselves as well. | 1141 // need to revert ourselves as well. |
| 1141 if (has_temporary_text_) { | 1142 if (has_temporary_text_) { |
| 1142 RevertTemporaryText(false); | 1143 RevertTemporaryText(false); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1192 if ((text_differs || selection_differs) && | 1193 if ((text_differs || selection_differs) && |
| 1193 (control_key_state_ == DOWN_WITHOUT_CHANGE)) | 1194 (control_key_state_ == DOWN_WITHOUT_CHANGE)) |
| 1194 control_key_state_ = DOWN_WITH_CHANGE; | 1195 control_key_state_ = DOWN_WITH_CHANGE; |
| 1195 | 1196 |
| 1196 if (!user_text_changed) | 1197 if (!user_text_changed) |
| 1197 return false; | 1198 return false; |
| 1198 | 1199 |
| 1199 // If the user text has not changed, we do not want to change the model's | 1200 // 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 | 1201 // state associated with the text. Otherwise, we can get surprising behavior |
| 1201 // where the autocompleted text unexpectedly reappears, e.g. crbug.com/55983 | 1202 // where the autocompleted text unexpectedly reappears, e.g. crbug.com/55983 |
| 1202 InternalSetUserText(UserTextFromDisplayText(new_text)); | 1203 InternalSetUserText(new_text); |
| 1203 has_temporary_text_ = false; | 1204 has_temporary_text_ = false; |
| 1204 | 1205 |
| 1205 // Track when the user has deleted text so we won't allow inline | 1206 // Track when the user has deleted text so we won't allow inline |
| 1206 // autocomplete. | 1207 // autocomplete. |
| 1207 just_deleted_text_ = just_deleted_text; | 1208 just_deleted_text_ = just_deleted_text; |
| 1208 | 1209 |
| 1209 if (user_input_in_progress_ && user_text_.empty()) { | 1210 if (user_input_in_progress_ && user_text_.empty()) { |
| 1210 // Log cases where the user started editing and then subsequently cleared | 1211 // Log cases where the user started editing and then subsequently cleared |
| 1211 // all the text. Note that this explicitly doesn't catch cases like | 1212 // 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 | 1213 // "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; | 1288 user_text_ = text; |
| 1288 just_deleted_text_ = false; | 1289 just_deleted_text_ = false; |
| 1289 inline_autocomplete_text_.clear(); | 1290 inline_autocomplete_text_.clear(); |
| 1290 view_->OnInlineAutocompleteTextCleared(); | 1291 view_->OnInlineAutocompleteTextCleared(); |
| 1291 } | 1292 } |
| 1292 | 1293 |
| 1293 void OmniboxEditModel::ClearPopupKeywordMode() const { | 1294 void OmniboxEditModel::ClearPopupKeywordMode() const { |
| 1294 omnibox_controller_->ClearPopupKeywordMode(); | 1295 omnibox_controller_->ClearPopupKeywordMode(); |
| 1295 } | 1296 } |
| 1296 | 1297 |
| 1297 base::string16 OmniboxEditModel::DisplayTextFromUserText( | 1298 base::string16 OmniboxEditModel::MaybeStripKeyword( |
| 1298 const base::string16& text) const { | 1299 const base::string16& text) const { |
| 1299 return is_keyword_selected() ? | 1300 return is_keyword_selected() ? |
| 1300 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; | 1301 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; |
| 1301 } | 1302 } |
| 1302 | 1303 |
| 1303 base::string16 OmniboxEditModel::UserTextFromDisplayText( | 1304 base::string16 OmniboxEditModel::MaybePrependKeyword( |
| 1304 const base::string16& text) const { | 1305 const base::string16& text) const { |
| 1305 return is_keyword_selected() ? (keyword_ + base::char16(' ') + text) : text; | 1306 return is_keyword_selected() ? (keyword_ + base::char16(' ') + text) : text; |
| 1306 } | 1307 } |
| 1307 | 1308 |
| 1308 void OmniboxEditModel::GetInfoForCurrentText(AutocompleteMatch* match, | 1309 void OmniboxEditModel::GetInfoForCurrentText(AutocompleteMatch* match, |
| 1309 GURL* alternate_nav_url) const { | 1310 GURL* alternate_nav_url) const { |
| 1310 DCHECK(match != NULL); | 1311 DCHECK(match != NULL); |
| 1311 | 1312 |
| 1312 if (controller_->GetToolbarModel()->WouldPerformSearchTermReplacement( | 1313 if (controller_->GetToolbarModel()->WouldPerformSearchTermReplacement( |
| 1313 false)) { | 1314 false)) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1345 result().match_at(popup_model()->selected_line()); | 1346 result().match_at(popup_model()->selected_line()); |
| 1346 *match = | 1347 *match = |
| 1347 (popup_model()->selected_line_state() == OmniboxPopupModel::KEYWORD) ? | 1348 (popup_model()->selected_line_state() == OmniboxPopupModel::KEYWORD) ? |
| 1348 *selected_match.associated_keyword : selected_match; | 1349 *selected_match.associated_keyword : selected_match; |
| 1349 } | 1350 } |
| 1350 if (alternate_nav_url && | 1351 if (alternate_nav_url && |
| 1351 (!popup_model() || popup_model()->manually_selected_match().empty())) | 1352 (!popup_model() || popup_model()->manually_selected_match().empty())) |
| 1352 *alternate_nav_url = result().alternate_nav_url(); | 1353 *alternate_nav_url = result().alternate_nav_url(); |
| 1353 } else { | 1354 } else { |
| 1354 client_->GetAutocompleteClassifier()->Classify( | 1355 client_->GetAutocompleteClassifier()->Classify( |
| 1355 UserTextFromDisplayText(view_->GetText()), is_keyword_selected(), true, | 1356 MaybePrependKeyword(user_text_), is_keyword_selected(), true, |
| 1356 ClassifyPage(), match, alternate_nav_url); | 1357 ClassifyPage(), match, alternate_nav_url); |
| 1357 } | 1358 } |
| 1358 } | 1359 } |
| 1359 | 1360 |
| 1360 void OmniboxEditModel::RevertTemporaryText(bool revert_popup) { | 1361 void OmniboxEditModel::RevertTemporaryText(bool revert_popup) { |
| 1361 // The user typed something, then selected a different item. Restore the | 1362 // The user typed something, then selected a different item. Restore the |
| 1362 // text they typed and change back to the default item. | 1363 // text they typed and change back to the default item. |
| 1363 // NOTE: This purposefully does not reset paste_state_. | 1364 // NOTE: This purposefully does not reset paste_state_. |
| 1364 just_deleted_text_ = false; | 1365 just_deleted_text_ = false; |
| 1365 has_temporary_text_ = false; | 1366 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 | 1464 // Update state and notify view if the omnibox has focus and the caret |
| 1464 // visibility changed. | 1465 // visibility changed. |
| 1465 const bool was_caret_visible = is_caret_visible(); | 1466 const bool was_caret_visible = is_caret_visible(); |
| 1466 focus_state_ = state; | 1467 focus_state_ = state; |
| 1467 if (focus_state_ != OMNIBOX_FOCUS_NONE && | 1468 if (focus_state_ != OMNIBOX_FOCUS_NONE && |
| 1468 is_caret_visible() != was_caret_visible) | 1469 is_caret_visible() != was_caret_visible) |
| 1469 view_->ApplyCaretVisibility(); | 1470 view_->ApplyCaretVisibility(); |
| 1470 | 1471 |
| 1471 client_->OnFocusChanged(focus_state_, reason); | 1472 client_->OnFocusChanged(focus_state_, reason); |
| 1472 } | 1473 } |
| OLD | NEW |