| Index: chrome/browser/autocomplete/search_provider.cc
|
| ===================================================================
|
| --- chrome/browser/autocomplete/search_provider.cc (revision 13665)
|
| +++ chrome/browser/autocomplete/search_provider.cc (working copy)
|
| @@ -1,4 +1,4 @@
|
| -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
| +// Copyright (c) 2009 The Chromium Authors. All rights reserved.
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| @@ -6,6 +6,7 @@
|
|
|
| #include "base/message_loop.h"
|
| #include "base/string_util.h"
|
| +#include "chrome/browser/autocomplete/keyword_provider.h"
|
| #include "chrome/browser/browser_process.h"
|
| #include "chrome/browser/google_util.h"
|
| #include "chrome/browser/net/url_fixer_upper.h"
|
| @@ -25,6 +26,19 @@
|
| using base::Time;
|
| using base::TimeDelta;
|
|
|
| +void SearchProvider::Providers::Set(const TemplateURL* default_provider,
|
| + const TemplateURL* keyword_provider) {
|
| + // TODO(pkasting): http://b/1162970 We shouldn't need to structure-copy
|
| + // this. Nor should we need |default_provider_| and |keyword_provider_|
|
| + // just to know whether the provider changed.
|
| + default_provider_ = default_provider;
|
| + if (default_provider)
|
| + cached_default_provider_ = *default_provider;
|
| + keyword_provider_ = keyword_provider;
|
| + if (keyword_provider)
|
| + cached_keyword_provider_ = *keyword_provider;
|
| +}
|
| +
|
| void SearchProvider::Start(const AutocompleteInput& input,
|
| bool minimal_changes) {
|
| matches_.clear();
|
| @@ -35,42 +49,53 @@
|
| return;
|
| }
|
|
|
| - // Can't search without a default provider.
|
| - const TemplateURL* const current_default_provider =
|
| + keyword_input_text_.clear();
|
| + const TemplateURL* keyword_provider =
|
| + KeywordProvider::GetSubstitutingTemplateURLForInput(profile_, input,
|
| + &keyword_input_text_);
|
| + if (!TemplateURL::SupportsReplacement(keyword_provider) ||
|
| + keyword_input_text_.empty()) {
|
| + keyword_provider = NULL;
|
| + }
|
| +
|
| + const TemplateURL* default_provider =
|
| profile_->GetTemplateURLModel()->GetDefaultSearchProvider();
|
| - // TODO(pkasting): http://b/1155786 Eventually we should not need all these
|
| - // checks.
|
| - if (!current_default_provider || !current_default_provider->url() ||
|
| - !current_default_provider->url()->SupportsReplacement()) {
|
| + if (!TemplateURL::SupportsReplacement(default_provider))
|
| + default_provider = NULL;
|
| +
|
| + if (keyword_provider == default_provider)
|
| + keyword_provider = NULL; // No use in querying the same provider twice.
|
| +
|
| + if (!default_provider && !keyword_provider) {
|
| + // No valid providers.
|
| Stop();
|
| return;
|
| }
|
|
|
| // If we're still running an old query but have since changed the query text
|
| - // or the default provider, abort the query.
|
| + // or the providers, abort the query.
|
| if (!done_ && (!minimal_changes ||
|
| - (last_default_provider_ != current_default_provider)))
|
| + !providers_.equals(default_provider, keyword_provider))) {
|
| Stop();
|
| + }
|
|
|
| - // TODO(pkasting): http://b/1162970 We shouldn't need to structure-copy this.
|
| - // Nor should we need |last_default_provider_| just to know whether the
|
| - // provider changed.
|
| - default_provider_ = *current_default_provider;
|
| - last_default_provider_ = current_default_provider;
|
| + providers_.Set(default_provider, keyword_provider);
|
|
|
| if (input.text().empty()) {
|
| // User typed "?" alone. Give them a placeholder result indicating what
|
| // this syntax does.
|
| - AutocompleteMatch match(this, 0, false,
|
| - AutocompleteMatch::SEARCH_WHAT_YOU_TYPED);
|
| - static const std::wstring kNoQueryInput(
|
| - l10n_util::GetString(IDS_AUTOCOMPLETE_NO_QUERY));
|
| - match.contents.assign(l10n_util::GetStringF(
|
| - IDS_AUTOCOMPLETE_SEARCH_CONTENTS, default_provider_.short_name(),
|
| - kNoQueryInput));
|
| - match.contents_class.push_back(
|
| - ACMatchClassification(0, ACMatchClassification::DIM));
|
| - matches_.push_back(match);
|
| + if (default_provider) {
|
| + AutocompleteMatch match(this, 0, false,
|
| + AutocompleteMatch::SEARCH_WHAT_YOU_TYPED);
|
| + static const std::wstring kNoQueryInput(
|
| + l10n_util::GetString(IDS_AUTOCOMPLETE_NO_QUERY));
|
| + match.contents.assign(l10n_util::GetStringF(
|
| + IDS_AUTOCOMPLETE_SEARCH_CONTENTS, default_provider->short_name(),
|
| + kNoQueryInput));
|
| + match.contents_class.push_back(
|
| + ACMatchClassification(0, ACMatchClassification::DIM));
|
| + matches_.push_back(match);
|
| + }
|
| Stop();
|
| return;
|
| }
|
| @@ -85,15 +110,21 @@
|
| void SearchProvider::Run() {
|
| // Start a new request with the current input.
|
| DCHECK(!done_);
|
| - const TemplateURLRef* const suggestions_url =
|
| - default_provider_.suggestions_url();
|
| - DCHECK(suggestions_url->SupportsReplacement());
|
| - fetcher_.reset(new URLFetcher(suggestions_url->ReplaceSearchTerms(
|
| - default_provider_, input_.text(),
|
| - TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, std::wstring()),
|
| - URLFetcher::GET, this));
|
| - fetcher_->set_request_context(profile_->GetRequestContext());
|
| - fetcher_->Start();
|
| + suggest_results_pending_ = 0;
|
| + if (providers_.valid_suggest_for_keyword_provider()) {
|
| + suggest_results_pending_++;
|
| + keyword_fetcher_.reset(
|
| + CreateSuggestFetcher(providers_.keyword_provider(),
|
| + keyword_input_text_));
|
| + }
|
| + if (providers_.valid_suggest_for_default_provider()) {
|
| + suggest_results_pending_++;
|
| + default_fetcher_.reset(
|
| + CreateSuggestFetcher(providers_.default_provider(), input_.text()));
|
| + }
|
| + // We should only get here if we have a suggest url for the keyword or default
|
| + // providers.
|
| + DCHECK(suggest_results_pending_ > 0);
|
| }
|
|
|
| void SearchProvider::Stop() {
|
| @@ -109,9 +140,8 @@
|
| const ResponseCookies& cookie,
|
| const std::string& data) {
|
| DCHECK(!done_);
|
| - suggest_results_pending_ = false;
|
| - suggest_results_.clear();
|
| - navigation_results_.clear();
|
| + suggest_results_pending_--;
|
| + DCHECK(suggest_results_pending_ >= 0); // Should never go negative.
|
| const net::HttpResponseHeaders* const response_headers =
|
| source->response_headers();
|
| std::string json_data(data);
|
| @@ -129,16 +159,24 @@
|
| }
|
| }
|
|
|
| + bool is_keyword_results = (source == keyword_fetcher_.get());
|
| + SuggestResults* suggest_results = is_keyword_results ?
|
| + &keyword_suggest_results_ : &default_suggest_results_;
|
| +
|
| if (status.is_success() && response_code == 200) {
|
| JSONStringValueSerializer deserializer(json_data);
|
| deserializer.set_allow_trailing_comma(true);
|
| scoped_ptr<Value> root_val(deserializer.Deserialize(NULL));
|
| + const std::wstring& input_text =
|
| + is_keyword_results ? keyword_input_text_ : input_.text();
|
| have_suggest_results_ =
|
| - root_val.get() && ParseSuggestResults(root_val.get());
|
| + root_val.get() &&
|
| + ParseSuggestResults(root_val.get(), is_keyword_results, input_text,
|
| + suggest_results);
|
| }
|
|
|
| ConvertResultsToAutocompleteMatches();
|
| - listener_->OnProviderUpdate(!suggest_results_.empty());
|
| + listener_->OnProviderUpdate(!suggest_results->empty());
|
| }
|
|
|
| void SearchProvider::StartOrStopHistoryQuery(bool minimal_changes) {
|
| @@ -156,14 +194,15 @@
|
| if (input_.synchronous_only())
|
| return;
|
|
|
| - // Start the history query.
|
| - HistoryService* const history_service =
|
| - profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
|
| - history_service->GetMostRecentKeywordSearchTerms(default_provider_.id(),
|
| - input_.text(), static_cast<int>(max_matches()),
|
| - &history_request_consumer_,
|
| - NewCallback(this, &SearchProvider::OnGotMostRecentKeywordSearchTerms));
|
| - history_request_pending_ = true;
|
| + // Request history for both the keyword and default provider.
|
| + if (providers_.valid_keyword_provider()) {
|
| + ScheduleHistoryQuery(providers_.keyword_provider().id(),
|
| + keyword_input_text_);
|
| + }
|
| + if (providers_.valid_default_provider()) {
|
| + ScheduleHistoryQuery(providers_.default_provider().id(),
|
| + input_.text());
|
| + }
|
| }
|
|
|
| void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes) {
|
| @@ -191,11 +230,14 @@
|
| if (input_.synchronous_only())
|
| return;
|
|
|
| + // We'll have at least one pending fetch. Set it to 1 now, but the value is
|
| + // correctly set in Run. As Run isn't invoked immediately we need to set this
|
| + // now, else we won't think we're waiting on results from the server when we
|
| + // really are.
|
| + suggest_results_pending_ = 1;
|
| +
|
| // Kick off a timer that will start the URL fetch if it completes before
|
| // the user types another character.
|
| - suggest_results_pending_ = true;
|
| -
|
| - timer_.Stop();
|
| timer_.Start(TimeDelta::FromMilliseconds(kQueryDelayMs), this,
|
| &SearchProvider::Run);
|
| }
|
| @@ -204,7 +246,8 @@
|
| // Don't run Suggest when off the record, the engine doesn't support it, or
|
| // the user has disabled it.
|
| if (profile_->IsOffTheRecord() ||
|
| - !default_provider_.suggestions_url() ||
|
| + (!providers_.valid_suggest_for_keyword_provider() &&
|
| + !providers_.valid_suggest_for_default_provider()) ||
|
| !profile_->GetPrefs()->GetBoolean(prefs::kSearchSuggestEnabled))
|
| return false;
|
|
|
| @@ -243,29 +286,80 @@
|
| void SearchProvider::StopHistory() {
|
| history_request_consumer_.CancelAllRequests();
|
| history_request_pending_ = false;
|
| - history_results_.clear();
|
| + keyword_history_results_.clear();
|
| + default_history_results_.clear();
|
| have_history_results_ = false;
|
| }
|
|
|
| void SearchProvider::StopSuggest() {
|
| - suggest_results_pending_ = false;
|
| + suggest_results_pending_ = 0;
|
| timer_.Stop();
|
| - fetcher_.reset(); // Stop any in-progress URL fetch.
|
| - suggest_results_.clear();
|
| + // Stop any in-progress URL fetches.
|
| + keyword_fetcher_.reset();
|
| + default_fetcher_.reset();
|
| + keyword_suggest_results_.clear();
|
| + default_suggest_results_.clear();
|
| + keyword_navigation_results_.clear();
|
| + default_navigation_results_.clear();
|
| have_suggest_results_ = false;
|
| }
|
|
|
| +void SearchProvider::ScheduleHistoryQuery(TemplateURL::IDType search_id,
|
| + const std::wstring& text) {
|
| + DCHECK(!text.empty());
|
| + HistoryService* const history_service =
|
| + profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
|
| + HistoryService::Handle request_handle =
|
| + history_service->GetMostRecentKeywordSearchTerms(
|
| + search_id, text, static_cast<int>(max_matches()),
|
| + &history_request_consumer_,
|
| + NewCallback(this,
|
| + &SearchProvider::OnGotMostRecentKeywordSearchTerms));
|
| + history_request_consumer_.SetClientData(history_service, request_handle,
|
| + search_id);
|
| + history_request_pending_ = true;
|
| +}
|
| +
|
| void SearchProvider::OnGotMostRecentKeywordSearchTerms(
|
| CancelableRequestProvider::Handle handle,
|
| HistoryResults* results) {
|
| - history_request_pending_ = false;
|
| - have_history_results_ = true;
|
| - history_results_ = *results;
|
| + HistoryService* history_service =
|
| + profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
|
| + DCHECK(history_service);
|
| + if (providers_.valid_keyword_provider() &&
|
| + (providers_.keyword_provider().id() ==
|
| + history_request_consumer_.GetClientData(history_service, handle))) {
|
| + keyword_history_results_ = *results;
|
| + } else {
|
| + default_history_results_ = *results;
|
| + }
|
| ConvertResultsToAutocompleteMatches();
|
| - listener_->OnProviderUpdate(!history_results_.empty());
|
| + listener_->OnProviderUpdate(!results->empty());
|
| +
|
| + if (history_request_consumer_.PendingRequestCount() == 1) {
|
| + // Requests are removed AFTER the callback is invoked. If the count == 1,
|
| + // it means no more history requests are pending.
|
| + history_request_pending_ = false;
|
| + have_history_results_ = true;
|
| + }
|
| }
|
|
|
| -bool SearchProvider::ParseSuggestResults(Value* root_val) {
|
| +URLFetcher* SearchProvider::CreateSuggestFetcher(const TemplateURL& provider,
|
| + const std::wstring& text) {
|
| + const TemplateURLRef* const suggestions_url = provider.suggestions_url();
|
| + DCHECK(suggestions_url->SupportsReplacement());
|
| + URLFetcher* fetcher = new URLFetcher(suggestions_url->ReplaceSearchTerms(
|
| + provider, text, TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, std::wstring()),
|
| + URLFetcher::GET, this);
|
| + fetcher->set_request_context(profile_->GetRequestContext());
|
| + fetcher->Start();
|
| + return fetcher;
|
| +}
|
| +
|
| +bool SearchProvider::ParseSuggestResults(Value* root_val,
|
| + bool is_keyword,
|
| + const std::wstring& input_text,
|
| + SuggestResults* suggest_results) {
|
| if (!root_val->IsType(Value::TYPE_LIST))
|
| return false;
|
| ListValue* root_list = static_cast<ListValue*>(root_val);
|
| @@ -274,7 +368,7 @@
|
| std::wstring query_str;
|
| Value* result_val;
|
| if ((root_list->GetSize() < 2) || !root_list->Get(0, &query_val) ||
|
| - !query_val->GetAsString(&query_str) || (query_str != input_.text()) ||
|
| + !query_val->GetAsString(&query_str) || (query_str != input_text) ||
|
| !root_list->Get(1, &result_val) || !result_val->IsType(Value::TYPE_LIST))
|
| return false;
|
|
|
| @@ -322,7 +416,10 @@
|
| type_val->GetAsString(&type_str) && (type_str == L"NAVIGATION")) {
|
| Value* site_val;
|
| std::wstring site_name;
|
| - if ((navigation_results_.size() < max_matches()) &&
|
| + NavigationResults& navigation_results =
|
| + is_keyword ? keyword_navigation_results_ :
|
| + default_navigation_results_;
|
| + if ((navigation_results.size() < max_matches()) &&
|
| description_list && description_list->Get(i, &site_val) &&
|
| site_val->IsType(Value::TYPE_STRING) &&
|
| site_val->GetAsString(&site_name)) {
|
| @@ -330,16 +427,14 @@
|
| GURL result_url =
|
| GURL(URLFixerUpper::FixupURL(WideToUTF8(suggestion_str),
|
| std::string()));
|
| - if (result_url.is_valid()) {
|
| - navigation_results_.push_back(NavigationResult(result_url,
|
| - site_name));
|
| - }
|
| + if (result_url.is_valid())
|
| + navigation_results.push_back(NavigationResult(result_url, site_name));
|
| }
|
| } else {
|
| // TODO(kochi): Currently we treat a calculator result as a query, but it
|
| // is better to have better presentation for caluculator results.
|
| - if (suggest_results_.size() < max_matches())
|
| - suggest_results_.push_back(suggestion_str);
|
| + if (suggest_results->size() < max_matches())
|
| + suggest_results->push_back(suggestion_str);
|
| }
|
| }
|
|
|
| @@ -350,39 +445,38 @@
|
| // Convert all the results to matches and add them to a map, so we can keep
|
| // the most relevant match for each result.
|
| MatchMap map;
|
| - const int did_not_accept_suggestion = suggest_results_.empty() ?
|
| + const Time no_time;
|
| + int did_not_accept_keyword_suggestion = keyword_suggest_results_.empty() ?
|
| TemplateURLRef::NO_SUGGESTIONS_AVAILABLE :
|
| TemplateURLRef::NO_SUGGESTION_CHOSEN;
|
| - const Time no_time;
|
| - AddMatchToMap(input_.text(), CalculateRelevanceForWhatYouTyped(),
|
| - AutocompleteMatch::SEARCH_WHAT_YOU_TYPED,
|
| - did_not_accept_suggestion, &map);
|
| + // Keyword what you typed results are handled by the KeywordProvider.
|
|
|
| - for (HistoryResults::const_iterator i(history_results_.begin());
|
| - i != history_results_.end(); ++i) {
|
| - AddMatchToMap(i->term, CalculateRelevanceForHistory(i->time),
|
| - AutocompleteMatch::SEARCH_HISTORY, did_not_accept_suggestion,
|
| - &map);
|
| + int did_not_accept_default_suggestion = default_suggest_results_.empty() ?
|
| + TemplateURLRef::NO_SUGGESTIONS_AVAILABLE :
|
| + TemplateURLRef::NO_SUGGESTION_CHOSEN;
|
| + if (providers_.valid_default_provider()) {
|
| + AddMatchToMap(input_.text(), CalculateRelevanceForWhatYouTyped(),
|
| + AutocompleteMatch::SEARCH_WHAT_YOU_TYPED,
|
| + did_not_accept_default_suggestion, false, &map);
|
| }
|
|
|
| - for (size_t i = 0; i < suggest_results_.size(); ++i) {
|
| - AddMatchToMap(suggest_results_[i], CalculateRelevanceForSuggestion(i),
|
| - AutocompleteMatch::SEARCH_SUGGEST,
|
| - static_cast<int>(i), &map);
|
| - }
|
| + AddHistoryResultsToMap(keyword_history_results_, true,
|
| + did_not_accept_keyword_suggestion, &map);
|
| + AddHistoryResultsToMap(default_history_results_, false,
|
| + did_not_accept_default_suggestion, &map);
|
|
|
| + AddSuggestResultsToMap(keyword_suggest_results_, true,
|
| + did_not_accept_keyword_suggestion, &map);
|
| + AddSuggestResultsToMap(default_suggest_results_, false,
|
| + did_not_accept_default_suggestion, &map);
|
| +
|
| // Now add the most relevant matches from the map to |matches_|.
|
| matches_.clear();
|
| for (MatchMap::const_iterator i(map.begin()); i != map.end(); ++i)
|
| matches_.push_back(i->second);
|
|
|
| - if (!navigation_results_.empty()) {
|
| - // TODO(kochi): http://b/1170574 We add only one results for navigational
|
| - // suggestions. If we can get more useful information about the score,
|
| - // consider adding more results.
|
| - matches_.push_back(NavigationToMatch(navigation_results_.front(),
|
| - CalculateRelevanceForNavigation(0)));
|
| - }
|
| + AddNavigationResultsToMatches(keyword_navigation_results_, true);
|
| + AddNavigationResultsToMatches(default_navigation_results_, false);
|
|
|
| const size_t max_total_matches = max_matches() + 1; // 1 for "what you typed"
|
| std::partial_sort(matches_.begin(),
|
| @@ -399,26 +493,65 @@
|
| // callback has returned, but we've reached here from inside that callback.
|
| // HasPendingRequests() would therefore return true, and if this is the last
|
| // thing left to calculate for this query, we'll never mark the query "done".
|
| - done_ = !history_request_pending_ &&
|
| - !suggest_results_pending_;
|
| + done_ = !history_request_pending_ && !suggest_results_pending_;
|
| }
|
|
|
| +void SearchProvider::AddNavigationResultsToMatches(
|
| + const NavigationResults& navigation_results,
|
| + bool is_keyword) {
|
| + if (!navigation_results.empty()) {
|
| + // TODO(kochi): http://b/1170574 We add only one results for navigational
|
| + // suggestions. If we can get more useful information about the score,
|
| + // consider adding more results.
|
| + matches_.push_back(
|
| + NavigationToMatch(navigation_results.front(),
|
| + CalculateRelevanceForNavigation(0, is_keyword),
|
| + is_keyword));
|
| + }
|
| +}
|
| +
|
| +void SearchProvider::AddHistoryResultsToMap(const HistoryResults& results,
|
| + bool is_keyword,
|
| + int did_not_accept_suggestion,
|
| + MatchMap* map) {
|
| + for (HistoryResults::const_iterator i(results.begin()); i != results.end();
|
| + ++i) {
|
| + AddMatchToMap(i->term, CalculateRelevanceForHistory(i->time, is_keyword),
|
| + AutocompleteMatch::SEARCH_HISTORY, did_not_accept_suggestion,
|
| + is_keyword, map);
|
| + }
|
| +}
|
| +
|
| +void SearchProvider::AddSuggestResultsToMap(
|
| + const SuggestResults& suggest_results,
|
| + bool is_keyword,
|
| + int did_not_accept_suggestion,
|
| + MatchMap* map) {
|
| + for (size_t i = 0; i < suggest_results.size(); ++i) {
|
| + AddMatchToMap(suggest_results[i],
|
| + CalculateRelevanceForSuggestion(suggest_results, i,
|
| + is_keyword),
|
| + AutocompleteMatch::SEARCH_SUGGEST,
|
| + static_cast<int>(i), is_keyword, map);
|
| + }
|
| +}
|
| +
|
| int SearchProvider::CalculateRelevanceForWhatYouTyped() const {
|
| switch (input_.type()) {
|
| case AutocompleteInput::UNKNOWN:
|
| - return 1300;
|
| + return providers_.valid_keyword_provider() ? 250 : 1300;
|
|
|
| case AutocompleteInput::REQUESTED_URL:
|
| - return 1200;
|
| + return providers_.valid_keyword_provider() ? 250 : 1200;
|
|
|
| case AutocompleteInput::URL:
|
| - return 850;
|
| + return providers_.valid_keyword_provider() ? 250 : 850;
|
|
|
| case AutocompleteInput::QUERY:
|
| - return 1300;
|
| + return providers_.valid_keyword_provider() ? 250 : 1300;
|
|
|
| case AutocompleteInput::FORCED_QUERY:
|
| - return 1500;
|
| + return providers_.valid_keyword_provider() ? 250 : 1500;
|
|
|
| default:
|
| NOTREACHED();
|
| @@ -426,7 +559,8 @@
|
| }
|
| }
|
|
|
| -int SearchProvider::CalculateRelevanceForHistory(const Time& time) const {
|
| +int SearchProvider::CalculateRelevanceForHistory(const Time& time,
|
| + bool is_keyword) const {
|
| // The relevance of past searches falls off over time. This curve is chosen
|
| // so that the relevance of a search 15 minutes ago is discounted about 50
|
| // points, while the relevance of a search two weeks ago is discounted about
|
| @@ -437,19 +571,20 @@
|
| // Don't let scores go below 0. Negative relevance scores are meaningful in
|
| // a different way.
|
| int base_score;
|
| + bool is_primary = providers_.is_primary_provider(is_keyword);
|
| switch (input_.type()) {
|
| case AutocompleteInput::UNKNOWN:
|
| case AutocompleteInput::REQUESTED_URL:
|
| - base_score = 1050;
|
| + base_score = is_primary ? 1050 : 200;
|
| break;
|
|
|
| case AutocompleteInput::URL:
|
| - base_score = 750;
|
| + base_score = is_primary ? 750 : 200;
|
| break;
|
|
|
| case AutocompleteInput::QUERY:
|
| case AutocompleteInput::FORCED_QUERY:
|
| - base_score = 1250;
|
| + base_score = is_primary ? 1250 : 200;
|
| break;
|
|
|
| default:
|
| @@ -461,21 +596,24 @@
|
| }
|
|
|
| int SearchProvider::CalculateRelevanceForSuggestion(
|
| - size_t suggestion_number) const {
|
| - DCHECK(suggestion_number < suggest_results_.size());
|
| + const SuggestResults& suggest_results,
|
| + size_t suggestion_number,
|
| + bool is_keyword) const {
|
| + DCHECK(suggestion_number < suggest_results.size());
|
| + bool is_primary = providers_.is_primary_provider(is_keyword);
|
| const int suggestion_value =
|
| - static_cast<int>(suggest_results_.size() - 1 - suggestion_number);
|
| + static_cast<int>(suggest_results.size() - 1 - suggestion_number);
|
| switch (input_.type()) {
|
| case AutocompleteInput::UNKNOWN:
|
| case AutocompleteInput::REQUESTED_URL:
|
| - return 600 + suggestion_value;
|
| + return suggestion_value + (is_primary ? 600 : 100);
|
|
|
| case AutocompleteInput::URL:
|
| - return 300 + suggestion_value;
|
| + return suggestion_value + (is_primary ? 300 : 100);
|
|
|
| case AutocompleteInput::QUERY:
|
| case AutocompleteInput::FORCED_QUERY:
|
| - return 800 + suggestion_value;
|
| + return suggestion_value + (is_primary ? 800 : 100);
|
|
|
| default:
|
| NOTREACHED();
|
| @@ -484,17 +622,21 @@
|
| }
|
|
|
| int SearchProvider::CalculateRelevanceForNavigation(
|
| - size_t suggestion_number) const {
|
| - DCHECK(suggestion_number < navigation_results_.size());
|
| + size_t suggestion_number,
|
| + bool is_keyword) const {
|
| + DCHECK(
|
| + (is_keyword && suggestion_number < keyword_navigation_results_.size()) ||
|
| + (!is_keyword && suggestion_number < default_navigation_results_.size()));
|
| // TODO(kochi): http://b/784900 Use relevance score from the NavSuggest
|
| // server if possible.
|
| + bool is_primary = providers_.is_primary_provider(is_keyword);
|
| switch (input_.type()) {
|
| case AutocompleteInput::QUERY:
|
| case AutocompleteInput::FORCED_QUERY:
|
| - return 1000 + static_cast<int>(suggestion_number);
|
| + return static_cast<int>(suggestion_number) + (is_primary ? 1000 : 150);
|
|
|
| default:
|
| - return 800 + static_cast<int>(suggestion_number);
|
| + return static_cast<int>(suggestion_number) + (is_primary ? 800 : 150);
|
| }
|
| }
|
|
|
| @@ -502,11 +644,16 @@
|
| int relevance,
|
| AutocompleteMatch::Type type,
|
| int accepted_suggestion,
|
| + bool is_keyword,
|
| MatchMap* map) {
|
| + const std::wstring& input_text =
|
| + is_keyword ? keyword_input_text_ : input_.text();
|
| AutocompleteMatch match(this, relevance, false, type);
|
| std::vector<size_t> content_param_offsets;
|
| + const TemplateURL& provider = is_keyword ? providers_.keyword_provider() :
|
| + providers_.default_provider();
|
| match.contents.assign(l10n_util::GetStringF(IDS_AUTOCOMPLETE_SEARCH_CONTENTS,
|
| - default_provider_.short_name(),
|
| + provider.short_name(),
|
| query_string,
|
| &content_param_offsets));
|
| if (content_param_offsets.size() == 2) {
|
| @@ -539,16 +686,16 @@
|
| // NOTE: All Google suggestions currently start with the original input, but
|
| // not all Yahoo! suggestions do.
|
| if (!input_.prevent_inline_autocomplete() &&
|
| - !match.fill_into_edit.compare(search_start, input_.text().length(),
|
| - input_.text()))
|
| - match.inline_autocomplete_offset = search_start + input_.text().length();
|
| + !match.fill_into_edit.compare(search_start, input_text.length(),
|
| + input_text))
|
| + match.inline_autocomplete_offset = search_start + input_text.length();
|
|
|
| - const TemplateURLRef* const search_url = default_provider_.url();
|
| + const TemplateURLRef* const search_url = provider.url();
|
| DCHECK(search_url->SupportsReplacement());
|
| - match.destination_url = search_url->ReplaceSearchTerms(default_provider_,
|
| + match.destination_url = search_url->ReplaceSearchTerms(provider,
|
| query_string,
|
| accepted_suggestion,
|
| - input_.text());
|
| + input_text);
|
|
|
| // Search results don't look like URLs.
|
| match.transition = PageTransition::GENERATED;
|
| @@ -573,22 +720,24 @@
|
|
|
| AutocompleteMatch SearchProvider::NavigationToMatch(
|
| const NavigationResult& navigation,
|
| - int relevance) {
|
| + int relevance,
|
| + bool is_keyword) {
|
| + const std::wstring& input_text =
|
| + is_keyword ? keyword_input_text_ : input_.text();
|
| AutocompleteMatch match(this, relevance, false,
|
| AutocompleteMatch::NAVSUGGEST);
|
| match.destination_url = navigation.url;
|
| match.contents = StringForURLDisplay(navigation.url, true);
|
| // TODO(kochi): Consider moving HistoryURLProvider::TrimHttpPrefix() to some
|
| // public utility function.
|
| - if (!url_util::FindAndCompareScheme(WideToUTF8(input_.text()),
|
| - "http", NULL))
|
| + if (!url_util::FindAndCompareScheme(WideToUTF8(input_text), "http", NULL))
|
| TrimHttpPrefix(&match.contents);
|
| - AutocompleteMatch::ClassifyMatchInString(input_.text(), match.contents,
|
| + AutocompleteMatch::ClassifyMatchInString(input_text, match.contents,
|
| ACMatchClassification::URL,
|
| &match.contents_class);
|
|
|
| match.description = navigation.site_name;
|
| - AutocompleteMatch::ClassifyMatchInString(input_.text(), navigation.site_name,
|
| + AutocompleteMatch::ClassifyMatchInString(input_text, navigation.site_name,
|
| ACMatchClassification::NONE,
|
| &match.description_class);
|
|
|
|
|