summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autocomplete/search_provider.cc
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-14 17:16:24 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-14 17:16:24 +0000
commit257ab718488a1cdb46a2423464e17933c8339a01 (patch)
treeb36111115dd00a00da78113758424603b45cb818 /chrome/browser/autocomplete/search_provider.cc
parent3f85caafb239d5725ec85af9b8ce9f1b1de15770 (diff)
downloadchromium_src-257ab718488a1cdb46a2423464e17933c8339a01.zip
chromium_src-257ab718488a1cdb46a2423464e17933c8339a01.tar.gz
chromium_src-257ab718488a1cdb46a2423464e17933c8339a01.tar.bz2
Makes the omnibox show past searches and suggestions for keywords.
We talked about primary and secondary, but after doing it all I felt keyword and default better portrayed what is going on. After trying this out I think we need to tune relevancy. But that can be done later BUG=3636 TEST=make sure omnibox isn't broken. Review URL: http://codereview.chromium.org/66073 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13668 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/autocomplete/search_provider.cc')
-rw-r--r--chrome/browser/autocomplete/search_provider.cc395
1 files changed, 272 insertions, 123 deletions
diff --git a/chrome/browser/autocomplete/search_provider.cc b/chrome/browser/autocomplete/search_provider.cc
index d462480..1c1dccdf 100644
--- a/chrome/browser/autocomplete/search_provider.cc
+++ b/chrome/browser/autocomplete/search_provider.cc
@@ -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 @@ void SearchProvider::Start(const AutocompleteInput& input,
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::Start(const AutocompleteInput& input,
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 @@ void SearchProvider::OnURLFetchComplete(const URLFetcher* source,
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 @@ void SearchProvider::OnURLFetchComplete(const URLFetcher* source,
}
}
+ 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 @@ void SearchProvider::StartOrStopHistoryQuery(bool minimal_changes) {
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 @@ void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes) {
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 @@ bool SearchProvider::IsQuerySuitableForSuggest() const {
// 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 @@ bool SearchProvider::IsQuerySuitableForSuggest() const {
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;
+ }
+}
+
+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 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 @@ bool SearchProvider::ParseSuggestResults(Value* root_val) {
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 @@ bool SearchProvider::ParseSuggestResults(Value* root_val) {
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 @@ bool SearchProvider::ParseSuggestResults(Value* root_val) {
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 @@ void SearchProvider::ConvertResultsToAutocompleteMatches() {
// 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);
-
- 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);
+ // Keyword what you typed results are handled by the KeywordProvider.
+
+ 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 @@ void SearchProvider::ConvertResultsToAutocompleteMatches() {
// 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::CalculateRelevanceForWhatYouTyped() const {
}
}
-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 @@ int SearchProvider::CalculateRelevanceForHistory(const Time& time) const {
// 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::CalculateRelevanceForHistory(const Time& time) const {
}
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::CalculateRelevanceForSuggestion(
}
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 @@ void SearchProvider::AddMatchToMap(const std::wstring& query_string,
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 @@ void SearchProvider::AddMatchToMap(const std::wstring& query_string,
// 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 @@ void SearchProvider::AddMatchToMap(const std::wstring& query_string,
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);