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