| // Copyright (c) 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/omnibox/browser/titled_url_match_utils.h" |
| |
| #include <vector> |
| |
| #include "base/strings/string_util.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "components/bookmarks/browser/titled_url_node.h" |
| #include "components/omnibox/browser/autocomplete_match.h" |
| #include "components/omnibox/browser/autocomplete_match_classification.h" |
| #include "components/omnibox/browser/history_provider.h" |
| #include "components/omnibox/browser/in_memory_url_index_types.h" |
| #include "components/omnibox/browser/url_prefix.h" |
| #include "components/url_formatter/url_formatter.h" |
| |
| namespace bookmarks { |
| |
| AutocompleteMatch TitledUrlMatchToAutocompleteMatch( |
| const TitledUrlMatch& titled_url_match, |
| AutocompleteMatchType::Type type, |
| int relevance, |
| AutocompleteProvider* provider, |
| const AutocompleteSchemeClassifier& scheme_classifier, |
| const AutocompleteInput& input, |
| const base::string16& fixed_up_input_text) { |
| const GURL& url = titled_url_match.node->GetTitledUrlNodeUrl(); |
| |
| // The AutocompleteMatch we construct is non-deletable because the only way to |
| // support this would be to delete the underlying object that created the |
| // titled_url_match. E.g., for the bookmark provider this would mean deleting |
| // the underlying bookmark, which is unlikely to be what the user intends. |
| AutocompleteMatch match(provider, relevance, false, type); |
| const base::string16& url_utf16 = base::UTF8ToUTF16(url.spec()); |
| match.destination_url = url; |
| |
| bool match_in_scheme = false; |
| bool match_in_subdomain = false; |
| AutocompleteMatch::GetMatchComponents(url, |
| titled_url_match.url_match_positions, |
| &match_in_scheme, &match_in_subdomain); |
| auto format_types = AutocompleteMatch::GetFormatTypes( |
| input.parts().scheme.len > 0 || match_in_scheme, match_in_subdomain); |
| |
| match.contents = url_formatter::FormatUrl( |
| url, format_types, net::UnescapeRule::SPACES, nullptr, nullptr, nullptr); |
| // Bookmark classification diverges from relevance scoring. Specifically, |
| // 1) All occurrences of the input contribute to relevance; e.g. for the input |
| // 'pre', the bookmark 'pre prefix' will be scored higher than 'pre suffix'. |
| // For classification though, if the input is a prefix of the suggestion text, |
| // only the prefix will be bolded; e.g. the 1st bookmark will display '[pre] |
| // prefix' as opposed to '[pre] [pre]fix'. This divergence allows consistency |
| // with other providers' and google.com's bolding. |
| // 2) Non-complete-word matches less than 3 characters long do not contribute |
| // to relevance; e.g. for the input 'a pr', the bookmark 'a pr prefix' will be |
| // scored the same as 'a pr suffix'. For classification though, both |
| // occurrences will be bolded, 'a [pr] [pr]efix'. |
| auto contents_terms = FindTermMatches(input.text(), match.contents); |
| match.contents_class = ClassifyTermMatches( |
| contents_terms, match.contents.length(), |
| ACMatchClassification::MATCH | ACMatchClassification::URL, |
| ACMatchClassification::URL); |
| |
| // The inline_autocomplete_offset should be adjusted based on the formatting |
| // applied to |fill_into_edit|. |
| size_t inline_autocomplete_offset = URLPrefix::GetInlineAutocompleteOffset( |
| input.text(), fixed_up_input_text, false, url_utf16); |
| auto fill_into_edit_format_types = url_formatter::kFormatUrlOmitDefaults; |
| if (match_in_scheme) |
| fill_into_edit_format_types &= ~url_formatter::kFormatUrlOmitHTTP; |
| match.fill_into_edit = |
| AutocompleteInput::FormattedStringWithEquivalentMeaning( |
| url, |
| url_formatter::FormatUrl(url, fill_into_edit_format_types, |
| net::UnescapeRule::SPACES, nullptr, nullptr, |
| &inline_autocomplete_offset), |
| scheme_classifier, &inline_autocomplete_offset); |
| if (inline_autocomplete_offset != base::string16::npos) { |
| match.inline_autocompletion = |
| match.fill_into_edit.substr(inline_autocomplete_offset); |
| match.allowed_to_be_default_match = |
| AutocompleteMatch::AllowedToBeDefault(input, match); |
| } |
| match.description = titled_url_match.node->GetTitledUrlNodeTitle(); |
| base::TrimWhitespace(match.description, base::TRIM_LEADING, |
| &match.description); |
| auto description_terms = FindTermMatches(input.text(), match.description); |
| match.description_class = ClassifyTermMatches( |
| description_terms, match.description.length(), |
| ACMatchClassification::MATCH, ACMatchClassification::NONE); |
| |
| return match; |
| } |
| |
| } // namespace bookmarks |