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

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

Issue 10274023: Omnibox SearchProvider Experiment Client Implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Working to some degree... Created 8 years, 7 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 // static 83 // static
84 const int SearchProvider::kDefaultProviderURLFetcherID = 1; 84 const int SearchProvider::kDefaultProviderURLFetcherID = 1;
85 // static 85 // static
86 const int SearchProvider::kKeywordProviderURLFetcherID = 2; 86 const int SearchProvider::kKeywordProviderURLFetcherID = 2;
87 // static 87 // static
88 bool SearchProvider::query_suggest_immediately_ = false; 88 bool SearchProvider::query_suggest_immediately_ = false;
89 89
90 SearchProvider::SearchProvider(ACProviderListener* listener, Profile* profile) 90 SearchProvider::SearchProvider(ACProviderListener* listener, Profile* profile)
91 : AutocompleteProvider(listener, profile, "Search"), 91 : AutocompleteProvider(listener, profile, "Search"),
92 providers_(profile), 92 providers_(profile),
93 has_verbatim_relevance_(false),
94 verbatim_relevance_(0),
93 suggest_results_pending_(0), 95 suggest_results_pending_(0),
94 have_suggest_results_(false), 96 have_suggest_results_(false),
95 instant_finalized_(false) { 97 instant_finalized_(false) {
96 // We use GetSuggestNumberOfGroups() as the group ID to mean "not in field 98 // We use GetSuggestNumberOfGroups() as the group ID to mean "not in field
97 // trial." Field trial groups run from 0 to GetSuggestNumberOfGroups() - 1 99 // trial." Field trial groups run from 0 to GetSuggestNumberOfGroups() - 1
98 // (inclusive). 100 // (inclusive).
99 int suggest_field_trial_group_number = 101 int suggest_field_trial_group_number =
100 AutocompleteFieldTrial::GetSuggestNumberOfGroups(); 102 AutocompleteFieldTrial::GetSuggestNumberOfGroups();
101 if (AutocompleteFieldTrial::InSuggestFieldTrial()) { 103 if (AutocompleteFieldTrial::InSuggestFieldTrial()) {
102 suggest_field_trial_group_number = 104 suggest_field_trial_group_number =
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 for (ACMatches::iterator i = matches_.begin(); i != matches_.end();) { 142 for (ACMatches::iterator i = matches_.begin(); i != matches_.end();) {
141 if (((i->type == AutocompleteMatch::SEARCH_HISTORY) || 143 if (((i->type == AutocompleteMatch::SEARCH_HISTORY) ||
142 (i->type == AutocompleteMatch::SEARCH_SUGGEST)) && 144 (i->type == AutocompleteMatch::SEARCH_SUGGEST)) &&
143 (i->fill_into_edit == text)) { 145 (i->fill_into_edit == text)) {
144 i = matches_.erase(i); 146 i = matches_.erase(i);
145 } else { 147 } else {
146 ++i; 148 ++i;
147 } 149 }
148 } 150 }
149 151
152 // TODO(msw): Update this or ensure it's not removed in
153 // ConvertResultsToAutocompleteMatches?
150 // Add the new suggest result. We give it a rank higher than 154 // Add the new suggest result. We give it a rank higher than
151 // SEARCH_WHAT_YOU_TYPED so that it gets autocompleted. 155 // SEARCH_WHAT_YOU_TYPED so that it gets autocompleted.
152 int did_not_accept_default_suggestion = default_suggest_results_.empty() ? 156 int did_not_accept_default_suggestion = default_suggest_results_.empty() ?
153 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE : 157 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE :
154 TemplateURLRef::NO_SUGGESTION_CHOSEN; 158 TemplateURLRef::NO_SUGGESTION_CHOSEN;
155 MatchMap match_map; 159 MatchMap match_map;
156 AddMatchToMap(text, adjusted_input_text, 160 AddMatchToMap(text, adjusted_input_text,
157 CalculateRelevanceForWhatYouTyped() + 1, 161 CalculateRelevanceForWhatYouTyped() + 1,
158 AutocompleteMatch::SEARCH_SUGGEST, 162 AutocompleteMatch::SEARCH_SUGGEST,
159 did_not_accept_default_suggestion, false, 163 did_not_accept_default_suggestion, false,
160 input_.prevent_inline_autocomplete(), &match_map); 164 input_.prevent_inline_autocomplete(), &match_map);
161 DCHECK_EQ(1u, match_map.size()); 165 DCHECK_EQ(1u, match_map.size());
162 matches_.push_back(match_map.begin()->second); 166 matches_.push_back(match_map.begin()->second);
163 167
164 listener_->OnProviderUpdate(true); 168 listener_->OnProviderUpdate(true);
165 } 169 }
166 170
167 void SearchProvider::Start(const AutocompleteInput& input, 171 void SearchProvider::Start(const AutocompleteInput& input,
168 bool minimal_changes) { 172 bool minimal_changes) {
169 matches_.clear();
170
171 instant_finalized_ = 173 instant_finalized_ =
172 (input.matches_requested() != AutocompleteInput::ALL_MATCHES); 174 (input.matches_requested() != AutocompleteInput::ALL_MATCHES);
173 175
174 // Can't return search/suggest results for bogus input or without a profile. 176 // Can't return search/suggest results for bogus input or without a profile.
175 if (!profile_ || (input.type() == AutocompleteInput::INVALID)) { 177 if (!profile_ || (input.type() == AutocompleteInput::INVALID)) {
176 Stop(); 178 Stop();
177 return; 179 return;
178 } 180 }
179 181
180 keyword_input_text_.clear(); 182 keyword_input_text_.clear();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 return; 229 return;
228 } 230 }
229 231
230 input_ = input; 232 input_ = input;
231 233
232 DoHistoryQuery(minimal_changes); 234 DoHistoryQuery(minimal_changes);
233 StartOrStopSuggestQuery(minimal_changes); 235 StartOrStopSuggestQuery(minimal_changes);
234 ConvertResultsToAutocompleteMatches(); 236 ConvertResultsToAutocompleteMatches();
235 } 237 }
236 238
239 SearchProvider::SuggestResult::SuggestResult(const string16& suggestion,
240 bool has_suggested_relevance,
241 int relevance)
242 : suggestion(suggestion),
243 has_suggested_relevance(has_suggested_relevance),
244 relevance(relevance) {
245 }
246
247 SearchProvider::NavigationResult::NavigationResult(
248 const GURL& url,
249 const string16& site_name,
250 bool has_suggested_relevance,
251 int relevance)
252 : url(url),
253 site_name(site_name),
254 has_suggested_relevance(has_suggested_relevance),
255 relevance(relevance) {
256 }
257
237 class SearchProvider::CompareScoredTerms { 258 class SearchProvider::CompareScoredTerms {
238 public: 259 public:
239 bool operator()(const ScoredTerm& a, const ScoredTerm& b) { 260 bool operator()(const ScoredTerm& a, const ScoredTerm& b) {
240 // Sort in descending relevance order. 261 // Sort in descending relevance order.
241 return a.second > b.second; 262 return a.second > b.second;
242 } 263 }
243 }; 264 };
244 265
245 void SearchProvider::Run() { 266 void SearchProvider::Run() {
246 // Start a new request with the current input. 267 // Start a new request with the current input.
(...skipping 10 matching lines...) Expand all
257 providers_.keyword_provider()->suggestions_url_ref(), 278 providers_.keyword_provider()->suggestions_url_ref(),
258 keyword_input_text_)); 279 keyword_input_text_));
259 } 280 }
260 // We should only get here if we have a suggest url for the keyword or default 281 // We should only get here if we have a suggest url for the keyword or default
261 // providers. 282 // providers.
262 DCHECK_GT(suggest_results_pending_, 0); 283 DCHECK_GT(suggest_results_pending_, 0);
263 } 284 }
264 285
265 void SearchProvider::Stop() { 286 void SearchProvider::Stop() {
266 StopSuggest(); 287 StopSuggest();
288 ClearResults();
267 done_ = true; 289 done_ = true;
268 default_provider_suggest_text_.clear(); 290 default_provider_suggest_text_.clear();
269 } 291 }
270 292
271 void SearchProvider::OnURLFetchComplete(const content::URLFetcher* source) { 293 void SearchProvider::OnURLFetchComplete(const content::URLFetcher* source) {
272 DCHECK(!done_); 294 DCHECK(!done_);
273 suggest_results_pending_--; 295 suggest_results_pending_--;
274 DCHECK_GE(suggest_results_pending_, 0); // Should never go negative. 296 DCHECK_GE(suggest_results_pending_, 0); // Should never go negative.
275 const net::HttpResponseHeaders* const response_headers = 297 const net::HttpResponseHeaders* const response_headers =
276 source->GetResponseHeaders(); 298 source->GetResponseHeaders();
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 keyword_input_text_, num_matches, &keyword_history_results_); 371 keyword_input_text_, num_matches, &keyword_history_results_);
350 } 372 }
351 } 373 }
352 374
353 void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes) { 375 void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes) {
354 // Don't send any queries to the server until some time has elapsed after 376 // Don't send any queries to the server until some time has elapsed after
355 // the last keypress, to avoid flooding the server with requests we are 377 // the last keypress, to avoid flooding the server with requests we are
356 // likely to end up throwing away anyway. 378 // likely to end up throwing away anyway.
357 const int kQueryDelayMs = 200; 379 const int kQueryDelayMs = 200;
358 380
381 // TODO(msw): Synchronously remove irrelevant inline autocomplete matches,
382 // update the remaining matches for the new input.
383 // Mark these matches from_previous = true?
384 for (ACMatches::iterator i = matches_.begin(); i != matches_.end();) {
385 if (i->contents.find(input_.text()) == string16::npos &&
386 i->description.find(input_.text()) == string16::npos) {
387 i = matches_.erase(i);
388 } else {
389 if (i->inline_autocomplete_offset != string16::npos) {
Peter Kasting 2012/05/04 00:11:33 I wouldn't try to adjust the offsets directly, I'd
msw 2012/05/04 09:43:40 Done; but I still may need to update the results s
390 if (StartsWith(i->fill_into_edit, input_.text(), false))
391 i->inline_autocomplete_offset = input_.text().length();
392 else
393 i->inline_autocomplete_offset = string16::npos;
394 }
395 // TODO(msw): Fixup navigational result highlighting/styling?
396 ++i;
397 }
398 }
399
359 if (!IsQuerySuitableForSuggest()) { 400 if (!IsQuerySuitableForSuggest()) {
360 StopSuggest(); 401 StopSuggest();
402 ClearResults();
361 return; 403 return;
362 } 404 }
363 405
364 // For the minimal_changes case, if we finished the previous query and still 406 // For the minimal_changes case, if we finished the previous query and still
365 // have its results, or are allowed to keep running it, just do that, rather 407 // have its results, or are allowed to keep running it, just do that, rather
366 // than starting a new query. 408 // than starting a new query.
367 if (minimal_changes && 409 if (minimal_changes &&
368 (have_suggest_results_ || 410 (have_suggest_results_ ||
369 (!done_ && 411 (!done_ &&
370 input_.matches_requested() == AutocompleteInput::ALL_MATCHES))) 412 input_.matches_requested() == AutocompleteInput::ALL_MATCHES)))
371 return; 413 return;
372 414
373 // We can't keep running any previous query, so halt it. 415 // We can't keep running any previous query, so halt it.
374 StopSuggest(); 416 StopSuggest();
417 ClearResults();
375 418
376 // We can't start a new query if we're only allowed synchronous results. 419 // We can't start a new query if we're only allowed synchronous results.
377 if (input_.matches_requested() != AutocompleteInput::ALL_MATCHES) 420 if (input_.matches_requested() != AutocompleteInput::ALL_MATCHES)
378 return; 421 return;
379 422
380 // We'll have at least one pending fetch. Set it to 1 now, but the value is 423 // We'll have at least one pending fetch. Set it to 1 now, but the value is
381 // correctly set in Run. As Run isn't invoked immediately we need to set this 424 // correctly set in Run. As Run isn't invoked immediately we need to set this
382 // now, else we won't think we're waiting on results from the server when we 425 // now, else we won't think we're waiting on results from the server when we
383 // really are. 426 // really are.
384 suggest_results_pending_ = 1; 427 suggest_results_pending_ = 1;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 485
443 return true; 486 return true;
444 } 487 }
445 488
446 void SearchProvider::StopSuggest() { 489 void SearchProvider::StopSuggest() {
447 suggest_results_pending_ = 0; 490 suggest_results_pending_ = 0;
448 timer_.Stop(); 491 timer_.Stop();
449 // Stop any in-progress URL fetches. 492 // Stop any in-progress URL fetches.
450 keyword_fetcher_.reset(); 493 keyword_fetcher_.reset();
451 default_fetcher_.reset(); 494 default_fetcher_.reset();
495 }
496
497 void SearchProvider::ClearResults() {
452 keyword_suggest_results_.clear(); 498 keyword_suggest_results_.clear();
453 default_suggest_results_.clear(); 499 default_suggest_results_.clear();
454 keyword_navigation_results_.clear(); 500 keyword_navigation_results_.clear();
455 default_navigation_results_.clear(); 501 default_navigation_results_.clear();
456 have_suggest_results_ = false; 502 have_suggest_results_ = false;
457 } 503 }
458 504
459 content::URLFetcher* SearchProvider::CreateSuggestFetcher( 505 content::URLFetcher* SearchProvider::CreateSuggestFetcher(
460 int id, 506 int id,
461 const TemplateURLRef& suggestions_url, 507 const TemplateURLRef& suggestions_url,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 if (root_list->Get(2, &description_val) && 541 if (root_list->Get(2, &description_val) &&
496 description_val->IsType(Value::TYPE_LIST)) 542 description_val->IsType(Value::TYPE_LIST))
497 description_list = static_cast<ListValue*>(description_val); 543 description_list = static_cast<ListValue*>(description_val);
498 } 544 }
499 545
500 // We don't care about the query URL list (the fourth element in the 546 // We don't care about the query URL list (the fourth element in the
501 // response) for now. 547 // response) for now.
502 548
503 // Parse optional data in the results from the Suggest server if any. 549 // Parse optional data in the results from the Suggest server if any.
504 ListValue* type_list = NULL; 550 ListValue* type_list = NULL;
551 ListValue* relevance_list = NULL;
552 has_verbatim_relevance_ = false;
553 verbatim_relevance_ = 0;
505 // 5th argument: Optional key-value pairs. 554 // 5th argument: Optional key-value pairs.
506 // TODO: We may iterate the 5th+ arguments of the root_list if any other 555 // TODO: We may iterate the 5th+ arguments of the root_list if any other
507 // optional data are defined. 556 // optional data are defined.
508 if (root_list->GetSize() > 4) { 557 if (root_list->GetSize() > 4) {
509 Value* optional_val; 558 Value* optional_val;
510 if (root_list->Get(4, &optional_val) && 559 if (root_list->Get(4, &optional_val) &&
511 optional_val->IsType(Value::TYPE_DICTIONARY)) { 560 optional_val->IsType(Value::TYPE_DICTIONARY)) {
512 DictionaryValue* dict_val = static_cast<DictionaryValue*>(optional_val); 561 DictionaryValue* dict_val = static_cast<DictionaryValue*>(optional_val);
513 562
514 // Parse Google Suggest specific type extension. 563 // Parse Google Suggest specific type extension.
515 const std::string kGoogleSuggestType("google:suggesttype"); 564 const std::string kGoogleSuggestType("google:suggesttype");
516 if (dict_val->HasKey(kGoogleSuggestType)) 565 if (dict_val->HasKey(kGoogleSuggestType))
517 dict_val->GetList(kGoogleSuggestType, &type_list); 566 dict_val->GetList(kGoogleSuggestType, &type_list);
567
568 // Parse Google Suggest specific relevance extension.
569 const std::string kGoogleSuggestRelevance("google:suggestrelevance");
570 if (dict_val->HasKey(kGoogleSuggestRelevance))
571 dict_val->GetList(kGoogleSuggestRelevance, &relevance_list);
572
573 // Parse Google Suggest specific verbatim relevance extension.
574 const std::string kGoogleVerbatimRelevance("google:verbatimrelevance");
575 if (dict_val->GetInteger(kGoogleVerbatimRelevance, &verbatim_relevance_))
576 has_verbatim_relevance_ = true;
518 } 577 }
519 } 578 }
520 579
521 ListValue* result_list = static_cast<ListValue*>(result_val); 580 ListValue* result_list = static_cast<ListValue*>(result_val);
522 for (size_t i = 0; i < result_list->GetSize(); ++i) { 581 for (size_t i = 0; i < result_list->GetSize(); ++i) {
523 Value* suggestion_val; 582 Value* suggestion_val;
524 string16 suggestion_str; 583 string16 suggestion_str;
525 if (!result_list->Get(i, &suggestion_val) || 584 if (!result_list->Get(i, &suggestion_val) ||
526 !suggestion_val->GetAsString(&suggestion_str)) 585 !suggestion_val->GetAsString(&suggestion_str))
527 return false; 586 return false;
528 587
529 // Google search may return empty suggestions for weird input characters, 588 // Google search may return empty suggestions for weird input characters,
530 // they make no sense at all and can cause problem in our code. 589 // they make no sense at all and can cause problem in our code.
531 // See http://crbug.com/56214 590 // See http://crbug.com/56214
532 if (!suggestion_str.length()) 591 if (!suggestion_str.length())
533 continue; 592 continue;
534 593
594 bool has_suggested_relevance = false;
595 int relevance = 0;
596 if (relevance_list && relevance_list->GetInteger(i, &relevance))
597 has_suggested_relevance = true;
598
535 Value* type_val; 599 Value* type_val;
536 std::string type_str; 600 std::string type_str;
537 if (type_list && type_list->Get(i, &type_val) && 601 if (type_list && type_list->Get(i, &type_val) &&
538 type_val->GetAsString(&type_str) && (type_str == "NAVIGATION")) { 602 type_val->GetAsString(&type_str) && (type_str == "NAVIGATION")) {
539 Value* site_val; 603 Value* site_val;
540 string16 site_name; 604 string16 site_name;
541 NavigationResults& navigation_results = 605 NavigationResults& navigation_results =
542 is_keyword ? keyword_navigation_results_ : 606 is_keyword ? keyword_navigation_results_ :
543 default_navigation_results_; 607 default_navigation_results_;
544 if ((navigation_results.size() < kMaxMatches) && 608 if ((navigation_results.size() < kMaxMatches) &&
545 description_list && description_list->Get(i, &site_val) && 609 description_list && description_list->Get(i, &site_val) &&
546 site_val->IsType(Value::TYPE_STRING) && 610 site_val->IsType(Value::TYPE_STRING) &&
547 site_val->GetAsString(&site_name)) { 611 site_val->GetAsString(&site_name)) {
548 // We can't blindly trust the URL coming from the server to be valid. 612 // We can't blindly trust the URL coming from the server to be valid.
549 GURL result_url(URLFixerUpper::FixupURL(UTF16ToUTF8(suggestion_str), 613 GURL result_url(URLFixerUpper::FixupURL(UTF16ToUTF8(suggestion_str),
550 std::string())); 614 std::string()));
551 if (result_url.is_valid()) { 615 if (result_url.is_valid()) {
552 navigation_results.push_back(NavigationResult(result_url, site_name)); 616 navigation_results.push_back(NavigationResult(result_url, site_name,
617 has_suggested_relevance,
618 relevance));
553 } 619 }
554 } 620 }
555 } else { 621 } else {
556 // TODO(kochi): Currently we treat a calculator result as a query, but it 622 // TODO(kochi): Currently we treat a calculator result as a query, but it
557 // is better to have better presentation for caluculator results. 623 // is better to have better presentation for caluculator results.
558 if (suggest_results->size() < kMaxMatches) 624 if (suggest_results->size() < kMaxMatches) {
559 suggest_results->push_back(suggestion_str); 625 suggest_results->push_back(SuggestResult(suggestion_str,
626 has_suggested_relevance,
627 relevance));
628 }
560 } 629 }
561 } 630 }
562 631
563 return true; 632 return true;
564 } 633 }
565 634
566 void SearchProvider::ConvertResultsToAutocompleteMatches() { 635 void SearchProvider::ConvertResultsToAutocompleteMatches() {
567 // Convert all the results to matches and add them to a map, so we can keep 636 // Convert all the results to matches and add them to a map, so we can keep
568 // the most relevant match for each result. 637 // the most relevant match for each result.
569 MatchMap map; 638 MatchMap map;
570 const Time no_time; 639 const Time no_time;
571 int did_not_accept_keyword_suggestion = keyword_suggest_results_.empty() ? 640 int did_not_accept_keyword_suggestion = keyword_suggest_results_.empty() ?
572 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE : 641 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE :
573 TemplateURLRef::NO_SUGGESTION_CHOSEN; 642 TemplateURLRef::NO_SUGGESTION_CHOSEN;
574 // Keyword what you typed results are handled by the KeywordProvider. 643 // Keyword what you typed results are handled by the KeywordProvider.
575 644
576 int did_not_accept_default_suggestion = default_suggest_results_.empty() ? 645 int did_not_accept_default_suggestion = default_suggest_results_.empty() ?
577 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE : 646 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE :
578 TemplateURLRef::NO_SUGGESTION_CHOSEN; 647 TemplateURLRef::NO_SUGGESTION_CHOSEN;
579 if (providers_.valid_default_provider()) { 648 if (providers_.valid_default_provider()) {
580 AddMatchToMap(input_.text(), input_.text(), 649 int verbatim_relevance = CalculateRelevanceForWhatYouTyped();
581 CalculateRelevanceForWhatYouTyped(), 650 if (verbatim_relevance > 0) {
582 AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, 651 AddMatchToMap(input_.text(), input_.text(), verbatim_relevance,
583 did_not_accept_default_suggestion, false, 652 AutocompleteMatch::SEARCH_WHAT_YOU_TYPED,
584 input_.prevent_inline_autocomplete(), &map); 653 did_not_accept_default_suggestion, false,
654 input_.prevent_inline_autocomplete(), &map);
655 }
656 // TODO(msw): Should verbatim_relevance affect and/or supress this result?
585 if (!default_provider_suggest_text_.empty()) { 657 if (!default_provider_suggest_text_.empty()) {
586 AddMatchToMap(input_.text() + default_provider_suggest_text_, 658 AddMatchToMap(input_.text() + default_provider_suggest_text_,
587 input_.text(), CalculateRelevanceForWhatYouTyped() + 1, 659 input_.text(), CalculateRelevanceForWhatYouTyped() + 1,
588 AutocompleteMatch::SEARCH_SUGGEST, 660 AutocompleteMatch::SEARCH_SUGGEST,
589 did_not_accept_default_suggestion, false, 661 did_not_accept_default_suggestion, false,
590 input_.prevent_inline_autocomplete(), &map); 662 input_.prevent_inline_autocomplete(), &map);
591 } 663 }
592 } 664 }
593 665
594 AddHistoryResultsToMap(keyword_history_results_, true, 666 AddHistoryResultsToMap(keyword_history_results_, true,
595 did_not_accept_keyword_suggestion, &map); 667 did_not_accept_keyword_suggestion, &map);
596 AddHistoryResultsToMap(default_history_results_, false, 668 AddHistoryResultsToMap(default_history_results_, false,
597 did_not_accept_default_suggestion, &map); 669 did_not_accept_default_suggestion, &map);
598 670
599 AddSuggestResultsToMap(keyword_suggest_results_, true, 671 AddSuggestResultsToMap(keyword_suggest_results_, true,
600 did_not_accept_keyword_suggestion, &map); 672 did_not_accept_keyword_suggestion, &map);
601 AddSuggestResultsToMap(default_suggest_results_, false, 673 AddSuggestResultsToMap(default_suggest_results_, false,
602 did_not_accept_default_suggestion, &map); 674 did_not_accept_default_suggestion, &map);
603 675
604 // Now add the most relevant matches from the map to |matches_|. 676 // Now add the most relevant matches from the map to |matches_|.
605 matches_.clear(); 677 // TODO(msw): Clear the old matches now?? (only if there are new ones to add?)
678 if (!map.empty())
679 matches_.clear();
680 // TODO(msw): Merge matches from_previous = true?
Peter Kasting 2012/05/04 00:11:33 So remember that if you merge previous matches, yo
msw 2012/05/04 09:43:40 Done.
681 // (I think removing and re-adding any repeats should be okay...)
606 for (MatchMap::const_iterator i(map.begin()); i != map.end(); ++i) 682 for (MatchMap::const_iterator i(map.begin()); i != map.end(); ++i)
607 matches_.push_back(i->second); 683 matches_.push_back(i->second);
608 684
685 // TODO(msw): Need additional logic to preserve the navigational matches from
686 // StartOrStopSuggestQuery cleanup through the ClearResults calls?
609 AddNavigationResultsToMatches(keyword_navigation_results_, true); 687 AddNavigationResultsToMatches(keyword_navigation_results_, true);
610 AddNavigationResultsToMatches(default_navigation_results_, false); 688 AddNavigationResultsToMatches(default_navigation_results_, false);
611 689
690 // TODO(msw): Additional logic to only +1 if we have a what-you-typed?
Peter Kasting 2012/05/04 00:11:33 Yeah
msw 2012/05/04 09:43:40 Done.
612 const size_t max_total_matches = kMaxMatches + 1; // 1 for "what you typed" 691 const size_t max_total_matches = kMaxMatches + 1; // 1 for "what you typed"
613 std::partial_sort(matches_.begin(), 692 std::partial_sort(matches_.begin(),
614 matches_.begin() + std::min(max_total_matches, matches_.size()), 693 matches_.begin() + std::min(max_total_matches, matches_.size()),
615 matches_.end(), &AutocompleteMatch::MoreRelevant); 694 matches_.end(), &AutocompleteMatch::MoreRelevant);
616 if (matches_.size() > max_total_matches) 695 if (matches_.size() > max_total_matches)
617 matches_.erase(matches_.begin() + max_total_matches, matches_.end()); 696 matches_.erase(matches_.begin() + max_total_matches, matches_.end());
618 697
619 UpdateStarredStateOfMatches(); 698 UpdateStarredStateOfMatches();
620 699
621 UpdateDone(); 700 UpdateDone();
622 } 701 }
623 702
624 void SearchProvider::AddNavigationResultsToMatches( 703 void SearchProvider::AddNavigationResultsToMatches(
625 const NavigationResults& navigation_results, 704 const NavigationResults& navigation_results,
626 bool is_keyword) { 705 bool is_keyword) {
627 if (!navigation_results.empty()) { 706 if (!navigation_results.empty()) {
628 // TODO(kochi): http://b/1170574 We add only one results for navigational 707 // TODO(kochi): http://b/1170574 We add only one results for navigational
629 // suggestions. If we can get more useful information about the score, 708 // suggestions. If we can get more useful information about the score,
630 // consider adding more results. 709 // consider adding more results.
631 const size_t num_results = is_keyword ?
632 keyword_navigation_results_.size() : default_navigation_results_.size();
633 matches_.push_back(NavigationToMatch(navigation_results.front(), 710 matches_.push_back(NavigationToMatch(navigation_results.front(),
634 CalculateRelevanceForNavigation(num_results, 0, is_keyword), 711 CalculateRelevanceForNavigation(navigation_results, 0, is_keyword),
635 is_keyword)); 712 is_keyword));
636 } 713 }
637 } 714 }
638 715
639 void SearchProvider::AddHistoryResultsToMap(const HistoryResults& results, 716 void SearchProvider::AddHistoryResultsToMap(const HistoryResults& results,
640 bool is_keyword, 717 bool is_keyword,
641 int did_not_accept_suggestion, 718 int did_not_accept_suggestion,
642 MatchMap* map) { 719 MatchMap* map) {
643 if (results.empty()) 720 if (results.empty())
644 return; 721 return;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 811
735 return scored_terms; 812 return scored_terms;
736 } 813 }
737 814
738 void SearchProvider::AddSuggestResultsToMap( 815 void SearchProvider::AddSuggestResultsToMap(
739 const SuggestResults& suggest_results, 816 const SuggestResults& suggest_results,
740 bool is_keyword, 817 bool is_keyword,
741 int did_not_accept_suggestion, 818 int did_not_accept_suggestion,
742 MatchMap* map) { 819 MatchMap* map) {
743 for (size_t i = 0; i < suggest_results.size(); ++i) { 820 for (size_t i = 0; i < suggest_results.size(); ++i) {
744 AddMatchToMap(suggest_results[i], 821 AddMatchToMap(suggest_results[i].suggestion,
745 is_keyword ? keyword_input_text_ : input_.text(), 822 is_keyword ? keyword_input_text_ : input_.text(),
746 CalculateRelevanceForSuggestion(suggest_results.size(), i, 823 CalculateRelevanceForSuggestion(suggest_results, i,
747 is_keyword), 824 is_keyword),
748 AutocompleteMatch::SEARCH_SUGGEST, 825 AutocompleteMatch::SEARCH_SUGGEST,
749 static_cast<int>(i), is_keyword, 826 static_cast<int>(i), is_keyword,
750 input_.prevent_inline_autocomplete(), map); 827 input_.prevent_inline_autocomplete(), map);
751 } 828 }
752 } 829 }
753 830
754 int SearchProvider::CalculateRelevanceForWhatYouTyped() const { 831 int SearchProvider::CalculateRelevanceForWhatYouTyped() const {
832 // TODO(msw): Effect just the exact SEARCH_WHAT_YOU_TYPED match (line 624) or
833 // also inline-autocomplete from FinalizeInstantQuery and
834 // default_provider_suggest_text_???
Peter Kasting 2012/05/04 00:11:33 It's not at all clear to me how instant is suppose
msw 2012/05/04 09:43:40 I have a TODO on the CR & in the CL, will e-mail/a
835
836 // TODO(msw): Do not demote on just_deleted_text_/prevent_inline_autocomplete?
Peter Kasting 2012/05/04 00:11:33 I think your code does this currently and is corre
msw 2012/05/04 09:43:40 Cool, thanks for the confirmation.
837 if (has_verbatim_relevance_ && !input_.prevent_inline_autocomplete())
838 return verbatim_relevance_;
839
755 if (providers_.valid_keyword_provider()) 840 if (providers_.valid_keyword_provider())
756 return 250; 841 return 250;
757 842
758 switch (input_.type()) { 843 switch (input_.type()) {
759 case AutocompleteInput::UNKNOWN: 844 case AutocompleteInput::UNKNOWN:
760 case AutocompleteInput::QUERY: 845 case AutocompleteInput::QUERY:
761 case AutocompleteInput::FORCED_QUERY: 846 case AutocompleteInput::FORCED_QUERY:
762 return 1300; 847 return 1300;
763 848
764 case AutocompleteInput::REQUESTED_URL: 849 case AutocompleteInput::REQUESTED_URL:
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 // Don't let scores go below 0. Negative relevance scores are meaningful in 886 // Don't let scores go below 0. Negative relevance scores are meaningful in
802 // a different way. 887 // a different way.
803 int base_score; 888 int base_score;
804 if (is_primary_provider) 889 if (is_primary_provider)
805 base_score = (input_.type() == AutocompleteInput::URL) ? 750 : 1050; 890 base_score = (input_.type() == AutocompleteInput::URL) ? 750 : 1050;
806 else 891 else
807 base_score = 200; 892 base_score = 200;
808 return std::max(0, base_score - score_discount); 893 return std::max(0, base_score - score_discount);
809 } 894 }
810 895
811 int SearchProvider::CalculateRelevanceForSuggestion(size_t num_results, 896 int SearchProvider::CalculateRelevanceForSuggestion(
812 size_t result_number, 897 const SuggestResults& results,
813 bool is_keyword) const { 898 size_t result_number,
814 DCHECK(result_number < num_results); 899 bool is_keyword) const {
900 DCHECK(result_number < results.size());
901 if (results[result_number].has_suggested_relevance)
902 return results[result_number].relevance;
903
815 int base_score; 904 int base_score;
816 if (!providers_.is_primary_provider(is_keyword)) 905 if (!providers_.is_primary_provider(is_keyword))
817 base_score = 100; 906 base_score = 100;
818 else 907 else
819 base_score = (input_.type() == AutocompleteInput::URL) ? 300 : 600; 908 base_score = (input_.type() == AutocompleteInput::URL) ? 300 : 600;
820 return base_score + 909 return base_score +
821 static_cast<int>(num_results - 1 - result_number); 910 static_cast<int>(results.size() - 1 - result_number);
822 } 911 }
823 912
824 int SearchProvider::CalculateRelevanceForNavigation(size_t num_results, 913 int SearchProvider::CalculateRelevanceForNavigation(
825 size_t result_number, 914 const NavigationResults& results,
826 bool is_keyword) const { 915 size_t result_number,
827 DCHECK(result_number < num_results); 916 bool is_keyword) const {
828 // TODO(kochi): http://b/784900 Use relevance score from the NavSuggest 917 DCHECK(result_number < results.size());
829 // server if possible. 918 if (results[result_number].has_suggested_relevance)
919 return results[result_number].relevance;
920
830 return (providers_.is_primary_provider(is_keyword) ? 800 : 150) + 921 return (providers_.is_primary_provider(is_keyword) ? 800 : 150) +
831 static_cast<int>(num_results - 1 - result_number); 922 static_cast<int>(results.size() - 1 - result_number);
832 } 923 }
833 924
834 void SearchProvider::AddMatchToMap(const string16& query_string, 925 void SearchProvider::AddMatchToMap(const string16& query_string,
835 const string16& input_text, 926 const string16& input_text,
836 int relevance, 927 int relevance,
837 AutocompleteMatch::Type type, 928 AutocompleteMatch::Type type,
838 int accepted_suggestion, 929 int accepted_suggestion,
839 bool is_keyword, 930 bool is_keyword,
840 bool prevent_inline_autocomplete, 931 bool prevent_inline_autocomplete,
841 MatchMap* map) { 932 MatchMap* map) {
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 &match.description_class); 1043 &match.description_class);
953 1044
954 // When the user forced a query, we need to make sure all the fill_into_edit 1045 // When the user forced a query, we need to make sure all the fill_into_edit
955 // values preserve that property. Otherwise, if the user starts editing a 1046 // values preserve that property. Otherwise, if the user starts editing a
956 // suggestion, non-Search results will suddenly appear. 1047 // suggestion, non-Search results will suddenly appear.
957 if (input_.type() == AutocompleteInput::FORCED_QUERY) 1048 if (input_.type() == AutocompleteInput::FORCED_QUERY)
958 match.fill_into_edit.assign(ASCIIToUTF16("?")); 1049 match.fill_into_edit.assign(ASCIIToUTF16("?"));
959 match.fill_into_edit.append( 1050 match.fill_into_edit.append(
960 AutocompleteInput::FormattedStringWithEquivalentMeaning(navigation.url, 1051 AutocompleteInput::FormattedStringWithEquivalentMeaning(navigation.url,
961 match.contents)); 1052 match.contents));
962 // TODO(pkasting): http://b/1112879 These should perhaps be 1053 // TODO(pkasting|msw): http://b/1112879 These should perhaps be
963 // inline-autocompletable? 1054 // inline-autocompletable?
964 1055
965 return match; 1056 return match;
966 } 1057 }
967 1058
968 void SearchProvider::UpdateDone() { 1059 void SearchProvider::UpdateDone() {
969 // We're done when there are no more suggest queries pending (this is set to 1 1060 // We're done when there are no more suggest queries pending (this is set to 1
970 // when the timer is started) and we're not waiting on instant. 1061 // when the timer is started) and we're not waiting on instant.
971 done_ = ((suggest_results_pending_ == 0) && 1062 done_ = ((suggest_results_pending_ == 0) &&
972 (instant_finalized_ || !InstantController::IsEnabled(profile_))); 1063 (instant_finalized_ || !InstantController::IsEnabled(profile_)));
973 } 1064 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698