Index: components/autocomplete/autocomplete_match.cc |
diff --git a/components/autocomplete/autocomplete_match.cc b/components/autocomplete/autocomplete_match.cc |
deleted file mode 100644 |
index 7aafcb1fc82ac35bedd674f0be2114357c65faf5..0000000000000000000000000000000000000000 |
--- a/components/autocomplete/autocomplete_match.cc |
+++ /dev/null |
@@ -1,543 +0,0 @@ |
-// Copyright 2014 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/autocomplete/autocomplete_match.h" |
- |
-#include "base/i18n/time_formatting.h" |
-#include "base/logging.h" |
-#include "base/strings/string16.h" |
-#include "base/strings/string_number_conversions.h" |
-#include "base/strings/string_util.h" |
-#include "base/strings/utf_string_conversions.h" |
-#include "base/time/time.h" |
-#include "components/autocomplete/autocomplete_provider.h" |
-#include "components/search_engines/template_url.h" |
-#include "components/search_engines/template_url_service.h" |
-#include "grit/component_scaled_resources.h" |
- |
-namespace { |
- |
-bool IsTrivialClassification(const ACMatchClassifications& classifications) { |
- return classifications.empty() || |
- ((classifications.size() == 1) && |
- (classifications.back().style == ACMatchClassification::NONE)); |
-} |
- |
-} // namespace |
- |
-// AutocompleteMatch ---------------------------------------------------------- |
- |
-// static |
-const base::char16 AutocompleteMatch::kInvalidChars[] = { |
- '\n', '\r', '\t', |
- 0x2028, // Line separator |
- 0x2029, // Paragraph separator |
- 0 |
-}; |
- |
-AutocompleteMatch::AutocompleteMatch() |
- : provider(NULL), |
- relevance(0), |
- typed_count(-1), |
- deletable(false), |
- allowed_to_be_default_match(false), |
- transition(content::PAGE_TRANSITION_GENERATED), |
- is_history_what_you_typed_match(false), |
- type(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED), |
- from_previous(false) { |
-} |
- |
-AutocompleteMatch::AutocompleteMatch(AutocompleteProvider* provider, |
- int relevance, |
- bool deletable, |
- Type type) |
- : provider(provider), |
- relevance(relevance), |
- typed_count(-1), |
- deletable(deletable), |
- allowed_to_be_default_match(false), |
- transition(content::PAGE_TRANSITION_TYPED), |
- is_history_what_you_typed_match(false), |
- type(type), |
- from_previous(false) { |
-} |
- |
-AutocompleteMatch::AutocompleteMatch(const AutocompleteMatch& match) |
- : provider(match.provider), |
- relevance(match.relevance), |
- typed_count(match.typed_count), |
- deletable(match.deletable), |
- fill_into_edit(match.fill_into_edit), |
- inline_autocompletion(match.inline_autocompletion), |
- allowed_to_be_default_match(match.allowed_to_be_default_match), |
- destination_url(match.destination_url), |
- stripped_destination_url(match.stripped_destination_url), |
- contents(match.contents), |
- contents_class(match.contents_class), |
- description(match.description), |
- description_class(match.description_class), |
- answer_contents(match.answer_contents), |
- answer_type(match.answer_type), |
- transition(match.transition), |
- is_history_what_you_typed_match(match.is_history_what_you_typed_match), |
- type(match.type), |
- associated_keyword(match.associated_keyword.get() ? |
- new AutocompleteMatch(*match.associated_keyword) : NULL), |
- keyword(match.keyword), |
- from_previous(match.from_previous), |
- search_terms_args(match.search_terms_args.get() ? |
- new TemplateURLRef::SearchTermsArgs(*match.search_terms_args) : |
- NULL), |
- additional_info(match.additional_info), |
- duplicate_matches(match.duplicate_matches) { |
-} |
- |
-AutocompleteMatch::~AutocompleteMatch() { |
-} |
- |
-AutocompleteMatch& AutocompleteMatch::operator=( |
- const AutocompleteMatch& match) { |
- if (this == &match) |
- return *this; |
- |
- provider = match.provider; |
- relevance = match.relevance; |
- typed_count = match.typed_count; |
- deletable = match.deletable; |
- fill_into_edit = match.fill_into_edit; |
- inline_autocompletion = match.inline_autocompletion; |
- allowed_to_be_default_match = match.allowed_to_be_default_match; |
- destination_url = match.destination_url; |
- stripped_destination_url = match.stripped_destination_url; |
- contents = match.contents; |
- contents_class = match.contents_class; |
- description = match.description; |
- description_class = match.description_class; |
- answer_contents = match.answer_contents; |
- answer_type = match.answer_type; |
- transition = match.transition; |
- is_history_what_you_typed_match = match.is_history_what_you_typed_match; |
- type = match.type; |
- associated_keyword.reset(match.associated_keyword.get() ? |
- new AutocompleteMatch(*match.associated_keyword) : NULL); |
- keyword = match.keyword; |
- from_previous = match.from_previous; |
- search_terms_args.reset(match.search_terms_args.get() ? |
- new TemplateURLRef::SearchTermsArgs(*match.search_terms_args) : NULL); |
- additional_info = match.additional_info; |
- duplicate_matches = match.duplicate_matches; |
- return *this; |
-} |
- |
-// static |
-int AutocompleteMatch::TypeToIcon(Type type) { |
- int icons[] = { |
- IDR_OMNIBOX_HTTP, |
- IDR_OMNIBOX_HTTP, |
- IDR_OMNIBOX_HTTP, |
- IDR_OMNIBOX_HTTP, |
- IDR_OMNIBOX_HTTP, |
- IDR_OMNIBOX_HTTP, |
- IDR_OMNIBOX_SEARCH, |
- IDR_OMNIBOX_SEARCH, |
- IDR_OMNIBOX_SEARCH, |
- IDR_OMNIBOX_SEARCH, |
- IDR_OMNIBOX_SEARCH, |
- IDR_OMNIBOX_SEARCH, |
- IDR_OMNIBOX_SEARCH, |
- IDR_OMNIBOX_SEARCH, |
- IDR_OMNIBOX_EXTENSION_APP, |
- IDR_OMNIBOX_SEARCH, |
- IDR_OMNIBOX_HTTP, |
- IDR_OMNIBOX_HTTP, |
- IDR_OMNIBOX_SEARCH, |
- }; |
- COMPILE_ASSERT(arraysize(icons) == AutocompleteMatchType::NUM_TYPES, |
- icons_array_must_match_type_enum); |
- return icons[type]; |
-} |
- |
-// static |
-bool AutocompleteMatch::MoreRelevant(const AutocompleteMatch& elem1, |
- const AutocompleteMatch& elem2) { |
- // For equal-relevance matches, we sort alphabetically, so that providers |
- // who return multiple elements at the same priority get a "stable" sort |
- // across multiple updates. |
- return (elem1.relevance == elem2.relevance) ? |
- (elem1.contents < elem2.contents) : (elem1.relevance > elem2.relevance); |
-} |
- |
-// static |
-bool AutocompleteMatch::DestinationsEqual(const AutocompleteMatch& elem1, |
- const AutocompleteMatch& elem2) { |
- if (elem1.stripped_destination_url.is_empty() && |
- elem2.stripped_destination_url.is_empty()) |
- return false; |
- return elem1.stripped_destination_url == elem2.stripped_destination_url; |
-} |
- |
-// static |
-void AutocompleteMatch::ClassifyMatchInString( |
- const base::string16& find_text, |
- const base::string16& text, |
- int style, |
- ACMatchClassifications* classification) { |
- ClassifyLocationInString(text.find(find_text), find_text.length(), |
- text.length(), style, classification); |
-} |
- |
-// static |
-void AutocompleteMatch::ClassifyLocationInString( |
- size_t match_location, |
- size_t match_length, |
- size_t overall_length, |
- int style, |
- ACMatchClassifications* classification) { |
- classification->clear(); |
- |
- // Don't classify anything about an empty string |
- // (AutocompleteMatch::Validate() checks this). |
- if (overall_length == 0) |
- return; |
- |
- // Mark pre-match portion of string (if any). |
- if (match_location != 0) { |
- classification->push_back(ACMatchClassification(0, style)); |
- } |
- |
- // Mark matching portion of string. |
- if (match_location == base::string16::npos) { |
- // No match, above classification will suffice for whole string. |
- return; |
- } |
- // Classifying an empty match makes no sense and will lead to validation |
- // errors later. |
- DCHECK_GT(match_length, 0U); |
- classification->push_back(ACMatchClassification(match_location, |
- (style | ACMatchClassification::MATCH) & ~ACMatchClassification::DIM)); |
- |
- // Mark post-match portion of string (if any). |
- const size_t after_match(match_location + match_length); |
- if (after_match < overall_length) { |
- classification->push_back(ACMatchClassification(after_match, style)); |
- } |
-} |
- |
-// static |
-AutocompleteMatch::ACMatchClassifications |
- AutocompleteMatch::MergeClassifications( |
- const ACMatchClassifications& classifications1, |
- const ACMatchClassifications& classifications2) { |
- // We must return the empty vector only if both inputs are truly empty. |
- // The result of merging an empty vector with a single (0, NONE) |
- // classification is the latter one-entry vector. |
- if (IsTrivialClassification(classifications1)) |
- return classifications2.empty() ? classifications1 : classifications2; |
- if (IsTrivialClassification(classifications2)) |
- return classifications1; |
- |
- ACMatchClassifications output; |
- for (ACMatchClassifications::const_iterator i = classifications1.begin(), |
- j = classifications2.begin(); i != classifications1.end();) { |
- AutocompleteMatch::AddLastClassificationIfNecessary(&output, |
- std::max(i->offset, j->offset), i->style | j->style); |
- const size_t next_i_offset = (i + 1) == classifications1.end() ? |
- static_cast<size_t>(-1) : (i + 1)->offset; |
- const size_t next_j_offset = (j + 1) == classifications2.end() ? |
- static_cast<size_t>(-1) : (j + 1)->offset; |
- if (next_i_offset >= next_j_offset) |
- ++j; |
- if (next_j_offset >= next_i_offset) |
- ++i; |
- } |
- |
- return output; |
-} |
- |
-// static |
-std::string AutocompleteMatch::ClassificationsToString( |
- const ACMatchClassifications& classifications) { |
- std::string serialized_classifications; |
- for (size_t i = 0; i < classifications.size(); ++i) { |
- if (i) |
- serialized_classifications += ','; |
- serialized_classifications += base::IntToString(classifications[i].offset) + |
- ',' + base::IntToString(classifications[i].style); |
- } |
- return serialized_classifications; |
-} |
- |
-// static |
-ACMatchClassifications AutocompleteMatch::ClassificationsFromString( |
- const std::string& serialized_classifications) { |
- ACMatchClassifications classifications; |
- std::vector<std::string> tokens; |
- Tokenize(serialized_classifications, ",", &tokens); |
- DCHECK(!(tokens.size() & 1)); // The number of tokens should be even. |
- for (size_t i = 0; i < tokens.size(); i += 2) { |
- int classification_offset = 0; |
- int classification_style = ACMatchClassification::NONE; |
- if (!base::StringToInt(tokens[i], &classification_offset) || |
- !base::StringToInt(tokens[i + 1], &classification_style)) { |
- NOTREACHED(); |
- return classifications; |
- } |
- classifications.push_back(ACMatchClassification(classification_offset, |
- classification_style)); |
- } |
- return classifications; |
-} |
- |
-// static |
-void AutocompleteMatch::AddLastClassificationIfNecessary( |
- ACMatchClassifications* classifications, |
- size_t offset, |
- int style) { |
- DCHECK(classifications); |
- if (classifications->empty() || classifications->back().style != style) { |
- DCHECK(classifications->empty() || |
- (offset > classifications->back().offset)); |
- classifications->push_back(ACMatchClassification(offset, style)); |
- } |
-} |
- |
-// static |
-base::string16 AutocompleteMatch::SanitizeString(const base::string16& text) { |
- // NOTE: This logic is mirrored by |sanitizeString()| in |
- // omnibox_custom_bindings.js. |
- base::string16 result; |
- base::TrimWhitespace(text, base::TRIM_LEADING, &result); |
- base::RemoveChars(result, kInvalidChars, &result); |
- return result; |
-} |
- |
-// static |
-bool AutocompleteMatch::IsSearchType(Type type) { |
- return type == AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED || |
- type == AutocompleteMatchType::SEARCH_HISTORY || |
- type == AutocompleteMatchType::SEARCH_SUGGEST || |
- type == AutocompleteMatchType::SEARCH_OTHER_ENGINE || |
- IsSpecializedSearchType(type); |
-} |
- |
-// static |
-bool AutocompleteMatch::IsSpecializedSearchType(Type type) { |
- return type == AutocompleteMatchType::SEARCH_SUGGEST_ENTITY || |
- type == AutocompleteMatchType::SEARCH_SUGGEST_INFINITE || |
- type == AutocompleteMatchType::SEARCH_SUGGEST_PERSONALIZED || |
- type == AutocompleteMatchType::SEARCH_SUGGEST_PROFILE || |
- type == AutocompleteMatchType::SEARCH_SUGGEST_ANSWER; |
-} |
- |
-// static |
-TemplateURL* AutocompleteMatch::GetTemplateURLWithKeyword( |
- TemplateURLService* template_url_service, |
- const base::string16& keyword, |
- const std::string& host) { |
- if (template_url_service == NULL) |
- return NULL; |
- TemplateURL* template_url = keyword.empty() ? |
- NULL : template_url_service->GetTemplateURLForKeyword(keyword); |
- return (template_url || host.empty()) ? |
- template_url : template_url_service->GetTemplateURLForHost(host); |
-} |
- |
-// static |
-GURL AutocompleteMatch::GURLToStrippedGURL( |
- const GURL& url, |
- TemplateURLService* template_url_service, |
- const base::string16& keyword) { |
- if (!url.is_valid()) |
- return url; |
- |
- GURL stripped_destination_url = url; |
- |
- // If the destination URL looks like it was generated from a TemplateURL, |
- // remove all substitutions other than the search terms. This allows us |
- // to eliminate cases like past search URLs from history that differ only |
- // by some obscure query param from each other or from the search/keyword |
- // provider matches. |
- TemplateURL* template_url = GetTemplateURLWithKeyword( |
- template_url_service, keyword, stripped_destination_url.host()); |
- if (template_url != NULL && |
- template_url->SupportsReplacement( |
- template_url_service->search_terms_data())) { |
- base::string16 search_terms; |
- if (template_url->ExtractSearchTermsFromURL( |
- stripped_destination_url, |
- template_url_service->search_terms_data(), |
- &search_terms)) { |
- stripped_destination_url = |
- GURL(template_url->url_ref().ReplaceSearchTerms( |
- TemplateURLRef::SearchTermsArgs(search_terms), |
- template_url_service->search_terms_data())); |
- } |
- } |
- |
- // |replacements| keeps all the substitions we're going to make to |
- // from {destination_url} to {stripped_destination_url}. |need_replacement| |
- // is a helper variable that helps us keep track of whether we need |
- // to apply the replacement. |
- bool needs_replacement = false; |
- GURL::Replacements replacements; |
- |
- // Remove the www. prefix from the host. |
- static const char prefix[] = "www."; |
- static const size_t prefix_len = arraysize(prefix) - 1; |
- std::string host = stripped_destination_url.host(); |
- if (host.compare(0, prefix_len, prefix) == 0) { |
- host = host.substr(prefix_len); |
- replacements.SetHostStr(host); |
- needs_replacement = true; |
- } |
- |
- // Replace https protocol with http protocol. |
- if (stripped_destination_url.SchemeIs(url::kHttpsScheme)) { |
- replacements.SetScheme(url::kHttpScheme, |
- url::Component(0, strlen(url::kHttpScheme))); |
- needs_replacement = true; |
- } |
- |
- if (needs_replacement) |
- stripped_destination_url = stripped_destination_url.ReplaceComponents( |
- replacements); |
- return stripped_destination_url; |
-} |
- |
-void AutocompleteMatch::ComputeStrippedDestinationURL( |
- TemplateURLService* template_url_service) { |
- stripped_destination_url = |
- GURLToStrippedGURL(destination_url, template_url_service, keyword); |
-} |
- |
-void AutocompleteMatch::EnsureUWYTIsAllowedToBeDefault( |
- const GURL& canonical_input_url, |
- TemplateURLService* template_url_service) { |
- if (!allowed_to_be_default_match) { |
- const GURL& stripped_canonical_input_url = |
- AutocompleteMatch::GURLToStrippedGURL( |
- canonical_input_url, template_url_service, base::string16()); |
- ComputeStrippedDestinationURL(template_url_service); |
- allowed_to_be_default_match = |
- stripped_canonical_input_url == stripped_destination_url; |
- } |
-} |
- |
-void AutocompleteMatch::GetKeywordUIState( |
- TemplateURLService* template_url_service, |
- base::string16* keyword, |
- bool* is_keyword_hint) const { |
- *is_keyword_hint = associated_keyword.get() != NULL; |
- keyword->assign(*is_keyword_hint ? associated_keyword->keyword : |
- GetSubstitutingExplicitlyInvokedKeyword(template_url_service)); |
-} |
- |
-base::string16 AutocompleteMatch::GetSubstitutingExplicitlyInvokedKeyword( |
- TemplateURLService* template_url_service) const { |
- if (transition != content::PAGE_TRANSITION_KEYWORD || |
- template_url_service == NULL) { |
- return base::string16(); |
- } |
- |
- const TemplateURL* t_url = GetTemplateURL(template_url_service, false); |
- return (t_url && |
- t_url->SupportsReplacement( |
- template_url_service->search_terms_data())) ? |
- keyword : base::string16(); |
-} |
- |
-TemplateURL* AutocompleteMatch::GetTemplateURL( |
- TemplateURLService* template_url_service, |
- bool allow_fallback_to_destination_host) const { |
- return GetTemplateURLWithKeyword( |
- template_url_service, keyword, |
- allow_fallback_to_destination_host ? |
- destination_url.host() : std::string()); |
-} |
- |
-void AutocompleteMatch::RecordAdditionalInfo(const std::string& property, |
- const std::string& value) { |
- DCHECK(!property.empty()); |
- DCHECK(!value.empty()); |
- additional_info[property] = value; |
-} |
- |
-void AutocompleteMatch::RecordAdditionalInfo(const std::string& property, |
- int value) { |
- RecordAdditionalInfo(property, base::IntToString(value)); |
-} |
- |
-void AutocompleteMatch::RecordAdditionalInfo(const std::string& property, |
- const base::Time& value) { |
- RecordAdditionalInfo(property, |
- base::UTF16ToUTF8( |
- base::TimeFormatShortDateAndTime(value))); |
-} |
- |
-std::string AutocompleteMatch::GetAdditionalInfo( |
- const std::string& property) const { |
- AdditionalInfo::const_iterator i(additional_info.find(property)); |
- return (i == additional_info.end()) ? std::string() : i->second; |
-} |
- |
-bool AutocompleteMatch::IsVerbatimType() const { |
- const bool is_keyword_verbatim_match = |
- (type == AutocompleteMatchType::SEARCH_OTHER_ENGINE && |
- provider != NULL && |
- provider->type() == AutocompleteProvider::TYPE_SEARCH); |
- return type == AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED || |
- type == AutocompleteMatchType::URL_WHAT_YOU_TYPED || |
- is_keyword_verbatim_match; |
-} |
- |
-bool AutocompleteMatch::SupportsDeletion() const { |
- if (deletable) |
- return true; |
- |
- for (ACMatches::const_iterator it(duplicate_matches.begin()); |
- it != duplicate_matches.end(); ++it) { |
- if (it->deletable) |
- return true; |
- } |
- return false; |
-} |
- |
-#ifndef NDEBUG |
-void AutocompleteMatch::Validate() const { |
- ValidateClassifications(contents, contents_class); |
- ValidateClassifications(description, description_class); |
-} |
- |
-void AutocompleteMatch::ValidateClassifications( |
- const base::string16& text, |
- const ACMatchClassifications& classifications) const { |
- if (text.empty()) { |
- DCHECK(classifications.empty()); |
- return; |
- } |
- |
- // The classifications should always cover the whole string. |
- DCHECK(!classifications.empty()) << "No classification for \"" << text << '"'; |
- DCHECK_EQ(0U, classifications[0].offset) |
- << "Classification misses beginning for \"" << text << '"'; |
- if (classifications.size() == 1) |
- return; |
- |
- // The classifications should always be sorted. |
- size_t last_offset = classifications[0].offset; |
- for (ACMatchClassifications::const_iterator i(classifications.begin() + 1); |
- i != classifications.end(); ++i) { |
- const char* provider_name = provider ? provider->GetName() : "None"; |
- DCHECK_GT(i->offset, last_offset) |
- << " Classification for \"" << text << "\" with offset of " << i->offset |
- << " is unsorted in relation to last offset of " << last_offset |
- << ". Provider: " << provider_name << "."; |
- DCHECK_LT(i->offset, text.length()) |
- << " Classification of [" << i->offset << "," << text.length() |
- << "] is out of bounds for \"" << text << "\". Provider: " |
- << provider_name << "."; |
- last_offset = i->offset; |
- } |
-} |
-#endif |