OLD | NEW |
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/base64.h" | 10 #include "base/base64.h" |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 match.keyword = providers_.default_provider(); | 253 match.keyword = providers_.default_provider(); |
254 match.allowed_to_be_default_match = true; | 254 match.allowed_to_be_default_match = true; |
255 matches_.push_back(match); | 255 matches_.push_back(match); |
256 } | 256 } |
257 Stop(true); | 257 Stop(true); |
258 return; | 258 return; |
259 } | 259 } |
260 | 260 |
261 input_ = input; | 261 input_ = input; |
262 | 262 |
| 263 // If Start() is called without minimal_changes, it likely means the user |
| 264 // has pressed a key. This is a good opportunity to change the inline |
| 265 // autocompletion (if any). Restore the results to the original reply |
| 266 // received from the server, thus clobbering any modification (if any) made |
| 267 // to the results to demote an brand new async inline autocompletion. |
| 268 if (!minimal_changes) { |
| 269 default_results_ = orig_default_results_; |
| 270 keyword_results_ = orig_keyword_results_; |
| 271 } |
| 272 |
263 DoHistoryQuery(minimal_changes); | 273 DoHistoryQuery(minimal_changes); |
264 DoAnswersQuery(input); | 274 DoAnswersQuery(input); |
265 StartOrStopSuggestQuery(minimal_changes); | 275 StartOrStopSuggestQuery(minimal_changes); |
266 UpdateMatches(); | 276 UpdateMatches(); |
267 } | 277 } |
268 | 278 |
269 void SearchProvider::SortResults(bool is_keyword, | 279 void SearchProvider::SortResults(bool is_keyword, |
270 SearchSuggestionParser::Results* results) { | 280 SearchSuggestionParser::Results* results) { |
271 // Ignore suggested scores for non-keyword matches in keyword mode; if the | 281 // Ignore suggested scores for non-keyword matches in keyword mode; if the |
272 // server is allowed to score these, it could interfere with the user's | 282 // server is allowed to score these, it could interfere with the user's |
(...skipping 24 matching lines...) Expand all Loading... |
297 return is_keyword ? providers_.GetKeywordProviderURL() | 307 return is_keyword ? providers_.GetKeywordProviderURL() |
298 : providers_.GetDefaultProviderURL(); | 308 : providers_.GetDefaultProviderURL(); |
299 } | 309 } |
300 | 310 |
301 const AutocompleteInput SearchProvider::GetInput(bool is_keyword) const { | 311 const AutocompleteInput SearchProvider::GetInput(bool is_keyword) const { |
302 return is_keyword ? keyword_input_ : input_; | 312 return is_keyword ? keyword_input_ : input_; |
303 } | 313 } |
304 | 314 |
305 SearchSuggestionParser::Results* SearchProvider::GetResultsToFill( | 315 SearchSuggestionParser::Results* SearchProvider::GetResultsToFill( |
306 bool is_keyword) { | 316 bool is_keyword) { |
307 return is_keyword ? &keyword_results_ : &default_results_; | 317 return is_keyword ? &orig_keyword_results_ : &orig_default_results_; |
| 318 } |
| 319 |
| 320 void SearchProvider::HandleReceivedResults(bool is_keyword) { |
| 321 // The general strategy of this function: |
| 322 // 1. Get the needed information from the previously-displayed results. |
| 323 // 2. Copy the newly-received results over the previously-displayed ones. |
| 324 // 3. Modify these results as necessary. |
| 325 |
| 326 // 1. Extract needed information. |
| 327 // Determine the previous inline autocompletion, if any. |
| 328 // We store the inlined suggestion (if any) in one of the two following |
| 329 // variables, leaving them blank if there is no inline suggestion or the |
| 330 // inlined suggestion is not of that type. |
| 331 base::string16 inlined_query_suggestion_match_contents; |
| 332 GURL inlined_navsuggestion; |
| 333 ACMatches::const_iterator first_match = FindTopMatch(); |
| 334 if ((first_match != matches_.end()) && |
| 335 !first_match->inline_autocompletion.empty()) { |
| 336 // Identify if this match came from a query suggestion or a navsuggestion. |
| 337 // In either case, extracts the identifying feature of the suggestion |
| 338 // (query string or navigation url). |
| 339 if (AutocompleteMatch::IsSearchType(first_match->type)) { |
| 340 inlined_query_suggestion_match_contents = first_match->contents; |
| 341 } else { |
| 342 inlined_navsuggestion = first_match->destination_url; |
| 343 } |
| 344 } |
| 345 |
| 346 // 2. Clobber the previous results. |
| 347 SearchSuggestionParser::Results* results_from_server = |
| 348 is_keyword ? &orig_keyword_results_ : &orig_default_results_; |
| 349 SearchSuggestionParser::Results* results = |
| 350 is_keyword ? &keyword_results_ : &default_results_; |
| 351 (*results) = (*results_from_server); |
| 352 |
| 353 // 3. Modify the results. |
| 354 // Mark all results aside from the previous inline autocompletion as not |
| 355 // allowed to be the default match. |
| 356 for (SearchSuggestionParser::SuggestResults::iterator sug_it = |
| 357 results->suggest_results.begin(); |
| 358 sug_it != results->suggest_results.end(); ++sug_it) { |
| 359 if (sug_it->match_contents() != |
| 360 inlined_query_suggestion_match_contents) { |
| 361 sug_it->set_never_allowed_to_be_default_match(true); |
| 362 } |
| 363 } |
| 364 for (SearchSuggestionParser::NavigationResults::iterator nav_it = |
| 365 results->navigation_results.begin(); |
| 366 nav_it != results->navigation_results.end(); ++nav_it) { |
| 367 if (nav_it->url() != inlined_navsuggestion) { |
| 368 nav_it->set_never_allowed_to_be_default_match(true); |
| 369 } |
| 370 } |
308 } | 371 } |
309 | 372 |
310 bool SearchProvider::ShouldAppendExtraParams( | 373 bool SearchProvider::ShouldAppendExtraParams( |
311 const SearchSuggestionParser::SuggestResult& result) const { | 374 const SearchSuggestionParser::SuggestResult& result) const { |
312 return !result.from_keyword_provider() || | 375 return !result.from_keyword_provider() || |
313 providers_.default_provider().empty(); | 376 providers_.default_provider().empty(); |
314 } | 377 } |
315 | 378 |
316 void SearchProvider::StopSuggest() { | 379 void SearchProvider::StopSuggest() { |
317 // Increment the appropriate field in the histogram by the number of | 380 // Increment the appropriate field in the histogram by the number of |
318 // pending requests that were invalidated. | 381 // pending requests that were invalidated. |
319 for (int i = 0; i < suggest_results_pending_; ++i) | 382 for (int i = 0; i < suggest_results_pending_; ++i) |
320 LogOmniboxSuggestRequest(REQUEST_INVALIDATED); | 383 LogOmniboxSuggestRequest(REQUEST_INVALIDATED); |
321 suggest_results_pending_ = 0; | 384 suggest_results_pending_ = 0; |
322 timer_.Stop(); | 385 timer_.Stop(); |
323 // Stop any in-progress URL fetches. | 386 // Stop any in-progress URL fetches. |
324 keyword_fetcher_.reset(); | 387 keyword_fetcher_.reset(); |
325 default_fetcher_.reset(); | 388 default_fetcher_.reset(); |
326 } | 389 } |
327 | 390 |
328 void SearchProvider::ClearAllResults() { | 391 void SearchProvider::ClearAllResults() { |
329 keyword_results_.Clear(); | 392 keyword_results_.Clear(); |
330 default_results_.Clear(); | 393 default_results_.Clear(); |
| 394 orig_keyword_results_.Clear(); |
| 395 orig_default_results_.Clear(); |
331 } | 396 } |
332 | 397 |
333 int SearchProvider::GetDefaultResultRelevance() const { | 398 int SearchProvider::GetDefaultResultRelevance() const { |
334 return -1; | 399 return -1; |
335 } | 400 } |
336 | 401 |
337 void SearchProvider::RecordDeletionResult(bool success) { | 402 void SearchProvider::RecordDeletionResult(bool success) { |
338 if (success) { | 403 if (success) { |
339 content::RecordAction( | 404 content::RecordAction( |
340 base::UserMetricsAction("Omnibox.ServerSuggestDelete.Success")); | 405 base::UserMetricsAction("Omnibox.ServerSuggestDelete.Success")); |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 } | 682 } |
618 | 683 |
619 void SearchProvider::ApplyCalculatedSuggestRelevance( | 684 void SearchProvider::ApplyCalculatedSuggestRelevance( |
620 SearchSuggestionParser::SuggestResults* list) { | 685 SearchSuggestionParser::SuggestResults* list) { |
621 for (size_t i = 0; i < list->size(); ++i) { | 686 for (size_t i = 0; i < list->size(); ++i) { |
622 SearchSuggestionParser::SuggestResult& result = (*list)[i]; | 687 SearchSuggestionParser::SuggestResult& result = (*list)[i]; |
623 result.set_relevance( | 688 result.set_relevance( |
624 result.CalculateRelevance(input_, providers_.has_keyword_provider()) + | 689 result.CalculateRelevance(input_, providers_.has_keyword_provider()) + |
625 (list->size() - i - 1)); | 690 (list->size() - i - 1)); |
626 result.set_relevance_from_server(false); | 691 result.set_relevance_from_server(false); |
| 692 result.set_never_allowed_to_be_default_match(false); |
627 } | 693 } |
628 } | 694 } |
629 | 695 |
630 void SearchProvider::ApplyCalculatedNavigationRelevance( | 696 void SearchProvider::ApplyCalculatedNavigationRelevance( |
631 SearchSuggestionParser::NavigationResults* list) { | 697 SearchSuggestionParser::NavigationResults* list) { |
632 for (size_t i = 0; i < list->size(); ++i) { | 698 for (size_t i = 0; i < list->size(); ++i) { |
633 SearchSuggestionParser::NavigationResult& result = (*list)[i]; | 699 SearchSuggestionParser::NavigationResult& result = (*list)[i]; |
634 result.set_relevance( | 700 result.set_relevance( |
635 result.CalculateRelevance(input_, providers_.has_keyword_provider()) + | 701 result.CalculateRelevance(input_, providers_.has_keyword_provider()) + |
636 (list->size() - i - 1)); | 702 (list->size() - i - 1)); |
637 result.set_relevance_from_server(false); | 703 result.set_relevance_from_server(false); |
| 704 result.set_never_allowed_to_be_default_match(false); |
638 } | 705 } |
639 } | 706 } |
640 | 707 |
641 net::URLFetcher* SearchProvider::CreateSuggestFetcher( | 708 net::URLFetcher* SearchProvider::CreateSuggestFetcher( |
642 int id, | 709 int id, |
643 const TemplateURL* template_url, | 710 const TemplateURL* template_url, |
644 const AutocompleteInput& input) { | 711 const AutocompleteInput& input) { |
645 if (!template_url || template_url->suggestions_url().empty()) | 712 if (!template_url || template_url->suggestions_url().empty()) |
646 return NULL; | 713 return NULL; |
647 | 714 |
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1167 match.fill_into_edit.substr(inline_autocomplete_offset); | 1234 match.fill_into_edit.substr(inline_autocomplete_offset); |
1168 } | 1235 } |
1169 // An inlineable navsuggestion can only be the default match when there | 1236 // An inlineable navsuggestion can only be the default match when there |
1170 // is no keyword provider active, lest it appear first and break the user | 1237 // is no keyword provider active, lest it appear first and break the user |
1171 // out of keyword mode. It can also only be default if either the inline | 1238 // out of keyword mode. It can also only be default if either the inline |
1172 // autocompletion is empty or we're not preventing inline autocompletion. | 1239 // autocompletion is empty or we're not preventing inline autocompletion. |
1173 // Finally, if we have an inlineable navsuggestion with an inline completion | 1240 // Finally, if we have an inlineable navsuggestion with an inline completion |
1174 // that we're not preventing, make sure we didn't trim any whitespace. | 1241 // that we're not preventing, make sure we didn't trim any whitespace. |
1175 // We don't want to claim http://foo.com/bar is inlineable against the | 1242 // We don't want to claim http://foo.com/bar is inlineable against the |
1176 // input "foo.com/b ". | 1243 // input "foo.com/b ". |
1177 match.allowed_to_be_default_match = (prefix != NULL) && | 1244 match.allowed_to_be_default_match = |
| 1245 !navigation.never_allowed_to_be_default_match() && |
| 1246 (prefix != NULL) && |
1178 (providers_.GetKeywordProviderURL() == NULL) && | 1247 (providers_.GetKeywordProviderURL() == NULL) && |
1179 (match.inline_autocompletion.empty() || | 1248 (match.inline_autocompletion.empty() || |
1180 (!input_.prevent_inline_autocomplete() && !trimmed_whitespace)); | 1249 (!input_.prevent_inline_autocomplete() && !trimmed_whitespace)); |
1181 match.EnsureUWYTIsAllowedToBeDefault( | 1250 match.EnsureUWYTIsAllowedToBeDefault( |
1182 input_.canonicalized_url(), providers_.template_url_service()); | 1251 input_.canonicalized_url(), providers_.template_url_service()); |
1183 | 1252 |
1184 match.contents = navigation.match_contents(); | 1253 match.contents = navigation.match_contents(); |
1185 match.contents_class = navigation.match_contents_class(); | 1254 match.contents_class = navigation.match_contents_class(); |
1186 match.description = navigation.description(); | 1255 match.description = navigation.description(); |
1187 AutocompleteMatch::ClassifyMatchInString(input, match.description, | 1256 AutocompleteMatch::ClassifyMatchInString(input, match.description, |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1241 last_answer_seen_.query_type = match->answer_type; | 1310 last_answer_seen_.query_type = match->answer_type; |
1242 } | 1311 } |
1243 | 1312 |
1244 void SearchProvider::DoAnswersQuery(const AutocompleteInput& input) { | 1313 void SearchProvider::DoAnswersQuery(const AutocompleteInput& input) { |
1245 // If the query text starts with trimmed input, this is valid prefetch data. | 1314 // If the query text starts with trimmed input, this is valid prefetch data. |
1246 prefetch_data_ = StartsWith(last_answer_seen_.full_query_text, | 1315 prefetch_data_ = StartsWith(last_answer_seen_.full_query_text, |
1247 base::CollapseWhitespace(input.text(), false), | 1316 base::CollapseWhitespace(input.text(), false), |
1248 false) ? | 1317 false) ? |
1249 last_answer_seen_ : AnswersQueryData(); | 1318 last_answer_seen_ : AnswersQueryData(); |
1250 } | 1319 } |
OLD | NEW |