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

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

Issue 7321001: Changes SearchProvider to set the description of the first consecutive (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix DCHECK Created 9 years, 5 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/search_provider.h" 5 #include "chrome/browser/autocomplete/search_provider.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 9
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 84
85 string16 adjusted_input_text(input_text); 85 string16 adjusted_input_text(input_text);
86 AutocompleteInput::RemoveForcedQueryStringIfNecessary(input_.type(), 86 AutocompleteInput::RemoveForcedQueryStringIfNecessary(input_.type(),
87 &adjusted_input_text); 87 &adjusted_input_text);
88 88
89 const string16 text = adjusted_input_text + suggest_text; 89 const string16 text = adjusted_input_text + suggest_text;
90 // Remove any matches that are identical to |text|. We don't use the 90 // Remove any matches that are identical to |text|. We don't use the
91 // destination_url for comparison as it varies depending upon the index passed 91 // destination_url for comparison as it varies depending upon the index passed
92 // to TemplateURL::ReplaceSearchTerms. 92 // to TemplateURL::ReplaceSearchTerms.
93 for (ACMatches::iterator i = matches_.begin(); i != matches_.end();) { 93 for (ACMatches::iterator i = matches_.begin(); i != matches_.end();) {
94 // Reset the description/description_class of all searches. We'll set the
95 // description of the new first match in the call to
96 // UpdateFirstSearchMatchDescription() below.
97 if ((i->type == AutocompleteMatch::SEARCH_HISTORY) ||
98 (i->type == AutocompleteMatch::SEARCH_SUGGEST) ||
99 (i->type == AutocompleteMatch::SEARCH_WHAT_YOU_TYPED)) {
100 i->description.clear();
101 i->description_class.clear();
102 }
103
104 if (((i->type == AutocompleteMatch::SEARCH_HISTORY) || 94 if (((i->type == AutocompleteMatch::SEARCH_HISTORY) ||
105 (i->type == AutocompleteMatch::SEARCH_SUGGEST)) && 95 (i->type == AutocompleteMatch::SEARCH_SUGGEST)) &&
106 (i->fill_into_edit == text)) { 96 (i->fill_into_edit == text)) {
107 i = matches_.erase(i); 97 i = matches_.erase(i);
108 } else { 98 } else {
109 ++i; 99 ++i;
110 } 100 }
111 } 101 }
112 102
113 // Add the new suggest result. We give it a rank higher than 103 // Add the new suggest result. We give it a rank higher than
114 // SEARCH_WHAT_YOU_TYPED so that it gets autocompleted. 104 // SEARCH_WHAT_YOU_TYPED so that it gets autocompleted.
115 int did_not_accept_default_suggestion = default_suggest_results_.empty() ? 105 int did_not_accept_default_suggestion = default_suggest_results_.empty() ?
116 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE : 106 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE :
117 TemplateURLRef::NO_SUGGESTION_CHOSEN; 107 TemplateURLRef::NO_SUGGESTION_CHOSEN;
118 MatchMap match_map; 108 MatchMap match_map;
119 AddMatchToMap(text, adjusted_input_text, 109 AddMatchToMap(text, adjusted_input_text,
120 CalculateRelevanceForWhatYouTyped() + 1, 110 CalculateRelevanceForWhatYouTyped() + 1,
121 AutocompleteMatch::SEARCH_SUGGEST, 111 AutocompleteMatch::SEARCH_SUGGEST,
122 did_not_accept_default_suggestion, false, 112 did_not_accept_default_suggestion, false,
123 input_.prevent_inline_autocomplete(), &match_map); 113 input_.prevent_inline_autocomplete(), &match_map);
124 DCHECK_EQ(1u, match_map.size()); 114 DCHECK_EQ(1u, match_map.size());
125 matches_.push_back(match_map.begin()->second); 115 matches_.push_back(match_map.begin()->second);
126 // Sort the results so that UpdateFirstSearchDescription does the right thing.
127 std::sort(matches_.begin(), matches_.end(), &AutocompleteMatch::MoreRelevant);
128
129 UpdateFirstSearchMatchDescription();
130 116
131 listener_->OnProviderUpdate(true); 117 listener_->OnProviderUpdate(true);
132 } 118 }
133 119
134 void SearchProvider::Start(const AutocompleteInput& input, 120 void SearchProvider::Start(const AutocompleteInput& input,
135 bool minimal_changes) { 121 bool minimal_changes) {
136 matches_.clear(); 122 matches_.clear();
137 123
138 instant_finalized_ = 124 instant_finalized_ =
139 (input.matches_requested() != AutocompleteInput::ALL_MATCHES); 125 (input.matches_requested() != AutocompleteInput::ALL_MATCHES);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 166
181 if (input.text().empty()) { 167 if (input.text().empty()) {
182 // User typed "?" alone. Give them a placeholder result indicating what 168 // User typed "?" alone. Give them a placeholder result indicating what
183 // this syntax does. 169 // this syntax does.
184 if (default_provider) { 170 if (default_provider) {
185 AutocompleteMatch match; 171 AutocompleteMatch match;
186 match.provider = this; 172 match.provider = this;
187 match.contents.assign(l10n_util::GetStringUTF16(IDS_EMPTY_KEYWORD_VALUE)); 173 match.contents.assign(l10n_util::GetStringUTF16(IDS_EMPTY_KEYWORD_VALUE));
188 match.contents_class.push_back( 174 match.contents_class.push_back(
189 ACMatchClassification(0, ACMatchClassification::NONE)); 175 ACMatchClassification(0, ACMatchClassification::NONE));
176 match.template_url = &providers_.default_provider();
190 matches_.push_back(match); 177 matches_.push_back(match);
191 UpdateFirstSearchMatchDescription();
192 } 178 }
193 Stop(); 179 Stop();
194 return; 180 return;
195 } 181 }
196 182
197 input_ = input; 183 input_ = input;
198 184
199 DoHistoryQuery(minimal_changes); 185 DoHistoryQuery(minimal_changes);
200 StartOrStopSuggestQuery(minimal_changes); 186 StartOrStopSuggestQuery(minimal_changes);
201 ConvertResultsToAutocompleteMatches(); 187 ConvertResultsToAutocompleteMatches();
(...skipping 20 matching lines...) Expand all
222 // providers. 208 // providers.
223 DCHECK_GT(suggest_results_pending_, 0); 209 DCHECK_GT(suggest_results_pending_, 0);
224 } 210 }
225 211
226 void SearchProvider::Stop() { 212 void SearchProvider::Stop() {
227 StopSuggest(); 213 StopSuggest();
228 done_ = true; 214 done_ = true;
229 default_provider_suggest_text_.clear(); 215 default_provider_suggest_text_.clear();
230 } 216 }
231 217
218 void SearchProvider::PostProcessResult(AutocompleteResult* result) {
219 // For each group of contiguous matches from the same TemplateURL, show the
220 // provider name as a description on the first match in the group.
221 const TemplateURL* last_template_url = NULL;
222 for (AutocompleteResult::iterator i = result->begin(); i != result->end();
223 ++i) {
224 if (i->provider == this &&
225 (i->type == AutocompleteMatch::SEARCH_WHAT_YOU_TYPED ||
226 i->type == AutocompleteMatch::SEARCH_HISTORY ||
227 i->type == AutocompleteMatch::SEARCH_SUGGEST)) {
228 i->description.clear();
229 i->description_class.clear();
230 DCHECK(i->template_url); // We should always set a template_url
231 if (last_template_url != i->template_url) {
232 i->description = l10n_util::GetStringFUTF16(
233 IDS_AUTOCOMPLETE_SEARCH_DESCRIPTION,
234 i->template_url->AdjustedShortNameForLocaleDirection());
235 i->description_class.push_back(
236 ACMatchClassification(0, ACMatchClassification::DIM));
237 }
238 last_template_url = i->template_url;
239 } else {
240 last_template_url = NULL;
241 }
242 }
243 }
244
232 void SearchProvider::OnURLFetchComplete(const URLFetcher* source, 245 void SearchProvider::OnURLFetchComplete(const URLFetcher* source,
233 const GURL& url, 246 const GURL& url,
234 const net::URLRequestStatus& status, 247 const net::URLRequestStatus& status,
235 int response_code, 248 int response_code,
236 const net::ResponseCookies& cookie, 249 const net::ResponseCookies& cookie,
237 const std::string& data) { 250 const std::string& data) {
238 DCHECK(!done_); 251 DCHECK(!done_);
239 suggest_results_pending_--; 252 suggest_results_pending_--;
240 DCHECK_GE(suggest_results_pending_, 0); // Should never go negative. 253 DCHECK_GE(suggest_results_pending_, 0); // Should never go negative.
241 const net::HttpResponseHeaders* const response_headers = 254 const net::HttpResponseHeaders* const response_headers =
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 AddNavigationResultsToMatches(keyword_navigation_results_, true); 583 AddNavigationResultsToMatches(keyword_navigation_results_, true);
571 AddNavigationResultsToMatches(default_navigation_results_, false); 584 AddNavigationResultsToMatches(default_navigation_results_, false);
572 585
573 const size_t max_total_matches = kMaxMatches + 1; // 1 for "what you typed" 586 const size_t max_total_matches = kMaxMatches + 1; // 1 for "what you typed"
574 std::partial_sort(matches_.begin(), 587 std::partial_sort(matches_.begin(),
575 matches_.begin() + std::min(max_total_matches, matches_.size()), 588 matches_.begin() + std::min(max_total_matches, matches_.size()),
576 matches_.end(), &AutocompleteMatch::MoreRelevant); 589 matches_.end(), &AutocompleteMatch::MoreRelevant);
577 if (matches_.size() > max_total_matches) 590 if (matches_.size() > max_total_matches)
578 matches_.erase(matches_.begin() + max_total_matches, matches_.end()); 591 matches_.erase(matches_.begin() + max_total_matches, matches_.end());
579 592
580 UpdateFirstSearchMatchDescription();
581
582 UpdateStarredStateOfMatches(); 593 UpdateStarredStateOfMatches();
583 594
584 UpdateDone(); 595 UpdateDone();
585 } 596 }
586 597
587 void SearchProvider::AddNavigationResultsToMatches( 598 void SearchProvider::AddNavigationResultsToMatches(
588 const NavigationResults& navigation_results, 599 const NavigationResults& navigation_results,
589 bool is_keyword) { 600 bool is_keyword) {
590 if (!navigation_results.empty()) { 601 if (!navigation_results.empty()) {
591 // TODO(kochi): http://b/1170574 We add only one results for navigational 602 // TODO(kochi): http://b/1170574 We add only one results for navigational
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 int relevance, 762 int relevance,
752 AutocompleteMatch::Type type, 763 AutocompleteMatch::Type type,
753 int accepted_suggestion, 764 int accepted_suggestion,
754 bool is_keyword, 765 bool is_keyword,
755 bool prevent_inline_autocomplete, 766 bool prevent_inline_autocomplete,
756 MatchMap* map) { 767 MatchMap* map) {
757 AutocompleteMatch match(this, relevance, false, type); 768 AutocompleteMatch match(this, relevance, false, type);
758 std::vector<size_t> content_param_offsets; 769 std::vector<size_t> content_param_offsets;
759 const TemplateURL& provider = is_keyword ? providers_.keyword_provider() : 770 const TemplateURL& provider = is_keyword ? providers_.keyword_provider() :
760 providers_.default_provider(); 771 providers_.default_provider();
772 match.template_url = &provider;
761 match.contents.assign(query_string); 773 match.contents.assign(query_string);
762 // We do intra-string highlighting for suggestions - the suggested segment 774 // We do intra-string highlighting for suggestions - the suggested segment
763 // will be highlighted, e.g. for input_text = "you" the suggestion may be 775 // will be highlighted, e.g. for input_text = "you" the suggestion may be
764 // "youtube", so we'll bold the "tube" section: you*tube*. 776 // "youtube", so we'll bold the "tube" section: you*tube*.
765 if (input_text != query_string) { 777 if (input_text != query_string) {
766 size_t input_position = match.contents.find(input_text); 778 size_t input_position = match.contents.find(input_text);
767 if (input_position == string16::npos) { 779 if (input_position == string16::npos) {
768 // The input text is not a substring of the query string, e.g. input 780 // The input text is not a substring of the query string, e.g. input
769 // text is "slasdot" and the query string is "slashdot", so we bold the 781 // text is "slasdot" and the query string is "slashdot", so we bold the
770 // whole thing. 782 // whole thing.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 // values preserve that property. Otherwise, if the user starts editing a 814 // values preserve that property. Otherwise, if the user starts editing a
803 // suggestion, non-Search results will suddenly appear. 815 // suggestion, non-Search results will suddenly appear.
804 size_t search_start = 0; 816 size_t search_start = 0;
805 if (input_.type() == AutocompleteInput::FORCED_QUERY) { 817 if (input_.type() == AutocompleteInput::FORCED_QUERY) {
806 match.fill_into_edit.assign(ASCIIToUTF16("?")); 818 match.fill_into_edit.assign(ASCIIToUTF16("?"));
807 ++search_start; 819 ++search_start;
808 } 820 }
809 if (is_keyword) { 821 if (is_keyword) {
810 match.fill_into_edit.append( 822 match.fill_into_edit.append(
811 providers_.keyword_provider().keyword() + char16(' ')); 823 providers_.keyword_provider().keyword() + char16(' '));
812 match.template_url = &providers_.keyword_provider();
813 } 824 }
814 match.fill_into_edit.append(query_string); 825 match.fill_into_edit.append(query_string);
815 // Not all suggestions start with the original input. 826 // Not all suggestions start with the original input.
816 if (!prevent_inline_autocomplete && 827 if (!prevent_inline_autocomplete &&
817 !match.fill_into_edit.compare(search_start, input_text.length(), 828 !match.fill_into_edit.compare(search_start, input_text.length(),
818 input_text)) 829 input_text))
819 match.inline_autocomplete_offset = search_start + input_text.length(); 830 match.inline_autocomplete_offset = search_start + input_text.length();
820 831
821 const TemplateURLRef* const search_url = provider.url(); 832 const TemplateURLRef* const search_url = provider.url();
822 DCHECK(search_url->SupportsReplacement()); 833 DCHECK(search_url->SupportsReplacement());
(...skipping 29 matching lines...) Expand all
852 const NavigationResult& navigation, 863 const NavigationResult& navigation,
853 int relevance, 864 int relevance,
854 bool is_keyword) { 865 bool is_keyword) {
855 const string16& input_text = 866 const string16& input_text =
856 is_keyword ? keyword_input_text_ : input_.text(); 867 is_keyword ? keyword_input_text_ : input_.text();
857 AutocompleteMatch match(this, relevance, false, 868 AutocompleteMatch match(this, relevance, false,
858 AutocompleteMatch::NAVSUGGEST); 869 AutocompleteMatch::NAVSUGGEST);
859 match.destination_url = navigation.url; 870 match.destination_url = navigation.url;
860 match.contents = 871 match.contents =
861 StringForURLDisplay(navigation.url, true, !HasHTTPScheme(input_text)); 872 StringForURLDisplay(navigation.url, true, !HasHTTPScheme(input_text));
873 match.template_url = is_keyword ? &providers_.keyword_provider() :
874 &providers_.default_provider();
862 AutocompleteMatch::ClassifyMatchInString(input_text, match.contents, 875 AutocompleteMatch::ClassifyMatchInString(input_text, match.contents,
863 ACMatchClassification::URL, 876 ACMatchClassification::URL,
864 &match.contents_class); 877 &match.contents_class);
865 878
866 match.description = navigation.site_name; 879 match.description = navigation.site_name;
867 AutocompleteMatch::ClassifyMatchInString(input_text, navigation.site_name, 880 AutocompleteMatch::ClassifyMatchInString(input_text, navigation.site_name,
868 ACMatchClassification::NONE, 881 ACMatchClassification::NONE,
869 &match.description_class); 882 &match.description_class);
870 883
871 // When the user forced a query, we need to make sure all the fill_into_edit 884 // When the user forced a query, we need to make sure all the fill_into_edit
872 // values preserve that property. Otherwise, if the user starts editing a 885 // values preserve that property. Otherwise, if the user starts editing a
873 // suggestion, non-Search results will suddenly appear. 886 // suggestion, non-Search results will suddenly appear.
874 if (input_.type() == AutocompleteInput::FORCED_QUERY) 887 if (input_.type() == AutocompleteInput::FORCED_QUERY)
875 match.fill_into_edit.assign(ASCIIToUTF16("?")); 888 match.fill_into_edit.assign(ASCIIToUTF16("?"));
876 match.fill_into_edit.append( 889 match.fill_into_edit.append(
877 AutocompleteInput::FormattedStringWithEquivalentMeaning(navigation.url, 890 AutocompleteInput::FormattedStringWithEquivalentMeaning(navigation.url,
878 match.contents)); 891 match.contents));
879 // TODO(pkasting): http://b/1112879 These should perhaps be 892 // TODO(pkasting): http://b/1112879 These should perhaps be
880 // inline-autocompletable? 893 // inline-autocompletable?
881 894
882 return match; 895 return match;
883 } 896 }
884 897
885 void SearchProvider::UpdateDone() { 898 void SearchProvider::UpdateDone() {
886 // We're done when there are no more suggest queries pending (this is set to 1 899 // We're done when there are no more suggest queries pending (this is set to 1
887 // when the timer is started) and we're not waiting on instant. 900 // when the timer is started) and we're not waiting on instant.
888 done_ = ((suggest_results_pending_ == 0) && 901 done_ = ((suggest_results_pending_ == 0) &&
889 (instant_finalized_ || !InstantController::IsEnabled(profile_))); 902 (instant_finalized_ || !InstantController::IsEnabled(profile_)));
890 } 903 }
891
892 void SearchProvider::UpdateFirstSearchMatchDescription() {
893 if (!providers_.valid_default_provider() || matches_.empty())
894 return;
895
896 for (ACMatches::iterator i = matches_.begin(); i != matches_.end(); ++i) {
897 AutocompleteMatch& match = *i;
898 switch (match.type) {
899 case AutocompleteMatch::SEARCH_WHAT_YOU_TYPED:
900 case AutocompleteMatch::SEARCH_HISTORY:
901 case AutocompleteMatch::SEARCH_SUGGEST:
902 match.description.assign(l10n_util::GetStringFUTF16(
903 IDS_AUTOCOMPLETE_SEARCH_DESCRIPTION,
904 providers_.default_provider().
905 AdjustedShortNameForLocaleDirection()));
906 match.description_class.push_back(
907 ACMatchClassification(0, ACMatchClassification::DIM));
908 // Only the first search match gets a description.
909 return;
910
911 default:
912 break;
913 }
914 }
915 }
OLDNEW
« no previous file with comments | « chrome/browser/autocomplete/search_provider.h ('k') | chrome/browser/autocomplete/search_provider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698