Chromium Code Reviews| 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_); | |
|
msw
2013/08/26 22:57:15
Drop "_str16", use "_string" or "_string16" if you
| |
| 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, |
| 299 current_query_str16, languages)); | |
| 296 } | 300 } |
| 297 } else { | 301 } else { |
| 298 suggest_results->push_back(SearchProvider::SuggestResult( | 302 suggest_results->push_back(SearchProvider::SuggestResult( |
| 299 result, false, relevance, relevances != NULL)); | 303 result, false, relevance, relevances != NULL, current_query_str16)); |
| 300 } | 304 } |
| 301 } | 305 } |
| 302 } | 306 } |
| 303 | 307 |
| 304 void ZeroSuggestProvider::AddSuggestResultsToMap( | 308 void ZeroSuggestProvider::AddSuggestResultsToMap( |
| 305 const SearchProvider::SuggestResults& results, | 309 const SearchProvider::SuggestResults& results, |
| 306 const TemplateURL* template_url, | 310 const TemplateURL* template_url, |
| 307 SearchProvider::MatchMap* map) { | 311 SearchProvider::MatchMap* map) { |
| 308 for (size_t i = 0; i < results.size(); ++i) { | 312 for (size_t i = 0; i < results.size(); ++i) { |
| 309 AddMatchToMap(results[i].relevance(), AutocompleteMatchType::SEARCH_SUGGEST, | 313 AddMatchToMap(results[i], AutocompleteMatchType::SEARCH_SUGGEST, |
| 310 template_url, results[i].suggestion(), i, map); | 314 template_url, i, map); |
| 311 } | 315 } |
| 312 } | 316 } |
| 313 | 317 |
| 314 void ZeroSuggestProvider::AddMatchToMap(int relevance, | 318 void ZeroSuggestProvider::AddMatchToMap( |
| 315 AutocompleteMatch::Type type, | 319 const SearchProvider::SuggestResult& result, |
| 316 const TemplateURL* template_url, | 320 AutocompleteMatch::Type type, |
| 317 const string16& query_string, | 321 const TemplateURL* template_url, |
| 318 int accepted_suggestion, | 322 int accepted_suggestion, |
| 319 SearchProvider::MatchMap* map) { | 323 SearchProvider::MatchMap* map) { |
| 320 // Pass in query_string as the input_text since we don't want any bolding. | 324 // Pass in result.suggestion() as the input_text since we don't want any |
|
msw
2013/08/26 22:57:15
nit: "to avoid bolding"
| |
| 325 // bolding. | |
| 321 // TODO(samarth|melevin): use the actual omnibox margin here as well instead | 326 // TODO(samarth|melevin): use the actual omnibox margin here as well instead |
| 322 // of passing in -1. | 327 // of passing in -1. |
| 323 AutocompleteMatch match = SearchProvider::CreateSearchSuggestion( | 328 AutocompleteMatch match = SearchProvider::CreateSearchSuggestion( |
| 324 this, relevance, type, template_url, query_string, query_string, | 329 this, result, type, template_url, result.suggestion(), |
| 325 AutocompleteInput(), false, accepted_suggestion, -1, true); | 330 AutocompleteInput(), accepted_suggestion, -1, true); |
| 326 if (!match.destination_url.is_valid()) | 331 if (!match.destination_url.is_valid()) |
| 327 return; | 332 return; |
| 328 | 333 |
| 329 // Try to add |match| to |map|. If a match for |query_string| is already in | 334 // Try to add |match| to |map|. If a match for |result.suggestion()| is |
| 330 // |map|, replace it if |match| is more relevant. | 335 // already in |map|, replace it if |match| is more relevant. |
| 331 // NOTE: Keep this ToLower() call in sync with url_database.cc. | 336 // NOTE: Keep this ToLower() call in sync with url_database.cc. |
| 332 const std::pair<SearchProvider::MatchMap::iterator, bool> i(map->insert( | 337 const std::pair<SearchProvider::MatchMap::iterator, bool> i(map->insert( |
| 333 std::make_pair(base::i18n::ToLower(query_string), match))); | 338 std::make_pair(base::i18n::ToLower(result.suggestion()), match))); |
| 334 // NOTE: We purposefully do a direct relevance comparison here instead of | 339 // NOTE: We purposefully do a direct relevance comparison here instead of |
| 335 // using AutocompleteMatch::MoreRelevant(), so that we'll prefer "items added | 340 // using AutocompleteMatch::MoreRelevant(), so that we'll prefer "items added |
| 336 // first" rather than "items alphabetically first" when the scores are equal. | 341 // 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 | 342 // 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 | 343 // that differ only by capitalization; because the history system returns |
| 339 // results sorted by recency, this means we'll pick the most recent such | 344 // 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 | 345 // result even if the precision of our relevance score is too low to |
| 341 // distinguish the two. | 346 // distinguish the two. |
| 342 if (!i.second && (match.relevance > i.first->second.relevance)) | 347 if (!i.second && (match.relevance > i.first->second.relevance)) |
| 343 i.first->second = match; | 348 i.first->second = match; |
| 344 } | 349 } |
| 345 | 350 |
| 346 AutocompleteMatch ZeroSuggestProvider::NavigationToMatch( | 351 AutocompleteMatch ZeroSuggestProvider::NavigationToMatch( |
| 347 const SearchProvider::NavigationResult& navigation) { | 352 const SearchProvider::NavigationResult& navigation) { |
| 348 AutocompleteMatch match(this, navigation.relevance(), false, | 353 AutocompleteMatch match(this, navigation.relevance(), false, |
| 349 AutocompleteMatchType::NAVSUGGEST); | 354 AutocompleteMatchType::NAVSUGGEST); |
| 350 match.destination_url = navigation.url(); | 355 match.destination_url = navigation.url(); |
| 351 | 356 |
| 357 // We ignore navigation.contents() and navigation.contents_class() | |
|
msw
2013/08/26 22:57:15
nit: "Zero suggest results should always omit prot
| |
| 358 // and instead compute our own contents and contents_class | |
| 359 // because we want a uniform style of display in zero suggest: | |
| 360 // - no bolding of URLs (it doesn't matter if the URL shares a prefix with | |
| 361 // the current URL). | |
| 362 // - always omit the protocol. | |
| 352 const std::string languages( | 363 const std::string languages( |
| 353 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); | 364 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); |
| 354 match.contents = net::FormatUrl(navigation.url(), languages, | 365 match.contents = net::FormatUrl(navigation.url(), languages, |
| 355 net::kFormatUrlOmitAll, net::UnescapeRule::SPACES, NULL, NULL, NULL); | 366 net::kFormatUrlOmitAll, net::UnescapeRule::SPACES, NULL, NULL, NULL); |
| 356 match.fill_into_edit += | 367 match.fill_into_edit += |
| 357 AutocompleteInput::FormattedStringWithEquivalentMeaning(navigation.url(), | 368 AutocompleteInput::FormattedStringWithEquivalentMeaning(navigation.url(), |
| 358 match.contents); | 369 match.contents); |
| 359 | 370 |
| 360 AutocompleteMatch::ClassifyLocationInString(string16::npos, 0, | 371 AutocompleteMatch::ClassifyLocationInString(string16::npos, 0, |
| 361 match.contents.length(), ACMatchClassification::URL, | 372 match.contents.length(), ACMatchClassification::URL, |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 466 match.is_history_what_you_typed_match = false; | 477 match.is_history_what_you_typed_match = false; |
| 467 match.allowed_to_be_default_match = true; | 478 match.allowed_to_be_default_match = true; |
| 468 | 479 |
| 469 // The placeholder suggestion for the current URL has high relevance so | 480 // The placeholder suggestion for the current URL has high relevance so |
| 470 // that it is in the first suggestion slot and inline autocompleted. It | 481 // that it is in the first suggestion slot and inline autocompleted. It |
| 471 // gets dropped as soon as the user types something. | 482 // gets dropped as soon as the user types something. |
| 472 match.relevance = verbatim_relevance_; | 483 match.relevance = verbatim_relevance_; |
| 473 | 484 |
| 474 return match; | 485 return match; |
| 475 } | 486 } |
| OLD | NEW |