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/history_url_provider.h" | 5 #include "chrome/browser/autocomplete/history_url_provider.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 #include "chrome/browser/search_engines/template_url_service.h" | 30 #include "chrome/browser/search_engines/template_url_service.h" |
31 #include "chrome/browser/search_engines/template_url_service_factory.h" | 31 #include "chrome/browser/search_engines/template_url_service_factory.h" |
32 #include "chrome/browser/search_engines/ui_thread_search_terms_data.h" | 32 #include "chrome/browser/search_engines/ui_thread_search_terms_data.h" |
33 #include "chrome/common/chrome_switches.h" | 33 #include "chrome/common/chrome_switches.h" |
34 #include "chrome/common/pref_names.h" | 34 #include "chrome/common/pref_names.h" |
35 #include "chrome/common/url_constants.h" | 35 #include "chrome/common/url_constants.h" |
36 #include "components/autocomplete/url_prefix.h" | 36 #include "components/autocomplete/url_prefix.h" |
37 #include "components/bookmarks/browser/bookmark_utils.h" | 37 #include "components/bookmarks/browser/bookmark_utils.h" |
38 #include "components/metrics/proto/omnibox_input_type.pb.h" | 38 #include "components/metrics/proto/omnibox_input_type.pb.h" |
39 #include "components/url_fixer/url_fixer.h" | 39 #include "components/url_fixer/url_fixer.h" |
| 40 #include "content/public/browser/browser_thread.h" |
40 #include "net/base/net_util.h" | 41 #include "net/base/net_util.h" |
41 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 42 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
42 #include "url/gurl.h" | 43 #include "url/gurl.h" |
43 #include "url/url_parse.h" | 44 #include "url/url_parse.h" |
44 #include "url/url_util.h" | 45 #include "url/url_util.h" |
45 | 46 |
46 namespace { | 47 namespace { |
47 | 48 |
48 // Acts like the > operator for URLInfo classes. | 49 // Acts like the > operator for URLInfo classes. |
49 bool CompareHistoryMatch(const history::HistoryMatch& a, | 50 bool CompareHistoryMatch(const history::HistoryMatch& a, |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 // No entry, so create one. | 223 // No entry, so create one. |
223 history::HistoryMatch match(info, input_location, match_in_scheme, true); | 224 history::HistoryMatch match(info, input_location, match_in_scheme, true); |
224 if (promote) | 225 if (promote) |
225 matches->push_front(match); | 226 matches->push_front(match); |
226 else | 227 else |
227 matches->push_back(match); | 228 matches->push_back(match); |
228 | 229 |
229 return true; | 230 return true; |
230 } | 231 } |
231 | 232 |
| 233 // Returns whether |match| is suitable for inline autocompletion. |
| 234 bool CanPromoteMatchForInlineAutocomplete(const history::HistoryMatch& match) { |
| 235 // We can promote this match if it's been marked for promotion or typed at |
| 236 // least n times, where n == 1 for "simple" (host-only) URLs and n == 2 for |
| 237 // others. We set a higher bar for these long URLs because it's less likely |
| 238 // that users will want to visit them again. Even though we don't increment |
| 239 // the typed_count for pasted-in URLs, if the user manually edits the URL or |
| 240 // types some long thing in by hand, we wouldn't want to immediately start |
| 241 // autocompleting it. |
| 242 return match.promoted || |
| 243 (match.url_info.typed_count() && |
| 244 ((match.url_info.typed_count() > 1) || match.IsHostOnly())); |
| 245 } |
| 246 |
232 // Given the user's |input| and a |match| created from it, reduce the match's | 247 // Given the user's |input| and a |match| created from it, reduce the match's |
233 // URL to just a host. If this host still matches the user input, return it. | 248 // URL to just a host. If this host still matches the user input, return it. |
234 // Returns the empty string on failure. | 249 // Returns the empty string on failure. |
235 GURL ConvertToHostOnly(const history::HistoryMatch& match, | 250 GURL ConvertToHostOnly(const history::HistoryMatch& match, |
236 const base::string16& input) { | 251 const base::string16& input) { |
237 // See if we should try to do host-only suggestions for this URL. Nonstandard | 252 // See if we should try to do host-only suggestions for this URL. Nonstandard |
238 // schemes means there's no authority section, so suggesting the host name | 253 // schemes means there's no authority section, so suggesting the host name |
239 // is useless. File URLs are standard, but host suggestion is not useful for | 254 // is useless. File URLs are standard, but host suggestion is not useful for |
240 // them either. | 255 // them either. |
241 const GURL& url = match.url_info.url(); | 256 const GURL& url = match.url_info.url(); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 // The user typed an intranet hostname that they've visited (albeit with a | 400 // The user typed an intranet hostname that they've visited (albeit with a |
386 // different port and/or path) before. | 401 // different port and/or path) before. |
387 url_row_ = history::URLRow(url); | 402 url_row_ = history::URLRow(url); |
388 type_ = UNVISITED_INTRANET; | 403 type_ = UNVISITED_INTRANET; |
389 } | 404 } |
390 } | 405 } |
391 | 406 |
392 HistoryURLProviderParams::HistoryURLProviderParams( | 407 HistoryURLProviderParams::HistoryURLProviderParams( |
393 const AutocompleteInput& input, | 408 const AutocompleteInput& input, |
394 bool trim_http, | 409 bool trim_http, |
| 410 const AutocompleteMatch& what_you_typed_match, |
395 const std::string& languages, | 411 const std::string& languages, |
396 TemplateURL* default_search_provider, | 412 TemplateURL* default_search_provider, |
397 const SearchTermsData& search_terms_data) | 413 const SearchTermsData& search_terms_data) |
398 : message_loop(base::MessageLoop::current()), | 414 : message_loop(base::MessageLoop::current()), |
399 input(input), | 415 input(input), |
400 prevent_inline_autocomplete(input.prevent_inline_autocomplete()), | 416 prevent_inline_autocomplete(input.prevent_inline_autocomplete()), |
401 trim_http(trim_http), | 417 trim_http(trim_http), |
| 418 what_you_typed_match(what_you_typed_match), |
402 failed(false), | 419 failed(false), |
403 languages(languages), | 420 languages(languages), |
404 dont_suggest_exact_input(false), | 421 dont_suggest_exact_input(false), |
405 default_search_provider(default_search_provider ? | 422 default_search_provider(default_search_provider ? |
406 new TemplateURL(default_search_provider->profile(), | 423 new TemplateURL(default_search_provider->profile(), |
407 default_search_provider->data()) : NULL), | 424 default_search_provider->data()) : NULL), |
408 search_terms_data(new SearchTermsDataSnapshot(search_terms_data)) { | 425 search_terms_data(new SearchTermsDataSnapshot(search_terms_data)) { |
409 } | 426 } |
410 | 427 |
411 HistoryURLProviderParams::~HistoryURLProviderParams() { | 428 HistoryURLProviderParams::~HistoryURLProviderParams() { |
412 } | 429 } |
413 | 430 |
414 HistoryURLProvider::HistoryURLProvider(AutocompleteProviderListener* listener, | 431 HistoryURLProvider::HistoryURLProvider(AutocompleteProviderListener* listener, |
415 Profile* profile) | 432 Profile* profile) |
416 : HistoryProvider(listener, profile, | 433 : HistoryProvider(listener, profile, |
417 AutocompleteProvider::TYPE_HISTORY_URL), | 434 AutocompleteProvider::TYPE_HISTORY_URL), |
418 params_(NULL), | 435 params_(NULL), |
419 cull_redirects_( | 436 cull_redirects_( |
420 !OmniboxFieldTrial::InHUPCullRedirectsFieldTrial() || | 437 !OmniboxFieldTrial::InHUPCullRedirectsFieldTrial() || |
421 !OmniboxFieldTrial::InHUPCullRedirectsFieldTrialExperimentGroup()), | 438 !OmniboxFieldTrial::InHUPCullRedirectsFieldTrialExperimentGroup()), |
422 create_shorter_match_( | 439 create_shorter_match_( |
423 !OmniboxFieldTrial::InHUPCreateShorterMatchFieldTrial() || | 440 !OmniboxFieldTrial::InHUPCreateShorterMatchFieldTrial() || |
424 !OmniboxFieldTrial:: | 441 !OmniboxFieldTrial:: |
425 InHUPCreateShorterMatchFieldTrialExperimentGroup()) { | 442 InHUPCreateShorterMatchFieldTrialExperimentGroup()) { |
426 // Initialize HUP scoring params based on the current experiment. | 443 // Initialize HUP scoring params based on the current experiment. |
427 OmniboxFieldTrial::GetExperimentalHUPScoringParams(&scoring_params_); | 444 OmniboxFieldTrial::GetExperimentalHUPScoringParams(&scoring_params_); |
(...skipping 12 matching lines...) Expand all Loading... |
440 | 457 |
441 // Cancel any in-progress query. | 458 // Cancel any in-progress query. |
442 Stop(false); | 459 Stop(false); |
443 | 460 |
444 matches_.clear(); | 461 matches_.clear(); |
445 | 462 |
446 if ((input.type() == metrics::OmniboxInputType::INVALID) || | 463 if ((input.type() == metrics::OmniboxInputType::INVALID) || |
447 (input.type() == metrics::OmniboxInputType::FORCED_QUERY)) | 464 (input.type() == metrics::OmniboxInputType::FORCED_QUERY)) |
448 return; | 465 return; |
449 | 466 |
450 // Create a match for exactly what the user typed. This will only be used as | 467 // Do some fixup on the user input before matching against it, so we provide |
451 // a fallback in case we can't get the history service or URL DB; otherwise, | 468 // good results for local file paths, input with spaces, etc. |
452 // we'll run this again in DoAutocomplete() and use that result instead. | 469 const FixupReturn fixup_return(FixupUserInput(input)); |
| 470 if (!fixup_return.first) |
| 471 return; |
| 472 url::Parsed parts; |
| 473 url_fixer::SegmentURL(fixup_return.second, &parts); |
| 474 AutocompleteInput fixed_up_input(input); |
| 475 fixed_up_input.UpdateText(fixup_return.second, base::string16::npos, parts); |
| 476 |
| 477 // Create a match for what the user typed. |
453 const bool trim_http = !AutocompleteInput::HasHTTPScheme(input.text()); | 478 const bool trim_http = !AutocompleteInput::HasHTTPScheme(input.text()); |
454 // Don't do this for queries -- while we can sometimes mark up a match for | 479 AutocompleteMatch what_you_typed_match(SuggestExactInput( |
455 // this, it's not what the user wants, and just adds noise. | 480 fixed_up_input.text(), fixed_up_input.canonicalized_url(), trim_http)); |
456 if (input.type() != metrics::OmniboxInputType::QUERY) { | 481 what_you_typed_match.relevance = CalculateRelevance(WHAT_YOU_TYPED, 0); |
457 AutocompleteMatch what_you_typed(SuggestExactInput( | 482 |
458 input.text(), input.canonicalized_url(), trim_http)); | 483 // Add the WYT match as a fallback in case we can't get the history service or |
459 what_you_typed.relevance = CalculateRelevance(WHAT_YOU_TYPED, 0); | 484 // URL DB; otherwise, we'll replace this match lower down. Don't do this for |
460 matches_.push_back(what_you_typed); | 485 // queries, though -- while we can sometimes mark up a match for them, it's |
461 } | 486 // not what the user wants, and just adds noise. |
| 487 if (fixed_up_input.type() != metrics::OmniboxInputType::QUERY) |
| 488 matches_.push_back(what_you_typed_match); |
462 | 489 |
463 // We'll need the history service to run both passes, so try to obtain it. | 490 // We'll need the history service to run both passes, so try to obtain it. |
464 if (!profile_) | 491 if (!profile_) |
465 return; | 492 return; |
466 HistoryService* const history_service = | 493 HistoryService* const history_service = |
467 HistoryServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS); | 494 HistoryServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS); |
468 if (!history_service) | 495 if (!history_service) |
469 return; | 496 return; |
470 | 497 |
471 // Get the default search provider and search terms data now since we have to | 498 // Get the default search provider and search terms data now since we have to |
472 // retrieve these on the UI thread, and the second pass runs on the history | 499 // retrieve these on the UI thread, and the second pass runs on the history |
473 // thread. |template_url_service| can be NULL when testing. | 500 // thread. |template_url_service| can be NULL when testing. |
474 TemplateURLService* template_url_service = | 501 TemplateURLService* template_url_service = |
475 TemplateURLServiceFactory::GetForProfile(profile_); | 502 TemplateURLServiceFactory::GetForProfile(profile_); |
476 TemplateURL* default_search_provider = template_url_service ? | 503 TemplateURL* default_search_provider = template_url_service ? |
477 template_url_service->GetDefaultSearchProvider() : NULL; | 504 template_url_service->GetDefaultSearchProvider() : NULL; |
478 UIThreadSearchTermsData data(profile_); | 505 UIThreadSearchTermsData data(profile_); |
479 | 506 |
480 // Do some fixup on the user input before matching against it, so we provide | |
481 // good results for local file paths, input with spaces, etc. | |
482 const FixupReturn fixup_return(FixupUserInput(input)); | |
483 if (!fixup_return.first) | |
484 return; | |
485 url::Parsed parts; | |
486 url_fixer::SegmentURL(fixup_return.second, &parts); | |
487 AutocompleteInput fixed_up_input(input); | |
488 fixed_up_input.UpdateText(fixup_return.second, base::string16::npos, parts); | |
489 | |
490 // Create the data structure for the autocomplete passes. We'll save this off | 507 // Create the data structure for the autocomplete passes. We'll save this off |
491 // onto the |params_| member for later deletion below if we need to run pass | 508 // onto the |params_| member for later deletion below if we need to run pass |
492 // 2. | 509 // 2. |
493 scoped_ptr<HistoryURLProviderParams> params( | 510 scoped_ptr<HistoryURLProviderParams> params( |
494 new HistoryURLProviderParams( | 511 new HistoryURLProviderParams( |
495 fixed_up_input, trim_http, | 512 fixed_up_input, trim_http, what_you_typed_match, |
496 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages), | 513 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages), |
497 default_search_provider, data)); | 514 default_search_provider, data)); |
498 // Note that we use the non-fixed-up input here, since fixup may strip | 515 // Note that we use the non-fixed-up input here, since fixup may strip |
499 // trailing whitespace. | 516 // trailing whitespace. |
500 params->prevent_inline_autocomplete = PreventInlineAutocomplete(input); | 517 params->prevent_inline_autocomplete = PreventInlineAutocomplete(input); |
501 | 518 |
502 // Pass 1: Get the in-memory URL database, and use it to find and promote | 519 // Pass 1: Get the in-memory URL database, and use it to find and promote |
503 // the inline autocomplete match, if any. | 520 // the inline autocomplete match, if any. |
504 history::URLDatabase* url_db = history_service->InMemoryDatabase(); | 521 history::URLDatabase* url_db = history_service->InMemoryDatabase(); |
505 // url_db can be NULL if it hasn't finished initializing (or failed to | 522 // url_db can be NULL if it hasn't finished initializing (or failed to |
506 // initialize). In this case all we can do is fall back on the second | 523 // initialize). In this case all we can do is fall back on the second |
507 // pass. | 524 // pass. |
508 // | 525 // |
509 // TODO(pkasting): We should just block here until this loads. Any time | 526 // TODO(pkasting): We should just block here until this loads. Any time |
510 // someone unloads the history backend, we'll get inconsistent inline | 527 // someone unloads the history backend, we'll get inconsistent inline |
511 // autocomplete behavior here. | 528 // autocomplete behavior here. |
512 if (url_db) { | 529 if (url_db) { |
513 DoAutocomplete(NULL, url_db, params.get()); | 530 DoAutocomplete(NULL, url_db, params.get()); |
514 // params->matches now has the matches we should expose to the provider. | 531 // params->matches now has the matches we should expose to the provider. |
515 // Pass 2 expects a "clean slate" set of matches. | 532 // Pass 2 expects a "clean slate" set of matches. |
516 matches_.clear(); | 533 matches_.clear(); |
517 matches_.swap(params->matches); | 534 matches_.swap(params->matches); |
518 UpdateStarredStateOfMatches(); | 535 UpdateStarredStateOfMatches(); |
| 536 // Reset the WYT match in |params| so that both passes get the same input |
| 537 // state, since DoAutocomplete() may have modified it. |
| 538 params->what_you_typed_match = what_you_typed_match; |
519 } | 539 } |
520 | 540 |
521 // Pass 2: Ask the history service to call us back on the history thread, | 541 // Pass 2: Ask the history service to call us back on the history thread, |
522 // where we can read the full on-disk DB. | 542 // where we can read the full on-disk DB. |
523 if (input.want_asynchronous_matches()) { | 543 if (input.want_asynchronous_matches()) { |
524 done_ = false; | 544 done_ = false; |
525 params_ = params.release(); // This object will be destroyed in | 545 params_ = params.release(); // This object will be destroyed in |
526 // QueryComplete() once we're done with it. | 546 // QueryComplete() once we're done with it. |
527 history_service->ScheduleAutocomplete(this, params_); | 547 history_service->ScheduleAutocomplete(this, params_); |
528 } | 548 } |
529 } | 549 } |
530 | 550 |
531 void HistoryURLProvider::Stop(bool clear_cached_results) { | 551 void HistoryURLProvider::Stop(bool clear_cached_results) { |
532 done_ = true; | 552 done_ = true; |
533 | 553 |
534 if (params_) | 554 if (params_) |
535 params_->cancel_flag.Set(); | 555 params_->cancel_flag.Set(); |
536 } | 556 } |
537 | 557 |
538 AutocompleteMatch HistoryURLProvider::SuggestExactInput( | 558 AutocompleteMatch HistoryURLProvider::SuggestExactInput( |
539 const base::string16& text, | 559 const base::string16& text, |
540 const GURL& destination_url, | 560 const GURL& destination_url, |
541 bool trim_http) { | 561 bool trim_http) { |
| 562 // The FormattedStringWithEquivalentMeaning() call below requires callers to |
| 563 // be on the UI thread. |
| 564 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI) || |
| 565 !content::BrowserThread::IsThreadInitialized(content::BrowserThread::UI)); |
| 566 |
542 AutocompleteMatch match(this, 0, false, | 567 AutocompleteMatch match(this, 0, false, |
543 AutocompleteMatchType::URL_WHAT_YOU_TYPED); | 568 AutocompleteMatchType::URL_WHAT_YOU_TYPED); |
544 | 569 |
545 if (destination_url.is_valid()) { | 570 if (destination_url.is_valid()) { |
546 match.destination_url = destination_url; | 571 match.destination_url = destination_url; |
547 | 572 |
548 // Trim off "http://" if the user didn't type it. | 573 // Trim off "http://" if the user didn't type it. |
549 // NOTE: We use TrimHttpPrefix() here rather than StringForURLDisplay() to | 574 // NOTE: We use TrimHttpPrefix() here rather than StringForURLDisplay() to |
550 // strip the scheme as we need to know the offset so we can adjust the | 575 // strip the scheme as we need to know the offset so we can adjust the |
551 // |match_location| below. StringForURLDisplay() and TrimHttpPrefix() have | 576 // |match_location| below. StringForURLDisplay() and TrimHttpPrefix() have |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 history::ScoredHistoryMatch::FilterTermMatchesByWordStarts( | 682 history::ScoredHistoryMatch::FilterTermMatchesByWordStarts( |
658 description_matches, offsets, description_word_starts, 0, | 683 description_matches, offsets, description_word_starts, 0, |
659 std::string::npos); | 684 std::string::npos); |
660 return SpansFromTermMatch( | 685 return SpansFromTermMatch( |
661 description_matches, clean_description.length(), false); | 686 description_matches, clean_description.length(), false); |
662 } | 687 } |
663 | 688 |
664 void HistoryURLProvider::DoAutocomplete(history::HistoryBackend* backend, | 689 void HistoryURLProvider::DoAutocomplete(history::HistoryBackend* backend, |
665 history::URLDatabase* db, | 690 history::URLDatabase* db, |
666 HistoryURLProviderParams* params) { | 691 HistoryURLProviderParams* params) { |
667 VisitClassifier classifier(this, params->input, db); | 692 // Get the matching URLs from the DB. |
668 // Create a What You Typed match, which we'll need below. | |
669 // | |
670 // We display this to the user when there's a reasonable chance they actually | |
671 // care: | |
672 // * Their input can be opened as a URL, and | |
673 // * We parsed the input as a URL, or it starts with an explicit "http:" or | |
674 // "https:". | |
675 // that is when their input can be opened as a URL. | |
676 // Otherwise, this is just low-quality noise. In the cases where we've parsed | |
677 // as UNKNOWN, we'll still show an accidental search infobar if need be. | |
678 bool have_what_you_typed_match = | |
679 (params->input.type() != metrics::OmniboxInputType::QUERY) && | |
680 ((params->input.type() != metrics::OmniboxInputType::UNKNOWN) || | |
681 (classifier.type() == VisitClassifier::UNVISITED_INTRANET) || | |
682 !params->trim_http || | |
683 (AutocompleteInput::NumNonHostComponents(params->input.parts()) > 0)); | |
684 AutocompleteMatch what_you_typed_match(SuggestExactInput( | |
685 params->input.text(), params->input.canonicalized_url(), | |
686 params->trim_http)); | |
687 what_you_typed_match.relevance = CalculateRelevance(WHAT_YOU_TYPED, 0); | |
688 | |
689 // Get the matching URLs from the DB | |
690 history::URLRows url_matches; | 693 history::URLRows url_matches; |
691 history::HistoryMatches history_matches; | 694 history::HistoryMatches history_matches; |
692 | 695 |
693 const URLPrefixes& prefixes = URLPrefix::GetURLPrefixes(); | 696 const URLPrefixes& prefixes = URLPrefix::GetURLPrefixes(); |
694 for (URLPrefixes::const_iterator i(prefixes.begin()); i != prefixes.end(); | 697 for (URLPrefixes::const_iterator i(prefixes.begin()); i != prefixes.end(); |
695 ++i) { | 698 ++i) { |
696 if (params->cancel_flag.IsSet()) | 699 if (params->cancel_flag.IsSet()) |
697 return; // Canceled in the middle of a query, give up. | 700 return; // Canceled in the middle of a query, give up. |
| 701 |
698 // We only need kMaxMatches results in the end, but before we get there we | 702 // We only need kMaxMatches results in the end, but before we get there we |
699 // need to promote lower-quality matches that are prefixes of higher-quality | 703 // need to promote lower-quality matches that are prefixes of higher-quality |
700 // matches, and remove lower-quality redirects. So we ask for more results | 704 // matches, and remove lower-quality redirects. So we ask for more results |
701 // than we need, of every prefix type, in hopes this will give us far more | 705 // than we need, of every prefix type, in hopes this will give us far more |
702 // than enough to work with. CullRedirects() will then reduce the list to | 706 // than enough to work with. CullRedirects() will then reduce the list to |
703 // the best kMaxMatches results. | 707 // the best kMaxMatches results. |
704 db->AutocompleteForPrefix( | 708 db->AutocompleteForPrefix( |
705 base::UTF16ToUTF8(i->prefix + params->input.text()), | 709 base::UTF16ToUTF8(i->prefix + params->input.text()), kMaxMatches * 2, |
706 kMaxMatches * 2, | 710 !backend, &url_matches); |
707 (backend == NULL), | |
708 &url_matches); | |
709 for (history::URLRows::const_iterator j(url_matches.begin()); | 711 for (history::URLRows::const_iterator j(url_matches.begin()); |
710 j != url_matches.end(); ++j) { | 712 j != url_matches.end(); ++j) { |
711 const URLPrefix* best_prefix = | 713 const URLPrefix* best_prefix = URLPrefix::BestURLPrefix( |
712 URLPrefix::BestURLPrefix(base::UTF8ToUTF16(j->url().spec()), | 714 base::UTF8ToUTF16(j->url().spec()), base::string16()); |
713 base::string16()); | 715 DCHECK(best_prefix); |
714 DCHECK(best_prefix != NULL); | 716 history_matches.push_back(history::HistoryMatch( |
715 history_matches.push_back(history::HistoryMatch(*j, i->prefix.length(), | 717 *j, i->prefix.length(), !i->num_components, |
716 i->num_components == 0, | |
717 i->num_components >= best_prefix->num_components)); | 718 i->num_components >= best_prefix->num_components)); |
718 } | 719 } |
719 } | 720 } |
720 | 721 |
721 // Create sorted list of suggestions. | 722 // Create sorted list of suggestions. |
722 CullPoorMatches(*params, &history_matches); | 723 CullPoorMatches(*params, &history_matches); |
723 SortAndDedupMatches(&history_matches); | 724 SortAndDedupMatches(&history_matches); |
| 725 |
| 726 // Try to create a shorter suggestion from the best match. |
| 727 // We allow the what you typed match to be displayed when there's a reasonable |
| 728 // chance the user actually cares: |
| 729 // * Their input can be opened as a URL, and |
| 730 // * We parsed the input as a URL, or it starts with an explicit "http:" or |
| 731 // "https:". |
| 732 // Otherwise, this is just low-quality noise. In the cases where we've parsed |
| 733 // as UNKNOWN, we'll still show an accidental search infobar if need be. |
| 734 VisitClassifier classifier(this, params->input, db); |
| 735 bool have_what_you_typed_match = |
| 736 (params->input.type() != metrics::OmniboxInputType::QUERY) && |
| 737 ((params->input.type() != metrics::OmniboxInputType::UNKNOWN) || |
| 738 (classifier.type() == VisitClassifier::UNVISITED_INTRANET) || |
| 739 !params->trim_http || |
| 740 (AutocompleteInput::NumNonHostComponents(params->input.parts()) > 0)); |
724 PromoteOrCreateShorterSuggestion(db, *params, have_what_you_typed_match, | 741 PromoteOrCreateShorterSuggestion(db, *params, have_what_you_typed_match, |
725 what_you_typed_match, &history_matches); | 742 &history_matches); |
726 | 743 |
727 // Try to promote a match as an exact/inline autocomplete match. This also | 744 // Try to promote a match as an exact/inline autocomplete match. This also |
728 // moves it to the front of |history_matches|, so skip over it when | 745 // moves it to the front of |history_matches|, so skip over it when |
729 // converting the rest of the matches. | 746 // converting the rest of the matches. |
730 size_t first_match = 1; | 747 size_t first_match = 1; |
731 size_t exact_suggestion = 0; | 748 size_t exact_suggestion = 0; |
732 // Checking |is_history_what_you_typed_match| tells us whether | 749 // Checking params->what_you_typed_match.is_history_what_you_typed_match tells |
733 // SuggestExactInput() succeeded in constructing a valid match. | 750 // us whether SuggestExactInput() succeeded in constructing a valid match. |
734 if (what_you_typed_match.is_history_what_you_typed_match && | 751 if (params->what_you_typed_match.is_history_what_you_typed_match && |
735 (!backend || !params->dont_suggest_exact_input) && | 752 (!backend || !params->dont_suggest_exact_input) && |
736 FixupExactSuggestion(db, params->input, classifier, &what_you_typed_match, | 753 FixupExactSuggestion(db, classifier, params, &history_matches)) { |
737 &history_matches)) { | |
738 // Got an exact match for the user's input. Treat it as the best match | 754 // Got an exact match for the user's input. Treat it as the best match |
739 // regardless of the input type. | 755 // regardless of the input type. |
740 exact_suggestion = 1; | 756 exact_suggestion = 1; |
741 params->matches.push_back(what_you_typed_match); | 757 params->matches.push_back(params->what_you_typed_match); |
742 } else if (params->prevent_inline_autocomplete || | 758 } else if (params->prevent_inline_autocomplete || |
743 history_matches.empty() || | 759 history_matches.empty() || |
744 !PromoteMatchForInlineAutocomplete(history_matches.front(), params)) { | 760 !PromoteMatchForInlineAutocomplete(history_matches.front(), params)) { |
745 // Failed to promote any URLs for inline autocompletion. Use the What You | 761 // Failed to promote any URLs for inline autocompletion. Use the What You |
746 // Typed match, if we have it. | 762 // Typed match, if we have it. |
747 first_match = 0; | 763 first_match = 0; |
748 if (have_what_you_typed_match) | 764 if (have_what_you_typed_match) |
749 params->matches.push_back(what_you_typed_match); | 765 params->matches.push_back(params->what_you_typed_match); |
750 } | 766 } |
751 | 767 |
752 // This is the end of the synchronous pass. | 768 // This is the end of the synchronous pass. |
753 if (!backend) | 769 if (!backend) |
754 return; | 770 return; |
755 | 771 |
756 // Determine relevancy of highest scoring match, if any. | 772 // Determine relevancy of highest scoring match, if any. |
757 int relevance = -1; | 773 int relevance = -1; |
758 for (ACMatches::const_iterator it = params->matches.begin(); | 774 for (ACMatches::const_iterator it = params->matches.begin(); |
759 it != params->matches.end(); ++it) { | 775 it != params->matches.end(); ++it) { |
(...skipping 28 matching lines...) Expand all Loading... |
788 // The experimental scoring must not change the top result's score. | 804 // The experimental scoring must not change the top result's score. |
789 if (!params->matches.empty()) { | 805 if (!params->matches.empty()) { |
790 relevance = CalculateRelevanceScoreUsingScoringParams(match, relevance, | 806 relevance = CalculateRelevanceScoreUsingScoringParams(match, relevance, |
791 scoring_params_); | 807 scoring_params_); |
792 ac_match.relevance = relevance; | 808 ac_match.relevance = relevance; |
793 } | 809 } |
794 params->matches.push_back(ac_match); | 810 params->matches.push_back(ac_match); |
795 } | 811 } |
796 } | 812 } |
797 | 813 |
798 // Called on the main thread when the query is complete. | |
799 void HistoryURLProvider::QueryComplete( | 814 void HistoryURLProvider::QueryComplete( |
800 HistoryURLProviderParams* params_gets_deleted) { | 815 HistoryURLProviderParams* params_gets_deleted) { |
801 // Ensure |params_gets_deleted| gets deleted on exit. | 816 // Ensure |params_gets_deleted| gets deleted on exit. |
802 scoped_ptr<HistoryURLProviderParams> params(params_gets_deleted); | 817 scoped_ptr<HistoryURLProviderParams> params(params_gets_deleted); |
803 | 818 |
804 // If the user hasn't already started another query, clear our member pointer | 819 // If the user hasn't already started another query, clear our member pointer |
805 // so we can't write into deleted memory. | 820 // so we can't write into deleted memory. |
806 if (params_ == params_gets_deleted) | 821 if (params_ == params_gets_deleted) |
807 params_ = NULL; | 822 params_ = NULL; |
808 | 823 |
809 // Don't send responses for queries that have been canceled. | 824 // Don't send responses for queries that have been canceled. |
810 if (params->cancel_flag.IsSet()) | 825 if (params->cancel_flag.IsSet()) |
811 return; // Already set done_ when we canceled, no need to set it again. | 826 return; // Already set done_ when we canceled, no need to set it again. |
812 | 827 |
813 // Don't modify |matches_| if the query failed, since it might have a default | 828 // Don't modify |matches_| if the query failed, since it might have a default |
814 // match in it, whereas |params->matches| will be empty. | 829 // match in it, whereas |params->matches| will be empty. |
815 if (!params->failed) { | 830 if (!params->failed) { |
816 matches_.swap(params->matches); | 831 matches_.swap(params->matches); |
817 UpdateStarredStateOfMatches(); | 832 UpdateStarredStateOfMatches(); |
818 } | 833 } |
819 | 834 |
820 done_ = true; | 835 done_ = true; |
821 listener_->OnProviderUpdate(true); | 836 listener_->OnProviderUpdate(true); |
822 } | 837 } |
823 | 838 |
824 bool HistoryURLProvider::FixupExactSuggestion( | 839 bool HistoryURLProvider::FixupExactSuggestion( |
825 history::URLDatabase* db, | 840 history::URLDatabase* db, |
826 const AutocompleteInput& input, | |
827 const VisitClassifier& classifier, | 841 const VisitClassifier& classifier, |
828 AutocompleteMatch* match, | 842 HistoryURLProviderParams* params, |
829 history::HistoryMatches* matches) const { | 843 history::HistoryMatches* matches) const { |
830 DCHECK(match != NULL); | |
831 DCHECK(matches != NULL); | 844 DCHECK(matches != NULL); |
832 | 845 |
833 MatchType type = INLINE_AUTOCOMPLETE; | 846 MatchType type = INLINE_AUTOCOMPLETE; |
834 switch (classifier.type()) { | 847 switch (classifier.type()) { |
835 case VisitClassifier::INVALID: | 848 case VisitClassifier::INVALID: |
836 return false; | 849 return false; |
837 case VisitClassifier::UNVISITED_INTRANET: | 850 case VisitClassifier::UNVISITED_INTRANET: |
838 type = UNVISITED_INTRANET; | 851 type = UNVISITED_INTRANET; |
839 break; | 852 break; |
840 default: | 853 default: |
841 DCHECK_EQ(VisitClassifier::VISITED, classifier.type()); | 854 DCHECK_EQ(VisitClassifier::VISITED, classifier.type()); |
842 // We have data for this match, use it. | 855 // We have data for this match, use it. |
843 match->deletable = true; | 856 params->what_you_typed_match.deletable = true; |
844 match->description = classifier.url_row().title(); | 857 params->what_you_typed_match.description = classifier.url_row().title(); |
845 RecordAdditionalInfoFromUrlRow(classifier.url_row(), match); | 858 RecordAdditionalInfoFromUrlRow(classifier.url_row(), |
846 match->description_class = | 859 ¶ms->what_you_typed_match); |
847 ClassifyDescription(input.text(), match->description); | 860 params->what_you_typed_match.description_class = ClassifyDescription( |
| 861 params->input.text(), params->what_you_typed_match.description); |
848 if (!classifier.url_row().typed_count()) { | 862 if (!classifier.url_row().typed_count()) { |
849 // If we reach here, we must be in the second pass, and we must not have | 863 // If we reach here, we must be in the second pass, and we must not have |
850 // this row's data available during the first pass. That means we | 864 // this row's data available during the first pass. That means we |
851 // either scored it as WHAT_YOU_TYPED or UNVISITED_INTRANET, and to | 865 // either scored it as WHAT_YOU_TYPED or UNVISITED_INTRANET, and to |
852 // maintain the ordering between passes consistent, we need to score it | 866 // maintain the ordering between passes consistent, we need to score it |
853 // the same way here. | 867 // the same way here. |
854 type = CanFindIntranetURL(db, input) ? | 868 type = CanFindIntranetURL(db, params->input) ? |
855 UNVISITED_INTRANET : WHAT_YOU_TYPED; | 869 UNVISITED_INTRANET : WHAT_YOU_TYPED; |
856 } | 870 } |
857 break; | 871 break; |
858 } | 872 } |
859 | 873 |
860 const GURL& url = match->destination_url; | 874 const GURL& url = params->what_you_typed_match.destination_url; |
861 const url::Parsed& parsed = url.parsed_for_possibly_invalid_spec(); | 875 const url::Parsed& parsed = url.parsed_for_possibly_invalid_spec(); |
862 // If the what-you-typed result looks like a single word (which can be | 876 // If the what-you-typed result looks like a single word (which can be |
863 // interpreted as an intranet address) followed by a pound sign ("#"), | 877 // interpreted as an intranet address) followed by a pound sign ("#"), |
864 // leave the score for the url-what-you-typed result as is. It will be | 878 // leave the score for the url-what-you-typed result as is. It will be |
865 // outscored by a search query from the SearchProvider. This test fixes | 879 // outscored by a search query from the SearchProvider. This test fixes |
866 // cases such as "c#" and "c# foo" where the user has visited an intranet | 880 // cases such as "c#" and "c# foo" where the user has visited an intranet |
867 // site "c". We want the search-what-you-typed score to beat the | 881 // site "c". We want the search-what-you-typed score to beat the |
868 // URL-what-you-typed score in this case. Most of the below test tries to | 882 // URL-what-you-typed score in this case. Most of the below test tries to |
869 // make sure that this code does not trigger if the user did anything to | 883 // make sure that this code does not trigger if the user did anything to |
870 // indicate the desired match is a URL. For instance, "c/# foo" will not | 884 // indicate the desired match is a URL. For instance, "c/# foo" will not |
871 // pass the test because that will be classified as input type URL. The | 885 // pass the test because that will be classified as input type URL. The |
872 // parsed.CountCharactersBefore() in the test looks for the presence of a | 886 // parsed.CountCharactersBefore() in the test looks for the presence of a |
873 // reference fragment in the URL by checking whether the position differs | 887 // reference fragment in the URL by checking whether the position differs |
874 // included the delimiter (pound sign) versus not including the delimiter. | 888 // included the delimiter (pound sign) versus not including the delimiter. |
875 // (One cannot simply check url.ref() because it will not distinguish | 889 // (One cannot simply check url.ref() because it will not distinguish |
876 // between the input "c" and the input "c#", both of which will have empty | 890 // between the input "c" and the input "c#", both of which will have empty |
877 // reference fragments.) | 891 // reference fragments.) |
878 if ((type == UNVISITED_INTRANET) && | 892 if ((type == UNVISITED_INTRANET) && |
879 (input.type() != metrics::OmniboxInputType::URL) && | 893 (params->input.type() != metrics::OmniboxInputType::URL) && |
880 url.username().empty() && url.password().empty() && url.port().empty() && | 894 url.username().empty() && url.password().empty() && url.port().empty() && |
881 (url.path() == "/") && url.query().empty() && | 895 (url.path() == "/") && url.query().empty() && |
882 (parsed.CountCharactersBefore(url::Parsed::REF, true) != | 896 (parsed.CountCharactersBefore(url::Parsed::REF, true) != |
883 parsed.CountCharactersBefore(url::Parsed::REF, false))) { | 897 parsed.CountCharactersBefore(url::Parsed::REF, false))) { |
884 return false; | 898 return false; |
885 } | 899 } |
886 | 900 |
887 match->relevance = CalculateRelevance(type, 0); | 901 params->what_you_typed_match.relevance = CalculateRelevance(type, 0); |
888 | 902 |
889 // If there are any other matches, then don't promote this match here, in | 903 // If there are any other matches, then don't promote this match here, in |
890 // hopes the caller will be able to inline autocomplete a better suggestion. | 904 // hopes the caller will be able to inline autocomplete a better suggestion. |
891 // DoAutocomplete() will fall back on this match if inline autocompletion | 905 // DoAutocomplete() will fall back on this match if inline autocompletion |
892 // fails. This matches how we react to never-visited URL inputs in the non- | 906 // fails. This matches how we react to never-visited URL inputs in the non- |
893 // intranet case. | 907 // intranet case. |
894 if (type == UNVISITED_INTRANET && !matches->empty()) | 908 if (type == UNVISITED_INTRANET && !matches->empty()) |
895 return false; | 909 return false; |
896 | 910 |
897 // Put it on the front of the HistoryMatches for redirect culling. | 911 // Put it on the front of the HistoryMatches for redirect culling. |
(...skipping 19 matching lines...) Expand all Loading... |
917 net::registry_controlled_domains::GetRegistryLength( | 931 net::registry_controlled_domains::GetRegistryLength( |
918 host, | 932 host, |
919 net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, | 933 net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, |
920 net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); | 934 net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); |
921 return registry_length == 0 && db->IsTypedHost(host); | 935 return registry_length == 0 && db->IsTypedHost(host); |
922 } | 936 } |
923 | 937 |
924 bool HistoryURLProvider::PromoteMatchForInlineAutocomplete( | 938 bool HistoryURLProvider::PromoteMatchForInlineAutocomplete( |
925 const history::HistoryMatch& match, | 939 const history::HistoryMatch& match, |
926 HistoryURLProviderParams* params) { | 940 HistoryURLProviderParams* params) { |
927 // Promote the first match if it's been marked for promotion or typed at least | 941 if (!CanPromoteMatchForInlineAutocomplete(match)) |
928 // n times, where n == 1 for "simple" (host-only) URLs and n == 2 for others. | |
929 // We set a higher bar for these long URLs because it's less likely that users | |
930 // will want to visit them again. Even though we don't increment the | |
931 // typed_count for pasted-in URLs, if the user manually edits the URL or types | |
932 // some long thing in by hand, we wouldn't want to immediately start | |
933 // autocompleting it. | |
934 if (!match.promoted && | |
935 (!match.url_info.typed_count() || | |
936 ((match.url_info.typed_count() == 1) && | |
937 !match.IsHostOnly()))) | |
938 return false; | 942 return false; |
939 | 943 |
940 // In the case where the user has typed "foo.com" and visited (but not typed) | 944 // In the case where the user has typed "foo.com" and visited (but not typed) |
941 // "foo/", and the input is "foo", we can reach here for "foo.com" during the | 945 // "foo/", and the input is "foo", we can reach here for "foo.com" during the |
942 // first pass but have the second pass suggest the exact input as a better | 946 // first pass but have the second pass suggest the exact input as a better |
943 // URL. Since we need both passes to agree, and since during the first pass | 947 // URL. Since we need both passes to agree, and since during the first pass |
944 // there's no way to know about "foo/", make reaching this point prevent any | 948 // there's no way to know about "foo/", make reaching this point prevent any |
945 // future pass from suggesting the exact input as a better match. | 949 // future pass from suggesting the exact input as a better match. |
946 if (params) { | 950 params->dont_suggest_exact_input = true; |
947 params->dont_suggest_exact_input = true; | 951 params->matches.push_back(HistoryMatchToACMatch( |
948 AutocompleteMatch ac_match = HistoryMatchToACMatch( | 952 *params, match, INLINE_AUTOCOMPLETE, |
949 *params, match, INLINE_AUTOCOMPLETE, | 953 CalculateRelevance(INLINE_AUTOCOMPLETE, 0))); |
950 CalculateRelevance(INLINE_AUTOCOMPLETE, 0)); | |
951 params->matches.push_back(ac_match); | |
952 } | |
953 return true; | 954 return true; |
954 } | 955 } |
955 | 956 |
956 // See if a shorter version of the best match should be created, and if so place | |
957 // it at the front of |matches|. This can suggest history URLs that are | |
958 // prefixes of the best match (if they've been visited enough, compared to the | |
959 // best match), or create host-only suggestions even when they haven't been | |
960 // visited before: if the user visited http://example.com/asdf once, we'll | |
961 // suggest http://example.com/ even if they've never been to it. | |
962 void HistoryURLProvider::PromoteOrCreateShorterSuggestion( | 957 void HistoryURLProvider::PromoteOrCreateShorterSuggestion( |
963 history::URLDatabase* db, | 958 history::URLDatabase* db, |
964 const HistoryURLProviderParams& params, | 959 const HistoryURLProviderParams& params, |
965 bool have_what_you_typed_match, | 960 bool have_what_you_typed_match, |
966 const AutocompleteMatch& what_you_typed_match, | |
967 history::HistoryMatches* matches) { | 961 history::HistoryMatches* matches) { |
968 if (matches->empty()) | 962 if (matches->empty()) |
969 return; // No matches, nothing to do. | 963 return; // No matches, nothing to do. |
970 | 964 |
971 // Determine the base URL from which to search, and whether that URL could | 965 // Determine the base URL from which to search, and whether that URL could |
972 // itself be added as a match. We can add the base iff it's not "effectively | 966 // itself be added as a match. We can add the base iff it's not "effectively |
973 // the same" as any "what you typed" match. | 967 // the same" as any "what you typed" match. |
974 const history::HistoryMatch& match = matches->front(); | 968 const history::HistoryMatch& match = matches->front(); |
975 GURL search_base = ConvertToHostOnly(match, params.input.text()); | 969 GURL search_base = ConvertToHostOnly(match, params.input.text()); |
976 bool can_add_search_base_to_matches = !have_what_you_typed_match; | 970 bool can_add_search_base_to_matches = !have_what_you_typed_match; |
977 if (search_base.is_empty()) { | 971 if (search_base.is_empty()) { |
978 // Search from what the user typed when we couldn't reduce the best match | 972 // Search from what the user typed when we couldn't reduce the best match |
979 // to a host. Careful: use a substring of |match| here, rather than the | 973 // to a host. Careful: use a substring of |match| here, rather than the |
980 // first match in |params|, because they might have different prefixes. If | 974 // first match in |params|, because they might have different prefixes. If |
981 // the user typed "google.com", |what_you_typed_match| will hold | 975 // the user typed "google.com", params->what_you_typed_match will hold |
982 // "http://google.com/", but |match| might begin with | 976 // "http://google.com/", but |match| might begin with |
983 // "http://www.google.com/". | 977 // "http://www.google.com/". |
984 // TODO: this should be cleaned up, and is probably incorrect for IDN. | 978 // TODO: this should be cleaned up, and is probably incorrect for IDN. |
985 std::string new_match = match.url_info.url().possibly_invalid_spec(). | 979 std::string new_match = match.url_info.url().possibly_invalid_spec(). |
986 substr(0, match.input_location + params.input.text().length()); | 980 substr(0, match.input_location + params.input.text().length()); |
987 search_base = GURL(new_match); | 981 search_base = GURL(new_match); |
988 // TODO(mrossetti): There is a degenerate case where the following may | |
989 // cause a failure: http://www/~someword/fubar.html. Diagnose. | |
990 // See: http://crbug.com/50101 | |
991 if (search_base.is_empty()) | 982 if (search_base.is_empty()) |
992 return; // Can't construct a valid URL from which to start a search. | 983 return; // Can't construct a valid URL from which to start a search. |
993 } else if (!can_add_search_base_to_matches) { | 984 } else if (!can_add_search_base_to_matches) { |
994 can_add_search_base_to_matches = | 985 can_add_search_base_to_matches = |
995 (search_base != what_you_typed_match.destination_url); | 986 (search_base != params.what_you_typed_match.destination_url); |
996 } | 987 } |
997 if (search_base == match.url_info.url()) | 988 if (search_base == match.url_info.url()) |
998 return; // Couldn't shorten |match|, so no range of URLs to search over. | 989 return; // Couldn't shorten |match|, so no range of URLs to search over. |
999 | 990 |
1000 // Search the DB for short URLs between our base and |match|. | 991 // Search the DB for short URLs between our base and |match|. |
1001 history::URLRow info(search_base); | 992 history::URLRow info(search_base); |
1002 bool promote = true; | 993 bool promote = true; |
1003 // A short URL is only worth suggesting if it's been visited at least a third | 994 // A short URL is only worth suggesting if it's been visited at least a third |
1004 // as often as the longer URL. | 995 // as often as the longer URL. |
1005 const int min_visit_count = ((match.url_info.visit_count() - 1) / 3) + 1; | 996 const int min_visit_count = ((match.url_info.visit_count() - 1) / 3) + 1; |
(...skipping 11 matching lines...) Expand all Loading... |
1017 return; // Couldn't find anything and can't add the search base, bail. | 1008 return; // Couldn't find anything and can't add the search base, bail. |
1018 | 1009 |
1019 // Try to get info on the search base itself. Promote it to the top if the | 1010 // Try to get info on the search base itself. Promote it to the top if the |
1020 // original best match isn't good enough to autocomplete. | 1011 // original best match isn't good enough to autocomplete. |
1021 db->GetRowForURL(search_base, &info); | 1012 db->GetRowForURL(search_base, &info); |
1022 promote = match.url_info.typed_count() <= 1; | 1013 promote = match.url_info.typed_count() <= 1; |
1023 } | 1014 } |
1024 | 1015 |
1025 // Promote or add the desired URL to the list of matches. | 1016 // Promote or add the desired URL to the list of matches. |
1026 bool ensure_can_inline = | 1017 bool ensure_can_inline = |
1027 promote && PromoteMatchForInlineAutocomplete(match, NULL); | 1018 promote && CanPromoteMatchForInlineAutocomplete(match); |
1028 ensure_can_inline &= CreateOrPromoteMatch(info, match.input_location, | 1019 ensure_can_inline &= CreateOrPromoteMatch(info, match.input_location, |
1029 match.match_in_scheme, matches, create_shorter_match_, promote); | 1020 match.match_in_scheme, matches, create_shorter_match_, promote); |
1030 if (ensure_can_inline) | 1021 if (ensure_can_inline) |
1031 matches->front().promoted = true; | 1022 matches->front().promoted = true; |
1032 } | 1023 } |
1033 | 1024 |
1034 void HistoryURLProvider::CullPoorMatches( | 1025 void HistoryURLProvider::CullPoorMatches( |
1035 const HistoryURLProviderParams& params, | 1026 const HistoryURLProviderParams& params, |
1036 history::HistoryMatches* matches) const { | 1027 history::HistoryMatches* matches) const { |
1037 const base::Time& threshold(history::AutocompleteAgeThreshold()); | 1028 const base::Time& threshold(history::AutocompleteAgeThreshold()); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1157 AutocompleteMatch::ClassifyLocationInString(base::string16::npos, 0, | 1148 AutocompleteMatch::ClassifyLocationInString(base::string16::npos, 0, |
1158 match.contents.length(), ACMatchClassification::URL, | 1149 match.contents.length(), ACMatchClassification::URL, |
1159 &match.contents_class); | 1150 &match.contents_class); |
1160 } | 1151 } |
1161 match.description = info.title(); | 1152 match.description = info.title(); |
1162 match.description_class = | 1153 match.description_class = |
1163 ClassifyDescription(params.input.text(), match.description); | 1154 ClassifyDescription(params.input.text(), match.description); |
1164 RecordAdditionalInfoFromUrlRow(info, &match); | 1155 RecordAdditionalInfoFromUrlRow(info, &match); |
1165 return match; | 1156 return match; |
1166 } | 1157 } |
OLD | NEW |