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

Side by Side 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: Address comments Created 6 years, 10 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/autocomplete/base_search_provider.h"
6
7 #include "base/strings/string_util.h"
8 #include "chrome/browser/autocomplete/autocomplete_provider_listener.h"
9 #include "chrome/browser/autocomplete/url_prefix.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "net/base/escape.h"
12 #include "net/base/net_util.h"
13
14 // BaseSearchProvider ---------------------------------------------------------
15
16 BaseSearchProvider::BaseSearchProvider(AutocompleteProviderListener* listener,
17 Profile* profile,
18 AutocompleteProvider::Type type)
19 : AutocompleteProvider(listener, profile, type) {}
20
21 BaseSearchProvider::~BaseSearchProvider() {}
22
23 // BaseSearchProvider::Result --------------------------------------------------
24
25 BaseSearchProvider::Result::Result(bool from_keyword_provider,
26 int relevance,
27 bool relevance_from_server)
28 : from_keyword_provider_(from_keyword_provider),
29 relevance_(relevance),
30 relevance_from_server_(relevance_from_server) {}
31
32 BaseSearchProvider::Result::~Result() {}
33
34 // BaseSearchProvider::SuggestResult -------------------------------------------
35
36 BaseSearchProvider::SuggestResult::SuggestResult(
37 const base::string16& suggestion,
38 AutocompleteMatchType::Type type,
39 const base::string16& match_contents,
40 const base::string16& annotation,
41 const std::string& suggest_query_params,
42 const std::string& deletion_url,
43 bool from_keyword_provider,
44 int relevance,
45 bool relevance_from_server,
46 bool should_prefetch,
47 const base::string16& input_text)
48 : Result(from_keyword_provider, relevance, relevance_from_server),
49 suggestion_(suggestion),
50 type_(type),
51 annotation_(annotation),
52 suggest_query_params_(suggest_query_params),
53 deletion_url_(deletion_url),
54 should_prefetch_(should_prefetch) {
55 match_contents_ = match_contents;
56 DCHECK(!match_contents_.empty());
57 ClassifyMatchContents(true, input_text);
58 }
59
60 BaseSearchProvider::SuggestResult::~SuggestResult() {}
61
62 void BaseSearchProvider::SuggestResult::ClassifyMatchContents(
63 const bool allow_bolding_all,
64 const base::string16& input_text) {
65 size_t input_position = match_contents_.find(input_text);
66 if (!allow_bolding_all && (input_position == base::string16::npos)) {
67 // Bail if the code below to update the bolding would bold the whole
68 // string. Note that the string may already be entirely bolded; if
69 // so, leave it as is.
70 return;
71 }
72 match_contents_class_.clear();
73 // We do intra-string highlighting for suggestions - the suggested segment
74 // will be highlighted, e.g. for input_text = "you" the suggestion may be
75 // "youtube", so we'll bold the "tube" section: you*tube*.
76 if (input_text != match_contents_) {
77 if (input_position == base::string16::npos) {
78 // The input text is not a substring of the query string, e.g. input
79 // text is "slasdot" and the query string is "slashdot", so we bold the
80 // whole thing.
81 match_contents_class_.push_back(
82 ACMatchClassification(0, ACMatchClassification::MATCH));
83 } else {
84 // We don't iterate over the string here annotating all matches because
85 // it looks odd to have every occurrence of a substring that may be as
86 // short as a single character highlighted in a query suggestion result,
87 // e.g. for input text "s" and query string "southwest airlines", it
88 // looks odd if both the first and last s are highlighted.
89 if (input_position != 0) {
90 match_contents_class_.push_back(
91 ACMatchClassification(0, ACMatchClassification::MATCH));
92 }
93 match_contents_class_.push_back(
94 ACMatchClassification(input_position, ACMatchClassification::NONE));
95 size_t next_fragment_position = input_position + input_text.length();
96 if (next_fragment_position < match_contents_.length()) {
97 match_contents_class_.push_back(ACMatchClassification(
98 next_fragment_position, ACMatchClassification::MATCH));
99 }
100 }
101 } else {
102 // Otherwise, match_contents_ is a verbatim (what-you-typed) match, either
103 // for the default provider or a keyword search provider.
104 match_contents_class_.push_back(
105 ACMatchClassification(0, ACMatchClassification::NONE));
106 }
107 }
108
109 bool BaseSearchProvider::SuggestResult::IsInlineable(
110 const base::string16& input) const {
111 return StartsWith(suggestion_, input, false);
112 }
113
114 int BaseSearchProvider::SuggestResult::CalculateRelevance(
115 const AutocompleteInput& input,
116 bool keyword_provider_requested) const {
117 if (!from_keyword_provider_ && keyword_provider_requested)
118 return 100;
119 return ((input.type() == AutocompleteInput::URL) ? 300 : 600);
120 }
121
122 // BaseSearchProvider::NavigationResult ----------------------------------------
123
124 BaseSearchProvider::NavigationResult::NavigationResult(
125 const AutocompleteProvider& provider,
126 const GURL& url,
127 const base::string16& description,
128 bool from_keyword_provider,
129 int relevance,
130 bool relevance_from_server,
131 const base::string16& input_text,
132 const std::string& languages)
133 : Result(from_keyword_provider, relevance, relevance_from_server),
134 url_(url),
135 formatted_url_(AutocompleteInput::FormattedStringWithEquivalentMeaning(
136 url,
137 provider.StringForURLDisplay(url, true, false))),
138 description_(description) {
139 DCHECK(url_.is_valid());
140 CalculateAndClassifyMatchContents(true, input_text, languages);
141 }
142
143 BaseSearchProvider::NavigationResult::~NavigationResult() {}
144
145 void BaseSearchProvider::NavigationResult::CalculateAndClassifyMatchContents(
146 const bool allow_bolding_nothing,
147 const base::string16& input_text,
148 const std::string& languages) {
149 // First look for the user's input inside the formatted url as it would be
150 // without trimming the scheme, so we can find matches at the beginning of the
151 // scheme.
152 const URLPrefix* prefix =
153 URLPrefix::BestURLPrefix(formatted_url_, input_text);
154 size_t match_start = (prefix == NULL) ? formatted_url_.find(input_text)
155 : prefix->prefix.length();
156 bool trim_http = !AutocompleteInput::HasHTTPScheme(input_text) &&
157 (!prefix || (match_start != 0));
158 const net::FormatUrlTypes format_types =
159 net::kFormatUrlOmitAll & ~(trim_http ? 0 : net::kFormatUrlOmitHTTP);
160
161 base::string16 match_contents = net::FormatUrl(url_, languages, format_types,
162 net::UnescapeRule::SPACES, NULL, NULL, &match_start);
163 // If the first match in the untrimmed string was inside a scheme that we
164 // trimmed, look for a subsequent match.
165 if (match_start == base::string16::npos)
166 match_start = match_contents.find(input_text);
167 // Update |match_contents_| and |match_contents_class_| if it's allowed.
168 if (allow_bolding_nothing || (match_start != base::string16::npos)) {
169 match_contents_ = match_contents;
170 // Safe if |match_start| is npos; also safe if the input is longer than the
171 // remaining contents after |match_start|.
172 AutocompleteMatch::ClassifyLocationInString(match_start,
173 input_text.length(), match_contents_.length(),
174 ACMatchClassification::URL, &match_contents_class_);
175 }
176 }
177
178 bool BaseSearchProvider::NavigationResult::IsInlineable(
179 const base::string16& input) const {
180 return URLPrefix::BestURLPrefix(formatted_url_, input) != NULL;
181 }
182
183 int BaseSearchProvider::NavigationResult::CalculateRelevance(
184 const AutocompleteInput& input,
185 bool keyword_provider_requested) const {
186 return (from_keyword_provider_ || !keyword_provider_requested) ? 800 : 150;
187 }
188
189 // BaseSearchProvider::Results -------------------------------------------------
190
191 BaseSearchProvider::Results::Results() : verbatim_relevance(-1) {}
192
193 BaseSearchProvider::Results::~Results() {}
194
195 void BaseSearchProvider::Results::Clear() {
196 suggest_results.clear();
197 navigation_results.clear();
198 verbatim_relevance = -1;
199 metadata.clear();
200 }
201
202 bool BaseSearchProvider::Results::HasServerProvidedScores() const {
203 if (verbatim_relevance >= 0)
204 return true;
205
206 // Right now either all results of one type will be server-scored or they will
207 // all be locally scored, but in case we change this later, we'll just check
208 // them all.
209 for (SuggestResults::const_iterator i(suggest_results.begin());
210 i != suggest_results.end(); ++i) {
211 if (i->relevance_from_server())
212 return true;
213 }
214 for (NavigationResults::const_iterator i(navigation_results.begin());
215 i != navigation_results.end(); ++i) {
216 if (i->relevance_from_server())
217 return true;
218 }
219
220 return false;
221 }
222
OLDNEW
« no previous file with comments | « chrome/browser/autocomplete/base_search_provider.h ('k') | chrome/browser/autocomplete/search_provider.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698