Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(186)

Side by Side Diff: chrome/browser/ui/omnibox/omnibox_edit_model.cc

Issue 13932034: Omnibox refactor, introduced OmniboxController. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/omnibox/omnibox_edit_model.h ('k') | chrome/chrome_browser_ui.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 just_deleted_text_(false), 127 just_deleted_text_(false),
128 has_temporary_text_(false), 128 has_temporary_text_(false),
129 is_temporary_text_set_by_instant_(false), 129 is_temporary_text_set_by_instant_(false),
130 paste_state_(NONE), 130 paste_state_(NONE),
131 control_key_state_(UP), 131 control_key_state_(UP),
132 is_keyword_hint_(false), 132 is_keyword_hint_(false),
133 profile_(profile), 133 profile_(profile),
134 in_revert_(false), 134 in_revert_(false),
135 in_escape_handler_(false), 135 in_escape_handler_(false),
136 allow_exact_keyword_match_(false) { 136 allow_exact_keyword_match_(false) {
137 // Use a restricted subset of the autocomplete providers if we're using the 137 omnibox_controller_.reset(new OmniboxController(this, profile));
138 // Instant Extended API, as it doesn't support them all.
139 autocomplete_controller_.reset(new AutocompleteController(profile, this,
140 chrome::IsInstantExtendedAPIEnabled() ?
141 AutocompleteClassifier::kInstantExtendedOmniboxProviders :
142 AutocompleteClassifier::kDefaultOmniboxProviders));
143 delegate_.reset(new OmniboxCurrentPageDelegateImpl(controller, profile)); 138 delegate_.reset(new OmniboxCurrentPageDelegateImpl(controller, profile));
144 } 139 }
145 140
146 OmniboxEditModel::~OmniboxEditModel() { 141 OmniboxEditModel::~OmniboxEditModel() {
147 } 142 }
148 143
149 const OmniboxEditModel::State OmniboxEditModel::GetStateForTabSwitch() { 144 const OmniboxEditModel::State OmniboxEditModel::GetStateForTabSwitch() {
150 // Like typing, switching tabs "accepts" the temporary text as the user 145 // Like typing, switching tabs "accepts" the temporary text as the user
151 // text, because it makes little sense to have temporary text when the 146 // text, because it makes little sense to have temporary text when the
152 // popup is closed. 147 // popup is closed.
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 const InstantSuggestion& suggestion, 226 const InstantSuggestion& suggestion,
232 bool skip_inline_autocomplete) { 227 bool skip_inline_autocomplete) {
233 if (skip_inline_autocomplete) { 228 if (skip_inline_autocomplete) {
234 const string16 final_text = input_text + suggestion.text; 229 const string16 final_text = input_text + suggestion.text;
235 view_->OnBeforePossibleChange(); 230 view_->OnBeforePossibleChange();
236 view_->SetWindowTextAndCaretPos(final_text, final_text.length(), false, 231 view_->SetWindowTextAndCaretPos(final_text, final_text.length(), false,
237 false); 232 false);
238 view_->OnAfterPossibleChange(); 233 view_->OnAfterPossibleChange();
239 } else if (popup_->IsOpen()) { 234 } else if (popup_->IsOpen()) {
240 SearchProvider* search_provider = 235 SearchProvider* search_provider =
241 autocomplete_controller_->search_provider(); 236 autocomplete_controller()->search_provider();
242 // There may be no providers during testing; guard against that. 237 // There may be no providers during testing; guard against that.
243 if (search_provider) 238 if (search_provider)
244 search_provider->FinalizeInstantQuery(input_text, suggestion); 239 search_provider->FinalizeInstantQuery(input_text, suggestion);
245 } 240 }
246 } 241 }
247 242
248 void OmniboxEditModel::SetInstantSuggestion( 243 void OmniboxEditModel::SetInstantSuggestion(
249 const InstantSuggestion& suggestion) { 244 const InstantSuggestion& suggestion) {
250 switch (suggestion.behavior) { 245 switch (suggestion.behavior) {
251 case INSTANT_COMPLETE_NOW: 246 case INSTANT_COMPLETE_NOW:
252 view_->SetInstantSuggestion(string16()); 247 view_->SetInstantSuggestion(string16());
253 if (!suggestion.text.empty()) 248 if (!suggestion.text.empty())
254 FinalizeInstantQuery(view_->GetText(), suggestion, false); 249 FinalizeInstantQuery(view_->GetText(), suggestion, false);
255 break; 250 break;
256 251
257 case INSTANT_COMPLETE_NEVER: { 252 case INSTANT_COMPLETE_NEVER: {
258 DCHECK_EQ(INSTANT_SUGGESTION_SEARCH, suggestion.type); 253 DCHECK_EQ(INSTANT_SUGGESTION_SEARCH, suggestion.type);
259 view_->SetInstantSuggestion(suggestion.text); 254 view_->SetInstantSuggestion(suggestion.text);
260 SearchProvider* search_provider = 255 SearchProvider* search_provider =
261 autocomplete_controller_->search_provider(); 256 autocomplete_controller()->search_provider();
262 if (search_provider) 257 if (search_provider)
263 search_provider->ClearInstantSuggestion(); 258 search_provider->ClearInstantSuggestion();
264 break; 259 break;
265 } 260 }
266 261
267 case INSTANT_COMPLETE_REPLACE: { 262 case INSTANT_COMPLETE_REPLACE: {
268 const bool save_original_selection = !has_temporary_text_; 263 const bool save_original_selection = !has_temporary_text_;
269 view_->SetInstantSuggestion(string16()); 264 view_->SetInstantSuggestion(string16());
270 has_temporary_text_ = true; 265 has_temporary_text_ = true;
271 is_temporary_text_set_by_instant_ = true; 266 is_temporary_text_set_by_instant_ = true;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 std::string())) { 360 std::string())) {
366 *title = controller_->GetTitle(); 361 *title = controller_->GetTitle();
367 *favicon = controller_->GetFavicon(); 362 *favicon = controller_->GetFavicon();
368 } 363 }
369 } 364 }
370 365
371 bool OmniboxEditModel::UseVerbatimInstant() { 366 bool OmniboxEditModel::UseVerbatimInstant() {
372 #if defined(OS_MACOSX) 367 #if defined(OS_MACOSX)
373 // TODO(suzhe): Fix Mac port to display Instant suggest in a separated NSView, 368 // TODO(suzhe): Fix Mac port to display Instant suggest in a separated NSView,
374 // so that we can display Instant suggest along with composition text. 369 // so that we can display Instant suggest along with composition text.
375 const AutocompleteInput& input = autocomplete_controller_->input(); 370 const AutocompleteInput& input = autocomplete_controller()->input();
376 if (input.prevent_inline_autocomplete()) 371 if (input.prevent_inline_autocomplete())
377 return true; 372 return true;
378 #endif 373 #endif
379 374
380 // The value of input.prevent_inline_autocomplete() is determined by the 375 // The value of input.prevent_inline_autocomplete() is determined by the
381 // following conditions: 376 // following conditions:
382 // 1. If the caret is at the end of the text. 377 // 1. If the caret is at the end of the text.
383 // 2. If it's in IME composition mode. 378 // 2. If it's in IME composition mode.
384 // We send the caret position to Instant (so it can determine #1 itself), and 379 // We send the caret position to Instant (so it can determine #1 itself), and
385 // we use a separated widget for displaying the Instant suggest (so it doesn't 380 // 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
461 } 456 }
462 457
463 void OmniboxEditModel::SetInputInProgress(bool in_progress) { 458 void OmniboxEditModel::SetInputInProgress(bool in_progress) {
464 if (user_input_in_progress_ == in_progress) 459 if (user_input_in_progress_ == in_progress)
465 return; 460 return;
466 461
467 user_input_in_progress_ = in_progress; 462 user_input_in_progress_ = in_progress;
468 if (user_input_in_progress_) { 463 if (user_input_in_progress_) {
469 time_user_first_modified_omnibox_ = base::TimeTicks::Now(); 464 time_user_first_modified_omnibox_ = base::TimeTicks::Now();
470 content::RecordAction(content::UserMetricsAction("OmniboxInputInProgress")); 465 content::RecordAction(content::UserMetricsAction("OmniboxInputInProgress"));
471 autocomplete_controller_->ResetSession(); 466 autocomplete_controller()->ResetSession();
472 } 467 }
473 controller_->OnInputInProgress(in_progress); 468 controller_->OnInputInProgress(in_progress);
474 469
475 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); 470 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_);
476 } 471 }
477 472
478 void OmniboxEditModel::Revert() { 473 void OmniboxEditModel::Revert() {
479 SetInputInProgress(false); 474 SetInputInProgress(false);
480 paste_state_ = NONE; 475 paste_state_ = NONE;
481 InternalSetUserText(string16()); 476 InternalSetUserText(string16());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 // One example is when user presses Ctrl key while having a highlighted 515 // One example is when user presses Ctrl key while having a highlighted
521 // inline autocomplete text. 516 // inline autocomplete text.
522 // TODO: Rethink how we are going to handle this case to avoid 517 // TODO: Rethink how we are going to handle this case to avoid
523 // inconsistent behavior when user presses Ctrl key. 518 // inconsistent behavior when user presses Ctrl key.
524 // See http://crbug.com/165961 and http://crbug.com/165968 for more details. 519 // See http://crbug.com/165961 and http://crbug.com/165968 for more details.
525 cursor_position = user_text_.length(); 520 cursor_position = user_text_.length();
526 } 521 }
527 522
528 // We don't explicitly clear OmniboxPopupModel::manually_selected_match, as 523 // We don't explicitly clear OmniboxPopupModel::manually_selected_match, as
529 // Start ends up invoking OmniboxPopupModel::OnResultChanged which clears it. 524 // Start ends up invoking OmniboxPopupModel::OnResultChanged which clears it.
530 autocomplete_controller_->Start(AutocompleteInput( 525 autocomplete_controller()->Start(AutocompleteInput(
531 user_text_, cursor_position, string16(), GURL(), 526 user_text_, cursor_position, string16(), GURL(),
532 prevent_inline_autocomplete || just_deleted_text_ || 527 prevent_inline_autocomplete || just_deleted_text_ ||
533 (has_selected_text && inline_autocomplete_text_.empty()) || 528 (has_selected_text && inline_autocomplete_text_.empty()) ||
534 (paste_state_ != NONE), keyword_is_selected, 529 (paste_state_ != NONE), keyword_is_selected,
535 keyword_is_selected || allow_exact_keyword_match_, 530 keyword_is_selected || allow_exact_keyword_match_,
536 AutocompleteInput::ALL_MATCHES)); 531 AutocompleteInput::ALL_MATCHES));
537 } 532 }
538 533
539 void OmniboxEditModel::StopAutocomplete() { 534 void OmniboxEditModel::StopAutocomplete() {
540 autocomplete_controller_->Stop(true); 535 autocomplete_controller()->Stop(true);
541 } 536 }
542 537
543 bool OmniboxEditModel::CanPasteAndGo(const string16& text) const { 538 bool OmniboxEditModel::CanPasteAndGo(const string16& text) const {
544 if (!view_->command_updater()->IsCommandEnabled(IDC_OPEN_CURRENT_URL)) 539 if (!view_->command_updater()->IsCommandEnabled(IDC_OPEN_CURRENT_URL))
545 return false; 540 return false;
546 541
547 AutocompleteMatch match; 542 AutocompleteMatch match;
548 ClassifyStringForPasteAndGo(text, &match, NULL); 543 ClassifyStringForPasteAndGo(text, &match, NULL);
549 return match.destination_url.is_valid(); 544 return match.destination_url.is_valid();
550 } 545 }
(...skipping 19 matching lines...) Expand all
570 // Get the URL and transition type for the selected entry. 565 // Get the URL and transition type for the selected entry.
571 AutocompleteMatch match; 566 AutocompleteMatch match;
572 GURL alternate_nav_url; 567 GURL alternate_nav_url;
573 GetInfoForCurrentText(&match, &alternate_nav_url); 568 GetInfoForCurrentText(&match, &alternate_nav_url);
574 569
575 // If CTRL is down it means the user wants to append ".com" to the text he 570 // If CTRL is down it means the user wants to append ".com" to the text he
576 // typed. If we can successfully generate a URL_WHAT_YOU_TYPED match doing 571 // typed. If we can successfully generate a URL_WHAT_YOU_TYPED match doing
577 // that, then we use this. These matches are marked as generated by the 572 // that, then we use this. These matches are marked as generated by the
578 // HistoryURLProvider so we only generate them if this provider is present. 573 // HistoryURLProvider so we only generate them if this provider is present.
579 if (control_key_state_ == DOWN_WITHOUT_CHANGE && !KeywordIsSelected() && 574 if (control_key_state_ == DOWN_WITHOUT_CHANGE && !KeywordIsSelected() &&
580 autocomplete_controller_->history_url_provider()) { 575 autocomplete_controller()->history_url_provider()) {
581 // Generate a new AutocompleteInput, copying the latest one but using "com" 576 // Generate a new AutocompleteInput, copying the latest one but using "com"
582 // as the desired TLD. Then use this autocomplete input to generate a 577 // as the desired TLD. Then use this autocomplete input to generate a
583 // URL_WHAT_YOU_TYPED AutocompleteMatch. Note that using the most recent 578 // URL_WHAT_YOU_TYPED AutocompleteMatch. Note that using the most recent
584 // input instead of the currently visible text means we'll ignore any 579 // input instead of the currently visible text means we'll ignore any
585 // visible inline autocompletion: if a user types "foo" and is autocompleted 580 // visible inline autocompletion: if a user types "foo" and is autocompleted
586 // to "foodnetwork.com", ctrl-enter will navigate to "foo.com", not 581 // to "foodnetwork.com", ctrl-enter will navigate to "foo.com", not
587 // "foodnetwork.com". At the time of writing, this behavior matches 582 // "foodnetwork.com". At the time of writing, this behavior matches
588 // Internet Explorer, but not Firefox. 583 // Internet Explorer, but not Firefox.
589 const AutocompleteInput& old_input = autocomplete_controller_->input(); 584 const AutocompleteInput& old_input = autocomplete_controller()->input();
590 AutocompleteInput input( 585 AutocompleteInput input(
591 old_input.text(), old_input.cursor_position(), ASCIIToUTF16("com"), 586 old_input.text(), old_input.cursor_position(), ASCIIToUTF16("com"),
592 GURL(), old_input.prevent_inline_autocomplete(), 587 GURL(), old_input.prevent_inline_autocomplete(),
593 old_input.prefer_keyword(), old_input.allow_exact_keyword_match(), 588 old_input.prefer_keyword(), old_input.allow_exact_keyword_match(),
594 old_input.matches_requested()); 589 old_input.matches_requested());
595 AutocompleteMatch url_match = HistoryURLProvider::SuggestExactInput( 590 AutocompleteMatch url_match = HistoryURLProvider::SuggestExactInput(
596 autocomplete_controller_->history_url_provider(), input, true); 591 autocomplete_controller()->history_url_provider(), input, true);
597 592
598 if (url_match.destination_url.is_valid()) { 593 if (url_match.destination_url.is_valid()) {
599 // We have a valid URL, we use this newly generated AutocompleteMatch. 594 // We have a valid URL, we use this newly generated AutocompleteMatch.
600 match = url_match; 595 match = url_match;
601 alternate_nav_url = GURL(); 596 alternate_nav_url = GURL();
602 } 597 }
603 } 598 }
604 599
605 if (!match.destination_url.is_valid()) 600 if (!match.destination_url.is_valid())
606 return; 601 return;
(...skipping 30 matching lines...) Expand all
637 void OmniboxEditModel::OpenMatch(const AutocompleteMatch& match, 632 void OmniboxEditModel::OpenMatch(const AutocompleteMatch& match,
638 WindowOpenDisposition disposition, 633 WindowOpenDisposition disposition,
639 const GURL& alternate_nav_url, 634 const GURL& alternate_nav_url,
640 size_t index) { 635 size_t index) {
641 // We only care about cases where there is a selection (i.e. the popup is 636 // We only care about cases where there is a selection (i.e. the popup is
642 // open). 637 // open).
643 if (popup_->IsOpen()) { 638 if (popup_->IsOpen()) {
644 const base::TimeTicks& now(base::TimeTicks::Now()); 639 const base::TimeTicks& now(base::TimeTicks::Now());
645 // TODO(sreeram): Handle is_temporary_text_set_by_instant_ correctly. 640 // TODO(sreeram): Handle is_temporary_text_set_by_instant_ correctly.
646 AutocompleteLog log( 641 AutocompleteLog log(
647 autocomplete_controller_->input().text(), 642 autocomplete_controller()->input().text(),
648 just_deleted_text_, 643 just_deleted_text_,
649 autocomplete_controller_->input().type(), 644 autocomplete_controller()->input().type(),
650 popup_->selected_line(), 645 popup_->selected_line(),
651 -1, // don't yet know tab ID; set later if appropriate 646 -1, // don't yet know tab ID; set later if appropriate
652 delegate_->CurrentPageExists() ? ClassifyPage(delegate_->GetURL()) : 647 delegate_->CurrentPageExists() ? ClassifyPage(delegate_->GetURL()) :
653 metrics::OmniboxEventProto_PageClassification_OTHER, 648 metrics::OmniboxEventProto_PageClassification_OTHER,
654 now - time_user_first_modified_omnibox_, 649 now - time_user_first_modified_omnibox_,
655 string16::npos, // completed_length; possibly set later 650 string16::npos, // completed_length; possibly set later
656 now - autocomplete_controller_->last_time_default_match_changed(), 651 now - autocomplete_controller()->last_time_default_match_changed(),
657 result()); 652 result());
658 DCHECK(user_input_in_progress_ || 653 DCHECK(user_input_in_progress_ ||
659 match.provider->type() == AutocompleteProvider::TYPE_ZERO_SUGGEST) 654 match.provider->type() == AutocompleteProvider::TYPE_ZERO_SUGGEST)
660 << "We didn't get here through the expected series of calls. " 655 << "We didn't get here through the expected series of calls. "
661 << "time_user_first_modified_omnibox_ is not set correctly and other " 656 << "time_user_first_modified_omnibox_ is not set correctly and other "
662 << "things may be wrong. Match provider: " << match.provider->GetName(); 657 << "things may be wrong. Match provider: " << match.provider->GetName();
663 DCHECK(log.elapsed_time_since_user_first_modified_omnibox >= 658 DCHECK(log.elapsed_time_since_user_first_modified_omnibox >=
664 log.elapsed_time_since_last_change_to_default_match) 659 log.elapsed_time_since_last_change_to_default_match)
665 << "We should've got the notification that the user modified the " 660 << "We should've got the notification that the user modified the "
666 << "omnibox text at same time or before the most recent time the " 661 << "omnibox text at same time or before the most recent time the "
667 << "default match changed."; 662 << "default match changed.";
668 if (index != OmniboxPopupModel::kNoMatch) 663 if (index != OmniboxPopupModel::kNoMatch)
669 log.selected_index = index; 664 log.selected_index = index;
670 if (match.inline_autocomplete_offset != string16::npos) { 665 if (match.inline_autocomplete_offset != string16::npos) {
671 DCHECK_GE(match.fill_into_edit.length(), 666 DCHECK_GE(match.fill_into_edit.length(),
672 match.inline_autocomplete_offset); 667 match.inline_autocomplete_offset);
673 log.completed_length = 668 log.completed_length =
674 match.fill_into_edit.length() - match.inline_autocomplete_offset; 669 match.fill_into_edit.length() - match.inline_autocomplete_offset;
675 } 670 }
676 671
677 if ((disposition == CURRENT_TAB) && delegate_->CurrentPageExists()) { 672 if ((disposition == CURRENT_TAB) && delegate_->CurrentPageExists()) {
678 // If we know the destination is being opened in the current tab, 673 // If we know the destination is being opened in the current tab,
679 // we can easily get the tab ID. (If it's being opened in a new 674 // we can easily get the tab ID. (If it's being opened in a new
680 // tab, we don't know the tab ID yet.) 675 // tab, we don't know the tab ID yet.)
681 log.tab_id = delegate_->GetSessionID().id(); 676 log.tab_id = delegate_->GetSessionID().id();
682 } 677 }
683 autocomplete_controller_->AddProvidersInfo(&log.providers_info); 678 autocomplete_controller()->AddProvidersInfo(&log.providers_info);
684 content::NotificationService::current()->Notify( 679 content::NotificationService::current()->Notify(
685 chrome::NOTIFICATION_OMNIBOX_OPENED_URL, 680 chrome::NOTIFICATION_OMNIBOX_OPENED_URL,
686 content::Source<Profile>(profile_), 681 content::Source<Profile>(profile_),
687 content::Details<AutocompleteLog>(&log)); 682 content::Details<AutocompleteLog>(&log));
688 HISTOGRAM_ENUMERATION("Omnibox.EventCount", 1, 2); 683 HISTOGRAM_ENUMERATION("Omnibox.EventCount", 1, 2);
689 } 684 }
690 685
691 TemplateURL* template_url = match.GetTemplateURL(profile_, false); 686 TemplateURL* template_url = match.GetTemplateURL(profile_, false);
692 if (template_url) { 687 if (template_url) {
693 if (match.transition == content::PAGE_TRANSITION_KEYWORD) { 688 if (match.transition == content::PAGE_TRANSITION_KEYWORD) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 if (disposition != NEW_BACKGROUND_TAB) { 723 if (disposition != NEW_BACKGROUND_TAB) {
729 base::AutoReset<bool> tmp(&in_revert_, true); 724 base::AutoReset<bool> tmp(&in_revert_, true);
730 view_->RevertAll(); // Revert the box to its unedited state 725 view_->RevertAll(); // Revert the box to its unedited state
731 } 726 }
732 727
733 if (match.type == AutocompleteMatch::EXTENSION_APP) { 728 if (match.type == AutocompleteMatch::EXTENSION_APP) {
734 ExtensionAppProvider::LaunchAppFromOmnibox(match, profile_, disposition); 729 ExtensionAppProvider::LaunchAppFromOmnibox(match, profile_, disposition);
735 } else { 730 } else {
736 base::TimeDelta query_formulation_time = 731 base::TimeDelta query_formulation_time =
737 base::TimeTicks::Now() - time_user_first_modified_omnibox_; 732 base::TimeTicks::Now() - time_user_first_modified_omnibox_;
738 const GURL destination_url = autocomplete_controller_-> 733 const GURL destination_url = autocomplete_controller()->
739 GetDestinationURL(match, query_formulation_time); 734 GetDestinationURL(match, query_formulation_time);
740 735
741 // If running with instant, notify the instant controller that a navigation 736 // If running with instant, notify the instant controller that a navigation
742 // is about to take place if we are navigating to a URL. This can be 737 // is about to take place if we are navigating to a URL. This can be
743 // determined by inspecting the transition type. To ensure that this is only 738 // determined by inspecting the transition type. To ensure that this is only
744 // done on Enter key press, check that the disposition is CURRENT_TAB. This 739 // done on Enter key press, check that the disposition is CURRENT_TAB. This
745 // is the same heuristic used by BrowserInstantController::OpenInstant 740 // is the same heuristic used by BrowserInstantController::OpenInstant
746 if (match.transition == content::PAGE_TRANSITION_TYPED && 741 if (match.transition == content::PAGE_TRANSITION_TYPED &&
747 disposition == CURRENT_TAB) { 742 disposition == CURRENT_TAB) {
748 InstantController* instant = controller_->GetInstant(); 743 InstantController* instant = controller_->GetInstant();
749 if (instant) 744 if (instant)
750 instant->OmniboxNavigateToURL(); 745 instant->OmniboxNavigateToURL();
751 } 746 }
752 747
753 // This calls RevertAll again. 748 // This calls RevertAll again.
754 base::AutoReset<bool> tmp(&in_revert_, true); 749 base::AutoReset<bool> tmp(&in_revert_, true);
755 controller_->OnAutocompleteAccept(destination_url, disposition, 750 controller_->OnAutocompleteAccept(destination_url, disposition,
756 match.transition, alternate_nav_url); 751 match.transition, alternate_nav_url);
757 } 752 }
758 753
759 if (match.starred) 754 if (match.starred)
760 bookmark_utils::RecordBookmarkLaunch(bookmark_utils::LAUNCH_OMNIBOX); 755 bookmark_utils::RecordBookmarkLaunch(bookmark_utils::LAUNCH_OMNIBOX);
761 } 756 }
762 757
763 bool OmniboxEditModel::AcceptKeyword(EnteredKeywordModeMethod entered_method) { 758 bool OmniboxEditModel::AcceptKeyword(EnteredKeywordModeMethod entered_method) {
764 DCHECK(is_keyword_hint_ && !keyword_.empty()); 759 DCHECK(is_keyword_hint_ && !keyword_.empty());
765 760
766 autocomplete_controller_->Stop(false); 761 autocomplete_controller()->Stop(false);
767 is_keyword_hint_ = false; 762 is_keyword_hint_ = false;
768 763
769 if (popup_->IsOpen()) 764 if (popup_->IsOpen())
770 popup_->SetSelectedLineState(OmniboxPopupModel::KEYWORD); 765 popup_->SetSelectedLineState(OmniboxPopupModel::KEYWORD);
771 else 766 else
772 StartAutocomplete(false, true); 767 StartAutocomplete(false, true);
773 768
774 // Ensure the current selection is saved before showing keyword mode 769 // Ensure the current selection is saved before showing keyword mode
775 // so that moving to another line and then reverting the text will restore 770 // so that moving to another line and then reverting the text will restore
776 // the current state properly. 771 // the current state properly.
777 bool save_original_selection = !has_temporary_text_; 772 bool save_original_selection = !has_temporary_text_;
778 has_temporary_text_ = true; 773 has_temporary_text_ = true;
779 is_temporary_text_set_by_instant_ = false; 774 is_temporary_text_set_by_instant_ = false;
780 view_->OnTemporaryTextMaybeChanged( 775 view_->OnTemporaryTextMaybeChanged(
781 DisplayTextFromUserText(CurrentMatch().fill_into_edit), 776 DisplayTextFromUserText(CurrentMatch().fill_into_edit),
782 save_original_selection, true); 777 save_original_selection, true);
783 778
784 content::RecordAction(UserMetricsAction("AcceptedKeywordHint")); 779 content::RecordAction(UserMetricsAction("AcceptedKeywordHint"));
785 UMA_HISTOGRAM_ENUMERATION(kEnteredKeywordModeHistogram, entered_method, 780 UMA_HISTOGRAM_ENUMERATION(kEnteredKeywordModeHistogram, entered_method,
786 ENTERED_KEYWORD_MODE_NUM_ITEMS); 781 ENTERED_KEYWORD_MODE_NUM_ITEMS);
787 782
788 return true; 783 return true;
789 } 784 }
790 785
791 void OmniboxEditModel::ClearKeyword(const string16& visible_text) { 786 void OmniboxEditModel::ClearKeyword(const string16& visible_text) {
792 autocomplete_controller_->Stop(false); 787 autocomplete_controller()->Stop(false);
793 ClearPopupKeywordMode(); 788 ClearPopupKeywordMode();
794 789
795 const string16 window_text(keyword_ + visible_text); 790 const string16 window_text(keyword_ + visible_text);
796 791
797 // Only reset the result if the edit text has changed since the 792 // Only reset the result if the edit text has changed since the
798 // keyword was accepted, or if the popup is closed. 793 // keyword was accepted, or if the popup is closed.
799 if (just_deleted_text_ || !visible_text.empty() || !popup_->IsOpen()) { 794 if (just_deleted_text_ || !visible_text.empty() || !popup_->IsOpen()) {
800 view_->OnBeforePossibleChange(); 795 view_->OnBeforePossibleChange();
801 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), 796 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(),
802 false, false); 797 false, false);
803 keyword_.clear(); 798 keyword_.clear();
804 is_keyword_hint_ = false; 799 is_keyword_hint_ = false;
805 view_->OnAfterPossibleChange(); 800 view_->OnAfterPossibleChange();
806 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this 801 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this
807 // since the edit contents have actually grown 802 // since the edit contents have actually grown
808 // longer. 803 // longer.
809 } else { 804 } else {
810 is_keyword_hint_ = true; 805 is_keyword_hint_ = true;
811 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), 806 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(),
812 false, true); 807 false, true);
813 } 808 }
814 } 809 }
815 810
816 const AutocompleteResult& OmniboxEditModel::result() const { 811 const AutocompleteResult& OmniboxEditModel::result() const {
817 return autocomplete_controller_->result(); 812 return autocomplete_controller()->result();
818 } 813 }
819 814
820 void OmniboxEditModel::OnSetFocus(bool control_down) { 815 void OmniboxEditModel::OnSetFocus(bool control_down) {
821 // If the omnibox lost focus while the caret was hidden and then regained 816 // If the omnibox lost focus while the caret was hidden and then regained
822 // focus, OnSetFocus() is called and should restore visibility. Note that 817 // focus, OnSetFocus() is called and should restore visibility. Note that
823 // focus can be regained without an accompanying call to 818 // focus can be regained without an accompanying call to
824 // OmniboxView::SetFocus(), e.g. by tabbing in. 819 // OmniboxView::SetFocus(), e.g. by tabbing in.
825 SetFocusState(OMNIBOX_FOCUS_VISIBLE, OMNIBOX_FOCUS_CHANGE_EXPLICIT); 820 SetFocusState(OMNIBOX_FOCUS_VISIBLE, OMNIBOX_FOCUS_CHANGE_EXPLICIT);
826 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; 821 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP;
827 822
828 if (delegate_->CurrentPageExists()) { 823 if (delegate_->CurrentPageExists()) {
829 // TODO(jered): We may want to merge this into Start() and just call that 824 // TODO(jered): We may want to merge this into Start() and just call that
830 // here rather than having a special entry point for zero-suggest. Note 825 // here rather than having a special entry point for zero-suggest. Note
831 // that we avoid PermanentURL() here because it's not guaranteed to give us 826 // that we avoid PermanentURL() here because it's not guaranteed to give us
832 // the actual underlying current URL, e.g. if we're on the NTP and the 827 // the actual underlying current URL, e.g. if we're on the NTP and the
833 // |permanent_text_| is empty. 828 // |permanent_text_| is empty.
834 autocomplete_controller_->StartZeroSuggest(delegate_->GetURL(), 829 autocomplete_controller()->StartZeroSuggest(delegate_->GetURL(),
835 user_text_); 830 user_text_);
836 } 831 }
837 832
838 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); 833 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_);
839 } 834 }
840 835
841 void OmniboxEditModel::SetCaretVisibility(bool visible) { 836 void OmniboxEditModel::SetCaretVisibility(bool visible) {
842 // Caret visibility only matters if the omnibox has focus. 837 // Caret visibility only matters if the omnibox has focus.
843 if (focus_state_ != OMNIBOX_FOCUS_NONE) { 838 if (focus_state_ != OMNIBOX_FOCUS_NONE) {
844 SetFocusState(visible ? OMNIBOX_FOCUS_VISIBLE : OMNIBOX_FOCUS_INVISIBLE, 839 SetFocusState(visible ? OMNIBOX_FOCUS_VISIBLE : OMNIBOX_FOCUS_INVISIBLE,
845 OMNIBOX_FOCUS_CHANGE_EXPLICIT); 840 OMNIBOX_FOCUS_CHANGE_EXPLICIT);
846 } 841 }
847 } 842 }
848 843
849 void OmniboxEditModel::OnWillKillFocus(gfx::NativeView view_gaining_focus) { 844 void OmniboxEditModel::OnWillKillFocus(gfx::NativeView view_gaining_focus) {
850 InstantController* instant = controller_->GetInstant(); 845 InstantController* instant = controller_->GetInstant();
851 if (instant) { 846 if (instant) {
852 instant->OmniboxFocusChanged(OMNIBOX_FOCUS_NONE, 847 instant->OmniboxFocusChanged(OMNIBOX_FOCUS_NONE,
853 OMNIBOX_FOCUS_CHANGE_EXPLICIT, 848 OMNIBOX_FOCUS_CHANGE_EXPLICIT,
854 view_gaining_focus); 849 view_gaining_focus);
855 } 850 }
856 851
857 // TODO(jered): Rip this out along with StartZeroSuggest. 852 // TODO(jered): Rip this out along with StartZeroSuggest.
858 autocomplete_controller_->StopZeroSuggest(); 853 autocomplete_controller()->StopZeroSuggest();
859 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); 854 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_);
860 } 855 }
861 856
862 void OmniboxEditModel::OnKillFocus() { 857 void OmniboxEditModel::OnKillFocus() {
863 // TODO(samarth): determine if it is safe to move the call to 858 // TODO(samarth): determine if it is safe to move the call to
864 // OmniboxFocusChanged() from OnWillKillFocus() to here, which would let us 859 // OmniboxFocusChanged() from OnWillKillFocus() to here, which would let us
865 // just call SetFocusState() to handle the state change. 860 // just call SetFocusState() to handle the state change.
866 focus_state_ = OMNIBOX_FOCUS_NONE; 861 focus_state_ = OMNIBOX_FOCUS_NONE;
867 control_key_state_ = UP; 862 control_key_state_ = UP;
868 paste_state_ = NONE; 863 paste_state_ = NONE;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 // TODO(pkasting): The popup is working on a query but is not open. We 940 // TODO(pkasting): The popup is working on a query but is not open. We
946 // should force it to open immediately. 941 // should force it to open immediately.
947 } 942 }
948 } else { 943 } else {
949 InstantController* instant = controller_->GetInstant(); 944 InstantController* instant = controller_->GetInstant();
950 if (instant && instant->OnUpOrDownKeyPressed(count)) { 945 if (instant && instant->OnUpOrDownKeyPressed(count)) {
951 // If Instant handles the key press, it's showing a list of suggestions 946 // If Instant handles the key press, it's showing a list of suggestions
952 // that it's stepping through. In that case, our popup model is 947 // that it's stepping through. In that case, our popup model is
953 // irrelevant, so don't process the key press ourselves. However, do stop 948 // irrelevant, so don't process the key press ourselves. However, do stop
954 // the autocomplete system from changing the results. 949 // the autocomplete system from changing the results.
955 autocomplete_controller_->Stop(false); 950 autocomplete_controller()->Stop(false);
956 } else { 951 } else {
957 // The popup is open, so the user should be able to interact with it 952 // The popup is open, so the user should be able to interact with it
958 // normally. 953 // normally.
959 popup_->Move(count); 954 popup_->Move(count);
960 } 955 }
961 } 956 }
962 } 957 }
963 958
964 void OmniboxEditModel::OnPopupDataChanged( 959 void OmniboxEditModel::OnPopupDataChanged(
965 const string16& text, 960 const string16& text,
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1178 } else { 1173 } else {
1179 popup_->OnResultChanged(); 1174 popup_->OnResultChanged();
1180 } 1175 }
1181 1176
1182 if (popup_->IsOpen()) { 1177 if (popup_->IsOpen()) {
1183 OnPopupBoundsChanged(popup_->view()->GetTargetBounds()); 1178 OnPopupBoundsChanged(popup_->view()->GetTargetBounds());
1184 1179
1185 InstantController* instant = controller_->GetInstant(); 1180 InstantController* instant = controller_->GetInstant();
1186 if (instant && !in_revert_) { 1181 if (instant && !in_revert_) {
1187 instant->HandleAutocompleteResults( 1182 instant->HandleAutocompleteResults(
1188 *autocomplete_controller_->providers()); 1183 *autocomplete_controller()->providers());
1189 } 1184 }
1190 } else if (was_open) { 1185 } else if (was_open) {
1191 // Accepts the temporary text as the user text, because it makes little 1186 // Accepts the temporary text as the user text, because it makes little
1192 // sense to have temporary text when the popup is closed. 1187 // sense to have temporary text when the popup is closed.
1193 InternalSetUserText(UserTextFromDisplayText(view_->GetText())); 1188 InternalSetUserText(UserTextFromDisplayText(view_->GetText()));
1194 has_temporary_text_ = false; 1189 has_temporary_text_ = false;
1195 is_temporary_text_set_by_instant_ = false; 1190 is_temporary_text_set_by_instant_ = false;
1196 OnPopupBoundsChanged(gfx::Rect()); 1191 OnPopupBoundsChanged(gfx::Rect());
1197 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); 1192 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_);
1198 } 1193 }
1199 } 1194 }
1200 1195
1201 bool OmniboxEditModel::query_in_progress() const { 1196 bool OmniboxEditModel::query_in_progress() const {
1202 return !autocomplete_controller_->done(); 1197 return !autocomplete_controller()->done();
1203 } 1198 }
1204 1199
1205 void OmniboxEditModel::InternalSetUserText(const string16& text) { 1200 void OmniboxEditModel::InternalSetUserText(const string16& text) {
1206 user_text_ = text; 1201 user_text_ = text;
1207 just_deleted_text_ = false; 1202 just_deleted_text_ = false;
1208 inline_autocomplete_text_.clear(); 1203 inline_autocomplete_text_.clear();
1209 } 1204 }
1210 1205
1211 bool OmniboxEditModel::KeywordIsSelected() const { 1206 bool OmniboxEditModel::KeywordIsSelected() const {
1212 return !is_keyword_hint_ && !keyword_.empty(); 1207 return !is_keyword_hint_ && !keyword_.empty();
(...skipping 11 matching lines...) Expand all
1224 } 1219 }
1225 1220
1226 string16 OmniboxEditModel::UserTextFromDisplayText(const string16& text) const { 1221 string16 OmniboxEditModel::UserTextFromDisplayText(const string16& text) const {
1227 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; 1222 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text;
1228 } 1223 }
1229 1224
1230 void OmniboxEditModel::InfoForCurrentSelection(AutocompleteMatch* match, 1225 void OmniboxEditModel::InfoForCurrentSelection(AutocompleteMatch* match,
1231 GURL* alternate_nav_url) const { 1226 GURL* alternate_nav_url) const {
1232 DCHECK(match != NULL); 1227 DCHECK(match != NULL);
1233 const AutocompleteResult& result = this->result(); 1228 const AutocompleteResult& result = this->result();
1234 if (!autocomplete_controller_->done()) { 1229 if (!autocomplete_controller()->done()) {
1235 // It's technically possible for |result| to be empty if no provider returns 1230 // It's technically possible for |result| to be empty if no provider returns
1236 // a synchronous result but the query has not completed synchronously; 1231 // a synchronous result but the query has not completed synchronously;
1237 // pratically, however, that should never actually happen. 1232 // pratically, however, that should never actually happen.
1238 if (result.empty()) 1233 if (result.empty())
1239 return; 1234 return;
1240 // The user cannot have manually selected a match, or the query would have 1235 // The user cannot have manually selected a match, or the query would have
1241 // stopped. So the default match must be the desired selection. 1236 // stopped. So the default match must be the desired selection.
1242 *match = *result.default_match(); 1237 *match = *result.default_match();
1243 } else { 1238 } else {
1244 CHECK(popup_->IsOpen()); 1239 CHECK(popup_->IsOpen());
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1328 old_text, space_position, 1323 old_text, space_position,
1329 old_text.length() - space_position)) { 1324 old_text.length() - space_position)) {
1330 return false; 1325 return false;
1331 } 1326 }
1332 1327
1333 // Then check if the text before the inserted space matches a keyword. 1328 // Then check if the text before the inserted space matches a keyword.
1334 string16 keyword; 1329 string16 keyword;
1335 TrimWhitespace(new_text.substr(0, space_position), TRIM_LEADING, &keyword); 1330 TrimWhitespace(new_text.substr(0, space_position), TRIM_LEADING, &keyword);
1336 // TODO(sreeram): Once the Instant extended API supports keywords properly, 1331 // TODO(sreeram): Once the Instant extended API supports keywords properly,
1337 // keyword_provider() should never be NULL. Remove that clause. 1332 // keyword_provider() should never be NULL. Remove that clause.
1338 return !keyword.empty() && autocomplete_controller_->keyword_provider() && 1333 return !keyword.empty() && autocomplete_controller()->keyword_provider() &&
1339 !autocomplete_controller_->keyword_provider()-> 1334 !autocomplete_controller()->keyword_provider()->
1340 GetKeywordForText(keyword).empty(); 1335 GetKeywordForText(keyword).empty();
1341 } 1336 }
1342 1337
1343 bool OmniboxEditModel::DoInstant(const AutocompleteMatch& match) { 1338 bool OmniboxEditModel::DoInstant(const AutocompleteMatch& match) {
1344 InstantController* instant = controller_->GetInstant(); 1339 InstantController* instant = controller_->GetInstant();
1345 if (!instant || in_revert_) 1340 if (!instant || in_revert_)
1346 return false; 1341 return false;
1347 1342
1348 // Don't call Update() if the change is a result of a 1343 // Don't call Update() if the change is a result of a
1349 // INSTANT_COMPLETE_REPLACE instant suggestion. 1344 // INSTANT_COMPLETE_REPLACE instant suggestion.
1350 if (has_temporary_text_ && is_temporary_text_set_by_instant_) 1345 if (has_temporary_text_ && is_temporary_text_set_by_instant_)
1351 return false; 1346 return false;
1352 1347
1353 // The two pieces of text we want to send Instant, viz., what the user has 1348 // The two pieces of text we want to send Instant, viz., what the user has
1354 // typed, and the full omnibox text including any inline autocompletion. 1349 // typed, and the full omnibox text including any inline autocompletion.
1355 string16 user_text = has_temporary_text_ ? 1350 string16 user_text = has_temporary_text_ ?
1356 match.fill_into_edit : DisplayTextFromUserText(user_text_); 1351 match.fill_into_edit : DisplayTextFromUserText(user_text_);
1357 string16 full_text = view_->GetText(); 1352 string16 full_text = view_->GetText();
1358 1353
1359 // Remove "?" if we're in forced query mode. 1354 // Remove "?" if we're in forced query mode.
1360 AutocompleteInput::RemoveForcedQueryStringIfNecessary( 1355 AutocompleteInput::RemoveForcedQueryStringIfNecessary(
1361 autocomplete_controller_->input().type(), &user_text); 1356 autocomplete_controller()->input().type(), &user_text);
1362 AutocompleteInput::RemoveForcedQueryStringIfNecessary( 1357 AutocompleteInput::RemoveForcedQueryStringIfNecessary(
1363 autocomplete_controller_->input().type(), &full_text); 1358 autocomplete_controller()->input().type(), &full_text);
1364 1359
1365 size_t start, end; 1360 size_t start, end;
1366 view_->GetSelectionBounds(&start, &end); 1361 view_->GetSelectionBounds(&start, &end);
1367 1362
1368 return instant->Update(match, user_text, full_text, start, end, 1363 return instant->Update(match, user_text, full_text, start, end,
1369 UseVerbatimInstant(), user_input_in_progress_, popup_->IsOpen(), 1364 UseVerbatimInstant(), user_input_in_progress_, popup_->IsOpen(),
1370 in_escape_handler_, KeywordIsSelected()); 1365 in_escape_handler_, KeywordIsSelected());
1371 } 1366 }
1372 1367
1373 void OmniboxEditModel::DoPreconnect(const AutocompleteMatch& match) { 1368 void OmniboxEditModel::DoPreconnect(const AutocompleteMatch& match) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1430 instant->OmniboxFocusChanged(state, reason, NULL); 1425 instant->OmniboxFocusChanged(state, reason, NULL);
1431 1426
1432 // Update state and notify view if the omnibox has focus and the caret 1427 // Update state and notify view if the omnibox has focus and the caret
1433 // visibility changed. 1428 // visibility changed.
1434 const bool was_caret_visible = is_caret_visible(); 1429 const bool was_caret_visible = is_caret_visible();
1435 focus_state_ = state; 1430 focus_state_ = state;
1436 if (focus_state_ != OMNIBOX_FOCUS_NONE && 1431 if (focus_state_ != OMNIBOX_FOCUS_NONE &&
1437 is_caret_visible() != was_caret_visible) 1432 is_caret_visible() != was_caret_visible)
1438 view_->ApplyCaretVisibility(); 1433 view_->ApplyCaretVisibility();
1439 } 1434 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/omnibox/omnibox_edit_model.h ('k') | chrome/chrome_browser_ui.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698