| 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 16 matching lines...) Expand all Loading... |
| 27 #include "chrome/browser/history/scored_history_match.h" | 27 #include "chrome/browser/history/scored_history_match.h" |
| 28 #include "chrome/browser/omnibox/omnibox_field_trial.h" | 28 #include "chrome/browser/omnibox/omnibox_field_trial.h" |
| 29 #include "chrome/browser/profiles/profile.h" | 29 #include "chrome/browser/profiles/profile.h" |
| 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/common/chrome_switches.h" | 32 #include "chrome/common/chrome_switches.h" |
| 33 #include "chrome/common/net/url_fixer_upper.h" | 33 #include "chrome/common/net/url_fixer_upper.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/bookmarks/browser/bookmark_utils.h" | 36 #include "components/bookmarks/browser/bookmark_utils.h" |
| 37 #include "components/metrics/proto/omnibox_input_type.pb.h" | |
| 38 #include "net/base/net_util.h" | 37 #include "net/base/net_util.h" |
| 39 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 38 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
| 40 #include "url/gurl.h" | 39 #include "url/gurl.h" |
| 41 #include "url/url_parse.h" | 40 #include "url/url_parse.h" |
| 42 #include "url/url_util.h" | 41 #include "url/url_util.h" |
| 43 | 42 |
| 44 namespace { | 43 namespace { |
| 45 | 44 |
| 46 // If |create_if_necessary| is true, ensures that |matches| contains an | 45 // If |create_if_necessary| is true, ensures that |matches| contains an |
| 47 // entry for |info|, creating a new such entry if necessary (using | 46 // entry for |info|, creating a new such entry if necessary (using |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 const AutocompleteInput& input, | 329 const AutocompleteInput& input, |
| 331 history::URLDatabase* db) | 330 history::URLDatabase* db) |
| 332 : provider_(provider), | 331 : provider_(provider), |
| 333 db_(db), | 332 db_(db), |
| 334 type_(INVALID) { | 333 type_(INVALID) { |
| 335 const GURL& url = input.canonicalized_url(); | 334 const GURL& url = input.canonicalized_url(); |
| 336 // Detect email addresses. These cases will look like "http://user@site/", | 335 // Detect email addresses. These cases will look like "http://user@site/", |
| 337 // and because the history backend strips auth creds, we'll get a bogus exact | 336 // and because the history backend strips auth creds, we'll get a bogus exact |
| 338 // match below if the user has visited "site". | 337 // match below if the user has visited "site". |
| 339 if (!url.is_valid() || | 338 if (!url.is_valid() || |
| 340 ((input.type() == metrics::OmniboxInputType::UNKNOWN) && | 339 ((input.type() == AutocompleteInput::UNKNOWN) && |
| 341 input.parts().username.is_nonempty() && | 340 input.parts().username.is_nonempty() && |
| 342 !input.parts().password.is_nonempty() && | 341 !input.parts().password.is_nonempty() && |
| 343 !input.parts().path.is_nonempty())) | 342 !input.parts().path.is_nonempty())) |
| 344 return; | 343 return; |
| 345 | 344 |
| 346 if (db_->GetRowForURL(url, &url_row_)) { | 345 if (db_->GetRowForURL(url, &url_row_)) { |
| 347 type_ = VISITED; | 346 type_ = VISITED; |
| 348 return; | 347 return; |
| 349 } | 348 } |
| 350 | 349 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 // running, we'd need to wait for it to return to the main thread before | 403 // running, we'd need to wait for it to return to the main thread before |
| 405 // doing this (we can't just write new data for it to read due to thread | 404 // doing this (we can't just write new data for it to read due to thread |
| 406 // safety issues). At that point it's just as fast, and easier, to simply | 405 // safety issues). At that point it's just as fast, and easier, to simply |
| 407 // re-run the query from scratch and ignore |minimal_changes|. | 406 // re-run the query from scratch and ignore |minimal_changes|. |
| 408 | 407 |
| 409 // Cancel any in-progress query. | 408 // Cancel any in-progress query. |
| 410 Stop(false); | 409 Stop(false); |
| 411 | 410 |
| 412 matches_.clear(); | 411 matches_.clear(); |
| 413 | 412 |
| 414 if ((input.type() == metrics::OmniboxInputType::INVALID) || | 413 if ((input.type() == AutocompleteInput::INVALID) || |
| 415 (input.type() == metrics::OmniboxInputType::FORCED_QUERY)) | 414 (input.type() == AutocompleteInput::FORCED_QUERY)) |
| 416 return; | 415 return; |
| 417 | 416 |
| 418 // Create a match for exactly what the user typed. This will only be used as | 417 // Create a match for exactly what the user typed. This will only be used as |
| 419 // a fallback in case we can't get the history service or URL DB; otherwise, | 418 // a fallback in case we can't get the history service or URL DB; otherwise, |
| 420 // we'll run this again in DoAutocomplete() and use that result instead. | 419 // we'll run this again in DoAutocomplete() and use that result instead. |
| 421 const bool trim_http = !AutocompleteInput::HasHTTPScheme(input.text()); | 420 const bool trim_http = !AutocompleteInput::HasHTTPScheme(input.text()); |
| 422 // Don't do this for queries -- while we can sometimes mark up a match for | 421 // Don't do this for queries -- while we can sometimes mark up a match for |
| 423 // this, it's not what the user wants, and just adds noise. | 422 // this, it's not what the user wants, and just adds noise. |
| 424 if (input.type() != metrics::OmniboxInputType::QUERY) { | 423 if (input.type() != AutocompleteInput::QUERY) { |
| 425 AutocompleteMatch what_you_typed(SuggestExactInput( | 424 AutocompleteMatch what_you_typed(SuggestExactInput( |
| 426 input.text(), input.canonicalized_url(), trim_http)); | 425 input.text(), input.canonicalized_url(), trim_http)); |
| 427 what_you_typed.relevance = CalculateRelevance(WHAT_YOU_TYPED, 0); | 426 what_you_typed.relevance = CalculateRelevance(WHAT_YOU_TYPED, 0); |
| 428 matches_.push_back(what_you_typed); | 427 matches_.push_back(what_you_typed); |
| 429 } | 428 } |
| 430 | 429 |
| 431 // We'll need the history service to run both passes, so try to obtain it. | 430 // We'll need the history service to run both passes, so try to obtain it. |
| 432 if (!profile_) | 431 if (!profile_) |
| 433 return; | 432 return; |
| 434 HistoryService* const history_service = | 433 HistoryService* const history_service = |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 // | 589 // |
| 591 // We display this to the user when there's a reasonable chance they actually | 590 // We display this to the user when there's a reasonable chance they actually |
| 592 // care: | 591 // care: |
| 593 // * Their input can be opened as a URL, and | 592 // * Their input can be opened as a URL, and |
| 594 // * We parsed the input as a URL, or it starts with an explicit "http:" or | 593 // * We parsed the input as a URL, or it starts with an explicit "http:" or |
| 595 // "https:". | 594 // "https:". |
| 596 // that is when their input can be opened as a URL. | 595 // that is when their input can be opened as a URL. |
| 597 // Otherwise, this is just low-quality noise. In the cases where we've parsed | 596 // Otherwise, this is just low-quality noise. In the cases where we've parsed |
| 598 // as UNKNOWN, we'll still show an accidental search infobar if need be. | 597 // as UNKNOWN, we'll still show an accidental search infobar if need be. |
| 599 bool have_what_you_typed_match = | 598 bool have_what_you_typed_match = |
| 600 (params->input.type() != metrics::OmniboxInputType::QUERY) && | 599 (params->input.type() != AutocompleteInput::QUERY) && |
| 601 ((params->input.type() != metrics::OmniboxInputType::UNKNOWN) || | 600 ((params->input.type() != AutocompleteInput::UNKNOWN) || |
| 602 (classifier.type() == VisitClassifier::UNVISITED_INTRANET) || | 601 (classifier.type() == VisitClassifier::UNVISITED_INTRANET) || |
| 603 !params->trim_http || | 602 !params->trim_http || |
| 604 (AutocompleteInput::NumNonHostComponents(params->input.parts()) > 0)); | 603 (AutocompleteInput::NumNonHostComponents(params->input.parts()) > 0)); |
| 605 AutocompleteMatch what_you_typed_match(SuggestExactInput( | 604 AutocompleteMatch what_you_typed_match(SuggestExactInput( |
| 606 params->input.text(), params->input.canonicalized_url(), | 605 params->input.text(), params->input.canonicalized_url(), |
| 607 params->trim_http)); | 606 params->trim_http)); |
| 608 what_you_typed_match.relevance = CalculateRelevance(WHAT_YOU_TYPED, 0); | 607 what_you_typed_match.relevance = CalculateRelevance(WHAT_YOU_TYPED, 0); |
| 609 | 608 |
| 610 // Get the matching URLs from the DB | 609 // Get the matching URLs from the DB |
| 611 history::URLRows url_matches; | 610 history::URLRows url_matches; |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 // make sure that this code does not trigger if the user did anything to | 820 // make sure that this code does not trigger if the user did anything to |
| 822 // indicate the desired match is a URL. For instance, "c/# foo" will not | 821 // indicate the desired match is a URL. For instance, "c/# foo" will not |
| 823 // pass the test because that will be classified as input type URL. The | 822 // pass the test because that will be classified as input type URL. The |
| 824 // parsed.CountCharactersBefore() in the test looks for the presence of a | 823 // parsed.CountCharactersBefore() in the test looks for the presence of a |
| 825 // reference fragment in the URL by checking whether the position differs | 824 // reference fragment in the URL by checking whether the position differs |
| 826 // included the delimiter (pound sign) versus not including the delimiter. | 825 // included the delimiter (pound sign) versus not including the delimiter. |
| 827 // (One cannot simply check url.ref() because it will not distinguish | 826 // (One cannot simply check url.ref() because it will not distinguish |
| 828 // between the input "c" and the input "c#", both of which will have empty | 827 // between the input "c" and the input "c#", both of which will have empty |
| 829 // reference fragments.) | 828 // reference fragments.) |
| 830 if ((type == UNVISITED_INTRANET) && | 829 if ((type == UNVISITED_INTRANET) && |
| 831 (input.type() != metrics::OmniboxInputType::URL) && | 830 (input.type() != AutocompleteInput::URL) && url.username().empty() && |
| 832 url.username().empty() && url.password().empty() && url.port().empty() && | 831 url.password().empty() && url.port().empty() && (url.path() == "/") && |
| 833 (url.path() == "/") && url.query().empty() && | 832 url.query().empty() && |
| 834 (parsed.CountCharactersBefore(url::Parsed::REF, true) != | 833 (parsed.CountCharactersBefore(url::Parsed::REF, true) != |
| 835 parsed.CountCharactersBefore(url::Parsed::REF, false))) { | 834 parsed.CountCharactersBefore(url::Parsed::REF, false))) { |
| 836 return false; | 835 return false; |
| 837 } | 836 } |
| 838 | 837 |
| 839 match->relevance = CalculateRelevance(type, 0); | 838 match->relevance = CalculateRelevance(type, 0); |
| 840 | 839 |
| 841 // If there are any other matches, then don't promote this match here, in | 840 // If there are any other matches, then don't promote this match here, in |
| 842 // hopes the caller will be able to inline autocomplete a better suggestion. | 841 // hopes the caller will be able to inline autocomplete a better suggestion. |
| 843 // DoAutocomplete() will fall back on this match if inline autocompletion | 842 // DoAutocomplete() will fall back on this match if inline autocompletion |
| 844 // fails. This matches how we react to never-visited URL inputs in the non- | 843 // fails. This matches how we react to never-visited URL inputs in the non- |
| 845 // intranet case. | 844 // intranet case. |
| 846 if (type == UNVISITED_INTRANET && !matches->empty()) | 845 if (type == UNVISITED_INTRANET && !matches->empty()) |
| 847 return false; | 846 return false; |
| 848 | 847 |
| 849 // Put it on the front of the HistoryMatches for redirect culling. | 848 // Put it on the front of the HistoryMatches for redirect culling. |
| 850 CreateOrPromoteMatch(classifier.url_row(), base::string16::npos, false, | 849 CreateOrPromoteMatch(classifier.url_row(), base::string16::npos, false, |
| 851 matches, true, true); | 850 matches, true, true); |
| 852 return true; | 851 return true; |
| 853 } | 852 } |
| 854 | 853 |
| 855 bool HistoryURLProvider::CanFindIntranetURL( | 854 bool HistoryURLProvider::CanFindIntranetURL( |
| 856 history::URLDatabase* db, | 855 history::URLDatabase* db, |
| 857 const AutocompleteInput& input) const { | 856 const AutocompleteInput& input) const { |
| 858 // Normally passing the first two conditions below ought to guarantee the | 857 // Normally passing the first two conditions below ought to guarantee the |
| 859 // third condition, but because FixupUserInput() can run and modify the | 858 // third condition, but because FixupUserInput() can run and modify the |
| 860 // input's text and parts between Parse() and here, it seems better to be | 859 // input's text and parts between Parse() and here, it seems better to be |
| 861 // paranoid and check. | 860 // paranoid and check. |
| 862 if ((input.type() != metrics::OmniboxInputType::UNKNOWN) || | 861 if ((input.type() != AutocompleteInput::UNKNOWN) || |
| 863 !LowerCaseEqualsASCII(input.scheme(), url::kHttpScheme) || | 862 !LowerCaseEqualsASCII(input.scheme(), url::kHttpScheme) || |
| 864 !input.parts().host.is_nonempty()) | 863 !input.parts().host.is_nonempty()) |
| 865 return false; | 864 return false; |
| 866 const std::string host(base::UTF16ToUTF8( | 865 const std::string host(base::UTF16ToUTF8( |
| 867 input.text().substr(input.parts().host.begin, input.parts().host.len))); | 866 input.text().substr(input.parts().host.begin, input.parts().host.len))); |
| 868 const size_t registry_length = | 867 const size_t registry_length = |
| 869 net::registry_controlled_domains::GetRegistryLength( | 868 net::registry_controlled_domains::GetRegistryLength( |
| 870 host, | 869 host, |
| 871 net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, | 870 net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, |
| 872 net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); | 871 net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1156 // If HistoryURL retrieves any matches (and hence we reach this code), we | 1155 // If HistoryURL retrieves any matches (and hence we reach this code), we |
| 1157 // are guaranteed that the beginning of input_text must be a word break. | 1156 // are guaranteed that the beginning of input_text must be a word break. |
| 1158 history::WordStarts offsets(1, 0u); | 1157 history::WordStarts offsets(1, 0u); |
| 1159 description_matches = | 1158 description_matches = |
| 1160 history::ScoredHistoryMatch::FilterTermMatchesByWordStarts( | 1159 history::ScoredHistoryMatch::FilterTermMatchesByWordStarts( |
| 1161 description_matches, offsets, description_word_starts, 0, | 1160 description_matches, offsets, description_word_starts, 0, |
| 1162 std::string::npos); | 1161 std::string::npos); |
| 1163 return SpansFromTermMatch( | 1162 return SpansFromTermMatch( |
| 1164 description_matches, clean_description.length(), false); | 1163 description_matches, clean_description.length(), false); |
| 1165 } | 1164 } |
| OLD | NEW |