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

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

Issue 12039053: Fix cursor position for default provider searches in keyword mode. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Addressed Mark's comments. Created 7 years, 11 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 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 220
221 instant_finalized_ = 221 instant_finalized_ =
222 (input.matches_requested() != AutocompleteInput::ALL_MATCHES); 222 (input.matches_requested() != AutocompleteInput::ALL_MATCHES);
223 223
224 // Can't return search/suggest results for bogus input or without a profile. 224 // Can't return search/suggest results for bogus input or without a profile.
225 if (!profile_ || (input.type() == AutocompleteInput::INVALID)) { 225 if (!profile_ || (input.type() == AutocompleteInput::INVALID)) {
226 Stop(false); 226 Stop(false);
227 return; 227 return;
228 } 228 }
229 229
230 keyword_input_text_.clear(); 230 keyword_input_ = input;
231 const TemplateURL* keyword_provider = 231 const TemplateURL* keyword_provider =
232 KeywordProvider::GetSubstitutingTemplateURLForInput(profile_, input, 232 KeywordProvider::GetSubstitutingTemplateURLForInput(model,
233 &keyword_input_text_); 233 &keyword_input_);
234 if (keyword_input_text_.empty()) 234 if (keyword_provider == NULL)
235 keyword_input_.Clear();
236 else if (keyword_input_.text().empty())
235 keyword_provider = NULL; 237 keyword_provider = NULL;
236 238
237 const TemplateURL* default_provider = model->GetDefaultSearchProvider(); 239 const TemplateURL* default_provider = model->GetDefaultSearchProvider();
238 if (default_provider && !default_provider->SupportsReplacement()) 240 if (default_provider && !default_provider->SupportsReplacement())
239 default_provider = NULL; 241 default_provider = NULL;
240 242
241 if (keyword_provider == default_provider) 243 if (keyword_provider == default_provider)
242 default_provider = NULL; // No use in querying the same provider twice. 244 default_provider = NULL; // No use in querying the same provider twice.
243 245
244 if (!default_provider && !keyword_provider) { 246 if (!default_provider && !keyword_provider) {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 return a.relevance() > b.relevance(); 325 return a.relevance() > b.relevance();
324 } 326 }
325 }; 327 };
326 328
327 void SearchProvider::Run() { 329 void SearchProvider::Run() {
328 // Start a new request with the current input. 330 // Start a new request with the current input.
329 suggest_results_pending_ = 0; 331 suggest_results_pending_ = 0;
330 time_suggest_request_sent_ = base::TimeTicks::Now(); 332 time_suggest_request_sent_ = base::TimeTicks::Now();
331 333
332 default_fetcher_.reset(CreateSuggestFetcher(kDefaultProviderURLFetcherID, 334 default_fetcher_.reset(CreateSuggestFetcher(kDefaultProviderURLFetcherID,
333 providers_.GetDefaultProviderURL(), input_.text())); 335 providers_.GetDefaultProviderURL(), input_));
334 keyword_fetcher_.reset(CreateSuggestFetcher(kKeywordProviderURLFetcherID, 336 keyword_fetcher_.reset(CreateSuggestFetcher(kKeywordProviderURLFetcherID,
335 providers_.GetKeywordProviderURL(), keyword_input_text_)); 337 providers_.GetKeywordProviderURL(), keyword_input_));
336 338
337 // Both the above can fail if the providers have been modified or deleted 339 // Both the above can fail if the providers have been modified or deleted
338 // since the query began. 340 // since the query began.
339 if (suggest_results_pending_ == 0) { 341 if (suggest_results_pending_ == 0) {
340 UpdateDone(); 342 UpdateDone();
341 // We only need to update the listener if we're actually done. 343 // We only need to update the listener if we're actually done.
342 if (done_) 344 if (done_)
343 listener_->OnProviderUpdate(false); 345 listener_->OnProviderUpdate(false);
344 } 346 }
345 } 347 }
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 // database. 465 // database.
464 int num_matches = kMaxMatches * 5; 466 int num_matches = kMaxMatches * 5;
465 const TemplateURL* default_url = providers_.GetDefaultProviderURL(); 467 const TemplateURL* default_url = providers_.GetDefaultProviderURL();
466 if (default_url) { 468 if (default_url) {
467 url_db->GetMostRecentKeywordSearchTerms(default_url->id(), input_.text(), 469 url_db->GetMostRecentKeywordSearchTerms(default_url->id(), input_.text(),
468 num_matches, &default_history_results_); 470 num_matches, &default_history_results_);
469 } 471 }
470 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL(); 472 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL();
471 if (keyword_url) { 473 if (keyword_url) {
472 url_db->GetMostRecentKeywordSearchTerms(keyword_url->id(), 474 url_db->GetMostRecentKeywordSearchTerms(keyword_url->id(),
473 keyword_input_text_, num_matches, &keyword_history_results_); 475 keyword_input_.text(), num_matches, &keyword_history_results_);
474 } 476 }
475 } 477 }
476 478
477 void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes) { 479 void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes) {
478 if (!IsQuerySuitableForSuggest()) { 480 if (!IsQuerySuitableForSuggest()) {
479 StopSuggest(); 481 StopSuggest();
480 ClearResults(); 482 ClearResults();
481 return; 483 return;
482 } 484 }
483 485
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 keyword_suggest_results_.clear(); 586 keyword_suggest_results_.clear();
585 default_suggest_results_.clear(); 587 default_suggest_results_.clear();
586 keyword_navigation_results_.clear(); 588 keyword_navigation_results_.clear();
587 default_navigation_results_.clear(); 589 default_navigation_results_.clear();
588 has_suggested_relevance_ = false; 590 has_suggested_relevance_ = false;
589 verbatim_relevance_ = -1; 591 verbatim_relevance_ = -1;
590 have_suggest_results_ = false; 592 have_suggest_results_ = false;
591 } 593 }
592 594
593 void SearchProvider::RemoveStaleResults() { 595 void SearchProvider::RemoveStaleResults() {
594 // Keyword provider results should match |keyword_input_text_|, unless 596 // Keyword provider results should match |keyword_input_.text()|, unless
595 // the input was just changed to non-keyword mode; in that case, compare 597 // the input was just changed to non-keyword mode; in that case, compare
596 // against |input_.text()|. 598 // against |input_.text()|.
597 const string16& keyword_input = 599 const string16& keyword_input =
598 !keyword_input_text_.empty() ? keyword_input_text_ : input_.text(); 600 !keyword_input_.text().empty() ? keyword_input_.text() : input_.text();
599 RemoveStaleSuggestResults(&keyword_suggest_results_, keyword_input); 601 RemoveStaleSuggestResults(&keyword_suggest_results_, keyword_input);
600 RemoveStaleSuggestResults(&default_suggest_results_, input_.text()); 602 RemoveStaleSuggestResults(&default_suggest_results_, input_.text());
601 RemoveStaleNavigationResults(&keyword_navigation_results_, keyword_input); 603 RemoveStaleNavigationResults(&keyword_navigation_results_, keyword_input);
602 RemoveStaleNavigationResults(&default_navigation_results_, input_.text()); 604 RemoveStaleNavigationResults(&default_navigation_results_, input_.text());
603 } 605 }
604 606
605 // static 607 // static
606 void SearchProvider::RemoveStaleSuggestResults(SuggestResults* list, 608 void SearchProvider::RemoveStaleSuggestResults(SuggestResults* list,
607 const string16& input) { 609 const string16& input) {
608 for (SuggestResults::iterator i = list->begin(); i < list->end();) 610 for (SuggestResults::iterator i = list->begin(); i < list->end();)
(...skipping 30 matching lines...) Expand all
639 bool is_keyword) { 641 bool is_keyword) {
640 for (size_t i = 0; i < list->size(); ++i) { 642 for (size_t i = 0; i < list->size(); ++i) {
641 (*list)[i].set_relevance(CalculateRelevanceForNavigation(is_keyword) + 643 (*list)[i].set_relevance(CalculateRelevanceForNavigation(is_keyword) +
642 (list->size() - i - 1)); 644 (list->size() - i - 1));
643 } 645 }
644 } 646 }
645 647
646 net::URLFetcher* SearchProvider::CreateSuggestFetcher( 648 net::URLFetcher* SearchProvider::CreateSuggestFetcher(
647 int id, 649 int id,
648 const TemplateURL* template_url, 650 const TemplateURL* template_url,
649 const string16& text) { 651 const AutocompleteInput& input) {
650 if (!template_url || template_url->suggestions_url().empty()) 652 if (!template_url || template_url->suggestions_url().empty())
651 return NULL; 653 return NULL;
652 654
653 // Bail if the suggestion URL is invalid with the given replacements. 655 // Bail if the suggestion URL is invalid with the given replacements.
654 TemplateURLRef::SearchTermsArgs search_term_args(text); 656 TemplateURLRef::SearchTermsArgs search_term_args(input.text());
655 search_term_args.cursor_position = input_.cursor_position(); 657 search_term_args.cursor_position = input.cursor_position();
656 GURL suggest_url(template_url->suggestions_url_ref().ReplaceSearchTerms( 658 GURL suggest_url(template_url->suggestions_url_ref().ReplaceSearchTerms(
657 search_term_args)); 659 search_term_args));
658 if (!suggest_url.is_valid()) 660 if (!suggest_url.is_valid())
659 return NULL; 661 return NULL;
660 662
661 suggest_results_pending_++; 663 suggest_results_pending_++;
662 LogOmniboxSuggestRequest(REQUEST_SENT); 664 LogOmniboxSuggestRequest(REQUEST_SENT);
663 665
664 net::URLFetcher* fetcher = 666 net::URLFetcher* fetcher =
665 net::URLFetcher::Create(id, suggest_url, net::URLFetcher::GET, this); 667 net::URLFetcher::Create(id, suggest_url, net::URLFetcher::GET, this);
666 fetcher->SetRequestContext(profile_->GetRequestContext()); 668 fetcher->SetRequestContext(profile_->GetRequestContext());
667 fetcher->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES); 669 fetcher->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES);
668 // Add Chrome experiment state to the request headers. 670 // Add Chrome experiment state to the request headers.
669 net::HttpRequestHeaders headers; 671 net::HttpRequestHeaders headers;
670 chrome_variations::VariationsHttpHeaderProvider::GetInstance()->AppendHeaders( 672 chrome_variations::VariationsHttpHeaderProvider::GetInstance()->AppendHeaders(
671 fetcher->GetOriginalURL(), profile_->IsOffTheRecord(), false, &headers); 673 fetcher->GetOriginalURL(), profile_->IsOffTheRecord(), false, &headers);
672 fetcher->SetExtraRequestHeaders(headers.ToString()); 674 fetcher->SetExtraRequestHeaders(headers.ToString());
673 fetcher->Start(); 675 fetcher->Start();
674 return fetcher; 676 return fetcher;
675 } 677 }
676 678
677 bool SearchProvider::ParseSuggestResults(Value* root_val, bool is_keyword) { 679 bool SearchProvider::ParseSuggestResults(Value* root_val, bool is_keyword) {
678 // TODO(pkasting): Fix |have_suggest_results_|; see http://crbug.com/130631 680 // TODO(pkasting): Fix |have_suggest_results_|; see http://crbug.com/130631
679 have_suggest_results_ = false; 681 have_suggest_results_ = false;
680 682
681 string16 query; 683 string16 query;
682 ListValue* root_list = NULL; 684 ListValue* root_list = NULL;
683 ListValue* results = NULL; 685 ListValue* results = NULL;
684 const string16& input_text = is_keyword ? keyword_input_text_ : input_.text(); 686 const string16& input_text =
687 is_keyword ? keyword_input_.text() : input_.text();
685 if (!root_val->GetAsList(&root_list) || !root_list->GetString(0, &query) || 688 if (!root_val->GetAsList(&root_list) || !root_list->GetString(0, &query) ||
686 (query != input_text) || !root_list->GetList(1, &results)) 689 (query != input_text) || !root_list->GetList(1, &results))
687 return false; 690 return false;
688 691
689 // 3rd element: Description list. 692 // 3rd element: Description list.
690 ListValue* descriptions = NULL; 693 ListValue* descriptions = NULL;
691 root_list->GetList(2, &descriptions); 694 root_list->GetList(2, &descriptions);
692 695
693 // 4th element: Disregard the query URL list for now. 696 // 4th element: Disregard the query URL list for now.
694 697
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
939 942
940 void SearchProvider::AddHistoryResultsToMap(const HistoryResults& results, 943 void SearchProvider::AddHistoryResultsToMap(const HistoryResults& results,
941 bool is_keyword, 944 bool is_keyword,
942 int did_not_accept_suggestion, 945 int did_not_accept_suggestion,
943 MatchMap* map) { 946 MatchMap* map) {
944 if (results.empty()) 947 if (results.empty())
945 return; 948 return;
946 949
947 bool prevent_inline_autocomplete = input_.prevent_inline_autocomplete() || 950 bool prevent_inline_autocomplete = input_.prevent_inline_autocomplete() ||
948 (input_.type() == AutocompleteInput::URL); 951 (input_.type() == AutocompleteInput::URL);
949 const string16& input_text = is_keyword ? keyword_input_text_ : input_.text(); 952 const string16& input_text =
953 is_keyword ? keyword_input_.text() : input_.text();
950 bool input_multiple_words = HasMultipleWords(input_text); 954 bool input_multiple_words = HasMultipleWords(input_text);
951 955
952 SuggestResults scored_results; 956 SuggestResults scored_results;
953 if (!prevent_inline_autocomplete && input_multiple_words) { 957 if (!prevent_inline_autocomplete && input_multiple_words) {
954 // ScoreHistoryResults() allows autocompletion of multi-word, 1-visit 958 // ScoreHistoryResults() allows autocompletion of multi-word, 1-visit
955 // queries if the input also has multiple words. But if we were already 959 // queries if the input also has multiple words. But if we were already
956 // autocompleting a multi-word, multi-visit query, and the current input is 960 // autocompleting a multi-word, multi-visit query, and the current input is
957 // still a prefix of it, then changing the autocompletion suddenly feels 961 // still a prefix of it, then changing the autocompletion suddenly feels
958 // wrong. To detect this case, first score as if only one word has been 962 // wrong. To detect this case, first score as if only one word has been
959 // typed, then check for a best result that is an autocompleted, multi-word 963 // typed, then check for a best result that is an autocompleted, multi-word
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1032 i->set_relevance(last_relevance - 1); 1036 i->set_relevance(last_relevance - 1);
1033 last_relevance = i->relevance(); 1037 last_relevance = i->relevance();
1034 } 1038 }
1035 1039
1036 return scored_results; 1040 return scored_results;
1037 } 1041 }
1038 1042
1039 void SearchProvider::AddSuggestResultsToMap(const SuggestResults& results, 1043 void SearchProvider::AddSuggestResultsToMap(const SuggestResults& results,
1040 bool is_keyword, 1044 bool is_keyword,
1041 MatchMap* map) { 1045 MatchMap* map) {
1042 const string16& input_text = is_keyword ? keyword_input_text_ : input_.text(); 1046 const string16& input_text =
1047 is_keyword ? keyword_input_.text() : input_.text();
1043 for (size_t i = 0; i < results.size(); ++i) { 1048 for (size_t i = 0; i < results.size(); ++i) {
1044 AddMatchToMap(results[i].suggestion(), input_text, results[i].relevance(), 1049 AddMatchToMap(results[i].suggestion(), input_text, results[i].relevance(),
1045 AutocompleteMatch::SEARCH_SUGGEST, i, is_keyword, map); 1050 AutocompleteMatch::SEARCH_SUGGEST, i, is_keyword, map);
1046 } 1051 }
1047 } 1052 }
1048 1053
1049 int SearchProvider::GetVerbatimRelevance() const { 1054 int SearchProvider::GetVerbatimRelevance() const {
1050 // Use the suggested verbatim relevance score if it is non-negative (valid), 1055 // Use the suggested verbatim relevance score if it is non-negative (valid),
1051 // if inline autocomplete isn't prevented (always show verbatim on backspace), 1056 // if inline autocomplete isn't prevented (always show verbatim on backspace),
1052 // and if it won't suppress verbatim, leaving no default provider matches. 1057 // and if it won't suppress verbatim, leaving no default provider matches.
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 // results sorted by recency, this means we'll pick the most recent such 1235 // results sorted by recency, this means we'll pick the most recent such
1231 // result even if the precision of our relevance score is too low to 1236 // result even if the precision of our relevance score is too low to
1232 // distinguish the two. 1237 // distinguish the two.
1233 if (!i.second && (match.relevance > i.first->second.relevance)) 1238 if (!i.second && (match.relevance > i.first->second.relevance))
1234 i.first->second = match; 1239 i.first->second = match;
1235 } 1240 }
1236 1241
1237 AutocompleteMatch SearchProvider::NavigationToMatch( 1242 AutocompleteMatch SearchProvider::NavigationToMatch(
1238 const NavigationResult& navigation, 1243 const NavigationResult& navigation,
1239 bool is_keyword) { 1244 bool is_keyword) {
1240 const string16& input = is_keyword ? keyword_input_text_ : input_.text(); 1245 const string16& input = is_keyword ? keyword_input_.text() : input_.text();
1241 AutocompleteMatch match(this, navigation.relevance(), false, 1246 AutocompleteMatch match(this, navigation.relevance(), false,
1242 AutocompleteMatch::NAVSUGGEST); 1247 AutocompleteMatch::NAVSUGGEST);
1243 match.destination_url = navigation.url(); 1248 match.destination_url = navigation.url();
1244 1249
1245 // First look for the user's input inside the fill_into_edit as it would be 1250 // First look for the user's input inside the fill_into_edit as it would be
1246 // without trimming the scheme, so we can find matches at the beginning of the 1251 // without trimming the scheme, so we can find matches at the beginning of the
1247 // scheme. 1252 // scheme.
1248 const string16 untrimmed_fill_into_edit( 1253 const string16 untrimmed_fill_into_edit(
1249 AutocompleteInput::FormattedStringWithEquivalentMeaning(navigation.url(), 1254 AutocompleteInput::FormattedStringWithEquivalentMeaning(navigation.url(),
1250 StringForURLDisplay(navigation.url(), true, false))); 1255 StringForURLDisplay(navigation.url(), true, false)));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 } 1302 }
1298 1303
1299 void SearchProvider::UpdateDone() { 1304 void SearchProvider::UpdateDone() {
1300 // We're done when the timer isn't running, there are no suggest queries 1305 // We're done when the timer isn't running, there are no suggest queries
1301 // pending, and we're not waiting on instant. 1306 // pending, and we're not waiting on instant.
1302 done_ = (!timer_.IsRunning() && (suggest_results_pending_ == 0) && 1307 done_ = (!timer_.IsRunning() && (suggest_results_pending_ == 0) &&
1303 (instant_finalized_ || 1308 (instant_finalized_ ||
1304 (!chrome::BrowserInstantController::IsInstantEnabled(profile_) && 1309 (!chrome::BrowserInstantController::IsInstantEnabled(profile_) &&
1305 !chrome::search::IsInstantExtendedAPIEnabled(profile_)))); 1310 !chrome::search::IsInstantExtendedAPIEnabled(profile_))));
1306 } 1311 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698