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

Side by Side Diff: chrome/browser/autocomplete/autocomplete.cc

Issue 6731036: Enabled pressing TAB to cycle through the Omnibox results. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 9 years, 8 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/autocomplete/autocomplete.h" 5 #include "chrome/browser/autocomplete/autocomplete.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set>
9 #include <utility>
8 10
9 #include "base/basictypes.h" 11 #include "base/basictypes.h"
10 #include "base/command_line.h" 12 #include "base/command_line.h"
11 #include "base/i18n/number_formatting.h" 13 #include "base/i18n/number_formatting.h"
12 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
13 #include "base/string_number_conversions.h" 15 #include "base/string_number_conversions.h"
14 #include "base/string_util.h" 16 #include "base/string_util.h"
15 #include "base/utf_string_conversions.h" 17 #include "base/utf_string_conversions.h"
16 #include "chrome/browser/autocomplete/autocomplete_controller_delegate.h" 18 #include "chrome/browser/autocomplete/autocomplete_controller_delegate.h"
17 #include "chrome/browser/autocomplete/autocomplete_match.h" 19 #include "chrome/browser/autocomplete/autocomplete_match.h"
18 #include "chrome/browser/autocomplete/builtin_provider.h" 20 #include "chrome/browser/autocomplete/builtin_provider.h"
19 #include "chrome/browser/autocomplete/history_contents_provider.h" 21 #include "chrome/browser/autocomplete/history_contents_provider.h"
20 #include "chrome/browser/autocomplete/history_quick_provider.h" 22 #include "chrome/browser/autocomplete/history_quick_provider.h"
21 #include "chrome/browser/autocomplete/history_url_provider.h" 23 #include "chrome/browser/autocomplete/history_url_provider.h"
22 #include "chrome/browser/autocomplete/keyword_provider.h" 24 #include "chrome/browser/autocomplete/keyword_provider.h"
23 #include "chrome/browser/autocomplete/search_provider.h" 25 #include "chrome/browser/autocomplete/search_provider.h"
24 #include "chrome/browser/bookmarks/bookmark_model.h" 26 #include "chrome/browser/bookmarks/bookmark_model.h"
27 #include "chrome/browser/extensions/extension_service.h"
25 #include "chrome/browser/external_protocol_handler.h" 28 #include "chrome/browser/external_protocol_handler.h"
26 #include "chrome/browser/net/url_fixer_upper.h" 29 #include "chrome/browser/net/url_fixer_upper.h"
27 #include "chrome/browser/prefs/pref_service.h" 30 #include "chrome/browser/prefs/pref_service.h"
28 #include "chrome/browser/profiles/profile.h" 31 #include "chrome/browser/profiles/profile.h"
32 #include "chrome/browser/search_engines/template_url.h"
33 #include "chrome/browser/search_engines/template_url_model.h"
29 #include "chrome/browser/ui/webui/history_ui.h" 34 #include "chrome/browser/ui/webui/history_ui.h"
30 #include "chrome/common/chrome_switches.h" 35 #include "chrome/common/chrome_switches.h"
31 #include "chrome/common/pref_names.h" 36 #include "chrome/common/pref_names.h"
32 #include "chrome/common/url_constants.h" 37 #include "chrome/common/url_constants.h"
33 #include "content/common/notification_service.h" 38 #include "content/common/notification_service.h"
34 #include "googleurl/src/gurl.h" 39 #include "googleurl/src/gurl.h"
35 #include "googleurl/src/url_canon_ip.h" 40 #include "googleurl/src/url_canon_ip.h"
36 #include "googleurl/src/url_util.h" 41 #include "googleurl/src/url_util.h"
37 #include "grit/generated_resources.h" 42 #include "grit/generated_resources.h"
38 #include "grit/theme_resources.h" 43 #include "grit/theme_resources.h"
(...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 std::upper_bound(begin(), end(), match, &AutocompleteMatch::MoreRelevant); 639 std::upper_bound(begin(), end(), match, &AutocompleteMatch::MoreRelevant);
635 ACMatches::iterator::difference_type default_offset = 640 ACMatches::iterator::difference_type default_offset =
636 default_match_ - begin(); 641 default_match_ - begin();
637 if ((insertion_point - begin()) <= default_offset) 642 if ((insertion_point - begin()) <= default_offset)
638 ++default_offset; 643 ++default_offset;
639 matches_.insert(insertion_point, match); 644 matches_.insert(insertion_point, match);
640 default_match_ = begin() + default_offset; 645 default_match_ = begin() + default_offset;
641 } 646 }
642 647
643 void AutocompleteResult::SortAndCull(const AutocompleteInput& input) { 648 void AutocompleteResult::SortAndCull(const AutocompleteInput& input) {
649 for (ACMatches::iterator i = matches_.begin(); i != matches_.end(); ++i)
650 i->ComputeStrippedDestinationURL();
651
644 // Remove duplicates. 652 // Remove duplicates.
645 std::sort(matches_.begin(), matches_.end(), 653 std::sort(matches_.begin(), matches_.end(),
646 &AutocompleteMatch::DestinationSortFunc); 654 &AutocompleteMatch::DestinationSortFunc);
647 matches_.erase(std::unique(matches_.begin(), matches_.end(), 655 matches_.erase(std::unique(matches_.begin(), matches_.end(),
648 &AutocompleteMatch::DestinationsEqual), 656 &AutocompleteMatch::DestinationsEqual),
649 matches_.end()); 657 matches_.end());
650 658
651 // Sort and trim to the most relevant kMaxMatches matches. 659 // Sort and trim to the most relevant kMaxMatches matches.
652 const size_t num_matches = std::min(kMaxMatches, matches_.size()); 660 const size_t num_matches = std::min(kMaxMatches, matches_.size());
653 std::partial_sort(matches_.begin(), matches_.begin() + num_matches, 661 std::partial_sort(matches_.begin(), matches_.begin() + num_matches,
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 // any copied entries. We do this from the time the user stopped typing as some 785 // any copied entries. We do this from the time the user stopped typing as some
778 // providers (such as SearchProvider) wait for the user to stop typing before 786 // providers (such as SearchProvider) wait for the user to stop typing before
779 // they initiate a query. 787 // they initiate a query.
780 static const int kExpireTimeMS = 500; 788 static const int kExpireTimeMS = 500;
781 789
782 AutocompleteController::AutocompleteController( 790 AutocompleteController::AutocompleteController(
783 Profile* profile, 791 Profile* profile,
784 AutocompleteControllerDelegate* delegate) 792 AutocompleteControllerDelegate* delegate)
785 : delegate_(delegate), 793 : delegate_(delegate),
786 done_(true), 794 done_(true),
787 in_start_(false) { 795 in_start_(false),
796 profile_(profile) {
788 search_provider_ = new SearchProvider(this, profile); 797 search_provider_ = new SearchProvider(this, profile);
789 providers_.push_back(search_provider_); 798 providers_.push_back(search_provider_);
790 if (!CommandLine::ForCurrentProcess()->HasSwitch( 799 if (!CommandLine::ForCurrentProcess()->HasSwitch(
791 switches::kDisableHistoryQuickProvider)) 800 switches::kDisableHistoryQuickProvider))
792 providers_.push_back(new HistoryQuickProvider(this, profile)); 801 providers_.push_back(new HistoryQuickProvider(this, profile));
793 if (!CommandLine::ForCurrentProcess()->HasSwitch( 802 if (!CommandLine::ForCurrentProcess()->HasSwitch(
794 switches::kDisableHistoryURLProvider)) 803 switches::kDisableHistoryURLProvider))
795 providers_.push_back(new HistoryURLProvider(this, profile)); 804 providers_.push_back(new HistoryURLProvider(this, profile));
796 providers_.push_back(new KeywordProvider(this, profile)); 805 providers_.push_back(new KeywordProvider(this, profile));
797 providers_.push_back(new HistoryContentsProvider(this, profile)); 806 providers_.push_back(new HistoryContentsProvider(this, profile));
(...skipping 13 matching lines...) Expand all
811 Stop(false); 820 Stop(false);
812 821
813 for (ACProviders::iterator i(providers_.begin()); i != providers_.end(); ++i) 822 for (ACProviders::iterator i(providers_.begin()); i != providers_.end(); ++i)
814 (*i)->Release(); 823 (*i)->Release();
815 824
816 providers_.clear(); // Not really necessary. 825 providers_.clear(); // Not really necessary.
817 } 826 }
818 827
819 void AutocompleteController::SetProfile(Profile* profile) { 828 void AutocompleteController::SetProfile(Profile* profile) {
820 Stop(true); 829 Stop(true);
830 profile_ = profile;
821 for (ACProviders::iterator i(providers_.begin()); i != providers_.end(); ++i) 831 for (ACProviders::iterator i(providers_.begin()); i != providers_.end(); ++i)
822 (*i)->SetProfile(profile); 832 (*i)->SetProfile(profile);
823 input_.Clear(); // Ensure we don't try to do a "minimal_changes" query on a 833 input_.Clear(); // Ensure we don't try to do a "minimal_changes" query on a
824 // different profile. 834 // different profile.
825 } 835 }
826 836
827 void AutocompleteController::Start( 837 void AutocompleteController::Start(
828 const string16& text, 838 const string16& text,
829 const string16& desired_tld, 839 const string16& desired_tld,
830 bool prevent_inline_autocomplete, 840 bool prevent_inline_autocomplete,
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 AutocompleteResult last_result; 933 AutocompleteResult last_result;
924 last_result.Swap(&result_); 934 last_result.Swap(&result_);
925 935
926 for (ACProviders::const_iterator i(providers_.begin()); i != providers_.end(); 936 for (ACProviders::const_iterator i(providers_.begin()); i != providers_.end();
927 ++i) 937 ++i)
928 result_.AppendMatches((*i)->matches()); 938 result_.AppendMatches((*i)->matches());
929 939
930 // Sort the matches and trim to a small number of "best" matches. 940 // Sort the matches and trim to a small number of "best" matches.
931 result_.SortAndCull(input_); 941 result_.SortAndCull(input_);
932 942
943 std::set<string16> keywords;
944 for (ACMatches::iterator match(result_.begin()); match != result_.end();
945 ++match) {
946 GetKeywordForMatch(&*match);
947
948 if (match->keyword.get()) {
949 std::pair<std::set<string16>::iterator, bool> result =
950 keywords.insert(match->keyword->text);
951
952 // If the match has a duplicate keyword with a
953 // more relevant match, don't show a hint.
954 if (match->keyword->is_keyword_hint && !result.second) {
955 match->keyword->is_keyword_hint = false;
956 match->keyword->text.clear();
957 }
958 }
959 }
960
933 // Need to validate before invoking CopyOldMatches as the old matches are not 961 // Need to validate before invoking CopyOldMatches as the old matches are not
934 // valid against the current input. 962 // valid against the current input.
935 #ifndef NDEBUG 963 #ifndef NDEBUG
936 result_.Validate(); 964 result_.Validate();
937 #endif 965 #endif
938 966
939 if (!done_) { 967 if (!done_) {
940 // This conditional needs to match the conditional in Start that invokes 968 // This conditional needs to match the conditional in Start that invokes
941 // StartExpireTimer. 969 // StartExpireTimer.
942 result_.CopyOldMatches(input_, last_result); 970 result_.CopyOldMatches(input_, last_result);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 } 1009 }
982 } 1010 }
983 done_ = true; 1011 done_ = true;
984 } 1012 }
985 1013
986 void AutocompleteController::StartExpireTimer() { 1014 void AutocompleteController::StartExpireTimer() {
987 if (result_.HasCopiedMatches()) 1015 if (result_.HasCopiedMatches())
988 expire_timer_.Start(base::TimeDelta::FromMilliseconds(kExpireTimeMS), 1016 expire_timer_.Start(base::TimeDelta::FromMilliseconds(kExpireTimeMS),
989 this, &AutocompleteController::ExpireCopiedEntries); 1017 this, &AutocompleteController::ExpireCopiedEntries);
990 } 1018 }
1019
Peter Kasting 2011/04/07 20:19:21 Nit: Extra newline
1020
1021 void AutocompleteController::GetKeywordForMatch(AutocompleteMatch* match) const {
Peter Kasting 2011/04/07 20:19:21 Nit: Line too long; wrap after '('
1022 // If the current match is a keyword, return that as the selected keyword.
1023 if (TemplateURL::SupportsReplacement(match->template_url)) {
1024 AutocompleteMatch::Keyword* keyword = new AutocompleteMatch::Keyword();
1025 keyword->text.assign(match->template_url->keyword());
1026 keyword->is_keyword_mode = true;
1027 match->keyword = keyword;
1028 return;
1029 }
1030
1031 // See if the current match's fill_into_edit corresponds to a keyword.
1032 string16 keyword_text;
1033 if (GetKeywordForText(match->fill_into_edit, &keyword_text)) {
1034 AutocompleteMatch::Keyword* keyword = new AutocompleteMatch::Keyword();
1035 keyword->is_keyword_hint = true;
1036 keyword->text = keyword_text;
1037 keyword->template_url =
1038 profile_->GetTemplateURLModel()->GetTemplateURLForKeyword(keyword_text);
1039 match->keyword = keyword;
1040 }
1041 }
1042
1043 bool AutocompleteController::GetKeywordForText(const string16& text,
1044 string16* keyword) const {
1045 // Creates keyword_hint first in case |keyword| is a pointer to |text|.
1046 const string16 keyword_hint(TemplateURLModel::CleanUserInputKeyword(text));
1047
1048 // Assume we have no keyword until we find otherwise.
1049 keyword->clear();
1050
1051 if (keyword_hint.empty())
1052 return false;
1053 if (!profile_->GetTemplateURLModel())
1054 return false;
1055 profile_->GetTemplateURLModel()->Load();
1056
1057 // Don't provide a hint if this keyword doesn't support replacement.
1058 const TemplateURL* const template_url =
1059 profile_->GetTemplateURLModel()->GetTemplateURLForKeyword(keyword_hint);
1060 if (!TemplateURL::SupportsReplacement(template_url))
1061 return false;
1062
1063 // Don't provide a hint for inactive/disabled extension keywords.
1064 if (template_url->IsExtensionKeyword()) {
1065 const Extension* extension = profile_->GetExtensionService()->
1066 GetExtensionById(template_url->GetExtensionId(), false);
1067 if (!extension ||
Peter Kasting 2011/04/07 20:19:21 Nit: Indenting is one space short
1068 (profile_->IsOffTheRecord() &&
1069 !profile_->GetExtensionService()->IsIncognitoEnabled(extension->id())))
1070 return false;
1071 }
1072
1073 keyword->assign(keyword_hint);
1074 return true;
1075 }
Peter Kasting 2011/04/07 20:19:21 Nit: Make sure there's a newline character at the
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698