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 "chrome/browser/ui/omnibox/omnibox_edit_model.h" | 5 #include "chrome/browser/ui/omnibox/omnibox_edit_model.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/format_macros.h" | 10 #include "base/format_macros.h" |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
122 just_deleted_text_(false), | 122 just_deleted_text_(false), |
123 has_temporary_text_(false), | 123 has_temporary_text_(false), |
124 is_temporary_text_set_by_instant_(false), | 124 is_temporary_text_set_by_instant_(false), |
125 paste_state_(NONE), | 125 paste_state_(NONE), |
126 control_key_state_(UP), | 126 control_key_state_(UP), |
127 is_keyword_hint_(false), | 127 is_keyword_hint_(false), |
128 profile_(profile), | 128 profile_(profile), |
129 in_revert_(false), | 129 in_revert_(false), |
130 in_escape_handler_(false), | 130 in_escape_handler_(false), |
131 allow_exact_keyword_match_(false) { | 131 allow_exact_keyword_match_(false) { |
132 // Use a restricted subset of the autocomplete providers if we're using the | 132 omnibox_controller_.reset(new OmniboxController(this, profile)); |
133 // Instant Extended API, as it doesn't support them all. | |
134 autocomplete_controller_.reset(new AutocompleteController(profile, this, | |
135 chrome::IsInstantExtendedAPIEnabled() ? | |
136 AutocompleteClassifier::kInstantExtendedOmniboxProviders : | |
137 AutocompleteClassifier::kDefaultOmniboxProviders)); | |
138 delegate_.reset(new OmniboxCurrentPageDelegateImpl(controller, profile)); | 133 delegate_.reset(new OmniboxCurrentPageDelegateImpl(controller, profile)); |
139 } | 134 } |
140 | 135 |
141 OmniboxEditModel::~OmniboxEditModel() { | 136 OmniboxEditModel::~OmniboxEditModel() { |
142 } | 137 } |
143 | 138 |
144 const OmniboxEditModel::State OmniboxEditModel::GetStateForTabSwitch() { | 139 const OmniboxEditModel::State OmniboxEditModel::GetStateForTabSwitch() { |
145 // Like typing, switching tabs "accepts" the temporary text as the user | 140 // Like typing, switching tabs "accepts" the temporary text as the user |
146 // text, because it makes little sense to have temporary text when the | 141 // text, because it makes little sense to have temporary text when the |
147 // popup is closed. | 142 // popup is closed. |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
226 const InstantSuggestion& suggestion, | 221 const InstantSuggestion& suggestion, |
227 bool skip_inline_autocomplete) { | 222 bool skip_inline_autocomplete) { |
228 if (skip_inline_autocomplete) { | 223 if (skip_inline_autocomplete) { |
229 const string16 final_text = input_text + suggestion.text; | 224 const string16 final_text = input_text + suggestion.text; |
230 view_->OnBeforePossibleChange(); | 225 view_->OnBeforePossibleChange(); |
231 view_->SetWindowTextAndCaretPos(final_text, final_text.length(), false, | 226 view_->SetWindowTextAndCaretPos(final_text, final_text.length(), false, |
232 false); | 227 false); |
233 view_->OnAfterPossibleChange(); | 228 view_->OnAfterPossibleChange(); |
234 } else if (popup_->IsOpen()) { | 229 } else if (popup_->IsOpen()) { |
235 SearchProvider* search_provider = | 230 SearchProvider* search_provider = |
236 autocomplete_controller_->search_provider(); | 231 autocomplete_controller()->search_provider(); |
237 // There may be no providers during testing; guard against that. | 232 // There may be no providers during testing; guard against that. |
238 if (search_provider) | 233 if (search_provider) |
239 search_provider->FinalizeInstantQuery(input_text, suggestion); | 234 search_provider->FinalizeInstantQuery(input_text, suggestion); |
240 } | 235 } |
241 } | 236 } |
242 | 237 |
243 void OmniboxEditModel::SetInstantSuggestion( | 238 void OmniboxEditModel::SetInstantSuggestion( |
244 const InstantSuggestion& suggestion) { | 239 const InstantSuggestion& suggestion) { |
240 | |
Mathieu
2013/04/23 15:26:07
nit: unnecessary new line
beaudoin
2013/04/23 18:04:02
Done.
| |
245 switch (suggestion.behavior) { | 241 switch (suggestion.behavior) { |
246 case INSTANT_COMPLETE_NOW: | 242 case INSTANT_COMPLETE_NOW: |
247 view_->SetInstantSuggestion(string16()); | 243 view_->SetInstantSuggestion(string16()); |
248 if (!suggestion.text.empty()) | 244 if (!suggestion.text.empty()) |
249 FinalizeInstantQuery(view_->GetText(), suggestion, false); | 245 FinalizeInstantQuery(view_->GetText(), suggestion, false); |
250 break; | 246 break; |
251 | 247 |
252 case INSTANT_COMPLETE_NEVER: { | 248 case INSTANT_COMPLETE_NEVER: { |
253 DCHECK_EQ(INSTANT_SUGGESTION_SEARCH, suggestion.type); | 249 DCHECK_EQ(INSTANT_SUGGESTION_SEARCH, suggestion.type); |
254 view_->SetInstantSuggestion(suggestion.text); | 250 view_->SetInstantSuggestion(suggestion.text); |
255 SearchProvider* search_provider = | 251 SearchProvider* search_provider = |
256 autocomplete_controller_->search_provider(); | 252 autocomplete_controller()->search_provider(); |
257 if (search_provider) | 253 if (search_provider) |
258 search_provider->ClearInstantSuggestion(); | 254 search_provider->ClearInstantSuggestion(); |
259 break; | 255 break; |
260 } | 256 } |
261 | 257 |
262 case INSTANT_COMPLETE_REPLACE: { | 258 case INSTANT_COMPLETE_REPLACE: { |
263 const bool save_original_selection = !has_temporary_text_; | 259 const bool save_original_selection = !has_temporary_text_; |
264 view_->SetInstantSuggestion(string16()); | 260 view_->SetInstantSuggestion(string16()); |
265 has_temporary_text_ = true; | 261 has_temporary_text_ = true; |
266 is_temporary_text_set_by_instant_ = true; | 262 is_temporary_text_set_by_instant_ = true; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
360 std::string())) { | 356 std::string())) { |
361 *title = controller_->GetTitle(); | 357 *title = controller_->GetTitle(); |
362 *favicon = controller_->GetFavicon(); | 358 *favicon = controller_->GetFavicon(); |
363 } | 359 } |
364 } | 360 } |
365 | 361 |
366 bool OmniboxEditModel::UseVerbatimInstant() { | 362 bool OmniboxEditModel::UseVerbatimInstant() { |
367 #if defined(OS_MACOSX) | 363 #if defined(OS_MACOSX) |
368 // TODO(suzhe): Fix Mac port to display Instant suggest in a separated NSView, | 364 // TODO(suzhe): Fix Mac port to display Instant suggest in a separated NSView, |
369 // so that we can display Instant suggest along with composition text. | 365 // so that we can display Instant suggest along with composition text. |
370 const AutocompleteInput& input = autocomplete_controller_->input(); | 366 const AutocompleteInput& input = autocomplete_controller()->input(); |
371 if (input.prevent_inline_autocomplete()) | 367 if (input.prevent_inline_autocomplete()) |
372 return true; | 368 return true; |
373 #endif | 369 #endif |
374 | 370 |
375 // The value of input.prevent_inline_autocomplete() is determined by the | 371 // The value of input.prevent_inline_autocomplete() is determined by the |
376 // following conditions: | 372 // following conditions: |
377 // 1. If the caret is at the end of the text. | 373 // 1. If the caret is at the end of the text. |
378 // 2. If it's in IME composition mode. | 374 // 2. If it's in IME composition mode. |
379 // We send the caret position to Instant (so it can determine #1 itself), and | 375 // We send the caret position to Instant (so it can determine #1 itself), and |
380 // we use a separated widget for displaying the Instant suggest (so it doesn't | 376 // we use a separated widget for displaying the Instant suggest (so it doesn't |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
456 } | 452 } |
457 | 453 |
458 void OmniboxEditModel::SetInputInProgress(bool in_progress) { | 454 void OmniboxEditModel::SetInputInProgress(bool in_progress) { |
459 if (user_input_in_progress_ == in_progress) | 455 if (user_input_in_progress_ == in_progress) |
460 return; | 456 return; |
461 | 457 |
462 user_input_in_progress_ = in_progress; | 458 user_input_in_progress_ = in_progress; |
463 if (user_input_in_progress_) { | 459 if (user_input_in_progress_) { |
464 time_user_first_modified_omnibox_ = base::TimeTicks::Now(); | 460 time_user_first_modified_omnibox_ = base::TimeTicks::Now(); |
465 content::RecordAction(content::UserMetricsAction("OmniboxInputInProgress")); | 461 content::RecordAction(content::UserMetricsAction("OmniboxInputInProgress")); |
466 autocomplete_controller_->ResetSession(); | 462 autocomplete_controller()->ResetSession(); |
467 } | 463 } |
468 controller_->OnInputInProgress(in_progress); | 464 controller_->OnInputInProgress(in_progress); |
469 | 465 |
470 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); | 466 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); |
471 } | 467 } |
472 | 468 |
473 void OmniboxEditModel::Revert() { | 469 void OmniboxEditModel::Revert() { |
474 SetInputInProgress(false); | 470 SetInputInProgress(false); |
475 paste_state_ = NONE; | 471 paste_state_ = NONE; |
476 InternalSetUserText(string16()); | 472 InternalSetUserText(string16()); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
515 // One example is when user presses Ctrl key while having a highlighted | 511 // One example is when user presses Ctrl key while having a highlighted |
516 // inline autocomplete text. | 512 // inline autocomplete text. |
517 // TODO: Rethink how we are going to handle this case to avoid | 513 // TODO: Rethink how we are going to handle this case to avoid |
518 // inconsistent behavior when user presses Ctrl key. | 514 // inconsistent behavior when user presses Ctrl key. |
519 // See http://crbug.com/165961 and http://crbug.com/165968 for more details. | 515 // See http://crbug.com/165961 and http://crbug.com/165968 for more details. |
520 cursor_position = user_text_.length(); | 516 cursor_position = user_text_.length(); |
521 } | 517 } |
522 | 518 |
523 // We don't explicitly clear OmniboxPopupModel::manually_selected_match, as | 519 // We don't explicitly clear OmniboxPopupModel::manually_selected_match, as |
524 // Start ends up invoking OmniboxPopupModel::OnResultChanged which clears it. | 520 // Start ends up invoking OmniboxPopupModel::OnResultChanged which clears it. |
525 autocomplete_controller_->Start(AutocompleteInput( | 521 autocomplete_controller()->Start(AutocompleteInput( |
526 user_text_, cursor_position, string16(), GURL(), | 522 user_text_, cursor_position, string16(), GURL(), |
527 prevent_inline_autocomplete || just_deleted_text_ || | 523 prevent_inline_autocomplete || just_deleted_text_ || |
528 (has_selected_text && inline_autocomplete_text_.empty()) || | 524 (has_selected_text && inline_autocomplete_text_.empty()) || |
529 (paste_state_ != NONE), keyword_is_selected, | 525 (paste_state_ != NONE), keyword_is_selected, |
530 keyword_is_selected || allow_exact_keyword_match_, | 526 keyword_is_selected || allow_exact_keyword_match_, |
531 AutocompleteInput::ALL_MATCHES)); | 527 AutocompleteInput::ALL_MATCHES)); |
532 } | 528 } |
533 | 529 |
534 void OmniboxEditModel::StopAutocomplete() { | 530 void OmniboxEditModel::StopAutocomplete() { |
535 autocomplete_controller_->Stop(true); | 531 autocomplete_controller()->Stop(true); |
536 } | 532 } |
537 | 533 |
538 bool OmniboxEditModel::CanPasteAndGo(const string16& text) const { | 534 bool OmniboxEditModel::CanPasteAndGo(const string16& text) const { |
539 if (!view_->command_updater()->IsCommandEnabled(IDC_OPEN_CURRENT_URL)) | 535 if (!view_->command_updater()->IsCommandEnabled(IDC_OPEN_CURRENT_URL)) |
540 return false; | 536 return false; |
541 | 537 |
542 AutocompleteMatch match; | 538 AutocompleteMatch match; |
543 ClassifyStringForPasteAndGo(text, &match, NULL); | 539 ClassifyStringForPasteAndGo(text, &match, NULL); |
544 return match.destination_url.is_valid(); | 540 return match.destination_url.is_valid(); |
545 } | 541 } |
(...skipping 19 matching lines...) Expand all Loading... | |
565 // Get the URL and transition type for the selected entry. | 561 // Get the URL and transition type for the selected entry. |
566 AutocompleteMatch match; | 562 AutocompleteMatch match; |
567 GURL alternate_nav_url; | 563 GURL alternate_nav_url; |
568 GetInfoForCurrentText(&match, &alternate_nav_url); | 564 GetInfoForCurrentText(&match, &alternate_nav_url); |
569 | 565 |
570 // If CTRL is down it means the user wants to append ".com" to the text he | 566 // If CTRL is down it means the user wants to append ".com" to the text he |
571 // typed. If we can successfully generate a URL_WHAT_YOU_TYPED match doing | 567 // typed. If we can successfully generate a URL_WHAT_YOU_TYPED match doing |
572 // that, then we use this. These matches are marked as generated by the | 568 // that, then we use this. These matches are marked as generated by the |
573 // HistoryURLProvider so we only generate them if this provider is present. | 569 // HistoryURLProvider so we only generate them if this provider is present. |
574 if (control_key_state_ == DOWN_WITHOUT_CHANGE && !KeywordIsSelected() && | 570 if (control_key_state_ == DOWN_WITHOUT_CHANGE && !KeywordIsSelected() && |
575 autocomplete_controller_->history_url_provider()) { | 571 autocomplete_controller()->history_url_provider()) { |
576 // Generate a new AutocompleteInput, copying the latest one but using "com" | 572 // Generate a new AutocompleteInput, copying the latest one but using "com" |
577 // 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 |
578 // URL_WHAT_YOU_TYPED AutocompleteMatch. Note that using the most recent | 574 // URL_WHAT_YOU_TYPED AutocompleteMatch. Note that using the most recent |
579 // 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 |
580 // visible inline autocompletion: if a user types "foo" and is autocompleted | 576 // visible inline autocompletion: if a user types "foo" and is autocompleted |
581 // to "foodnetwork.com", ctrl-enter will navigate to "foo.com", not | 577 // to "foodnetwork.com", ctrl-enter will navigate to "foo.com", not |
582 // "foodnetwork.com". At the time of writing, this behavior matches | 578 // "foodnetwork.com". At the time of writing, this behavior matches |
583 // Internet Explorer, but not Firefox. | 579 // Internet Explorer, but not Firefox. |
584 const AutocompleteInput& old_input = autocomplete_controller_->input(); | 580 const AutocompleteInput& old_input = autocomplete_controller()->input(); |
585 AutocompleteInput input( | 581 AutocompleteInput input( |
586 old_input.text(), old_input.cursor_position(), ASCIIToUTF16("com"), | 582 old_input.text(), old_input.cursor_position(), ASCIIToUTF16("com"), |
587 GURL(), old_input.prevent_inline_autocomplete(), | 583 GURL(), old_input.prevent_inline_autocomplete(), |
588 old_input.prefer_keyword(), old_input.allow_exact_keyword_match(), | 584 old_input.prefer_keyword(), old_input.allow_exact_keyword_match(), |
589 old_input.matches_requested()); | 585 old_input.matches_requested()); |
590 AutocompleteMatch url_match = HistoryURLProvider::SuggestExactInput( | 586 AutocompleteMatch url_match = HistoryURLProvider::SuggestExactInput( |
591 autocomplete_controller_->history_url_provider(), input, true); | 587 autocomplete_controller()->history_url_provider(), input, true); |
592 | 588 |
593 if (url_match.destination_url.is_valid()) { | 589 if (url_match.destination_url.is_valid()) { |
594 // We have a valid URL, we use this newly generated AutocompleteMatch. | 590 // We have a valid URL, we use this newly generated AutocompleteMatch. |
595 match = url_match; | 591 match = url_match; |
596 alternate_nav_url = GURL(); | 592 alternate_nav_url = GURL(); |
597 } | 593 } |
598 } | 594 } |
599 | 595 |
600 if (!match.destination_url.is_valid()) | 596 if (!match.destination_url.is_valid()) |
601 return; | 597 return; |
(...skipping 30 matching lines...) Expand all Loading... | |
632 void OmniboxEditModel::OpenMatch(const AutocompleteMatch& match, | 628 void OmniboxEditModel::OpenMatch(const AutocompleteMatch& match, |
633 WindowOpenDisposition disposition, | 629 WindowOpenDisposition disposition, |
634 const GURL& alternate_nav_url, | 630 const GURL& alternate_nav_url, |
635 size_t index) { | 631 size_t index) { |
636 // We only care about cases where there is a selection (i.e. the popup is | 632 // We only care about cases where there is a selection (i.e. the popup is |
637 // open). | 633 // open). |
638 if (popup_->IsOpen()) { | 634 if (popup_->IsOpen()) { |
639 const base::TimeTicks& now(base::TimeTicks::Now()); | 635 const base::TimeTicks& now(base::TimeTicks::Now()); |
640 // TODO(sreeram): Handle is_temporary_text_set_by_instant_ correctly. | 636 // TODO(sreeram): Handle is_temporary_text_set_by_instant_ correctly. |
641 AutocompleteLog log( | 637 AutocompleteLog log( |
642 autocomplete_controller_->input().text(), | 638 autocomplete_controller()->input().text(), |
643 just_deleted_text_, | 639 just_deleted_text_, |
644 autocomplete_controller_->input().type(), | 640 autocomplete_controller()->input().type(), |
645 popup_->selected_line(), | 641 popup_->selected_line(), |
646 -1, // don't yet know tab ID; set later if appropriate | 642 -1, // don't yet know tab ID; set later if appropriate |
647 delegate_->CurrentPageExists() ? ClassifyPage(delegate_->GetURL()) : | 643 delegate_->CurrentPageExists() ? ClassifyPage(delegate_->GetURL()) : |
648 metrics::OmniboxEventProto_PageClassification_OTHER, | 644 metrics::OmniboxEventProto_PageClassification_OTHER, |
649 now - time_user_first_modified_omnibox_, | 645 now - time_user_first_modified_omnibox_, |
650 string16::npos, // completed_length; possibly set later | 646 string16::npos, // completed_length; possibly set later |
651 now - autocomplete_controller_->last_time_default_match_changed(), | 647 now - autocomplete_controller()->last_time_default_match_changed(), |
652 result()); | 648 result()); |
653 DCHECK(user_input_in_progress_ || | 649 DCHECK(user_input_in_progress_ || |
654 match.provider->type() == AutocompleteProvider::TYPE_ZERO_SUGGEST) | 650 match.provider->type() == AutocompleteProvider::TYPE_ZERO_SUGGEST) |
655 << "We didn't get here through the expected series of calls. " | 651 << "We didn't get here through the expected series of calls. " |
656 << "time_user_first_modified_omnibox_ is not set correctly and other " | 652 << "time_user_first_modified_omnibox_ is not set correctly and other " |
657 << "things may be wrong. Match provider: " << match.provider->GetName(); | 653 << "things may be wrong. Match provider: " << match.provider->GetName(); |
658 DCHECK(log.elapsed_time_since_user_first_modified_omnibox >= | 654 DCHECK(log.elapsed_time_since_user_first_modified_omnibox >= |
659 log.elapsed_time_since_last_change_to_default_match) | 655 log.elapsed_time_since_last_change_to_default_match) |
660 << "We should've got the notification that the user modified the " | 656 << "We should've got the notification that the user modified the " |
661 << "omnibox text at same time or before the most recent time the " | 657 << "omnibox text at same time or before the most recent time the " |
662 << "default match changed."; | 658 << "default match changed."; |
663 if (index != OmniboxPopupModel::kNoMatch) | 659 if (index != OmniboxPopupModel::kNoMatch) |
664 log.selected_index = index; | 660 log.selected_index = index; |
665 if (match.inline_autocomplete_offset != string16::npos) { | 661 if (match.inline_autocomplete_offset != string16::npos) { |
666 DCHECK_GE(match.fill_into_edit.length(), | 662 DCHECK_GE(match.fill_into_edit.length(), |
667 match.inline_autocomplete_offset); | 663 match.inline_autocomplete_offset); |
668 log.completed_length = | 664 log.completed_length = |
669 match.fill_into_edit.length() - match.inline_autocomplete_offset; | 665 match.fill_into_edit.length() - match.inline_autocomplete_offset; |
670 } | 666 } |
671 | 667 |
672 if ((disposition == CURRENT_TAB) && delegate_->CurrentPageExists()) { | 668 if ((disposition == CURRENT_TAB) && delegate_->CurrentPageExists()) { |
673 // If we know the destination is being opened in the current tab, | 669 // If we know the destination is being opened in the current tab, |
674 // we can easily get the tab ID. (If it's being opened in a new | 670 // we can easily get the tab ID. (If it's being opened in a new |
675 // tab, we don't know the tab ID yet.) | 671 // tab, we don't know the tab ID yet.) |
676 log.tab_id = delegate_->GetSessionID().id(); | 672 log.tab_id = delegate_->GetSessionID().id(); |
677 } | 673 } |
678 autocomplete_controller_->AddProvidersInfo(&log.providers_info); | 674 autocomplete_controller()->AddProvidersInfo(&log.providers_info); |
679 content::NotificationService::current()->Notify( | 675 content::NotificationService::current()->Notify( |
680 chrome::NOTIFICATION_OMNIBOX_OPENED_URL, | 676 chrome::NOTIFICATION_OMNIBOX_OPENED_URL, |
681 content::Source<Profile>(profile_), | 677 content::Source<Profile>(profile_), |
682 content::Details<AutocompleteLog>(&log)); | 678 content::Details<AutocompleteLog>(&log)); |
683 HISTOGRAM_ENUMERATION("Omnibox.EventCount", 1, 2); | 679 HISTOGRAM_ENUMERATION("Omnibox.EventCount", 1, 2); |
684 } | 680 } |
685 | 681 |
686 TemplateURL* template_url = match.GetTemplateURL(profile_, false); | 682 TemplateURL* template_url = match.GetTemplateURL(profile_, false); |
687 if (template_url) { | 683 if (template_url) { |
688 if (match.transition == content::PAGE_TRANSITION_KEYWORD) { | 684 if (match.transition == content::PAGE_TRANSITION_KEYWORD) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
722 if (disposition != NEW_BACKGROUND_TAB) { | 718 if (disposition != NEW_BACKGROUND_TAB) { |
723 base::AutoReset<bool> tmp(&in_revert_, true); | 719 base::AutoReset<bool> tmp(&in_revert_, true); |
724 view_->RevertAll(); // Revert the box to its unedited state | 720 view_->RevertAll(); // Revert the box to its unedited state |
725 } | 721 } |
726 | 722 |
727 if (match.type == AutocompleteMatch::EXTENSION_APP) { | 723 if (match.type == AutocompleteMatch::EXTENSION_APP) { |
728 ExtensionAppProvider::LaunchAppFromOmnibox(match, profile_, disposition); | 724 ExtensionAppProvider::LaunchAppFromOmnibox(match, profile_, disposition); |
729 } else { | 725 } else { |
730 base::TimeDelta query_formulation_time = | 726 base::TimeDelta query_formulation_time = |
731 base::TimeTicks::Now() - time_user_first_modified_omnibox_; | 727 base::TimeTicks::Now() - time_user_first_modified_omnibox_; |
732 const GURL destination_url = autocomplete_controller_-> | 728 const GURL destination_url = autocomplete_controller()-> |
733 GetDestinationURL(match, query_formulation_time); | 729 GetDestinationURL(match, query_formulation_time); |
734 | 730 |
735 // If running with instant, notify the instant controller that a navigation | 731 // If running with instant, notify the instant controller that a navigation |
736 // is about to take place if we are navigating to a URL. This can be | 732 // is about to take place if we are navigating to a URL. This can be |
737 // determined by inspecting the transition type. To ensure that this is only | 733 // determined by inspecting the transition type. To ensure that this is only |
738 // done on Enter key press, check that the disposition is CURRENT_TAB. This | 734 // done on Enter key press, check that the disposition is CURRENT_TAB. This |
739 // is the same heuristic used by BrowserInstantController::OpenInstant | 735 // is the same heuristic used by BrowserInstantController::OpenInstant |
740 if (match.transition == content::PAGE_TRANSITION_TYPED && | 736 if (match.transition == content::PAGE_TRANSITION_TYPED && |
741 disposition == CURRENT_TAB) { | 737 disposition == CURRENT_TAB) { |
742 InstantController* instant = controller_->GetInstant(); | 738 InstantController* instant = controller_->GetInstant(); |
743 if (instant) | 739 if (instant) |
744 instant->OmniboxNavigateToURL(); | 740 instant->OmniboxNavigateToURL(); |
745 } | 741 } |
746 | 742 |
747 // This calls RevertAll again. | 743 // This calls RevertAll again. |
748 base::AutoReset<bool> tmp(&in_revert_, true); | 744 base::AutoReset<bool> tmp(&in_revert_, true); |
749 controller_->OnAutocompleteAccept(destination_url, disposition, | 745 controller_->OnAutocompleteAccept(destination_url, disposition, |
750 match.transition, alternate_nav_url); | 746 match.transition, alternate_nav_url); |
751 } | 747 } |
752 | 748 |
753 if (match.starred) | 749 if (match.starred) |
754 bookmark_utils::RecordBookmarkLaunch(bookmark_utils::LAUNCH_OMNIBOX); | 750 bookmark_utils::RecordBookmarkLaunch(bookmark_utils::LAUNCH_OMNIBOX); |
755 } | 751 } |
756 | 752 |
757 bool OmniboxEditModel::AcceptKeyword() { | 753 bool OmniboxEditModel::AcceptKeyword() { |
758 DCHECK(is_keyword_hint_ && !keyword_.empty()); | 754 DCHECK(is_keyword_hint_ && !keyword_.empty()); |
759 | 755 |
760 autocomplete_controller_->Stop(false); | 756 autocomplete_controller()->Stop(false); |
761 is_keyword_hint_ = false; | 757 is_keyword_hint_ = false; |
762 | 758 |
763 if (popup_->IsOpen()) | 759 if (popup_->IsOpen()) |
764 popup_->SetSelectedLineState(OmniboxPopupModel::KEYWORD); | 760 popup_->SetSelectedLineState(OmniboxPopupModel::KEYWORD); |
765 else | 761 else |
766 StartAutocomplete(false, true); | 762 StartAutocomplete(false, true); |
767 | 763 |
768 // Ensure the current selection is saved before showing keyword mode | 764 // Ensure the current selection is saved before showing keyword mode |
769 // so that moving to another line and then reverting the text will restore | 765 // so that moving to another line and then reverting the text will restore |
770 // the current state properly. | 766 // the current state properly. |
771 bool save_original_selection = !has_temporary_text_; | 767 bool save_original_selection = !has_temporary_text_; |
772 has_temporary_text_ = true; | 768 has_temporary_text_ = true; |
773 is_temporary_text_set_by_instant_ = false; | 769 is_temporary_text_set_by_instant_ = false; |
774 view_->OnTemporaryTextMaybeChanged( | 770 view_->OnTemporaryTextMaybeChanged( |
775 DisplayTextFromUserText(CurrentMatch().fill_into_edit), | 771 DisplayTextFromUserText(CurrentMatch().fill_into_edit), |
776 save_original_selection, true); | 772 save_original_selection, true); |
777 | 773 |
778 content::RecordAction(UserMetricsAction("AcceptedKeywordHint")); | 774 content::RecordAction(UserMetricsAction("AcceptedKeywordHint")); |
779 return true; | 775 return true; |
780 } | 776 } |
781 | 777 |
782 void OmniboxEditModel::ClearKeyword(const string16& visible_text) { | 778 void OmniboxEditModel::ClearKeyword(const string16& visible_text) { |
783 autocomplete_controller_->Stop(false); | 779 autocomplete_controller()->Stop(false); |
784 ClearPopupKeywordMode(); | 780 ClearPopupKeywordMode(); |
785 | 781 |
786 const string16 window_text(keyword_ + visible_text); | 782 const string16 window_text(keyword_ + visible_text); |
787 | 783 |
788 // Only reset the result if the edit text has changed since the | 784 // Only reset the result if the edit text has changed since the |
789 // keyword was accepted, or if the popup is closed. | 785 // keyword was accepted, or if the popup is closed. |
790 if (just_deleted_text_ || !visible_text.empty() || !popup_->IsOpen()) { | 786 if (just_deleted_text_ || !visible_text.empty() || !popup_->IsOpen()) { |
791 view_->OnBeforePossibleChange(); | 787 view_->OnBeforePossibleChange(); |
792 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), | 788 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), |
793 false, false); | 789 false, false); |
794 keyword_.clear(); | 790 keyword_.clear(); |
795 is_keyword_hint_ = false; | 791 is_keyword_hint_ = false; |
796 view_->OnAfterPossibleChange(); | 792 view_->OnAfterPossibleChange(); |
797 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this | 793 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this |
798 // since the edit contents have actually grown | 794 // since the edit contents have actually grown |
799 // longer. | 795 // longer. |
800 } else { | 796 } else { |
801 is_keyword_hint_ = true; | 797 is_keyword_hint_ = true; |
802 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), | 798 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), |
803 false, true); | 799 false, true); |
804 } | 800 } |
805 } | 801 } |
806 | 802 |
807 const AutocompleteResult& OmniboxEditModel::result() const { | 803 const AutocompleteResult& OmniboxEditModel::result() const { |
808 return autocomplete_controller_->result(); | 804 return autocomplete_controller()->result(); |
809 } | 805 } |
810 | 806 |
811 void OmniboxEditModel::OnSetFocus(bool control_down) { | 807 void OmniboxEditModel::OnSetFocus(bool control_down) { |
812 // If the omnibox lost focus while the caret was hidden and then regained | 808 // If the omnibox lost focus while the caret was hidden and then regained |
813 // focus, OnSetFocus() is called and should restore visibility. Note that | 809 // focus, OnSetFocus() is called and should restore visibility. Note that |
814 // focus can be regained without an accompanying call to | 810 // focus can be regained without an accompanying call to |
815 // OmniboxView::SetFocus(), e.g. by tabbing in. | 811 // OmniboxView::SetFocus(), e.g. by tabbing in. |
816 SetFocusState(OMNIBOX_FOCUS_VISIBLE, OMNIBOX_FOCUS_CHANGE_EXPLICIT); | 812 SetFocusState(OMNIBOX_FOCUS_VISIBLE, OMNIBOX_FOCUS_CHANGE_EXPLICIT); |
817 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; | 813 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; |
818 | 814 |
819 if (delegate_->CurrentPageExists()) { | 815 if (delegate_->CurrentPageExists()) { |
820 // TODO(jered): We may want to merge this into Start() and just call that | 816 // TODO(jered): We may want to merge this into Start() and just call that |
821 // here rather than having a special entry point for zero-suggest. Note | 817 // here rather than having a special entry point for zero-suggest. Note |
822 // that we avoid PermanentURL() here because it's not guaranteed to give us | 818 // that we avoid PermanentURL() here because it's not guaranteed to give us |
823 // the actual underlying current URL, e.g. if we're on the NTP and the | 819 // the actual underlying current URL, e.g. if we're on the NTP and the |
824 // |permanent_text_| is empty. | 820 // |permanent_text_| is empty. |
825 autocomplete_controller_->StartZeroSuggest(delegate_->GetURL(), | 821 autocomplete_controller()->StartZeroSuggest(delegate_->GetURL(), |
826 user_text_); | 822 user_text_); |
827 } | 823 } |
828 | 824 |
829 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); | 825 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); |
830 } | 826 } |
831 | 827 |
832 void OmniboxEditModel::SetCaretVisibility(bool visible) { | 828 void OmniboxEditModel::SetCaretVisibility(bool visible) { |
833 // Caret visibility only matters if the omnibox has focus. | 829 // Caret visibility only matters if the omnibox has focus. |
834 if (focus_state_ != OMNIBOX_FOCUS_NONE) { | 830 if (focus_state_ != OMNIBOX_FOCUS_NONE) { |
835 SetFocusState(visible ? OMNIBOX_FOCUS_VISIBLE : OMNIBOX_FOCUS_INVISIBLE, | 831 SetFocusState(visible ? OMNIBOX_FOCUS_VISIBLE : OMNIBOX_FOCUS_INVISIBLE, |
836 OMNIBOX_FOCUS_CHANGE_EXPLICIT); | 832 OMNIBOX_FOCUS_CHANGE_EXPLICIT); |
837 } | 833 } |
838 } | 834 } |
839 | 835 |
840 void OmniboxEditModel::OnWillKillFocus(gfx::NativeView view_gaining_focus) { | 836 void OmniboxEditModel::OnWillKillFocus(gfx::NativeView view_gaining_focus) { |
841 InstantController* instant = controller_->GetInstant(); | 837 InstantController* instant = controller_->GetInstant(); |
842 if (instant) { | 838 if (instant) { |
843 instant->OmniboxFocusChanged(OMNIBOX_FOCUS_NONE, | 839 instant->OmniboxFocusChanged(OMNIBOX_FOCUS_NONE, |
844 OMNIBOX_FOCUS_CHANGE_EXPLICIT, | 840 OMNIBOX_FOCUS_CHANGE_EXPLICIT, |
845 view_gaining_focus); | 841 view_gaining_focus); |
846 } | 842 } |
847 | 843 |
848 // TODO(jered): Rip this out along with StartZeroSuggest. | 844 // TODO(jered): Rip this out along with StartZeroSuggest. |
849 autocomplete_controller_->StopZeroSuggest(); | 845 autocomplete_controller()->StopZeroSuggest(); |
850 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); | 846 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); |
851 } | 847 } |
852 | 848 |
853 void OmniboxEditModel::OnKillFocus() { | 849 void OmniboxEditModel::OnKillFocus() { |
854 // TODO(samarth): determine if it is safe to move the call to | 850 // TODO(samarth): determine if it is safe to move the call to |
855 // OmniboxFocusChanged() from OnWillKillFocus() to here, which would let us | 851 // OmniboxFocusChanged() from OnWillKillFocus() to here, which would let us |
856 // just call SetFocusState() to handle the state change. | 852 // just call SetFocusState() to handle the state change. |
857 focus_state_ = OMNIBOX_FOCUS_NONE; | 853 focus_state_ = OMNIBOX_FOCUS_NONE; |
858 control_key_state_ = UP; | 854 control_key_state_ = UP; |
859 paste_state_ = NONE; | 855 paste_state_ = NONE; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
936 // TODO(pkasting): The popup is working on a query but is not open. We | 932 // TODO(pkasting): The popup is working on a query but is not open. We |
937 // should force it to open immediately. | 933 // should force it to open immediately. |
938 } | 934 } |
939 } else { | 935 } else { |
940 InstantController* instant = controller_->GetInstant(); | 936 InstantController* instant = controller_->GetInstant(); |
941 if (instant && instant->OnUpOrDownKeyPressed(count)) { | 937 if (instant && instant->OnUpOrDownKeyPressed(count)) { |
942 // If Instant handles the key press, it's showing a list of suggestions | 938 // If Instant handles the key press, it's showing a list of suggestions |
943 // that it's stepping through. In that case, our popup model is | 939 // that it's stepping through. In that case, our popup model is |
944 // irrelevant, so don't process the key press ourselves. However, do stop | 940 // irrelevant, so don't process the key press ourselves. However, do stop |
945 // the autocomplete system from changing the results. | 941 // the autocomplete system from changing the results. |
946 autocomplete_controller_->Stop(false); | 942 autocomplete_controller()->Stop(false); |
947 } else { | 943 } else { |
948 // The popup is open, so the user should be able to interact with it | 944 // The popup is open, so the user should be able to interact with it |
949 // normally. | 945 // normally. |
950 popup_->Move(count); | 946 popup_->Move(count); |
951 } | 947 } |
952 } | 948 } |
953 } | 949 } |
954 | 950 |
955 void OmniboxEditModel::OnPopupDataChanged( | 951 void OmniboxEditModel::OnPopupDataChanged( |
956 const string16& text, | 952 const string16& text, |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1172 // sense to have temporary text when the popup is closed. | 1168 // sense to have temporary text when the popup is closed. |
1173 InternalSetUserText(UserTextFromDisplayText(view_->GetText())); | 1169 InternalSetUserText(UserTextFromDisplayText(view_->GetText())); |
1174 has_temporary_text_ = false; | 1170 has_temporary_text_ = false; |
1175 is_temporary_text_set_by_instant_ = false; | 1171 is_temporary_text_set_by_instant_ = false; |
1176 OnPopupBoundsChanged(gfx::Rect()); | 1172 OnPopupBoundsChanged(gfx::Rect()); |
1177 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); | 1173 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); |
1178 } | 1174 } |
1179 | 1175 |
1180 InstantController* instant = controller_->GetInstant(); | 1176 InstantController* instant = controller_->GetInstant(); |
1181 if (instant && !in_revert_) | 1177 if (instant && !in_revert_) |
1182 instant->HandleAutocompleteResults(*autocomplete_controller_->providers()); | 1178 instant->HandleAutocompleteResults(*autocomplete_controller()->providers()); |
1183 } | 1179 } |
1184 | 1180 |
1185 bool OmniboxEditModel::query_in_progress() const { | 1181 bool OmniboxEditModel::query_in_progress() const { |
1186 return !autocomplete_controller_->done(); | 1182 return !autocomplete_controller()->done(); |
1187 } | 1183 } |
1188 | 1184 |
1189 void OmniboxEditModel::InternalSetUserText(const string16& text) { | 1185 void OmniboxEditModel::InternalSetUserText(const string16& text) { |
1190 user_text_ = text; | 1186 user_text_ = text; |
1191 just_deleted_text_ = false; | 1187 just_deleted_text_ = false; |
1192 inline_autocomplete_text_.clear(); | 1188 inline_autocomplete_text_.clear(); |
1193 } | 1189 } |
1194 | 1190 |
1195 bool OmniboxEditModel::KeywordIsSelected() const { | 1191 bool OmniboxEditModel::KeywordIsSelected() const { |
1196 return !is_keyword_hint_ && !keyword_.empty(); | 1192 return !is_keyword_hint_ && !keyword_.empty(); |
(...skipping 11 matching lines...) Expand all Loading... | |
1208 } | 1204 } |
1209 | 1205 |
1210 string16 OmniboxEditModel::UserTextFromDisplayText(const string16& text) const { | 1206 string16 OmniboxEditModel::UserTextFromDisplayText(const string16& text) const { |
1211 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; | 1207 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; |
1212 } | 1208 } |
1213 | 1209 |
1214 void OmniboxEditModel::InfoForCurrentSelection(AutocompleteMatch* match, | 1210 void OmniboxEditModel::InfoForCurrentSelection(AutocompleteMatch* match, |
1215 GURL* alternate_nav_url) const { | 1211 GURL* alternate_nav_url) const { |
1216 DCHECK(match != NULL); | 1212 DCHECK(match != NULL); |
1217 const AutocompleteResult& result = this->result(); | 1213 const AutocompleteResult& result = this->result(); |
1218 if (!autocomplete_controller_->done()) { | 1214 if (!autocomplete_controller()->done()) { |
1219 // It's technically possible for |result| to be empty if no provider returns | 1215 // It's technically possible for |result| to be empty if no provider returns |
1220 // a synchronous result but the query has not completed synchronously; | 1216 // a synchronous result but the query has not completed synchronously; |
1221 // pratically, however, that should never actually happen. | 1217 // pratically, however, that should never actually happen. |
1222 if (result.empty()) | 1218 if (result.empty()) |
1223 return; | 1219 return; |
1224 // The user cannot have manually selected a match, or the query would have | 1220 // The user cannot have manually selected a match, or the query would have |
1225 // stopped. So the default match must be the desired selection. | 1221 // stopped. So the default match must be the desired selection. |
1226 *match = *result.default_match(); | 1222 *match = *result.default_match(); |
1227 } else { | 1223 } else { |
1228 CHECK(popup_->IsOpen()); | 1224 CHECK(popup_->IsOpen()); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1312 old_text, space_position, | 1308 old_text, space_position, |
1313 old_text.length() - space_position)) { | 1309 old_text.length() - space_position)) { |
1314 return false; | 1310 return false; |
1315 } | 1311 } |
1316 | 1312 |
1317 // Then check if the text before the inserted space matches a keyword. | 1313 // Then check if the text before the inserted space matches a keyword. |
1318 string16 keyword; | 1314 string16 keyword; |
1319 TrimWhitespace(new_text.substr(0, space_position), TRIM_LEADING, &keyword); | 1315 TrimWhitespace(new_text.substr(0, space_position), TRIM_LEADING, &keyword); |
1320 // TODO(sreeram): Once the Instant extended API supports keywords properly, | 1316 // TODO(sreeram): Once the Instant extended API supports keywords properly, |
1321 // keyword_provider() should never be NULL. Remove that clause. | 1317 // keyword_provider() should never be NULL. Remove that clause. |
1322 return !keyword.empty() && autocomplete_controller_->keyword_provider() && | 1318 return !keyword.empty() && autocomplete_controller()->keyword_provider() && |
1323 !autocomplete_controller_->keyword_provider()-> | 1319 !autocomplete_controller()->keyword_provider()-> |
1324 GetKeywordForText(keyword).empty(); | 1320 GetKeywordForText(keyword).empty(); |
1325 } | 1321 } |
1326 | 1322 |
1327 bool OmniboxEditModel::DoInstant(const AutocompleteMatch& match) { | 1323 bool OmniboxEditModel::DoInstant(const AutocompleteMatch& match) { |
1328 InstantController* instant = controller_->GetInstant(); | 1324 InstantController* instant = controller_->GetInstant(); |
1329 if (!instant || in_revert_) | 1325 if (!instant || in_revert_) |
1330 return false; | 1326 return false; |
1331 | 1327 |
1332 // Don't call Update() if the change is a result of a | 1328 // Don't call Update() if the change is a result of a |
1333 // INSTANT_COMPLETE_REPLACE instant suggestion. | 1329 // INSTANT_COMPLETE_REPLACE instant suggestion. |
1334 if (has_temporary_text_ && is_temporary_text_set_by_instant_) | 1330 if (has_temporary_text_ && is_temporary_text_set_by_instant_) |
1335 return false; | 1331 return false; |
1336 | 1332 |
1337 // The two pieces of text we want to send Instant, viz., what the user has | 1333 // The two pieces of text we want to send Instant, viz., what the user has |
1338 // typed, and the full omnibox text including any inline autocompletion. | 1334 // typed, and the full omnibox text including any inline autocompletion. |
1339 string16 user_text = has_temporary_text_ ? | 1335 string16 user_text = has_temporary_text_ ? |
1340 match.fill_into_edit : DisplayTextFromUserText(user_text_); | 1336 match.fill_into_edit : DisplayTextFromUserText(user_text_); |
1341 string16 full_text = view_->GetText(); | 1337 string16 full_text = view_->GetText(); |
1342 | 1338 |
1343 // Remove "?" if we're in forced query mode. | 1339 // Remove "?" if we're in forced query mode. |
1344 AutocompleteInput::RemoveForcedQueryStringIfNecessary( | 1340 AutocompleteInput::RemoveForcedQueryStringIfNecessary( |
1345 autocomplete_controller_->input().type(), &user_text); | 1341 autocomplete_controller()->input().type(), &user_text); |
1346 AutocompleteInput::RemoveForcedQueryStringIfNecessary( | 1342 AutocompleteInput::RemoveForcedQueryStringIfNecessary( |
1347 autocomplete_controller_->input().type(), &full_text); | 1343 autocomplete_controller()->input().type(), &full_text); |
1348 | 1344 |
1349 size_t start, end; | 1345 size_t start, end; |
1350 view_->GetSelectionBounds(&start, &end); | 1346 view_->GetSelectionBounds(&start, &end); |
1351 | 1347 |
1352 return instant->Update(match, user_text, full_text, start, end, | 1348 return instant->Update(match, user_text, full_text, start, end, |
1353 UseVerbatimInstant(), user_input_in_progress_, popup_->IsOpen(), | 1349 UseVerbatimInstant(), user_input_in_progress_, popup_->IsOpen(), |
1354 in_escape_handler_, KeywordIsSelected()); | 1350 in_escape_handler_, KeywordIsSelected()); |
1355 } | 1351 } |
1356 | 1352 |
1357 void OmniboxEditModel::DoPreconnect(const AutocompleteMatch& match) { | 1353 void OmniboxEditModel::DoPreconnect(const AutocompleteMatch& match) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1414 instant->OmniboxFocusChanged(state, reason, NULL); | 1410 instant->OmniboxFocusChanged(state, reason, NULL); |
1415 | 1411 |
1416 // Update state and notify view if the omnibox has focus and the caret | 1412 // Update state and notify view if the omnibox has focus and the caret |
1417 // visibility changed. | 1413 // visibility changed. |
1418 const bool was_caret_visible = is_caret_visible(); | 1414 const bool was_caret_visible = is_caret_visible(); |
1419 focus_state_ = state; | 1415 focus_state_ = state; |
1420 if (focus_state_ != OMNIBOX_FOCUS_NONE && | 1416 if (focus_state_ != OMNIBOX_FOCUS_NONE && |
1421 is_caret_visible() != was_caret_visible) | 1417 is_caret_visible() != was_caret_visible) |
1422 view_->ApplyCaretVisibility(); | 1418 view_->ApplyCaretVisibility(); |
1423 } | 1419 } |
OLD | NEW |