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

Side by Side Diff: components/omnibox/search_provider.cc

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

Powered by Google App Engine
This is Rietveld 408576698