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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
163 // functions are currently in sync, but there's no reason we | 163 // functions are currently in sync, but there's no reason we |
164 // couldn't decide in the future to score verbatim matches | 164 // couldn't decide in the future to score verbatim matches |
165 // differently for extension and non-extension keywords. If you | 165 // differently for extension and non-extension keywords. If you |
166 // make such a change, however, you should update this comment to | 166 // make such a change, however, you should update this comment to |
167 // describe it, so it's clear why the functions diverge. | 167 // describe it, so it's clear why the functions diverge. |
168 if (prefer_keyword) | 168 if (prefer_keyword) |
169 return 1500; | 169 return 1500; |
170 return (type == metrics::OmniboxInputType::QUERY) ? 1450 : 1100; | 170 return (type == metrics::OmniboxInputType::QUERY) ? 1450 : 1100; |
171 } | 171 } |
172 | 172 |
173 // static | |
174 void SearchProvider::RemoveOrReviseOldResultsForOneProvider( | |
175 bool minimal_changes, SearchSuggestionParser::Results* results) { | |
176 // When called without |minimal_changes|, it likely means the user has | |
177 // pressed a key. Revise the cached results appropriately. | |
178 if (!minimal_changes) { | |
179 for (SearchSuggestionParser::SuggestResults::iterator sug_it = | |
180 results->suggest_results.begin(); | |
181 sug_it != results->suggest_results.end(); ++sug_it) { | |
182 sug_it->set_received_after_last_keystroke(false); | |
183 } | |
184 for (SearchSuggestionParser::NavigationResults::iterator nav_it = | |
185 results->navigation_results.begin(); | |
186 nav_it != results->navigation_results.end(); ++nav_it) { | |
187 nav_it->set_received_after_last_keystroke(false); | |
188 } | |
189 } | |
190 } | |
191 | |
192 // static | |
193 ACMatches::iterator SearchProvider::FindTopMatch(ACMatches* matches) { | |
194 ACMatches::iterator it = matches->begin(); | |
195 while ((it != matches->end()) && !it->allowed_to_be_default_match) | |
196 ++it; | |
197 return it; | |
198 } | |
199 | |
173 void SearchProvider::Start(const AutocompleteInput& input, | 200 void SearchProvider::Start(const AutocompleteInput& input, |
174 bool minimal_changes) { | 201 bool minimal_changes) { |
175 // Do our best to load the model as early as possible. This will reduce | 202 // Do our best to load the model as early as possible. This will reduce |
176 // odds of having the model not ready when really needed (a non-empty input). | 203 // odds of having the model not ready when really needed (a non-empty input). |
177 TemplateURLService* model = providers_.template_url_service(); | 204 TemplateURLService* model = providers_.template_url_service(); |
178 DCHECK(model); | 205 DCHECK(model); |
179 model->Load(); | 206 model->Load(); |
180 | 207 |
181 matches_.clear(); | 208 matches_.clear(); |
182 field_trial_triggered_ = false; | 209 field_trial_triggered_ = false; |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
385 UMA_HISTOGRAM_TIMES("Omnibox.SuggestRequest.Success.GoogleResponseTime", | 412 UMA_HISTOGRAM_TIMES("Omnibox.SuggestRequest.Success.GoogleResponseTime", |
386 elapsed_time); | 413 elapsed_time); |
387 } else { | 414 } else { |
388 UMA_HISTOGRAM_TIMES("Omnibox.SuggestRequest.Failure.GoogleResponseTime", | 415 UMA_HISTOGRAM_TIMES("Omnibox.SuggestRequest.Failure.GoogleResponseTime", |
389 elapsed_time); | 416 elapsed_time); |
390 } | 417 } |
391 } | 418 } |
392 } | 419 } |
393 | 420 |
394 void SearchProvider::UpdateMatches() { | 421 void SearchProvider::UpdateMatches() { |
422 PersistGoodResultsForOneProvider(&default_results_); | |
423 PersistGoodResultsForOneProvider(&keyword_results_); | |
395 ConvertResultsToAutocompleteMatches(); | 424 ConvertResultsToAutocompleteMatches(); |
396 | 425 |
397 // Check constraints that may be violated by suggested relevances. | 426 // Check constraints that may be violated by suggested relevances. |
398 if (!matches_.empty() && | 427 if (!matches_.empty() && |
399 (default_results_.HasServerProvidedScores() || | 428 (default_results_.HasServerProvidedScores() || |
400 keyword_results_.HasServerProvidedScores())) { | 429 keyword_results_.HasServerProvidedScores())) { |
401 // These blocks attempt to repair undesirable behavior by suggested | 430 // These blocks attempt to repair undesirable behavior by suggested |
402 // relevances with minimal impact, preserving other suggested relevances. | 431 // relevances with minimal impact, preserving other suggested relevances. |
403 | 432 |
404 if ((providers_.GetKeywordProviderURL() != NULL) && | 433 if ((providers_.GetKeywordProviderURL() != NULL) && |
405 (FindTopMatch() == matches_.end())) { | 434 (FindTopMatch() == matches_.end())) { |
406 // In keyword mode, disregard the keyword verbatim suggested relevance | 435 // In keyword mode, disregard the keyword verbatim suggested relevance |
407 // if necessary, so at least one match is allowed to be default. | 436 // if necessary, so at least one match is allowed to be default. (This |
408 keyword_results_.verbatim_relevance = -1; | 437 // is only necessary if we were told to suppress keyword verbatim and |
438 // hence have no default keyword match.) Give keyword verbatim the | |
439 // lowest non-zero score to best reflect what the server desired. | |
440 DCHECK_EQ(0, keyword_results_.verbatim_relevance); | |
441 keyword_results_.verbatim_relevance = 1; | |
409 ConvertResultsToAutocompleteMatches(); | 442 ConvertResultsToAutocompleteMatches(); |
410 } | 443 } |
411 if (IsTopMatchSearchWithURLInput()) { | 444 if (IsTopMatchSearchWithURLInput()) { |
412 // Disregard the suggested search and verbatim relevances if the input | 445 // Disregard the suggested search and verbatim relevances if the input |
413 // type is URL and the top match is a highly-ranked search suggestion. | 446 // type is URL and the top match is a highly-ranked search suggestion. |
414 // For example, prevent a search for "foo.com" from outranking another | 447 // For example, prevent a search for "foo.com" from outranking another |
415 // provider's navigation for "foo.com" or "foo.com/url_from_history". | 448 // provider's navigation for "foo.com" or "foo.com/url_from_history". |
416 ApplyCalculatedSuggestRelevance(&keyword_results_.suggest_results); | 449 ApplyCalculatedSuggestRelevance(&keyword_results_.suggest_results); |
417 ApplyCalculatedSuggestRelevance(&default_results_.suggest_results); | 450 ApplyCalculatedSuggestRelevance(&default_results_.suggest_results); |
418 default_results_.verbatim_relevance = -1; | 451 default_results_.verbatim_relevance = -1; |
419 keyword_results_.verbatim_relevance = -1; | 452 keyword_results_.verbatim_relevance = -1; |
420 ConvertResultsToAutocompleteMatches(); | 453 ConvertResultsToAutocompleteMatches(); |
421 } | 454 } |
422 if (FindTopMatch() == matches_.end()) { | 455 if (FindTopMatch() == matches_.end()) { |
423 // Guarantee that SearchProvider returns a legal default match. (The | 456 // Guarantee that SearchProvider returns a legal default match. (The |
424 // omnibox always needs at least one legal default match, and it relies | 457 // omnibox always needs at least one legal default match, and it relies |
425 // on SearchProvider to always return one.) | 458 // on SearchProvider to always return one.) Give the verbatim suggestion |
426 ApplyCalculatedRelevance(); | 459 // the lowest non-zero scores to best reflect what the server desired. |
460 DCHECK_EQ(0, default_results_.verbatim_relevance); | |
461 default_results_.verbatim_relevance = 1; | |
462 // We do not have to alter keyword_results_.verbatim_relevance here. | |
463 // If the user is in keyword mode, we already reverted (earlier in this | |
464 // function) the instructions to suppress keyword verbatim. | |
427 ConvertResultsToAutocompleteMatches(); | 465 ConvertResultsToAutocompleteMatches(); |
428 } | 466 } |
429 DCHECK(!IsTopMatchSearchWithURLInput()); | 467 DCHECK(!IsTopMatchSearchWithURLInput()); |
430 DCHECK(FindTopMatch() != matches_.end()); | 468 DCHECK(FindTopMatch() != matches_.end()); |
431 } | 469 } |
432 UMA_HISTOGRAM_CUSTOM_COUNTS( | 470 UMA_HISTOGRAM_CUSTOM_COUNTS( |
433 "Omnibox.SearchProviderMatches", matches_.size(), 1, 6, 7); | 471 "Omnibox.SearchProviderMatches", matches_.size(), 1, 6, 7); |
472 | |
473 // Record the inlined suggestion (if any) for future use. | |
474 inlined_query_suggestion_match_contents_ = base::string16(); | |
475 inlined_navsuggestion_ = GURL(); | |
476 ACMatches::const_iterator first_match = FindTopMatch(); | |
477 if ((first_match != matches_.end()) && | |
478 !first_match->inline_autocompletion.empty()) { | |
479 // Identify if this match came from a query suggestion or a navsuggestion. | |
480 // In either case, extracts the identifying feature of the suggestion | |
481 // (query string or navigation url). | |
482 if (AutocompleteMatch::IsSearchType(first_match->type)) { | |
483 inlined_query_suggestion_match_contents_ = first_match->contents; | |
484 } else { | |
485 inlined_navsuggestion_ = first_match->destination_url; | |
486 } | |
487 } | |
488 | |
434 UpdateDone(); | 489 UpdateDone(); |
435 } | 490 } |
436 | 491 |
437 void SearchProvider::Run() { | 492 void SearchProvider::Run() { |
438 // Start a new request with the current input. | 493 // Start a new request with the current input. |
439 suggest_results_pending_ = 0; | 494 suggest_results_pending_ = 0; |
440 time_suggest_request_sent_ = base::TimeTicks::Now(); | 495 time_suggest_request_sent_ = base::TimeTicks::Now(); |
441 | 496 |
442 default_fetcher_.reset(CreateSuggestFetcher(kDefaultProviderURLFetcherID, | 497 default_fetcher_.reset(CreateSuggestFetcher(kDefaultProviderURLFetcherID, |
443 providers_.GetDefaultProviderURL(), input_)); | 498 providers_.GetDefaultProviderURL(), input_)); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
514 (!default_results_.suggest_results.empty() || | 569 (!default_results_.suggest_results.empty() || |
515 !default_results_.navigation_results.empty() || | 570 !default_results_.navigation_results.empty() || |
516 !keyword_results_.suggest_results.empty() || | 571 !keyword_results_.suggest_results.empty() || |
517 !keyword_results_.navigation_results.empty() || | 572 !keyword_results_.navigation_results.empty() || |
518 (!done_ && input_.want_asynchronous_matches()))) | 573 (!done_ && input_.want_asynchronous_matches()))) |
519 return; | 574 return; |
520 | 575 |
521 // We can't keep running any previous query, so halt it. | 576 // We can't keep running any previous query, so halt it. |
522 StopSuggest(); | 577 StopSuggest(); |
523 | 578 |
524 // Remove existing results that cannot inline autocomplete the new input. | 579 RemoveOrReviseOldResults(minimal_changes); |
525 RemoveAllStaleResults(); | |
526 | 580 |
527 // Update the content classifications of remaining results so they look good | 581 // Update the content classifications of remaining results so they look good |
528 // against the current input. | 582 // against the current input. |
529 UpdateMatchContentsClass(input_.text(), &default_results_); | 583 UpdateMatchContentsClass(input_.text(), &default_results_); |
530 if (!keyword_input_.text().empty()) | 584 if (!keyword_input_.text().empty()) |
531 UpdateMatchContentsClass(keyword_input_.text(), &keyword_results_); | 585 UpdateMatchContentsClass(keyword_input_.text(), &keyword_results_); |
532 | 586 |
533 // We can't start a new query if we're only allowed synchronous results. | 587 // We can't start a new query if we're only allowed synchronous results. |
534 if (!input_.want_asynchronous_matches()) | 588 if (!input_.want_asynchronous_matches()) |
535 return; | 589 return; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
599 // Don't send anything for https except the hostname. Hostnames are OK | 653 // Don't send anything for https except the hostname. Hostnames are OK |
600 // because they are visible when the TCP connection is established, but the | 654 // because they are visible when the TCP connection is established, but the |
601 // specific path may reveal private information. | 655 // specific path may reveal private information. |
602 if (LowerCaseEqualsASCII(input_.scheme(), url::kHttpsScheme) && | 656 if (LowerCaseEqualsASCII(input_.scheme(), url::kHttpsScheme) && |
603 parts.path.is_nonempty()) | 657 parts.path.is_nonempty()) |
604 return false; | 658 return false; |
605 | 659 |
606 return true; | 660 return true; |
607 } | 661 } |
608 | 662 |
609 void SearchProvider::RemoveAllStaleResults() { | 663 void SearchProvider::RemoveOrReviseOldResults(bool minimal_changes) { |
610 if (keyword_input_.text().empty()) { | 664 if (keyword_input_.text().empty()) { |
611 // User is either in keyword mode with a blank input or out of | 665 // User is either in keyword mode with a blank input or out of |
612 // keyword mode entirely. | 666 // keyword mode entirely. |
613 keyword_results_.Clear(); | 667 keyword_results_.Clear(); |
614 } | 668 } |
669 RemoveOrReviseOldResultsForOneProvider(minimal_changes, &default_results_); | |
670 RemoveOrReviseOldResultsForOneProvider(minimal_changes, &keyword_results_); | |
615 } | 671 } |
616 | 672 |
617 void SearchProvider::ApplyCalculatedRelevance() { | 673 void SearchProvider::PersistGoodResultsForOneProvider( |
618 ApplyCalculatedSuggestRelevance(&keyword_results_.suggest_results); | 674 SearchSuggestionParser::Results* results) { |
619 ApplyCalculatedSuggestRelevance(&default_results_.suggest_results); | 675 // Mark the result corresponding to the previous inline autocompletion as |
620 ApplyCalculatedNavigationRelevance(&keyword_results_.navigation_results); | 676 // having been received on a previous keystroke (as indeed it must have |
621 ApplyCalculatedNavigationRelevance(&default_results_.navigation_results); | 677 // because we prohibit newly-received results from becoming the inline |
622 default_results_.verbatim_relevance = -1; | 678 // autocompletion). |
623 keyword_results_.verbatim_relevance = -1; | 679 if (!inlined_query_suggestion_match_contents_.empty()) { |
680 for (SearchSuggestionParser::SuggestResults::iterator sug_it = | |
681 results->suggest_results.begin(); | |
682 sug_it != results->suggest_results.end(); ++sug_it) { | |
683 if (sug_it->match_contents() == | |
684 inlined_query_suggestion_match_contents_) | |
685 sug_it->set_received_after_last_keystroke(false); | |
686 } | |
687 } | |
688 if (inlined_navsuggestion_.is_valid()) { | |
689 for (SearchSuggestionParser::NavigationResults::iterator nav_it = | |
690 results->navigation_results.begin(); | |
691 nav_it != results->navigation_results.end(); ++nav_it) { | |
692 if (nav_it->url() == inlined_navsuggestion_) | |
693 nav_it->set_received_after_last_keystroke(false); | |
694 } | |
695 } | |
624 } | 696 } |
625 | 697 |
626 void SearchProvider::ApplyCalculatedSuggestRelevance( | 698 void SearchProvider::ApplyCalculatedSuggestRelevance( |
627 SearchSuggestionParser::SuggestResults* list) { | 699 SearchSuggestionParser::SuggestResults* list) { |
628 for (size_t i = 0; i < list->size(); ++i) { | 700 for (size_t i = 0; i < list->size(); ++i) { |
629 SearchSuggestionParser::SuggestResult& result = (*list)[i]; | 701 SearchSuggestionParser::SuggestResult& result = (*list)[i]; |
630 result.set_relevance( | 702 result.set_relevance( |
631 result.CalculateRelevance(input_, providers_.has_keyword_provider()) + | 703 result.CalculateRelevance(input_, providers_.has_keyword_provider()) + |
632 (list->size() - i - 1)); | 704 (list->size() - i - 1)); |
633 result.set_relevance_from_server(false); | 705 result.set_relevance_from_server(false); |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
782 default_results_.metadata, &map); | 854 default_results_.metadata, &map); |
783 | 855 |
784 ACMatches matches; | 856 ACMatches matches; |
785 for (MatchMap::const_iterator i(map.begin()); i != map.end(); ++i) | 857 for (MatchMap::const_iterator i(map.begin()); i != map.end(); ++i) |
786 matches.push_back(i->second); | 858 matches.push_back(i->second); |
787 | 859 |
788 AddNavigationResultsToMatches(keyword_results_.navigation_results, &matches); | 860 AddNavigationResultsToMatches(keyword_results_.navigation_results, &matches); |
789 AddNavigationResultsToMatches(default_results_.navigation_results, &matches); | 861 AddNavigationResultsToMatches(default_results_.navigation_results, &matches); |
790 | 862 |
791 // Now add the most relevant matches to |matches_|. We take up to kMaxMatches | 863 // Now add the most relevant matches to |matches_|. We take up to kMaxMatches |
792 // suggest/navsuggest matches, regardless of origin. If Instant Extended is | 864 // suggest/navsuggest matches, regardless of origin. We always include in |
793 // enabled and we have server-provided (and thus hopefully more accurate) | 865 // that set a legal default match if possible. If Instant Extended is enabled |
794 // scores for some suggestions, we allow more of those, until we reach | 866 // and we have server-provided (and thus hopefully more accurate) scores for |
867 // some suggestions, we allow more of those, until we reach | |
795 // AutocompleteResult::kMaxMatches total matches (that is, enough to fill the | 868 // AutocompleteResult::kMaxMatches total matches (that is, enough to fill the |
796 // whole popup). | 869 // whole popup). |
797 // | 870 // |
798 // We will always return any verbatim matches, no matter how we obtained their | 871 // We will always return any verbatim matches, no matter how we obtained their |
799 // scores, unless we have already accepted AutocompleteResult::kMaxMatches | 872 // scores, unless we have already accepted AutocompleteResult::kMaxMatches |
800 // higher-scoring matches under the conditions above. | 873 // higher-scoring matches under the conditions above. |
801 std::sort(matches.begin(), matches.end(), &AutocompleteMatch::MoreRelevant); | 874 std::sort(matches.begin(), matches.end(), &AutocompleteMatch::MoreRelevant); |
802 matches_.clear(); | 875 matches_.clear(); |
876 // Guarantee that if there's a legal default match anywhere in the result | |
877 // set that it'll get returned by moving the default match to the front | |
878 // of the list. | |
879 ACMatches::iterator default_match = FindTopMatch(&matches); | |
880 if (default_match != matches.end()) { | |
881 std::rotate(matches.begin(), default_match, default_match + 1); | |
882 } | |
803 | 883 |
804 size_t num_suggestions = 0; | 884 size_t num_suggestions = 0; |
805 for (ACMatches::const_iterator i(matches.begin()); | 885 for (ACMatches::const_iterator i(matches.begin()); |
806 (i != matches.end()) && | 886 (i != matches.end()) && |
807 (matches_.size() < AutocompleteResult::kMaxMatches); | 887 (matches_.size() < AutocompleteResult::kMaxMatches); |
808 ++i) { | 888 ++i) { |
809 // SEARCH_OTHER_ENGINE is only used in the SearchProvider for the keyword | 889 // SEARCH_OTHER_ENGINE is only used in the SearchProvider for the keyword |
810 // verbatim result, so this condition basically means "if this match is a | 890 // verbatim result, so this condition basically means "if this match is a |
811 // suggestion of some sort". | 891 // suggestion of some sort". |
812 if ((i->type != AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED) && | 892 if ((i->type != AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED) && |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
931 prevent_search_history_inlining); | 1011 prevent_search_history_inlining); |
932 // Add the match to |scored_results| by putting the what-you-typed match | 1012 // Add the match to |scored_results| by putting the what-you-typed match |
933 // on the front and appending all other matches. We want the what-you- | 1013 // on the front and appending all other matches. We want the what-you- |
934 // typed match to always be first. | 1014 // typed match to always be first. |
935 SearchSuggestionParser::SuggestResults::iterator insertion_position = | 1015 SearchSuggestionParser::SuggestResults::iterator insertion_position = |
936 scored_results.end(); | 1016 scored_results.end(); |
937 if (trimmed_suggestion == trimmed_input) { | 1017 if (trimmed_suggestion == trimmed_input) { |
938 found_what_you_typed_match = true; | 1018 found_what_you_typed_match = true; |
939 insertion_position = scored_results.begin(); | 1019 insertion_position = scored_results.begin(); |
940 } | 1020 } |
941 scored_results.insert( | 1021 SearchSuggestionParser::SuggestResult history_suggestion( |
942 insertion_position, | 1022 trimmed_suggestion, AutocompleteMatchType::SEARCH_HISTORY, |
943 SearchSuggestionParser::SuggestResult( | 1023 trimmed_suggestion, base::string16(), base::string16(), |
944 trimmed_suggestion, AutocompleteMatchType::SEARCH_HISTORY, | 1024 base::string16(), base::string16(), std::string(), std::string(), |
945 trimmed_suggestion, base::string16(), base::string16(), | 1025 is_keyword, relevance, false, false, trimmed_input); |
946 base::string16(), base::string16(), std::string(), std::string(), | 1026 // History results are synchronous; they are received at the last keystroke, |
947 is_keyword, relevance, false, false, trimmed_input)); | 1027 // not after it. |
1028 history_suggestion.set_received_after_last_keystroke(false); | |
1029 scored_results.insert(insertion_position, history_suggestion); | |
948 } | 1030 } |
949 | 1031 |
950 // History returns results sorted for us. However, we may have docked some | 1032 // History returns results sorted for us. However, we may have docked some |
951 // results' scores, so things are no longer in order. While keeping the | 1033 // results' scores, so things are no longer in order. While keeping the |
952 // what-you-typed match at the front (if it exists), do a stable sort to get | 1034 // what-you-typed match at the front (if it exists), do a stable sort to get |
953 // things back in order without otherwise disturbing results with equal | 1035 // things back in order without otherwise disturbing results with equal |
954 // scores, then force the scores to be unique, so that the order in which | 1036 // scores, then force the scores to be unique, so that the order in which |
955 // they're shown is deterministic. | 1037 // they're shown is deterministic. |
956 std::stable_sort(scored_results.begin() + | 1038 std::stable_sort(scored_results.begin() + |
957 (found_what_you_typed_match ? 1 : 0), | 1039 (found_what_you_typed_match ? 1 : 0), |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1172 if (inline_autocomplete_offset != base::string16::npos) | 1254 if (inline_autocomplete_offset != base::string16::npos) |
1173 ++inline_autocomplete_offset; | 1255 ++inline_autocomplete_offset; |
1174 } | 1256 } |
1175 if (inline_autocomplete_offset != base::string16::npos) { | 1257 if (inline_autocomplete_offset != base::string16::npos) { |
1176 DCHECK(inline_autocomplete_offset <= match.fill_into_edit.length()); | 1258 DCHECK(inline_autocomplete_offset <= match.fill_into_edit.length()); |
1177 match.inline_autocompletion = | 1259 match.inline_autocompletion = |
1178 match.fill_into_edit.substr(inline_autocomplete_offset); | 1260 match.fill_into_edit.substr(inline_autocomplete_offset); |
1179 } | 1261 } |
1180 // An inlineable navsuggestion can only be the default match when there | 1262 // An inlineable navsuggestion can only be the default match when there |
1181 // is no keyword provider active, lest it appear first and break the user | 1263 // is no keyword provider active, lest it appear first and break the user |
1182 // out of keyword mode. It can also only be default if either the inline | 1264 // out of keyword mode. We also must have received the navsuggestion before |
1265 // the last keystroke. (We don't want asynchronous inline autocompletions.) | |
1266 // The navsuggestion can also only be default if either the inline | |
1183 // autocompletion is empty or we're not preventing inline autocompletion. | 1267 // autocompletion is empty or we're not preventing inline autocompletion. |
1184 // Finally, if we have an inlineable navsuggestion with an inline completion | 1268 // Finally, if we have an inlineable navsuggestion with an inline completion |
1185 // that we're not preventing, make sure we didn't trim any whitespace. | 1269 // that we're not preventing, make sure we didn't trim any whitespace. |
1186 // We don't want to claim http://foo.com/bar is inlineable against the | 1270 // We don't want to claim http://foo.com/bar is inlineable against the |
1187 // input "foo.com/b ". | 1271 // input "foo.com/b ". |
1188 match.allowed_to_be_default_match = (prefix != NULL) && | 1272 match.allowed_to_be_default_match = |
1273 (prefix != NULL) && | |
1189 (providers_.GetKeywordProviderURL() == NULL) && | 1274 (providers_.GetKeywordProviderURL() == NULL) && |
1275 !navigation.received_after_last_keystroke() && | |
msw
2014/08/15 21:27:59
ditto to my other comment in this round.
Mark P
2014/08/15 22:09:22
ditto my other answer. :-)
| |
1190 (match.inline_autocompletion.empty() || | 1276 (match.inline_autocompletion.empty() || |
1191 (!input_.prevent_inline_autocomplete() && !trimmed_whitespace)); | 1277 (!input_.prevent_inline_autocomplete() && !trimmed_whitespace)); |
1192 match.EnsureUWYTIsAllowedToBeDefault( | 1278 match.EnsureUWYTIsAllowedToBeDefault( |
1193 input_.canonicalized_url(), providers_.template_url_service()); | 1279 input_.canonicalized_url(), providers_.template_url_service()); |
1194 | 1280 |
1195 match.contents = navigation.match_contents(); | 1281 match.contents = navigation.match_contents(); |
1196 match.contents_class = navigation.match_contents_class(); | 1282 match.contents_class = navigation.match_contents_class(); |
1197 match.description = navigation.description(); | 1283 match.description = navigation.description(); |
1198 AutocompleteMatch::ClassifyMatchInString(input, match.description, | 1284 AutocompleteMatch::ClassifyMatchInString(input, match.description, |
1199 ACMatchClassification::NONE, &match.description_class); | 1285 ACMatchClassification::NONE, &match.description_class); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1252 last_answer_seen_.query_type = match->answer_type; | 1338 last_answer_seen_.query_type = match->answer_type; |
1253 } | 1339 } |
1254 | 1340 |
1255 void SearchProvider::DoAnswersQuery(const AutocompleteInput& input) { | 1341 void SearchProvider::DoAnswersQuery(const AutocompleteInput& input) { |
1256 // If the query text starts with trimmed input, this is valid prefetch data. | 1342 // If the query text starts with trimmed input, this is valid prefetch data. |
1257 prefetch_data_ = StartsWith(last_answer_seen_.full_query_text, | 1343 prefetch_data_ = StartsWith(last_answer_seen_.full_query_text, |
1258 base::CollapseWhitespace(input.text(), false), | 1344 base::CollapseWhitespace(input.text(), false), |
1259 false) ? | 1345 false) ? |
1260 last_answer_seen_ : AnswersQueryData(); | 1346 last_answer_seen_ : AnswersQueryData(); |
1261 } | 1347 } |
OLD | NEW |