Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Unified Diff: chrome/browser/autocomplete/base_search_provider.cc

Issue 131003011: Part 1 of search provider refactoring. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Line wrap fixes Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/autocomplete/base_search_provider.cc
diff --git a/chrome/browser/autocomplete/base_search_provider.cc b/chrome/browser/autocomplete/base_search_provider.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7dc72bd2315924a90a559052dffc4b50f9bead23
--- /dev/null
+++ b/chrome/browser/autocomplete/base_search_provider.cc
@@ -0,0 +1,238 @@
+// 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 "chrome/browser/autocomplete/base_search_provider.h"
+
+#include "base/strings/string16.h"
+#include "base/strings/string_util.h"
+#include "chrome/browser/autocomplete/autocomplete_input.h"
+#include "chrome/browser/autocomplete/autocomplete_match.h"
+#include "chrome/browser/autocomplete/autocomplete_provider.h"
+#include "chrome/browser/autocomplete/autocomplete_provider_listener.h"
+#include "chrome/browser/autocomplete/url_prefix.h"
+#include "chrome/browser/profiles/profile.h"
+#include "net/base/escape.h"
+#include "net/base/net_util.h"
+#include "net/url_request/url_fetcher_delegate.h"
+#include "url/gurl.h"
+
+// BaseSearchProvider ---------------------------------------------------------
+
+BaseSearchProvider::BaseSearchProvider(AutocompleteProviderListener* listener,
+ Profile* profile,
+ AutocompleteProvider::Type type)
+ : AutocompleteProvider(listener, profile, type) {}
+
+// BaseSearchProvider::Result --------------------------------------------------
+
+BaseSearchProvider::Result::Result(bool from_keyword_provider,
+ int relevance,
+ bool relevance_from_server)
+ : from_keyword_provider_(from_keyword_provider),
+ relevance_(relevance),
+ relevance_from_server_(relevance_from_server) {}
+
+BaseSearchProvider::Result::~Result() {}
+
+// BaseSearchProvider::SuggestResult -------------------------------------------
+
+BaseSearchProvider::SuggestResult::SuggestResult(
+ const base::string16& suggestion,
+ AutocompleteMatchType::Type type,
+ const base::string16& match_contents,
+ const base::string16& annotation,
+ const std::string& suggest_query_params,
+ const std::string& deletion_url,
+ bool from_keyword_provider,
+ int relevance,
+ bool relevance_from_server,
+ bool should_prefetch,
+ const base::string16& input_text)
+ : Result(from_keyword_provider, relevance, relevance_from_server),
+ suggestion_(suggestion),
+ type_(type),
+ annotation_(annotation),
+ suggest_query_params_(suggest_query_params),
+ deletion_url_(deletion_url),
+ should_prefetch_(should_prefetch) {
+ match_contents_ = match_contents;
+ DCHECK(!match_contents_.empty());
+ ClassifyMatchContents(true, input_text);
+}
+
+BaseSearchProvider::SuggestResult::~SuggestResult() {}
+
+void BaseSearchProvider::SuggestResult::ClassifyMatchContents(
+ const bool allow_bolding_all,
+ const base::string16& input_text) {
+ size_t input_position = match_contents_.find(input_text);
+ if (!allow_bolding_all && (input_position == base::string16::npos)) {
+ // Bail if the code below to update the bolding would bold the whole
+ // string. Note that the string may already be entirely bolded; if
+ // so, leave it as is.
+ return;
+ }
+ match_contents_class_.clear();
+ // We do intra-string highlighting for suggestions - the suggested segment
+ // will be highlighted, e.g. for input_text = "you" the suggestion may be
+ // "youtube", so we'll bold the "tube" section: you*tube*.
+ if (input_text != match_contents_) {
+ if (input_position == base::string16::npos) {
+ // The input text is not a substring of the query string, e.g. input
+ // text is "slasdot" and the query string is "slashdot", so we bold the
+ // whole thing.
+ match_contents_class_.push_back(
+ ACMatchClassification(0, ACMatchClassification::MATCH));
+ } else {
+ // We don't iterate over the string here annotating all matches because
+ // it looks odd to have every occurrence of a substring that may be as
+ // short as a single character highlighted in a query suggestion result,
+ // e.g. for input text "s" and query string "southwest airlines", it
+ // looks odd if both the first and last s are highlighted.
+ if (input_position != 0) {
+ match_contents_class_.push_back(
+ ACMatchClassification(0, ACMatchClassification::MATCH));
+ }
+ match_contents_class_.push_back(
+ ACMatchClassification(input_position, ACMatchClassification::NONE));
+ size_t next_fragment_position = input_position + input_text.length();
+ if (next_fragment_position < match_contents_.length()) {
+ match_contents_class_.push_back(ACMatchClassification(
+ next_fragment_position, ACMatchClassification::MATCH));
+ }
+ }
+ } else {
+ // Otherwise, match_contents_ is a verbatim (what-you-typed) match, either
+ // for the default provider or a keyword search provider.
+ match_contents_class_.push_back(
+ ACMatchClassification(0, ACMatchClassification::NONE));
+ }
+}
+
+bool BaseSearchProvider::SuggestResult::IsInlineable(
+ const base::string16& input) const {
+ return StartsWith(suggestion_, input, false);
+}
+
+int BaseSearchProvider::SuggestResult::CalculateRelevance(
+ const AutocompleteInput& input,
+ bool keyword_provider_requested) const {
+ if (!from_keyword_provider_ && keyword_provider_requested)
+ return 100;
+ return ((input.type() == AutocompleteInput::URL) ? 300 : 600);
+}
+
+// BaseSearchProvider::NavigationResult ----------------------------------------
+
+BaseSearchProvider::NavigationResult::NavigationResult(
+ const AutocompleteProvider& provider,
+ const GURL& url,
+ const base::string16& description,
+ bool from_keyword_provider,
+ int relevance,
+ bool relevance_from_server,
+ const base::string16& input_text,
+ const std::string& languages)
+ : Result(from_keyword_provider, relevance, relevance_from_server),
+ url_(url),
+ formatted_url_(AutocompleteInput::FormattedStringWithEquivalentMeaning(
+ url,
+ provider.StringForURLDisplay(url, true, false))),
+ description_(description) {
+ DCHECK(url_.is_valid());
+ CalculateAndClassifyMatchContents(true, input_text, languages);
+}
+
+BaseSearchProvider::NavigationResult::~NavigationResult() {}
+
+void BaseSearchProvider::NavigationResult::CalculateAndClassifyMatchContents(
+ const bool allow_bolding_nothing,
+ const base::string16& input_text,
+ const std::string& languages) {
+ // First look for the user's input inside the formatted url as it would be
+ // without trimming the scheme, so we can find matches at the beginning of the
+ // scheme.
+ const URLPrefix* prefix =
+ URLPrefix::BestURLPrefix(formatted_url_, input_text);
+ size_t match_start = (prefix == NULL) ? formatted_url_.find(input_text)
+ : prefix->prefix.length();
+ bool trim_http = !AutocompleteInput::HasHTTPScheme(input_text) &&
+ (!prefix || (match_start != 0));
+ const net::FormatUrlTypes format_types =
+ net::kFormatUrlOmitAll & ~(trim_http ? 0 : net::kFormatUrlOmitHTTP);
+
+ base::string16 match_contents = net::FormatUrl(url_,
+ languages,
+ format_types,
+ net::UnescapeRule::SPACES,
+ NULL,
+ NULL,
+ &match_start);
+ // If the first match in the untrimmed string was inside a scheme that we
+ // trimmed, look for a subsequent match.
+ if (match_start == base::string16::npos)
+ match_start = match_contents.find(input_text);
+ // Update |match_contents_| and |match_contents_class_| if it's allowed.
+ if (allow_bolding_nothing || (match_start != base::string16::npos)) {
+ match_contents_ = match_contents;
+ // Safe if |match_start| is npos; also safe if the input is longer than the
+ // remaining contents after |match_start|.
+ AutocompleteMatch::ClassifyLocationInString(match_start,
+ input_text.length(),
+ match_contents_.length(),
+ ACMatchClassification::URL,
+ &match_contents_class_);
+ }
+}
+
+bool BaseSearchProvider::NavigationResult::IsInlineable(
+ const base::string16& input) const {
+ return URLPrefix::BestURLPrefix(formatted_url_, input) != NULL;
+}
+
+int BaseSearchProvider::NavigationResult::CalculateRelevance(
+ const AutocompleteInput& input,
+ bool keyword_provider_requested) const {
+ return (from_keyword_provider_ || !keyword_provider_requested) ? 800 : 150;
+}
+
+// BaseSearchProvider::Results -------------------------------------------------
+
+BaseSearchProvider::Results::Results() : verbatim_relevance(-1) {}
+
+BaseSearchProvider::Results::~Results() {}
+
+void BaseSearchProvider::Results::Clear() {
+ suggest_results.clear();
+ navigation_results.clear();
+ verbatim_relevance = -1;
+ metadata.clear();
+}
+
+bool BaseSearchProvider::Results::HasServerProvidedScores() const {
+ if (verbatim_relevance >= 0)
+ return true;
+
+ // Right now either all results of one type will be server-scored or they will
+ // all be locally scored, but in case we change this later, we'll just check
+ // them all.
+ for (SuggestResults::const_iterator i(suggest_results.begin());
+ i != suggest_results.end();
+ ++i) {
+ if (i->relevance_from_server())
+ return true;
+ }
+ for (NavigationResults::const_iterator i(navigation_results.begin());
+ i != navigation_results.end();
+ ++i) {
+ if (i->relevance_from_server())
+ return true;
+ }
+
+ return false;
+}
+
+// BaseSearchProvider ---------------------------------------------------------
+
+BaseSearchProvider::~BaseSearchProvider() {}

Powered by Google App Engine
This is Rietveld 408576698