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

Side by Side Diff: chrome/browser/autocomplete/search_provider.cc

Issue 23164011: Omnibox: Reduce Bolding Flicker in SearchProvider (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: even fancier solution Created 7 years, 4 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
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/autocomplete/search_provider.h" 5 #include "chrome/browser/autocomplete/search_provider.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 9
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 if (i.IsWord()) { 90 if (i.IsWord()) {
91 if (found_word) 91 if (found_word)
92 return true; 92 return true;
93 found_word = true; 93 found_word = true;
94 } 94 }
95 } 95 }
96 } 96 }
97 return false; 97 return false;
98 } 98 }
99 99
100 // When displaying a match for |formatted_url| against omnibox input
101 // |input_text|, determine:
102 // * if Chrome should strip the http scheme
103 // * where |input_text| matches in |formatted_url| (if it does)
104 // * where |input_text| matches as an inline autocompletion in |formatted_url_|
105 // (if it does)
106 void GetTrimHttpAndOffsets(const string16& formatted_url,
107 const string16& input_text,
108 bool* trim_http,
109 size_t* match_start,
110 size_t* inline_autocomplete_offset) {
111 // Look for the user's input inside the formatted_url as it would be without
Mark P 2013/08/16 23:25:58 This logic was moved here from NavigationToMatch()
112 // trimming the scheme, so we can find matches at the beginning of the
113 // scheme.
114 const URLPrefix* prefix = URLPrefix::BestURLPrefix(formatted_url, input_text);
115 (*match_start) = (prefix == NULL) ?
116 formatted_url.find(input_text) : prefix->prefix.length();
117 (*trim_http) = !AutocompleteProvider::HasHTTPScheme(input_text) &&
118 (!prefix || (match_start != 0));
119 (*inline_autocomplete_offset) = (prefix == NULL) ?
120 string16::npos : (*match_start + input_text.length());
121 }
122
100 } // namespace 123 } // namespace
101 124
102 125
103 // SearchProvider::Providers -------------------------------------------------- 126 // SearchProvider::Providers --------------------------------------------------
104 127
105 SearchProvider::Providers::Providers(TemplateURLService* template_url_service) 128 SearchProvider::Providers::Providers(TemplateURLService* template_url_service)
106 : template_url_service_(template_url_service) { 129 : template_url_service_(template_url_service) {
107 } 130 }
108 131
109 const TemplateURL* SearchProvider::Providers::GetDefaultProviderURL() const { 132 const TemplateURL* SearchProvider::Providers::GetDefaultProviderURL() const {
(...skipping 16 matching lines...) Expand all
126 relevance_(relevance), 149 relevance_(relevance),
127 relevance_from_server_(relevance_from_server) { 150 relevance_from_server_(relevance_from_server) {
128 } 151 }
129 152
130 SearchProvider::Result::~Result() { 153 SearchProvider::Result::~Result() {
131 } 154 }
132 155
133 156
134 // SearchProvider::SuggestResult ---------------------------------------------- 157 // SearchProvider::SuggestResult ----------------------------------------------
135 158
136 SearchProvider::SuggestResult::SuggestResult(const string16& suggestion, 159 SearchProvider::SuggestResult::SuggestResult(
137 bool from_keyword_provider, 160 const string16& suggestion,
138 int relevance, 161 bool from_keyword_provider,
139 bool relevance_from_server) 162 int relevance,
163 bool relevance_from_server,
164 const string16& input_text)
140 : Result(from_keyword_provider, relevance, relevance_from_server), 165 : Result(from_keyword_provider, relevance, relevance_from_server),
141 suggestion_(suggestion) { 166 suggestion_(suggestion) {
167 CalculateContents(true, input_text);
142 } 168 }
143 169
144 SearchProvider::SuggestResult::~SuggestResult() { 170 SearchProvider::SuggestResult::~SuggestResult() {
145 } 171 }
146 172
147 bool SearchProvider::SuggestResult::IsInlineable(const string16& input) const { 173 bool SearchProvider::SuggestResult::IsInlineable(const string16& input) const {
148 return StartsWith(suggestion_, input, false); 174 return StartsWith(suggestion_, input, false);
149 } 175 }
150 176
151 int SearchProvider::SuggestResult::CalculateRelevance( 177 int SearchProvider::SuggestResult::CalculateRelevance(
152 const AutocompleteInput& input, 178 const AutocompleteInput& input,
153 bool keyword_provider_requested) const { 179 bool keyword_provider_requested) const {
154 if (!from_keyword_provider_ && keyword_provider_requested) 180 if (!from_keyword_provider_ && keyword_provider_requested)
155 return 100; 181 return 100;
156 return ((input.type() == AutocompleteInput::URL) ? 300 : 600); 182 return ((input.type() == AutocompleteInput::URL) ? 300 : 600);
157 } 183 }
158 184
185 void SearchProvider::SuggestResult::CalculateContents(
Mark P 2013/08/16 23:25:58 This is still basically a cut-and-paste from Creat
186 bool allow_bolding_all,
187 const string16& input_text) {
188 size_t input_position = suggestion_.find(input_text);
189 if (!allow_bolding_all && (input_text != suggestion_) &&
190 (input_position == string16::npos)) {
191 // Bail if the code below to update the bolding would bold the whole
192 // string. Note that the string may already be entirely bolded; if
193 // so, leave it as is.
194 return;
195 }
196 contents_.assign(suggestion_);
197 contents_class_.clear();
198 // We do intra-string highlighting for suggestions - the suggested segment
199 // will be highlighted, e.g. for input_text = "you" the suggestion may be
200 // "youtube", so we'll bold the "tube" section: you*tube*.
201 if (input_text != suggestion_) {
202 if (input_position == string16::npos) {
203 // The input text is not a substring of the query string, e.g. input
204 // text is "slasdot" and the query string is "slashdot", so we bold the
205 // whole thing.
206 contents_class_.push_back(
207 ACMatchClassification(0, ACMatchClassification::MATCH));
208 } else {
209 // TODO(beng): ACMatchClassification::MATCH now seems to just mean
210 // "bold" this. Consider modifying the terminology.
211 // We don't iterate over the string here annotating all matches because
212 // it looks odd to have every occurrence of a substring that may be as
213 // short as a single character highlighted in a query suggestion result,
214 // e.g. for input text "s" and query string "southwest airlines", it
215 // looks odd if both the first and last s are highlighted.
216 if (input_position != 0) {
217 contents_class_.push_back(
218 ACMatchClassification(0, ACMatchClassification::MATCH));
219 }
220 contents_class_.push_back(
221 ACMatchClassification(input_position, ACMatchClassification::NONE));
222 size_t next_fragment_position = input_position + input_text.length();
223 if (next_fragment_position < suggestion_.length()) {
224 contents_class_.push_back(
225 ACMatchClassification(next_fragment_position,
226 ACMatchClassification::MATCH));
227 }
228 }
229 } else {
230 // Otherwise, |match| is a verbatim (what-you-typed) match, either for the
231 // default provider or a keyword search provider.
232 contents_class_.push_back(
233 ACMatchClassification(0, ACMatchClassification::NONE));
234
235 }
236 }
159 237
160 // SearchProvider::NavigationResult ------------------------------------------- 238 // SearchProvider::NavigationResult -------------------------------------------
161 239
162 SearchProvider::NavigationResult::NavigationResult( 240 SearchProvider::NavigationResult::NavigationResult(
163 const AutocompleteProvider& provider, 241 const AutocompleteProvider& provider,
164 const GURL& url, 242 const GURL& url,
165 const string16& description, 243 const string16& description,
166 bool from_keyword_provider, 244 bool from_keyword_provider,
167 int relevance, 245 int relevance,
168 bool relevance_from_server) 246 bool relevance_from_server,
247 const string16& input_text,
248 const std::string& languages)
169 : Result(from_keyword_provider, relevance, relevance_from_server), 249 : Result(from_keyword_provider, relevance, relevance_from_server),
170 url_(url), 250 url_(url),
171 formatted_url_(AutocompleteInput::FormattedStringWithEquivalentMeaning( 251 formatted_url_(AutocompleteInput::FormattedStringWithEquivalentMeaning(
172 url, provider.StringForURLDisplay(url, true, false))), 252 url, provider.StringForURLDisplay(url, true, false))),
173 description_(description) { 253 description_(description) {
174 DCHECK(url_.is_valid()); 254 DCHECK(url_.is_valid());
255 CalculateContents(true, input_text, languages);
175 } 256 }
176 257
177 SearchProvider::NavigationResult::~NavigationResult() { 258 SearchProvider::NavigationResult::~NavigationResult() {
178 } 259 }
179 260
180 bool SearchProvider::NavigationResult::IsInlineable( 261 bool SearchProvider::NavigationResult::IsInlineable(
181 const string16& input) const { 262 const string16& input) const {
182 return URLPrefix::BestURLPrefix(formatted_url_, input) != NULL; 263 return URLPrefix::BestURLPrefix(formatted_url_, input) != NULL;
183 } 264 }
184 265
185 int SearchProvider::NavigationResult::CalculateRelevance( 266 int SearchProvider::NavigationResult::CalculateRelevance(
186 const AutocompleteInput& input, 267 const AutocompleteInput& input,
187 bool keyword_provider_requested) const { 268 bool keyword_provider_requested) const {
188 return (from_keyword_provider_ || !keyword_provider_requested) ? 800 : 150; 269 return (from_keyword_provider_ || !keyword_provider_requested) ? 800 : 150;
189 } 270 }
190 271
272 void SearchProvider::NavigationResult::CalculateContents(
273 bool allow_bolding_nothing,
274 const string16& input_text,
275 const std::string languages) {
276 bool trim_http;
277 size_t match_start, inline_autocomplete_offset;
278 GetTrimHttpAndOffsets(formatted_url_, input_text, &trim_http, &match_start,
279 &inline_autocomplete_offset);
280 if (!allow_bolding_nothing && (match_start == string16::npos)) {
281 // Bail if the code below to update the bolding would make the stirng
282 // entirely not bolded. Note that the string may already be entirely
283 // not bolded; if so, leave it as is.
284 return;
285 }
286 const net::FormatUrlTypes format_types =
Mark P 2013/08/16 23:25:58 This logic here and below was moved here from Navi
287 net::kFormatUrlOmitAll & ~(trim_http ? 0 : net::kFormatUrlOmitHTTP);
288 contents_ = net::FormatUrl(url_, languages,
289 format_types, net::UnescapeRule::SPACES, NULL, NULL, &match_start);
290 // If the first match in the untrimmed string was inside a scheme that we
291 // trimmed, look for a subsequent match.
292 if (match_start == string16::npos)
293 match_start = contents_.find(input_text);
294 // Safe if |match_start| is npos; also safe if the input is longer than the
295 // remaining contents after |match_start|.
296 AutocompleteMatch::ClassifyLocationInString(match_start, input_text.length(),
297 contents_.length(), ACMatchClassification::URL,
298 &contents_class_);
299 }
191 300
192 // SearchProvider::CompareScoredResults --------------------------------------- 301 // SearchProvider::CompareScoredResults ---------------------------------------
193 302
194 class SearchProvider::CompareScoredResults { 303 class SearchProvider::CompareScoredResults {
195 public: 304 public:
196 bool operator()(const Result& a, const Result& b) { 305 bool operator()(const Result& a, const Result& b) {
197 // Sort in descending relevance order. 306 // Sort in descending relevance order.
198 return a.relevance() > b.relevance(); 307 return a.relevance() > b.relevance();
199 } 308 }
200 }; 309 };
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 Profile* profile) 359 Profile* profile)
251 : AutocompleteProvider(listener, profile, 360 : AutocompleteProvider(listener, profile,
252 AutocompleteProvider::TYPE_SEARCH), 361 AutocompleteProvider::TYPE_SEARCH),
253 providers_(TemplateURLServiceFactory::GetForProfile(profile)), 362 providers_(TemplateURLServiceFactory::GetForProfile(profile)),
254 suggest_results_pending_(0), 363 suggest_results_pending_(0),
255 field_trial_triggered_(false), 364 field_trial_triggered_(false),
256 field_trial_triggered_in_session_(false) { 365 field_trial_triggered_in_session_(false) {
257 } 366 }
258 367
259 // static 368 // static
260 AutocompleteMatch SearchProvider::CreateSearchSuggestion( 369 AutocompleteMatch SearchProvider::CreateSearchSuggestion(
Mark P 2013/08/16 23:25:58 When this review is almost complete, I will move t
261 AutocompleteProvider* autocomplete_provider, 370 AutocompleteProvider* autocomplete_provider,
262 int relevance, 371 const SuggestResult& result,
263 AutocompleteMatch::Type type, 372 AutocompleteMatch::Type type,
264 const TemplateURL* template_url, 373 const TemplateURL* template_url,
265 const string16& query_string,
266 const string16& input_text, 374 const string16& input_text,
267 const AutocompleteInput& input, 375 const AutocompleteInput& input,
268 bool is_keyword,
269 int accepted_suggestion, 376 int accepted_suggestion,
270 int omnibox_start_margin, 377 int omnibox_start_margin,
271 bool append_extra_query_params) { 378 bool append_extra_query_params) {
272 AutocompleteMatch match(autocomplete_provider, relevance, false, type); 379 AutocompleteMatch match(
380 autocomplete_provider, result.relevance(), false, type);
273 381
274 if (!template_url) 382 if (!template_url)
275 return match; 383 return match;
276 match.keyword = template_url->keyword(); 384 match.keyword = template_url->keyword();
277 385
278 match.contents.assign(query_string); 386 match.contents = result.contents();
279 // We do intra-string highlighting for suggestions - the suggested segment 387 match.contents_class = result.contents_class();
280 // will be highlighted, e.g. for input_text = "you" the suggestion may be 388 if (input_text == result.suggestion())
281 // "youtube", so we'll bold the "tube" section: you*tube*.
282 if (input_text != query_string) {
283 size_t input_position = match.contents.find(input_text);
284 if (input_position == string16::npos) {
285 // The input text is not a substring of the query string, e.g. input
286 // text is "slasdot" and the query string is "slashdot", so we bold the
287 // whole thing.
288 match.contents_class.push_back(
289 ACMatchClassification(0, ACMatchClassification::MATCH));
290 } else {
291 // TODO(beng): ACMatchClassification::MATCH now seems to just mean
292 // "bold" this. Consider modifying the terminology.
293 // We don't iterate over the string here annotating all matches because
294 // it looks odd to have every occurrence of a substring that may be as
295 // short as a single character highlighted in a query suggestion result,
296 // e.g. for input text "s" and query string "southwest airlines", it
297 // looks odd if both the first and last s are highlighted.
298 if (input_position != 0) {
299 match.contents_class.push_back(
300 ACMatchClassification(0, ACMatchClassification::MATCH));
301 }
302 match.contents_class.push_back(
303 ACMatchClassification(input_position, ACMatchClassification::NONE));
304 size_t next_fragment_position = input_position + input_text.length();
305 if (next_fragment_position < query_string.length()) {
306 match.contents_class.push_back(
307 ACMatchClassification(next_fragment_position,
308 ACMatchClassification::MATCH));
309 }
310 }
311 } else {
312 // Otherwise, |match| is a verbatim (what-you-typed) match, either for the
313 // default provider or a keyword search provider.
314 match.contents_class.push_back(
315 ACMatchClassification(0, ACMatchClassification::NONE));
316 match.allowed_to_be_default_match = true; 389 match.allowed_to_be_default_match = true;
317 }
318 390
319 // When the user forced a query, we need to make sure all the fill_into_edit 391 // When the user forced a query, we need to make sure all the fill_into_edit
320 // values preserve that property. Otherwise, if the user starts editing a 392 // values preserve that property. Otherwise, if the user starts editing a
321 // suggestion, non-Search results will suddenly appear. 393 // suggestion, non-Search results will suddenly appear.
322 if (input.type() == AutocompleteInput::FORCED_QUERY) 394 if (input.type() == AutocompleteInput::FORCED_QUERY)
323 match.fill_into_edit.assign(ASCIIToUTF16("?")); 395 match.fill_into_edit.assign(ASCIIToUTF16("?"));
324 if (is_keyword) 396 if (result.from_keyword_provider())
325 match.fill_into_edit.append(match.keyword + char16(' ')); 397 match.fill_into_edit.append(match.keyword + char16(' '));
326 if (!input.prevent_inline_autocomplete() && 398 if (!input.prevent_inline_autocomplete() &&
327 StartsWith(query_string, input_text, false)) { 399 StartsWith(result.suggestion(), input_text, false)) {
328 match.inline_autocompletion = query_string.substr(input_text.length()); 400 match.inline_autocompletion =
401 result.suggestion().substr(input_text.length());
329 match.allowed_to_be_default_match = true; 402 match.allowed_to_be_default_match = true;
330 } 403 }
331 match.fill_into_edit.append(query_string); 404 match.fill_into_edit.append(result.suggestion());
332 405
333 const TemplateURLRef& search_url = template_url->url_ref(); 406 const TemplateURLRef& search_url = template_url->url_ref();
334 DCHECK(search_url.SupportsReplacement()); 407 DCHECK(search_url.SupportsReplacement());
335 match.search_terms_args.reset( 408 match.search_terms_args.reset(
336 new TemplateURLRef::SearchTermsArgs(query_string)); 409 new TemplateURLRef::SearchTermsArgs(result.suggestion()));
337 match.search_terms_args->original_query = input_text; 410 match.search_terms_args->original_query = input_text;
338 match.search_terms_args->accepted_suggestion = accepted_suggestion; 411 match.search_terms_args->accepted_suggestion = accepted_suggestion;
339 match.search_terms_args->omnibox_start_margin = omnibox_start_margin; 412 match.search_terms_args->omnibox_start_margin = omnibox_start_margin;
340 match.search_terms_args->append_extra_query_params = 413 match.search_terms_args->append_extra_query_params =
341 append_extra_query_params; 414 append_extra_query_params;
342 // This is the destination URL sans assisted query stats. This must be set 415 // This is the destination URL sans assisted query stats. This must be set
343 // so the AutocompleteController can properly de-dupe; the controller will 416 // so the AutocompleteController can properly de-dupe; the controller will
344 // eventually overwrite it before it reaches the user. 417 // eventually overwrite it before it reaches the user.
345 match.destination_url = 418 match.destination_url =
346 GURL(search_url.ReplaceSearchTerms(*match.search_terms_args.get())); 419 GURL(search_url.ReplaceSearchTerms(*match.search_terms_args.get()));
347 420
348 // Search results don't look like URLs. 421 // Search results don't look like URLs.
349 match.transition = is_keyword ? 422 match.transition = result.from_keyword_provider() ?
350 content::PAGE_TRANSITION_KEYWORD : content::PAGE_TRANSITION_GENERATED; 423 content::PAGE_TRANSITION_KEYWORD : content::PAGE_TRANSITION_GENERATED;
351 424
352 return match; 425 return match;
353 } 426 }
354 427
355 void SearchProvider::AddProviderInfo(ProvidersInfo* provider_info) const { 428 void SearchProvider::AddProviderInfo(ProvidersInfo* provider_info) const {
356 provider_info->push_back(metrics::OmniboxEventProto_ProviderInfo()); 429 provider_info->push_back(metrics::OmniboxEventProto_ProviderInfo());
357 metrics::OmniboxEventProto_ProviderInfo& new_entry = provider_info->back(); 430 metrics::OmniboxEventProto_ProviderInfo& new_entry = provider_info->back();
358 new_entry.set_provider(AsOmniboxEventProviderType()); 431 new_entry.set_provider(AsOmniboxEventProviderType());
359 new_entry.set_provider_done(done_); 432 new_entry.set_provider_done(done_);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 } else { 496 } else {
424 // The current top result is a navigational suggestion. 497 // The current top result is a navigational suggestion.
425 if (nav_it->IsInlineable(input)) 498 if (nav_it->IsInlineable(input))
426 break; 499 break;
427 nav_it = navigation_results->erase(nav_it); 500 nav_it = navigation_results->erase(nav_it);
428 } 501 }
429 } 502 }
430 } 503 }
431 504
432 // static 505 // static
506 void SearchProvider::RecalculateBolding(const string16& input_text,
507 const std::string languages,
508 Results* results) {
509 for (SuggestResults::iterator sug_it = results->suggest_results.begin();
510 sug_it != results->suggest_results.end(); ++sug_it) {
511 sug_it->CalculateContents(false, input_text);
512 }
513 for (NavigationResults::iterator nav_it = results->navigation_results.begin();
514 nav_it != results->navigation_results.end(); ++nav_it) {
515 nav_it->CalculateContents(false, input_text, languages);
516 }
517 }
518
519 // static
433 int SearchProvider::CalculateRelevanceForKeywordVerbatim( 520 int SearchProvider::CalculateRelevanceForKeywordVerbatim(
434 AutocompleteInput::Type type, 521 AutocompleteInput::Type type,
435 bool prefer_keyword) { 522 bool prefer_keyword) {
436 // This function is responsible for scoring verbatim query matches 523 // This function is responsible for scoring verbatim query matches
437 // for non-extension keywords. KeywordProvider::CalculateRelevance() 524 // for non-extension keywords. KeywordProvider::CalculateRelevance()
438 // scores verbatim query matches for extension keywords, as well as 525 // scores verbatim query matches for extension keywords, as well as
439 // for keyword matches (i.e., suggestions of a keyword itself, not a 526 // for keyword matches (i.e., suggestions of a keyword itself, not a
440 // suggestion of a query on a keyword search engine). These two 527 // suggestion of a query on a keyword search engine). These two
441 // functions are currently in sync, but there's no reason we 528 // functions are currently in sync, but there's no reason we
442 // couldn't decide in the future to score verbatim matches 529 // couldn't decide in the future to score verbatim matches
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 (!done_ && 765 (!done_ &&
679 input_.matches_requested() == AutocompleteInput::ALL_MATCHES))) 766 input_.matches_requested() == AutocompleteInput::ALL_MATCHES)))
680 return; 767 return;
681 768
682 // We can't keep running any previous query, so halt it. 769 // We can't keep running any previous query, so halt it.
683 StopSuggest(); 770 StopSuggest();
684 771
685 // Remove existing results that cannot inline autocomplete the new input. 772 // Remove existing results that cannot inline autocomplete the new input.
686 RemoveAllStaleResults(); 773 RemoveAllStaleResults();
687 774
775 // Revise the bolding of all results that remain so they look good against
776 // the current input.
777 const std::string& languages =
778 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages);
779 RecalculateBolding(input_.text(), languages, &default_results_);
780 RecalculateBolding(keyword_input_.text(), languages, &keyword_results_);
781
688 // We can't start a new query if we're only allowed synchronous results. 782 // We can't start a new query if we're only allowed synchronous results.
689 if (input_.matches_requested() != AutocompleteInput::ALL_MATCHES) 783 if (input_.matches_requested() != AutocompleteInput::ALL_MATCHES)
690 return; 784 return;
691 785
692 // To avoid flooding the suggest server, don't send a query until at 786 // To avoid flooding the suggest server, don't send a query until at
693 // least 100 ms since the last query. 787 // least 100 ms since the last query.
694 base::TimeTicks next_suggest_time(time_suggest_request_sent_ + 788 base::TimeTicks next_suggest_time(time_suggest_request_sent_ +
695 base::TimeDelta::FromMilliseconds(kMinimumTimeBetweenSuggestQueriesMs)); 789 base::TimeDelta::FromMilliseconds(kMinimumTimeBetweenSuggestQueriesMs));
696 base::TimeTicks now(base::TimeTicks::Now()); 790 base::TimeTicks now(base::TimeTicks::Now());
697 if (now >= next_suggest_time) { 791 if (now >= next_suggest_time) {
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
899 field_trial_triggered_in_session_ |= triggered; 993 field_trial_triggered_in_session_ |= triggered;
900 } 994 }
901 995
902 // Clear the previous results now that new results are available. 996 // Clear the previous results now that new results are available.
903 results->suggest_results.clear(); 997 results->suggest_results.clear();
904 results->navigation_results.clear(); 998 results->navigation_results.clear();
905 999
906 string16 result, title; 1000 string16 result, title;
907 std::string type; 1001 std::string type;
908 int relevance = -1; 1002 int relevance = -1;
1003 const std::string& languages =
1004 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages);
909 for (size_t index = 0; results_list->GetString(index, &result); ++index) { 1005 for (size_t index = 0; results_list->GetString(index, &result); ++index) {
910 // Google search may return empty suggestions for weird input characters, 1006 // Google search may return empty suggestions for weird input characters,
911 // they make no sense at all and can cause problems in our code. 1007 // they make no sense at all and can cause problems in our code.
912 if (result.empty()) 1008 if (result.empty())
913 continue; 1009 continue;
914 1010
915 // Apply valid suggested relevance scores; discard invalid lists. 1011 // Apply valid suggested relevance scores; discard invalid lists.
916 if (relevances != NULL && !relevances->GetInteger(index, &relevance)) 1012 if (relevances != NULL && !relevances->GetInteger(index, &relevance))
917 relevances = NULL; 1013 relevances = NULL;
918 if (types && types->GetString(index, &type) && (type == "NAVIGATION")) { 1014 if (types && types->GetString(index, &type) && (type == "NAVIGATION")) {
919 // Do not blindly trust the URL coming from the server to be valid. 1015 // Do not blindly trust the URL coming from the server to be valid.
920 GURL url(URLFixerUpper::FixupURL(UTF16ToUTF8(result), std::string())); 1016 GURL url(URLFixerUpper::FixupURL(UTF16ToUTF8(result), std::string()));
921 if (url.is_valid()) { 1017 if (url.is_valid()) {
922 if (descriptions != NULL) 1018 if (descriptions != NULL)
923 descriptions->GetString(index, &title); 1019 descriptions->GetString(index, &title);
924 results->navigation_results.push_back(NavigationResult( 1020 results->navigation_results.push_back(NavigationResult(
925 *this, url, title, is_keyword, relevance, true)); 1021 *this, url, title, is_keyword, relevance, true, input_text,
1022 languages));
926 } 1023 }
927 } else { 1024 } else {
928 // TODO(kochi): Improve calculator result presentation. 1025 // TODO(kochi): Improve calculator result presentation.
929 results->suggest_results.push_back( 1026 results->suggest_results.push_back(
930 SuggestResult(result, is_keyword, relevance, true)); 1027 SuggestResult(result, is_keyword, relevance, true, input_text));
931 } 1028 }
932 } 1029 }
933 1030
934 // Apply calculated relevance scores if a valid list was not provided. 1031 // Apply calculated relevance scores if a valid list was not provided.
935 if (relevances == NULL) { 1032 if (relevances == NULL) {
936 ApplyCalculatedSuggestRelevance(&results->suggest_results); 1033 ApplyCalculatedSuggestRelevance(&results->suggest_results);
937 ApplyCalculatedNavigationRelevance(&results->navigation_results); 1034 ApplyCalculatedNavigationRelevance(&results->navigation_results);
938 } 1035 }
939 // Keep the result lists sorted. 1036 // Keep the result lists sorted.
940 const CompareScoredResults comparator = CompareScoredResults(); 1037 const CompareScoredResults comparator = CompareScoredResults();
(...skipping 16 matching lines...) Expand all
957 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE : 1054 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE :
958 TemplateURLRef::NO_SUGGESTION_CHOSEN; 1055 TemplateURLRef::NO_SUGGESTION_CHOSEN;
959 1056
960 bool relevance_from_server; 1057 bool relevance_from_server;
961 int verbatim_relevance = GetVerbatimRelevance(&relevance_from_server); 1058 int verbatim_relevance = GetVerbatimRelevance(&relevance_from_server);
962 int did_not_accept_default_suggestion = 1059 int did_not_accept_default_suggestion =
963 default_results_.suggest_results.empty() ? 1060 default_results_.suggest_results.empty() ?
964 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE : 1061 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE :
965 TemplateURLRef::NO_SUGGESTION_CHOSEN; 1062 TemplateURLRef::NO_SUGGESTION_CHOSEN;
966 if (verbatim_relevance > 0) { 1063 if (verbatim_relevance > 0) {
967 AddMatchToMap(input_.text(), input_.text(), verbatim_relevance, 1064 SuggestResult verbatim(input_.text(), false, verbatim_relevance,
968 relevance_from_server, 1065 relevance_from_server, input_.text());
1066 AddMatchToMap(verbatim, input_.text(),
969 AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, 1067 AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
970 did_not_accept_default_suggestion, false, &map); 1068 did_not_accept_default_suggestion, &map);
971 } 1069 }
972 if (!keyword_input_.text().empty()) { 1070 if (!keyword_input_.text().empty()) {
973 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL(); 1071 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL();
974 // We only create the verbatim search query match for a keyword 1072 // We only create the verbatim search query match for a keyword
975 // if it's not an extension keyword. Extension keywords are handled 1073 // if it's not an extension keyword. Extension keywords are handled
976 // in KeywordProvider::Start(). (Extensions are complicated...) 1074 // in KeywordProvider::Start(). (Extensions are complicated...)
977 // Note: in this provider, SEARCH_OTHER_ENGINE must correspond 1075 // Note: in this provider, SEARCH_OTHER_ENGINE must correspond
978 // to the keyword verbatim search query. Do not create other matches 1076 // to the keyword verbatim search query. Do not create other matches
979 // of type SEARCH_OTHER_ENGINE. 1077 // of type SEARCH_OTHER_ENGINE.
980 if (keyword_url && !keyword_url->IsExtensionKeyword()) { 1078 if (keyword_url && !keyword_url->IsExtensionKeyword()) {
981 bool keyword_relevance_from_server; 1079 bool keyword_relevance_from_server;
982 const int keyword_verbatim_relevance = 1080 const int keyword_verbatim_relevance =
983 GetKeywordVerbatimRelevance(&keyword_relevance_from_server); 1081 GetKeywordVerbatimRelevance(&keyword_relevance_from_server);
984 if (keyword_verbatim_relevance > 0) { 1082 if (keyword_verbatim_relevance > 0) {
985 AddMatchToMap(keyword_input_.text(), keyword_input_.text(), 1083 SuggestResult keyword_verbatim(
986 keyword_verbatim_relevance, keyword_relevance_from_server, 1084 keyword_input_.text(), true, keyword_verbatim_relevance,
1085 keyword_relevance_from_server, keyword_input_.text());
1086 AddMatchToMap(keyword_verbatim, keyword_input_.text(),
987 AutocompleteMatchType::SEARCH_OTHER_ENGINE, 1087 AutocompleteMatchType::SEARCH_OTHER_ENGINE,
988 did_not_accept_keyword_suggestion, true, &map); 1088 did_not_accept_keyword_suggestion, &map);
989 } 1089 }
990 } 1090 }
991 } 1091 }
992 AddHistoryResultsToMap(keyword_history_results_, true, 1092 AddHistoryResultsToMap(keyword_history_results_, true,
993 did_not_accept_keyword_suggestion, &map); 1093 did_not_accept_keyword_suggestion, &map);
994 AddHistoryResultsToMap(default_history_results_, false, 1094 AddHistoryResultsToMap(default_history_results_, false,
995 did_not_accept_default_suggestion, &map); 1095 did_not_accept_default_suggestion, &map);
996 1096
997 AddSuggestResultsToMap(keyword_results_.suggest_results, &map); 1097 AddSuggestResultsToMap(keyword_results_.suggest_results, &map);
998 AddSuggestResultsToMap(default_results_.suggest_results, &map); 1098 AddSuggestResultsToMap(default_results_.suggest_results, &map);
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
1201 AutocompleteResult::kLowestDefaultScore) || 1301 AutocompleteResult::kLowestDefaultScore) ||
1202 !HasMultipleWords(scored_results.front().suggestion())) 1302 !HasMultipleWords(scored_results.front().suggestion()))
1203 scored_results.clear(); // Didn't detect the case above, score normally. 1303 scored_results.clear(); // Didn't detect the case above, score normally.
1204 } 1304 }
1205 if (scored_results.empty()) 1305 if (scored_results.empty())
1206 scored_results = ScoreHistoryResults(results, prevent_inline_autocomplete, 1306 scored_results = ScoreHistoryResults(results, prevent_inline_autocomplete,
1207 input_multiple_words, input_text, 1307 input_multiple_words, input_text,
1208 is_keyword); 1308 is_keyword);
1209 for (SuggestResults::const_iterator i(scored_results.begin()); 1309 for (SuggestResults::const_iterator i(scored_results.begin());
1210 i != scored_results.end(); ++i) { 1310 i != scored_results.end(); ++i) {
1211 AddMatchToMap(i->suggestion(), input_text, i->relevance(), false, 1311 AddMatchToMap(*i, input_text,
1212 AutocompleteMatchType::SEARCH_HISTORY, 1312 AutocompleteMatchType::SEARCH_HISTORY,
1213 did_not_accept_suggestion, 1313 did_not_accept_suggestion, map);
1214 is_keyword, map);
1215 } 1314 }
1216 } 1315 }
1217 1316
1218 SearchProvider::SuggestResults SearchProvider::ScoreHistoryResults( 1317 SearchProvider::SuggestResults SearchProvider::ScoreHistoryResults(
1219 const HistoryResults& results, 1318 const HistoryResults& results,
1220 bool base_prevent_inline_autocomplete, 1319 bool base_prevent_inline_autocomplete,
1221 bool input_multiple_words, 1320 bool input_multiple_words,
1222 const string16& input_text, 1321 const string16& input_text,
1223 bool is_keyword) { 1322 bool is_keyword) {
1224 AutocompleteClassifier* classifier = 1323 AutocompleteClassifier* classifier =
(...skipping 26 matching lines...) Expand all
1251 AutocompleteMatch match; 1350 AutocompleteMatch match;
1252 classifier->Classify(i->term, false, false, &match, NULL); 1351 classifier->Classify(i->term, false, false, &match, NULL);
1253 prevent_inline_autocomplete = 1352 prevent_inline_autocomplete =
1254 !AutocompleteMatch::IsSearchType(match.type); 1353 !AutocompleteMatch::IsSearchType(match.type);
1255 } 1354 }
1256 1355
1257 int relevance = CalculateRelevanceForHistory( 1356 int relevance = CalculateRelevanceForHistory(
1258 i->time, is_keyword, !prevent_inline_autocomplete, 1357 i->time, is_keyword, !prevent_inline_autocomplete,
1259 prevent_search_history_inlining); 1358 prevent_search_history_inlining);
1260 scored_results.push_back( 1359 scored_results.push_back(
1261 SuggestResult(i->term, is_keyword, relevance, false)); 1360 SuggestResult(i->term, is_keyword, relevance, false, input_text));
1262 } 1361 }
1263 1362
1264 // History returns results sorted for us. However, we may have docked some 1363 // History returns results sorted for us. However, we may have docked some
1265 // results' scores, so things are no longer in order. Do a stable sort to get 1364 // results' scores, so things are no longer in order. Do a stable sort to get
1266 // things back in order without otherwise disturbing results with equal 1365 // things back in order without otherwise disturbing results with equal
1267 // scores, then force the scores to be unique, so that the order in which 1366 // scores, then force the scores to be unique, so that the order in which
1268 // they're shown is deterministic. 1367 // they're shown is deterministic.
1269 std::stable_sort(scored_results.begin(), scored_results.end(), 1368 std::stable_sort(scored_results.begin(), scored_results.end(),
1270 CompareScoredResults()); 1369 CompareScoredResults());
1271 int last_relevance = 0; 1370 int last_relevance = 0;
1272 for (SuggestResults::iterator i(scored_results.begin()); 1371 for (SuggestResults::iterator i(scored_results.begin());
1273 i != scored_results.end(); ++i) { 1372 i != scored_results.end(); ++i) {
1274 if ((i != scored_results.begin()) && (i->relevance() >= last_relevance)) 1373 if ((i != scored_results.begin()) && (i->relevance() >= last_relevance))
1275 i->set_relevance(last_relevance - 1); 1374 i->set_relevance(last_relevance - 1);
1276 last_relevance = i->relevance(); 1375 last_relevance = i->relevance();
1277 } 1376 }
1278 1377
1279 return scored_results; 1378 return scored_results;
1280 } 1379 }
1281 1380
1282 void SearchProvider::AddSuggestResultsToMap(const SuggestResults& results, 1381 void SearchProvider::AddSuggestResultsToMap(const SuggestResults& results,
1283 MatchMap* map) { 1382 MatchMap* map) {
1284 for (size_t i = 0; i < results.size(); ++i) { 1383 for (size_t i = 0; i < results.size(); ++i) {
1285 const bool is_keyword = results[i].from_keyword_provider(); 1384 const string16& input = results[i].from_keyword_provider() ?
1286 const string16& input = is_keyword ? keyword_input_.text() : input_.text(); 1385 keyword_input_.text() : input_.text();
1287 AddMatchToMap(results[i].suggestion(), input, results[i].relevance(), 1386 AddMatchToMap(results[i], input,
1288 results[i].relevance_from_server(), 1387 AutocompleteMatchType::SEARCH_SUGGEST, i, map);
1289 AutocompleteMatchType::SEARCH_SUGGEST, i, is_keyword, map);
1290 } 1388 }
1291 } 1389 }
1292 1390
1293 int SearchProvider::GetVerbatimRelevance(bool* relevance_from_server) const { 1391 int SearchProvider::GetVerbatimRelevance(bool* relevance_from_server) const {
1294 // Use the suggested verbatim relevance score if it is non-negative (valid), 1392 // Use the suggested verbatim relevance score if it is non-negative (valid),
1295 // if inline autocomplete isn't prevented (always show verbatim on backspace), 1393 // if inline autocomplete isn't prevented (always show verbatim on backspace),
1296 // and if it won't suppress verbatim, leaving no default provider matches. 1394 // and if it won't suppress verbatim, leaving no default provider matches.
1297 // Otherwise, if the default provider returned no matches and was still able 1395 // Otherwise, if the default provider returned no matches and was still able
1298 // to suppress verbatim, the user would have no search/nav matches and may be 1396 // to suppress verbatim, the user would have no search/nav matches and may be
1299 // left unable to search using their default provider from the omnibox. 1397 // left unable to search using their default provider from the omnibox.
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1391 // Don't let scores go below 0. Negative relevance scores are meaningful in 1489 // Don't let scores go below 0. Negative relevance scores are meaningful in
1392 // a different way. 1490 // a different way.
1393 int base_score; 1491 int base_score;
1394 if (is_primary_provider) 1492 if (is_primary_provider)
1395 base_score = (input_.type() == AutocompleteInput::URL) ? 750 : 1050; 1493 base_score = (input_.type() == AutocompleteInput::URL) ? 750 : 1050;
1396 else 1494 else
1397 base_score = 200; 1495 base_score = 200;
1398 return std::max(0, base_score - score_discount); 1496 return std::max(0, base_score - score_discount);
1399 } 1497 }
1400 1498
1401 void SearchProvider::AddMatchToMap(const string16& query_string, 1499 void SearchProvider::AddMatchToMap(const SuggestResult& result,
1402 const string16& input_text, 1500 const string16& input_text,
1403 int relevance,
1404 bool relevance_from_server,
1405 AutocompleteMatch::Type type, 1501 AutocompleteMatch::Type type,
1406 int accepted_suggestion, 1502 int accepted_suggestion,
1407 bool is_keyword,
1408 MatchMap* map) { 1503 MatchMap* map) {
1409 // On non-mobile, ask the instant controller for the appropriate start margin. 1504 // On non-mobile, ask the instant controller for the appropriate start margin.
1410 // On mobile the start margin is unused, so leave the value as default there. 1505 // On mobile the start margin is unused, so leave the value as default there.
1411 int omnibox_start_margin = chrome::kDisableStartMargin; 1506 int omnibox_start_margin = chrome::kDisableStartMargin;
1412 #if !defined(OS_ANDROID) && !defined(IOS) 1507 #if !defined(OS_ANDROID) && !defined(IOS)
1413 if (chrome::IsInstantExtendedAPIEnabled()) { 1508 if (chrome::IsInstantExtendedAPIEnabled()) {
1414 Browser* browser = 1509 Browser* browser =
1415 chrome::FindBrowserWithProfile(profile_, chrome::GetActiveDesktop()); 1510 chrome::FindBrowserWithProfile(profile_, chrome::GetActiveDesktop());
1416 if (browser && browser->instant_controller() && 1511 if (browser && browser->instant_controller() &&
1417 browser->instant_controller()->instant()) { 1512 browser->instant_controller()->instant()) {
1418 omnibox_start_margin = 1513 omnibox_start_margin =
1419 browser->instant_controller()->instant()->omnibox_bounds().x(); 1514 browser->instant_controller()->instant()->omnibox_bounds().x();
1420 } 1515 }
1421 } 1516 }
1422 #endif // !defined(OS_ANDROID) && !defined(IOS) 1517 #endif // !defined(OS_ANDROID) && !defined(IOS)
1423 1518
1424 const TemplateURL* template_url = is_keyword ? 1519 const TemplateURL* template_url = result.from_keyword_provider() ?
1425 providers_.GetKeywordProviderURL() : providers_.GetDefaultProviderURL(); 1520 providers_.GetKeywordProviderURL() : providers_.GetDefaultProviderURL();
1426 AutocompleteMatch match = CreateSearchSuggestion(this, relevance, type, 1521 AutocompleteMatch match = CreateSearchSuggestion(this, result,
1427 template_url, query_string, input_text, input_, is_keyword, 1522 type, template_url, input_text, input_, accepted_suggestion,
1428 accepted_suggestion, omnibox_start_margin, 1523 omnibox_start_margin,
1429 !is_keyword || providers_.default_provider().empty()); 1524 !result.from_keyword_provider() || providers_.default_provider().empty());
1430 if (!match.destination_url.is_valid()) 1525 if (!match.destination_url.is_valid())
1431 return; 1526 return;
1432 match.RecordAdditionalInfo(kRelevanceFromServerKey, 1527 match.RecordAdditionalInfo(kRelevanceFromServerKey,
1433 relevance_from_server ? kTrue : kFalse); 1528 result.relevance_from_server() ? kTrue : kFalse);
1434 1529
1435 // Try to add |match| to |map|. If a match for |query_string| is already in 1530 // Try to add |match| to |map|. If a match for |query_string| is already in
1436 // |map|, replace it if |match| is more relevant. 1531 // |map|, replace it if |match| is more relevant.
1437 // NOTE: Keep this ToLower() call in sync with url_database.cc. 1532 // NOTE: Keep this ToLower() call in sync with url_database.cc.
1438 const std::pair<MatchMap::iterator, bool> i( 1533 const std::pair<MatchMap::iterator, bool> i(map->insert(std::make_pair(
1439 map->insert(std::make_pair(base::i18n::ToLower(query_string), match))); 1534 base::i18n::ToLower(result.suggestion()), match)));
1440 // NOTE: We purposefully do a direct relevance comparison here instead of 1535 // NOTE: We purposefully do a direct relevance comparison here instead of
1441 // using AutocompleteMatch::MoreRelevant(), so that we'll prefer "items added 1536 // using AutocompleteMatch::MoreRelevant(), so that we'll prefer "items added
1442 // first" rather than "items alphabetically first" when the scores are equal. 1537 // first" rather than "items alphabetically first" when the scores are equal.
1443 // The only case this matters is when a user has results with the same score 1538 // The only case this matters is when a user has results with the same score
1444 // that differ only by capitalization; because the history system returns 1539 // that differ only by capitalization; because the history system returns
1445 // results sorted by recency, this means we'll pick the most recent such 1540 // results sorted by recency, this means we'll pick the most recent such
1446 // result even if the precision of our relevance score is too low to 1541 // result even if the precision of our relevance score is too low to
1447 // distinguish the two. 1542 // distinguish the two.
1448 if (!i.second && (match.relevance > i.first->second.relevance)) 1543 if (!i.second && (match.relevance > i.first->second.relevance))
1449 i.first->second = match; 1544 i.first->second = match;
1450 } 1545 }
1451 1546
1452 AutocompleteMatch SearchProvider::NavigationToMatch( 1547 AutocompleteMatch SearchProvider::NavigationToMatch(
1453 const NavigationResult& navigation) { 1548 const NavigationResult& navigation) {
1454 const string16& input = navigation.from_keyword_provider() ? 1549 const string16& input = navigation.from_keyword_provider() ?
1455 keyword_input_.text() : input_.text(); 1550 keyword_input_.text() : input_.text();
1456 AutocompleteMatch match(this, navigation.relevance(), false, 1551 AutocompleteMatch match(this, navigation.relevance(), false,
1457 AutocompleteMatchType::NAVSUGGEST); 1552 AutocompleteMatchType::NAVSUGGEST);
1458 match.destination_url = navigation.url(); 1553 match.destination_url = navigation.url();
1459 1554
1460 // First look for the user's input inside the fill_into_edit as it would be 1555 bool trim_http;
1461 // without trimming the scheme, so we can find matches at the beginning of the 1556 size_t match_start, inline_autocomplete_offset;
1462 // scheme. 1557 GetTrimHttpAndOffsets(navigation.formatted_url(), input, &trim_http,
1463 const string16& untrimmed_fill_into_edit = navigation.formatted_url(); 1558 &match_start, &inline_autocomplete_offset);
1464 const URLPrefix* prefix =
1465 URLPrefix::BestURLPrefix(untrimmed_fill_into_edit, input);
1466 size_t match_start = (prefix == NULL) ?
1467 untrimmed_fill_into_edit.find(input) : prefix->prefix.length();
1468 size_t inline_autocomplete_offset = (prefix == NULL) ?
1469 string16::npos : (match_start + input.length());
1470 bool trim_http = !HasHTTPScheme(input) && (!prefix || (match_start != 0));
1471
1472 // Preserve the forced query '?' prefix in |match.fill_into_edit|. 1559 // Preserve the forced query '?' prefix in |match.fill_into_edit|.
1473 // Otherwise, user edits to a suggestion would show non-Search results. 1560 // Otherwise, user edits to a suggestion would show non-Search results.
1474 if (input_.type() == AutocompleteInput::FORCED_QUERY) { 1561 if (input_.type() == AutocompleteInput::FORCED_QUERY) {
1475 match.fill_into_edit = ASCIIToUTF16("?"); 1562 match.fill_into_edit = ASCIIToUTF16("?");
1476 if (inline_autocomplete_offset != string16::npos) 1563 if (inline_autocomplete_offset != string16::npos)
1477 ++inline_autocomplete_offset; 1564 ++inline_autocomplete_offset;
1478 } 1565 }
1479 1566
1480 const std::string languages( 1567 const std::string languages(
1481 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); 1568 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages));
1482 const net::FormatUrlTypes format_types = 1569 const net::FormatUrlTypes format_types =
1483 net::kFormatUrlOmitAll & ~(trim_http ? 0 : net::kFormatUrlOmitHTTP); 1570 net::kFormatUrlOmitAll & ~(trim_http ? 0 : net::kFormatUrlOmitHTTP);
1484 match.fill_into_edit += 1571 match.fill_into_edit +=
1485 AutocompleteInput::FormattedStringWithEquivalentMeaning(navigation.url(), 1572 AutocompleteInput::FormattedStringWithEquivalentMeaning(navigation.url(),
1486 net::FormatUrl(navigation.url(), languages, format_types, 1573 net::FormatUrl(navigation.url(), languages, format_types,
1487 net::UnescapeRule::SPACES, NULL, NULL, 1574 net::UnescapeRule::SPACES, NULL, NULL,
1488 &inline_autocomplete_offset)); 1575 &inline_autocomplete_offset));
1489 if (!input_.prevent_inline_autocomplete() && 1576 if (!input_.prevent_inline_autocomplete() &&
1490 (inline_autocomplete_offset != string16::npos)) { 1577 (inline_autocomplete_offset != string16::npos)) {
1491 DCHECK(inline_autocomplete_offset <= match.fill_into_edit.length()); 1578 DCHECK(inline_autocomplete_offset <= match.fill_into_edit.length());
1492 match.allowed_to_be_default_match = true; 1579 match.allowed_to_be_default_match = true;
1493 match.inline_autocompletion = 1580 match.inline_autocompletion =
1494 match.fill_into_edit.substr(inline_autocomplete_offset); 1581 match.fill_into_edit.substr(inline_autocomplete_offset);
1495 } 1582 }
1496 1583
1497 match.contents = net::FormatUrl(navigation.url(), languages, 1584 match.contents = navigation.contents();
1498 format_types, net::UnescapeRule::SPACES, NULL, NULL, &match_start); 1585 match.contents_class = navigation.contents_class();
1499 // If the first match in the untrimmed string was inside a scheme that we
1500 // trimmed, look for a subsequent match.
1501 if (match_start == string16::npos)
1502 match_start = match.contents.find(input);
1503 // Safe if |match_start| is npos; also safe if the input is longer than the
1504 // remaining contents after |match_start|.
1505 AutocompleteMatch::ClassifyLocationInString(match_start, input.length(),
1506 match.contents.length(), ACMatchClassification::URL,
1507 &match.contents_class);
1508
1509 match.description = navigation.description(); 1586 match.description = navigation.description();
1510 AutocompleteMatch::ClassifyMatchInString(input, match.description, 1587 AutocompleteMatch::ClassifyMatchInString(input, match.description,
1511 ACMatchClassification::NONE, &match.description_class); 1588 ACMatchClassification::NONE, &match.description_class);
1512 1589
1513 match.RecordAdditionalInfo( 1590 match.RecordAdditionalInfo(
1514 kRelevanceFromServerKey, 1591 kRelevanceFromServerKey,
1515 navigation.relevance_from_server() ? kTrue : kFalse); 1592 navigation.relevance_from_server() ? kTrue : kFalse);
1516 1593
1517 return match; 1594 return match;
1518 } 1595 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1556 it->set_relevance(max_query_relevance); 1633 it->set_relevance(max_query_relevance);
1557 it->set_relevance_from_server(relevance_from_server); 1634 it->set_relevance_from_server(relevance_from_server);
1558 } 1635 }
1559 } 1636 }
1560 1637
1561 void SearchProvider::UpdateDone() { 1638 void SearchProvider::UpdateDone() {
1562 // We're done when the timer isn't running, there are no suggest queries 1639 // We're done when the timer isn't running, there are no suggest queries
1563 // pending, and we're not waiting on Instant. 1640 // pending, and we're not waiting on Instant.
1564 done_ = !timer_.IsRunning() && (suggest_results_pending_ == 0); 1641 done_ = !timer_.IsRunning() && (suggest_results_pending_ == 0);
1565 } 1642 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698