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

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

Issue 58003005: Modify Entity Suggestion support and Add Profile Suggest support (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed classifications from server Created 7 years 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
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/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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 } 100 }
101 } 101 }
102 return false; 102 return false;
103 } 103 }
104 104
105 // Builds the match contents and classification for the contents, and updates 105 // Builds the match contents and classification for the contents, and updates
106 // the given |AutocompleteMatch|. 106 // the given |AutocompleteMatch|.
107 void SetAndClassifyMatchContents(const base::string16& query_string, 107 void SetAndClassifyMatchContents(const base::string16& query_string,
108 const base::string16& input_text, 108 const base::string16& input_text,
109 const base::string16& match_contents, 109 const base::string16& match_contents,
110 const base::string16& annotation,
111 AutocompleteMatch* match) { 110 AutocompleteMatch* match) {
112 size_t match_contents_start = 0; 111 match->contents = match_contents.empty() ? query_string : match_contents;
113 size_t annotation_start = match_contents.size();
114 // Append annotation if present.
115 if (annotation.empty()) {
116 match->contents = match_contents;
117 } else {
118 std::vector<size_t> positions;
119 match->contents = l10n_util::GetStringFUTF16(
120 IDS_ANNOTATED_SUGGESTION, match_contents, annotation, &positions);
Peter Kasting 2013/12/10 03:52:30 If we're removing the only reference to IDS_ANNOTA
Anuj 2013/12/10 23:08:09 Done.
121 match_contents_start = positions[0];
122 annotation_start = positions[1];
123 }
124 size_t match_contents_end = match_contents_start + match_contents.size();
125
126 if (!annotation.empty() && (annotation_start < match_contents_start))
127 match->contents_class.push_back(ACMatchClassification(
128 annotation_start, ACMatchClassification::DIM));
129 112
130 // We do intra-string highlighting for suggestions - the suggested segment 113 // We do intra-string highlighting for suggestions - the suggested segment
131 // will be highlighted, e.g. for input_text = "you" the suggestion may be 114 // will be highlighted, e.g. for input_text = "you" the suggestion may be
132 // "youtube", so we'll bold the "tube" section: you*tube*. 115 // "youtube", so we'll bold the "tube" section: you*tube*.
133 if (input_text != match_contents) { 116 if (input_text != match_contents) {
134 size_t input_position = match->contents.substr( 117 size_t input_position = match->contents.find(input_text);
135 match_contents_start, match_contents.length()).find(input_text);
136 if (input_position == base::string16::npos) { 118 if (input_position == base::string16::npos) {
137 // The input text is not a substring of the query string, e.g. input 119 // The input text is not a substring of the query string, e.g. input
138 // text is "slasdot" and the query string is "slashdot", so we bold the 120 // text is "slasdot" and the query string is "slashdot", so we bold the
139 // whole thing. 121 // whole thing.
140 match->contents_class.push_back(ACMatchClassification( 122 match->contents_class.push_back(ACMatchClassification(
141 match_contents_start, ACMatchClassification::MATCH)); 123 0, ACMatchClassification::MATCH));
142 } else { 124 } else {
143 input_position += match_contents_start;
144
145 // TODO(beng): ACMatchClassification::MATCH now seems to just mean 125 // TODO(beng): ACMatchClassification::MATCH now seems to just mean
146 // "bold" this. Consider modifying the terminology. 126 // "bold" this. Consider modifying the terminology.
147 // We don't iterate over the string here annotating all matches because 127 // We don't iterate over the string here annotating all matches because
148 // it looks odd to have every occurrence of a substring that may be as 128 // it looks odd to have every occurrence of a substring that may be as
149 // short as a single character highlighted in a query suggestion result, 129 // short as a single character highlighted in a query suggestion result,
150 // e.g. for input text "s" and query string "southwest airlines", it 130 // e.g. for input text "s" and query string "southwest airlines", it
151 // looks odd if both the first and last s are highlighted. 131 // looks odd if both the first and last s are highlighted.
152 if (input_position != match_contents_start) { 132 if (input_position != 0) {
153 match->contents_class.push_back(ACMatchClassification( 133 match->contents_class.push_back(ACMatchClassification(
154 match_contents_start, ACMatchClassification::MATCH)); 134 0, ACMatchClassification::MATCH));
155 } 135 }
156 match->contents_class.push_back( 136 match->contents_class.push_back(
157 ACMatchClassification(input_position, ACMatchClassification::NONE)); 137 ACMatchClassification(input_position, ACMatchClassification::NONE));
158 size_t next_fragment_position = input_position + input_text.length(); 138 size_t next_fragment_position = input_position + input_text.length();
159 if (next_fragment_position < query_string.length()) { 139 if (next_fragment_position < query_string.length()) {
160 match->contents_class.push_back(ACMatchClassification( 140 match->contents_class.push_back(ACMatchClassification(
161 next_fragment_position, ACMatchClassification::MATCH)); 141 next_fragment_position, ACMatchClassification::MATCH));
162 } 142 }
163 } 143 }
164 } else { 144 } else {
165 // Otherwise, |match| is a verbatim (what-you-typed) match, either for the 145 // Otherwise, |match| is a verbatim (what-you-typed) match, either for the
166 // default provider or a keyword search provider. 146 // default provider or a keyword search provider.
167 match->contents_class.push_back(ACMatchClassification( 147 match->contents_class.push_back(ACMatchClassification(
168 match_contents_start, ACMatchClassification::NONE)); 148 0, ACMatchClassification::NONE));
169 } 149 }
150 }
170 151
171 if (!annotation.empty() && (annotation_start >= match_contents_start)) 152 AutocompleteMatchType::Type GetAutocompleteMatchType(const std::string& type) {
172 match->contents_class.push_back(ACMatchClassification( 153 if (type == "ENTITY")
173 match_contents_end, ACMatchClassification::DIM)); 154 return AutocompleteMatchType::SEARCH_SUGGEST_ENTITY;
155 if (type == "INFINITE")
156 return AutocompleteMatchType::SEARCH_SUGGEST_INFINITE;
157 if (type == "PERSONALIZED")
158 return AutocompleteMatchType::SEARCH_SUGGEST_PERSONALIZED;
159 if (type == "PROFILE")
160 return AutocompleteMatchType::SEARCH_SUGGEST_PROFILE;
161 return AutocompleteMatchType::SEARCH_SUGGEST;
174 } 162 }
175 163
176 } // namespace 164 } // namespace
177 165
178 166
179 // SuggestionDeletionHandler ------------------------------------------------- 167 // SuggestionDeletionHandler -------------------------------------------------
180 168
181 // This class handles making requests to the server in order to delete 169 // This class handles making requests to the server in order to delete
182 // personalized suggestions. 170 // personalized suggestions.
183 class SuggestionDeletionHandler : public net::URLFetcherDelegate { 171 class SuggestionDeletionHandler : public net::URLFetcherDelegate {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 } 247 }
260 248
261 SearchProvider::Result::~Result() { 249 SearchProvider::Result::~Result() {
262 } 250 }
263 251
264 252
265 // SearchProvider::SuggestResult ---------------------------------------------- 253 // SearchProvider::SuggestResult ----------------------------------------------
266 254
267 SearchProvider::SuggestResult::SuggestResult( 255 SearchProvider::SuggestResult::SuggestResult(
268 const base::string16& suggestion, 256 const base::string16& suggestion,
257 AutocompleteMatchType::Type type,
269 const base::string16& match_contents, 258 const base::string16& match_contents,
270 const base::string16& annotation, 259 const base::string16& annotation,
271 const std::string& suggest_query_params, 260 const std::string& suggest_query_params,
272 const std::string& deletion_url, 261 const std::string& deletion_url,
273 bool from_keyword_provider, 262 bool from_keyword_provider,
274 int relevance, 263 int relevance,
275 bool relevance_from_server, 264 bool relevance_from_server,
276 bool should_prefetch) 265 bool should_prefetch)
277 : Result(from_keyword_provider, relevance, relevance_from_server), 266 : Result(from_keyword_provider, relevance, relevance_from_server),
278 suggestion_(suggestion), 267 suggestion_(suggestion),
268 type_(type),
279 match_contents_(match_contents), 269 match_contents_(match_contents),
280 annotation_(annotation), 270 annotation_(annotation),
281 suggest_query_params_(suggest_query_params), 271 suggest_query_params_(suggest_query_params),
282 deletion_url_(deletion_url), 272 deletion_url_(deletion_url),
283 should_prefetch_(should_prefetch) { 273 should_prefetch_(should_prefetch) {
284 } 274 }
285 275
286 SearchProvider::SuggestResult::~SuggestResult() { 276 SearchProvider::SuggestResult::~SuggestResult() {
287 } 277 }
288 278
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 const std::string& suggest_query_params, 409 const std::string& suggest_query_params,
420 int accepted_suggestion, 410 int accepted_suggestion,
421 int omnibox_start_margin, 411 int omnibox_start_margin,
422 bool append_extra_query_params) { 412 bool append_extra_query_params) {
423 AutocompleteMatch match(autocomplete_provider, relevance, false, type); 413 AutocompleteMatch match(autocomplete_provider, relevance, false, type);
424 414
425 if (!template_url) 415 if (!template_url)
426 return match; 416 return match;
427 match.keyword = template_url->keyword(); 417 match.keyword = template_url->keyword();
428 418
429 SetAndClassifyMatchContents( 419 SetAndClassifyMatchContents(query_string, input_text, match_contents, &match);
430 query_string, input_text, match_contents, annotation, &match); 420
421 if (!annotation.empty())
422 match.description = annotation;
431 423
432 match.allowed_to_be_default_match = (input_text == match_contents); 424 match.allowed_to_be_default_match = (input_text == match_contents);
433 425
434 // When the user forced a query, we need to make sure all the fill_into_edit 426 // When the user forced a query, we need to make sure all the fill_into_edit
435 // values preserve that property. Otherwise, if the user starts editing a 427 // values preserve that property. Otherwise, if the user starts editing a
436 // suggestion, non-Search results will suddenly appear. 428 // suggestion, non-Search results will suddenly appear.
437 if (input.type() == AutocompleteInput::FORCED_QUERY) 429 if (input.type() == AutocompleteInput::FORCED_QUERY)
438 match.fill_into_edit.assign(ASCIIToUTF16("?")); 430 match.fill_into_edit.assign(ASCIIToUTF16("?"));
439 if (is_keyword) 431 if (is_keyword)
440 match.fill_into_edit.append(match.keyword + char16(' ')); 432 match.fill_into_edit.append(match.keyword + char16(' '));
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after
1172 // Do not blindly trust the URL coming from the server to be valid. 1164 // Do not blindly trust the URL coming from the server to be valid.
1173 GURL url(URLFixerUpper::FixupURL(UTF16ToUTF8(suggestion), std::string())); 1165 GURL url(URLFixerUpper::FixupURL(UTF16ToUTF8(suggestion), std::string()));
1174 if (url.is_valid() && allow_navsuggest) { 1166 if (url.is_valid() && allow_navsuggest) {
1175 base::string16 title; 1167 base::string16 title;
1176 if (descriptions != NULL) 1168 if (descriptions != NULL)
1177 descriptions->GetString(index, &title); 1169 descriptions->GetString(index, &title);
1178 results->navigation_results.push_back(NavigationResult( 1170 results->navigation_results.push_back(NavigationResult(
1179 *this, url, title, is_keyword, relevance, true)); 1171 *this, url, title, is_keyword, relevance, true));
1180 } 1172 }
1181 } else { 1173 } else {
1174 AutocompleteMatchType::Type match_type = GetAutocompleteMatchType(type);
1182 bool should_prefetch = static_cast<int>(index) == prefetch_index; 1175 bool should_prefetch = static_cast<int>(index) == prefetch_index;
1183 DictionaryValue* suggestion_detail = NULL; 1176 DictionaryValue* suggestion_detail = NULL;
1184 base::string16 match_contents = suggestion; 1177 base::string16 match_contents = suggestion;
1185 base::string16 annotation; 1178 base::string16 annotation;
1186 std::string suggest_query_params; 1179 std::string suggest_query_params;
1187 std::string deletion_url; 1180 std::string deletion_url;
1188 1181
1189 if (suggestion_details) { 1182 if (suggestion_details) {
1190 suggestion_details->GetDictionary(index, &suggestion_detail); 1183 suggestion_details->GetDictionary(index, &suggestion_detail);
1191 if (suggestion_detail) { 1184 if (suggestion_detail) {
1192 suggestion_detail->GetString("du", &deletion_url); 1185 suggestion_detail->GetString("du", &deletion_url);
1193 1186 suggestion_detail->GetString("title", &match_contents) ||
1194 if (type == "ENTITY") { 1187 suggestion_detail->GetString("t", &match_contents);
1195 suggestion_detail->GetString("a", &annotation); 1188 suggestion_detail->GetString("annotation", &annotation) ||
1196 1189 suggestion_detail->GetString("a", &annotation);
1197 base::string16 disambiguating_query; 1190 suggestion_detail->GetString("query_params", &suggest_query_params) ||
1198 if (suggestion_detail->GetString("dq", &disambiguating_query) && 1191 suggestion_detail->GetString("q", &suggest_query_params);
1199 !disambiguating_query.empty())
1200 suggestion = disambiguating_query;
1201
1202 suggestion_detail->GetString("q", &suggest_query_params);
1203 }
1204 } 1192 }
1205 } 1193 }
1206 1194
1207 // TODO(kochi): Improve calculator suggestion presentation. 1195 // TODO(kochi): Improve calculator suggestion presentation.
1208 results->suggest_results.push_back(SuggestResult( 1196 results->suggest_results.push_back(SuggestResult(
1209 suggestion, match_contents, annotation, suggest_query_params, 1197 suggestion, match_type, match_contents, annotation,
1210 deletion_url, is_keyword, relevance, true, should_prefetch)); 1198 suggest_query_params, deletion_url, is_keyword, relevance, true,
1199 should_prefetch));
1211 } 1200 }
1212 } 1201 }
1213 1202
1214 // Ignore suggested scores for non-keyword matches in keyword mode; if the 1203 // Ignore suggested scores for non-keyword matches in keyword mode; if the
1215 // server is allowed to score these, it could interfere with the user's 1204 // server is allowed to score these, it could interfere with the user's
1216 // ability to get good keyword results. 1205 // ability to get good keyword results.
1217 const bool abandon_suggested_scores = 1206 const bool abandon_suggested_scores =
1218 !is_keyword && !providers_.keyword_provider().empty(); 1207 !is_keyword && !providers_.keyword_provider().empty();
1219 // Apply calculated relevance scores to suggestions if a valid list was 1208 // Apply calculated relevance scores to suggestions if a valid list was
1220 // not provided or we're abandoning suggested scores entirely. 1209 // not provided or we're abandoning suggested scores entirely.
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
1647 if (!prevent_inline_autocomplete && classifier && (i->term != input_text)) { 1636 if (!prevent_inline_autocomplete && classifier && (i->term != input_text)) {
1648 AutocompleteMatch match; 1637 AutocompleteMatch match;
1649 classifier->Classify(i->term, false, false, &match, NULL); 1638 classifier->Classify(i->term, false, false, &match, NULL);
1650 prevent_inline_autocomplete = 1639 prevent_inline_autocomplete =
1651 !AutocompleteMatch::IsSearchType(match.type); 1640 !AutocompleteMatch::IsSearchType(match.type);
1652 } 1641 }
1653 1642
1654 int relevance = CalculateRelevanceForHistory( 1643 int relevance = CalculateRelevanceForHistory(
1655 i->time, is_keyword, !prevent_inline_autocomplete, 1644 i->time, is_keyword, !prevent_inline_autocomplete,
1656 prevent_search_history_inlining); 1645 prevent_search_history_inlining);
1657 scored_results.push_back( 1646 scored_results.push_back(SuggestResult(
1658 SuggestResult(i->term, base::string16(), base::string16(), 1647 i->term, AutocompleteMatchType::SEARCH_HISTORY, base::string16(),
1659 std::string(), std::string(), is_keyword, relevance, 1648 base::string16(), std::string(), std::string(), is_keyword, relevance,
1660 false, false)); 1649 false, false));
1661 } 1650 }
1662 1651
1663 // History returns results sorted for us. However, we may have docked some 1652 // History returns results sorted for us. However, we may have docked some
1664 // results' scores, so things are no longer in order. Do a stable sort to get 1653 // results' scores, so things are no longer in order. Do a stable sort to get
1665 // things back in order without otherwise disturbing results with equal 1654 // things back in order without otherwise disturbing results with equal
1666 // scores, then force the scores to be unique, so that the order in which 1655 // scores, then force the scores to be unique, so that the order in which
1667 // they're shown is deterministic. 1656 // they're shown is deterministic.
1668 std::stable_sort(scored_results.begin(), scored_results.end(), 1657 std::stable_sort(scored_results.begin(), scored_results.end(),
1669 CompareScoredResults()); 1658 CompareScoredResults());
1670 int last_relevance = 0; 1659 int last_relevance = 0;
(...skipping 12 matching lines...) Expand all
1683 MatchMap* map) { 1672 MatchMap* map) {
1684 for (size_t i = 0; i < results.size(); ++i) { 1673 for (size_t i = 0; i < results.size(); ++i) {
1685 const bool is_keyword = results[i].from_keyword_provider(); 1674 const bool is_keyword = results[i].from_keyword_provider();
1686 const base::string16& input = is_keyword ? keyword_input_.text() 1675 const base::string16& input = is_keyword ? keyword_input_.text()
1687 : input_.text(); 1676 : input_.text();
1688 AddMatchToMap(input, 1677 AddMatchToMap(input,
1689 results[i].relevance(), 1678 results[i].relevance(),
1690 results[i].relevance_from_server(), 1679 results[i].relevance_from_server(),
1691 results[i].should_prefetch(), 1680 results[i].should_prefetch(),
1692 metadata, 1681 metadata,
1693 AutocompleteMatchType::SEARCH_SUGGEST, 1682 results[i].type(),
1694 is_keyword, 1683 is_keyword,
1695 results[i].match_contents(), 1684 results[i].match_contents(),
1696 results[i].annotation(), 1685 results[i].annotation(),
1697 results[i].suggestion(), 1686 results[i].suggestion(),
1698 i, 1687 i,
1699 results[i].suggest_query_params(), 1688 results[i].suggest_query_params(),
1700 results[i].deletion_url(), 1689 results[i].deletion_url(),
1701 map); 1690 map);
1702 } 1691 }
1703 } 1692 }
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
2084 if (!OmniboxFieldTrial::InZeroSuggestFieldTrial() || 2073 if (!OmniboxFieldTrial::InZeroSuggestFieldTrial() ||
2085 service == NULL || 2074 service == NULL ||
2086 !service->IsSyncEnabledAndLoggedIn() || 2075 !service->IsSyncEnabledAndLoggedIn() ||
2087 !sync_prefs.GetPreferredDataTypes(syncer::UserTypes()).Has( 2076 !sync_prefs.GetPreferredDataTypes(syncer::UserTypes()).Has(
2088 syncer::PROXY_TABS) || 2077 syncer::PROXY_TABS) ||
2089 service->GetEncryptedDataTypes().Has(syncer::SESSIONS)) 2078 service->GetEncryptedDataTypes().Has(syncer::SESSIONS))
2090 return false; 2079 return false;
2091 2080
2092 return true; 2081 return true;
2093 } 2082 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698