OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/zero_suggest_provider.h" | 5 #include "chrome/browser/autocomplete/zero_suggest_provider.h" |
6 | 6 |
7 #include "base/callback.h" | 7 #include "base/callback.h" |
8 #include "base/i18n/case_conversion.h" | 8 #include "base/i18n/case_conversion.h" |
9 #include "base/json/json_string_value_serializer.h" | 9 #include "base/json/json_string_value_serializer.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 field_trial_triggered_ |= triggered; | 267 field_trial_triggered_ |= triggered; |
268 field_trial_triggered_in_session_ |= triggered; | 268 field_trial_triggered_in_session_ |= triggered; |
269 } | 269 } |
270 | 270 |
271 // Clear the previous results now that new results are available. | 271 // Clear the previous results now that new results are available. |
272 suggest_results->clear(); | 272 suggest_results->clear(); |
273 navigation_results->clear(); | 273 navigation_results->clear(); |
274 | 274 |
275 string16 result, title; | 275 string16 result, title; |
276 std::string type; | 276 std::string type; |
| 277 const string16 current_query_str16 = ASCIIToUTF16(current_query_); |
| 278 const std::string& languages = |
| 279 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages); |
277 for (size_t index = 0; results->GetString(index, &result); ++index) { | 280 for (size_t index = 0; results->GetString(index, &result); ++index) { |
278 // Google search may return empty suggestions for weird input characters, | 281 // Google search may return empty suggestions for weird input characters, |
279 // they make no sense at all and can cause problems in our code. | 282 // they make no sense at all and can cause problems in our code. |
280 if (result.empty()) | 283 if (result.empty()) |
281 continue; | 284 continue; |
282 | 285 |
283 int relevance = kDefaultZeroSuggestRelevance; | 286 int relevance = kDefaultZeroSuggestRelevance; |
284 | 287 |
285 // Apply valid suggested relevance scores; discard invalid lists. | 288 // Apply valid suggested relevance scores; discard invalid lists. |
286 if (relevances != NULL && !relevances->GetInteger(index, &relevance)) | 289 if (relevances != NULL && !relevances->GetInteger(index, &relevance)) |
287 relevances = NULL; | 290 relevances = NULL; |
288 if (types && types->GetString(index, &type) && (type == "NAVIGATION")) { | 291 if (types && types->GetString(index, &type) && (type == "NAVIGATION")) { |
289 // Do not blindly trust the URL coming from the server to be valid. | 292 // Do not blindly trust the URL coming from the server to be valid. |
290 GURL url(URLFixerUpper::FixupURL(UTF16ToUTF8(result), std::string())); | 293 GURL url(URLFixerUpper::FixupURL(UTF16ToUTF8(result), std::string())); |
291 if (url.is_valid()) { | 294 if (url.is_valid()) { |
292 if (descriptions != NULL) | 295 if (descriptions != NULL) |
293 descriptions->GetString(index, &title); | 296 descriptions->GetString(index, &title); |
294 navigation_results->push_back(SearchProvider::NavigationResult( | 297 navigation_results->push_back(SearchProvider::NavigationResult( |
295 *this, url, title, false, relevance, relevances != NULL)); | 298 *this, url, title, false, relevance, relevances != NULL, current_que
ry_str16, languages)); |
296 } | 299 } |
297 } else { | 300 } else { |
298 suggest_results->push_back(SearchProvider::SuggestResult( | 301 suggest_results->push_back(SearchProvider::SuggestResult( |
299 result, false, relevance, relevances != NULL)); | 302 result, false, relevance, relevances != NULL, current_query_str16)); |
300 } | 303 } |
301 } | 304 } |
302 } | 305 } |
303 | 306 |
304 void ZeroSuggestProvider::AddSuggestResultsToMap( | 307 void ZeroSuggestProvider::AddSuggestResultsToMap( |
305 const SearchProvider::SuggestResults& results, | 308 const SearchProvider::SuggestResults& results, |
306 const TemplateURL* template_url, | 309 const TemplateURL* template_url, |
307 SearchProvider::MatchMap* map) { | 310 SearchProvider::MatchMap* map) { |
308 for (size_t i = 0; i < results.size(); ++i) { | 311 for (size_t i = 0; i < results.size(); ++i) { |
309 AddMatchToMap(results[i].relevance(), AutocompleteMatchType::SEARCH_SUGGEST, | 312 AddMatchToMap(results[i], AutocompleteMatchType::SEARCH_SUGGEST, |
310 template_url, results[i].suggestion(), i, map); | 313 template_url, i, map); |
311 } | 314 } |
312 } | 315 } |
313 | 316 |
314 void ZeroSuggestProvider::AddMatchToMap(int relevance, | 317 void ZeroSuggestProvider::AddMatchToMap(const SearchProvider::SuggestResult& res
ult, |
315 AutocompleteMatch::Type type, | 318 AutocompleteMatch::Type type, |
316 const TemplateURL* template_url, | 319 const TemplateURL* template_url, |
317 const string16& query_string, | |
318 int accepted_suggestion, | 320 int accepted_suggestion, |
319 SearchProvider::MatchMap* map) { | 321 SearchProvider::MatchMap* map) { |
320 // Pass in query_string as the input_text since we don't want any bolding. | 322 // Pass in result.suggestion() as the input_text since we don't want any boldi
ng. |
321 // TODO(samarth|melevin): use the actual omnibox margin here as well instead | 323 // TODO(samarth|melevin): use the actual omnibox margin here as well instead |
322 // of passing in -1. | 324 // of passing in -1. |
323 AutocompleteMatch match = SearchProvider::CreateSearchSuggestion( | 325 AutocompleteMatch match = SearchProvider::CreateSearchSuggestion( |
324 this, relevance, type, template_url, query_string, query_string, | 326 this, result, type, template_url, result.suggestion(), |
325 AutocompleteInput(), false, accepted_suggestion, -1, true); | 327 AutocompleteInput(), accepted_suggestion, -1, true); |
326 if (!match.destination_url.is_valid()) | 328 if (!match.destination_url.is_valid()) |
327 return; | 329 return; |
328 | 330 |
329 // Try to add |match| to |map|. If a match for |query_string| is already in | 331 // Try to add |match| to |map|. If a match for |query_string| is already in |
330 // |map|, replace it if |match| is more relevant. | 332 // |map|, replace it if |match| is more relevant. |
331 // NOTE: Keep this ToLower() call in sync with url_database.cc. | 333 // NOTE: Keep this ToLower() call in sync with url_database.cc. |
332 const std::pair<SearchProvider::MatchMap::iterator, bool> i(map->insert( | 334 const std::pair<SearchProvider::MatchMap::iterator, bool> i(map->insert( |
333 std::make_pair(base::i18n::ToLower(query_string), match))); | 335 std::make_pair(base::i18n::ToLower(result.suggestion()), match))); |
334 // NOTE: We purposefully do a direct relevance comparison here instead of | 336 // NOTE: We purposefully do a direct relevance comparison here instead of |
335 // using AutocompleteMatch::MoreRelevant(), so that we'll prefer "items added | 337 // using AutocompleteMatch::MoreRelevant(), so that we'll prefer "items added |
336 // first" rather than "items alphabetically first" when the scores are equal. | 338 // first" rather than "items alphabetically first" when the scores are equal. |
337 // The only case this matters is when a user has results with the same score | 339 // The only case this matters is when a user has results with the same score |
338 // that differ only by capitalization; because the history system returns | 340 // that differ only by capitalization; because the history system returns |
339 // results sorted by recency, this means we'll pick the most recent such | 341 // results sorted by recency, this means we'll pick the most recent such |
340 // result even if the precision of our relevance score is too low to | 342 // result even if the precision of our relevance score is too low to |
341 // distinguish the two. | 343 // distinguish the two. |
342 if (!i.second && (match.relevance > i.first->second.relevance)) | 344 if (!i.second && (match.relevance > i.first->second.relevance)) |
343 i.first->second = match; | 345 i.first->second = match; |
344 } | 346 } |
345 | 347 |
346 AutocompleteMatch ZeroSuggestProvider::NavigationToMatch( | 348 AutocompleteMatch ZeroSuggestProvider::NavigationToMatch( |
347 const SearchProvider::NavigationResult& navigation) { | 349 const SearchProvider::NavigationResult& navigation) { |
348 AutocompleteMatch match(this, navigation.relevance(), false, | 350 AutocompleteMatch match(this, navigation.relevance(), false, |
349 AutocompleteMatchType::NAVSUGGEST); | 351 AutocompleteMatchType::NAVSUGGEST); |
350 match.destination_url = navigation.url(); | 352 match.destination_url = navigation.url(); |
| 353 // We ignore navigation.contents() and navigation.contents_class() |
| 354 // and instead compute our own contents and contents_class |
| 355 // because we want a uniform style of display in zero suggest: |
| 356 // no highlighting of URLs (it doesn't matter if the URL shares |
| 357 // a prefix with the current URL) and always omit the protocol. |
351 | 358 |
352 const std::string languages( | 359 const std::string languages( |
353 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); | 360 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); |
354 match.contents = net::FormatUrl(navigation.url(), languages, | 361 match.contents = net::FormatUrl(navigation.url(), languages, |
355 net::kFormatUrlOmitAll, net::UnescapeRule::SPACES, NULL, NULL, NULL); | 362 net::kFormatUrlOmitAll, net::UnescapeRule::SPACES, NULL, NULL, NULL); |
356 match.fill_into_edit += | 363 match.fill_into_edit += |
357 AutocompleteInput::FormattedStringWithEquivalentMeaning(navigation.url(), | 364 AutocompleteInput::FormattedStringWithEquivalentMeaning(navigation.url(), |
358 match.contents); | 365 match.contents); |
359 | 366 |
360 AutocompleteMatch::ClassifyLocationInString(string16::npos, 0, | 367 AutocompleteMatch::ClassifyLocationInString(string16::npos, 0, |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 match.is_history_what_you_typed_match = false; | 473 match.is_history_what_you_typed_match = false; |
467 match.allowed_to_be_default_match = true; | 474 match.allowed_to_be_default_match = true; |
468 | 475 |
469 // The placeholder suggestion for the current URL has high relevance so | 476 // The placeholder suggestion for the current URL has high relevance so |
470 // that it is in the first suggestion slot and inline autocompleted. It | 477 // that it is in the first suggestion slot and inline autocompleted. It |
471 // gets dropped as soon as the user types something. | 478 // gets dropped as soon as the user types something. |
472 match.relevance = verbatim_relevance_; | 479 match.relevance = verbatim_relevance_; |
473 | 480 |
474 return match; | 481 return match; |
475 } | 482 } |
OLD | NEW |