diff options
author | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-09 04:44:08 +0000 |
---|---|---|
committer | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-09 04:44:08 +0000 |
commit | 55ce8f1934570a6edf9909d7c1bd6a89b2779f60 (patch) | |
tree | 5e31e45cfbd14e9b4cfbb1e0c489c20f1e24f7d5 | |
parent | 4f4e597baf96e733dc8baf9e3c2de7a3671c6a6b (diff) | |
download | chromium_src-55ce8f1934570a6edf9909d7c1bd6a89b2779f60.zip chromium_src-55ce8f1934570a6edf9909d7c1bd6a89b2779f60.tar.gz chromium_src-55ce8f1934570a6edf9909d7c1bd6a89b2779f60.tar.bz2 |
Cleanup SearchProvider.
Use new [Suggest|Navigation]Result classes (replaces ScoredTerm, etc.).
Split ClearResults() from StopSuggest(), keep calls paired for now.
Calculate search/nav relevance while parsing results (same exact scoring).
Remove various unused and redundant function arguments.
Simplify JSON parsing code; minor refactoring.
BUG=125871
TEST=No behavior changes.
Review URL: https://chromiumcodereview.appspot.com/10379028
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135984 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/autocomplete/search_provider.cc | 318 | ||||
-rw-r--r-- | chrome/browser/autocomplete/search_provider.h | 116 |
2 files changed, 220 insertions, 214 deletions
diff --git a/chrome/browser/autocomplete/search_provider.cc b/chrome/browser/autocomplete/search_provider.cc index 0a1af9f..d6d34d7 100644 --- a/chrome/browser/autocomplete/search_provider.cc +++ b/chrome/browser/autocomplete/search_provider.cc @@ -149,7 +149,7 @@ void SearchProvider::FinalizeInstantQuery(const string16& input_text, } } - // Add the new suggest result. We give it a rank higher than + // Add the new instant suggest result. We give it a rank higher than // SEARCH_WHAT_YOU_TYPED so that it gets autocompleted. int did_not_accept_default_suggestion = default_suggest_results_.empty() ? TemplateURLRef::NO_SUGGESTIONS_AVAILABLE : @@ -158,8 +158,7 @@ void SearchProvider::FinalizeInstantQuery(const string16& input_text, AddMatchToMap(text, adjusted_input_text, CalculateRelevanceForWhatYouTyped() + 1, AutocompleteMatch::SEARCH_SUGGEST, - did_not_accept_default_suggestion, false, - input_.prevent_inline_autocomplete(), &match_map); + did_not_accept_default_suggestion, false, &match_map); DCHECK_EQ(1u, match_map.size()); matches_.push_back(match_map.begin()->second); @@ -241,11 +240,33 @@ void SearchProvider::Start(const AutocompleteInput& input, ConvertResultsToAutocompleteMatches(); } -class SearchProvider::CompareScoredTerms { +SearchProvider::Result::Result(int relevance) : relevance_(relevance) {} +SearchProvider::Result::~Result() {} + +SearchProvider::SuggestResult::SuggestResult(const string16& suggestion, + int relevance) + : Result(relevance), + suggestion_(suggestion) { +} + +SearchProvider::SuggestResult::~SuggestResult() {} + +SearchProvider::NavigationResult::NavigationResult(const GURL& url, + const string16& description, + int relevance) + : Result(relevance), + url_(url), + description_(description) { + DCHECK(url_.is_valid()); +} + +SearchProvider::NavigationResult::~NavigationResult() {} + +class SearchProvider::CompareScoredResults { public: - bool operator()(const ScoredTerm& a, const ScoredTerm& b) { + bool operator()(const Result& a, const Result& b) { // Sort in descending relevance order. - return a.second > b.second; + return a.relevance() > b.relevance(); } }; @@ -279,6 +300,7 @@ void SearchProvider::Run() { void SearchProvider::Stop() { StopSuggest(); + ClearResults(); done_ = true; default_provider_suggest_text_.clear(); } @@ -306,9 +328,9 @@ void SearchProvider::OnURLFetchComplete(const content::URLFetcher* source) { } } - bool is_keyword_results = (source == keyword_fetcher_.get()); - SuggestResults* suggest_results = is_keyword_results ? - &keyword_suggest_results_ : &default_suggest_results_; + bool is_keyword = (source == keyword_fetcher_.get()); + SuggestResults* suggest_results = + is_keyword ? &keyword_suggest_results_ : &default_suggest_results_; std::string histogram_name = "Omnibox.SuggestRequest.Failure.GoogleResponseTime"; @@ -316,12 +338,9 @@ void SearchProvider::OnURLFetchComplete(const content::URLFetcher* source) { JSONStringValueSerializer deserializer(json_data); deserializer.set_allow_trailing_comma(true); scoped_ptr<Value> root_val(deserializer.Deserialize(NULL, NULL)); - const string16& input_text = - is_keyword_results ? keyword_input_text_ : input_.text(); - have_suggest_results_ = - root_val.get() && - ParseSuggestResults(root_val.get(), is_keyword_results, input_text, - suggest_results); + const string16& input = is_keyword ? keyword_input_text_ : input_.text(); + have_suggest_results_ = root_val.get() && + ParseSuggestResults(root_val.get(), is_keyword, input, suggest_results); histogram_name = "Omnibox.SuggestRequest.Success.GoogleResponseTime"; } @@ -329,7 +348,7 @@ void SearchProvider::OnURLFetchComplete(const content::URLFetcher* source) { // only about the common case: the Google default provider used in // non-keyword mode. const TemplateURL* default_url = providers_.GetDefaultProviderURL(); - if (!is_keyword_results && default_url && + if (!is_keyword && default_url && (default_url->prepopulate_id() == SEARCH_ENGINE_GOOGLE)) { UMA_HISTOGRAM_TIMES(histogram_name, base::TimeTicks::Now() - time_suggest_request_sent_); @@ -388,6 +407,7 @@ void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes) { if (!IsQuerySuitableForSuggest()) { StopSuggest(); + ClearResults(); return; } @@ -402,6 +422,7 @@ void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes) { // We can't keep running any previous query, so halt it. StopSuggest(); + ClearResults(); // We can't start a new query if we're only allowed synchronous results. if (input_.matches_requested() != AutocompleteInput::ALL_MATCHES) @@ -481,6 +502,9 @@ void SearchProvider::StopSuggest() { // Stop any in-progress URL fetches. keyword_fetcher_.reset(); default_fetcher_.reset(); +} + +void SearchProvider::ClearResults() { keyword_suggest_results_.clear(); default_suggest_results_.clear(); keyword_navigation_results_.clear(); @@ -511,84 +535,69 @@ bool SearchProvider::ParseSuggestResults(Value* root_val, return false; ListValue* root_list = static_cast<ListValue*>(root_val); - Value* query_val; string16 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) || - !root_list->Get(1, &result_val) || !result_val->IsType(Value::TYPE_LIST)) + ListValue* result_list = NULL; + if ((root_list->GetSize() < 2) || !root_list->GetString(0, &query_str) || + (query_str != input_text) || !root_list->GetList(1, &result_list)) return false; + // 3rd element: Description list. ListValue* description_list = NULL; - if (root_list->GetSize() > 2) { - // 3rd element: Description list. - Value* description_val; - if (root_list->Get(2, &description_val) && - description_val->IsType(Value::TYPE_LIST)) - description_list = static_cast<ListValue*>(description_val); - } + if (root_list->GetSize() > 2) + root_list->GetList(2, &description_list); - // We don't care about the query URL list (the fourth element in the - // response) for now. + // 4th element: Disregard the query URL list for now. - // Parse optional data in the results from the Suggest server if any. + // 5th element: Optional key-value pairs from the Suggest server. + DictionaryValue* dict_val = NULL; ListValue* type_list = NULL; - // 5th argument: Optional key-value pairs. - // TODO: We may iterate the 5th+ arguments of the root_list if any other - // optional data are defined. - if (root_list->GetSize() > 4) { - Value* optional_val; - if (root_list->Get(4, &optional_val) && - optional_val->IsType(Value::TYPE_DICTIONARY)) { - DictionaryValue* dict_val = static_cast<DictionaryValue*>(optional_val); - - // Parse Google Suggest specific type extension. - const std::string kGoogleSuggestType("google:suggesttype"); - if (dict_val->HasKey(kGoogleSuggestType)) - dict_val->GetList(kGoogleSuggestType, &type_list); - } + if (root_list->GetSize() > 4 && root_list->GetDictionary(4, &dict_val)) { + // Parse Google Suggest specific type extension. + const std::string kGoogleSuggestType("google:suggesttype"); + dict_val->GetList(kGoogleSuggestType, &type_list); } - ListValue* result_list = static_cast<ListValue*>(result_val); - for (size_t i = 0; i < result_list->GetSize(); ++i) { - Value* suggestion_val; - string16 suggestion_str; - if (!result_list->Get(i, &suggestion_val) || - !suggestion_val->GetAsString(&suggestion_str)) + // Add the suggestions in reverse order to assist relevance calculation. + for (size_t i = result_list->GetSize(); i > 0; --i) { + size_t current_index = i - 1; + string16 suggestion; + if (!result_list->GetString(current_index, &suggestion)) return false; // Google search may return empty suggestions for weird input characters, - // they make no sense at all and can cause problem in our code. + // they make no sense at all and can cause problems in our code. // See http://crbug.com/56214 - if (!suggestion_str.length()) + if (!suggestion.length()) continue; - Value* type_val; - std::string type_str; - if (type_list && type_list->Get(i, &type_val) && - type_val->GetAsString(&type_str) && (type_str == "NAVIGATION")) { - Value* site_val; - string16 site_name; - NavigationResults& navigation_results = - is_keyword ? keyword_navigation_results_ : - default_navigation_results_; - if ((navigation_results.size() < kMaxMatches) && - description_list && description_list->Get(i, &site_val) && - site_val->IsType(Value::TYPE_STRING) && - site_val->GetAsString(&site_name)) { + std::string type; + if (type_list && type_list->GetString(current_index, &type) && + (type == "NAVIGATION")) { + string16 description; + NavigationResults& navigation_results = is_keyword ? + keyword_navigation_results_ : default_navigation_results_; + if ((navigation_results.size() < kMaxMatches) && description_list && + description_list->GetString(current_index, &description)) { // We can't blindly trust the URL coming from the server to be valid. - GURL result_url(URLFixerUpper::FixupURL(UTF16ToUTF8(suggestion_str), - std::string())); - if (result_url.is_valid()) { - navigation_results.push_back(NavigationResult(result_url, site_name)); + GURL url(URLFixerUpper::FixupURL(UTF16ToUTF8(suggestion), + std::string())); + if (url.is_valid()) { + // Increment the relevance for successive results to preserve order. + int relevance = CalculateRelevanceForNavigation(is_keyword) + + navigation_results.size(); + navigation_results.push_back( + NavigationResult(url, description, relevance)); } } } 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() < kMaxMatches) - suggest_results->push_back(suggestion_str); + if (suggest_results->size() < kMaxMatches) { + // Increment the relevance for successive results to preserve order. + int relevance = CalculateRelevanceForSuggestion(is_keyword) + + suggest_results->size(); + suggest_results->push_back(SuggestResult(suggestion, relevance)); + } } } @@ -605,20 +614,18 @@ void SearchProvider::ConvertResultsToAutocompleteMatches() { TemplateURLRef::NO_SUGGESTION_CHOSEN; // Keyword what you typed results are handled by the KeywordProvider. + int verbatim_relevance = CalculateRelevanceForWhatYouTyped(); int did_not_accept_default_suggestion = default_suggest_results_.empty() ? - TemplateURLRef::NO_SUGGESTIONS_AVAILABLE : - TemplateURLRef::NO_SUGGESTION_CHOSEN; - AddMatchToMap(input_.text(), input_.text(), - CalculateRelevanceForWhatYouTyped(), + TemplateURLRef::NO_SUGGESTIONS_AVAILABLE : + TemplateURLRef::NO_SUGGESTION_CHOSEN; + AddMatchToMap(input_.text(), input_.text(), verbatim_relevance, AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, - did_not_accept_default_suggestion, false, - input_.prevent_inline_autocomplete(), &map); + did_not_accept_default_suggestion, false, &map); if (!default_provider_suggest_text_.empty()) { AddMatchToMap(input_.text() + default_provider_suggest_text_, - input_.text(), CalculateRelevanceForWhatYouTyped() + 1, + input_.text(), verbatim_relevance + 1, AutocompleteMatch::SEARCH_SUGGEST, - did_not_accept_default_suggestion, false, - input_.prevent_inline_autocomplete(), &map); + did_not_accept_default_suggestion, false, &map); } AddHistoryResultsToMap(keyword_history_results_, true, @@ -626,10 +633,8 @@ void SearchProvider::ConvertResultsToAutocompleteMatches() { 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); + AddSuggestResultsToMap(keyword_suggest_results_, true, &map); + AddSuggestResultsToMap(default_suggest_results_, false, &map); // Now add the most relevant matches from the map to |matches_|. matches_.clear(); @@ -639,7 +644,8 @@ void SearchProvider::ConvertResultsToAutocompleteMatches() { AddNavigationResultsToMatches(keyword_navigation_results_, true); AddNavigationResultsToMatches(default_navigation_results_, false); - const size_t max_total_matches = kMaxMatches + 1; // 1 for "what you typed" + // Allow an additional match for "what you typed". + const size_t max_total_matches = kMaxMatches + 1; std::partial_sort(matches_.begin(), matches_.begin() + std::min(max_total_matches, matches_.size()), matches_.end(), &AutocompleteMatch::MoreRelevant); @@ -647,7 +653,6 @@ void SearchProvider::ConvertResultsToAutocompleteMatches() { matches_.erase(matches_.begin() + max_total_matches, matches_.end()); UpdateStarredStateOfMatches(); - UpdateDone(); } @@ -658,11 +663,8 @@ void SearchProvider::AddNavigationResultsToMatches( // 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. - const size_t num_results = is_keyword ? - keyword_navigation_results_.size() : default_navigation_results_.size(); - matches_.push_back(NavigationToMatch(navigation_results.front(), - CalculateRelevanceForNavigation(num_results, 0, is_keyword), - is_keyword)); + matches_.push_back( + NavigationToMatch(navigation_results.front(), is_keyword)); } } @@ -673,48 +675,48 @@ void SearchProvider::AddHistoryResultsToMap(const HistoryResults& results, if (results.empty()) return; - bool base_prevent_inline_autocomplete = + bool prevent_inline_autocomplete = (input_.type() == AutocompleteInput::URL) || input_.prevent_inline_autocomplete(); - const string16& input_text( - is_keyword ? keyword_input_text_ : input_.text()); + const string16& input_text(is_keyword ? keyword_input_text_ : input_.text()); bool input_multiple_words = HasMultipleWords(input_text); - ScoredTerms scored_terms; - if (!base_prevent_inline_autocomplete && input_multiple_words) { - // ScoreHistoryTerms() allows autocompletion of multi-word, 1-visit queries - // if the input also has multiple words. But if we were already + SuggestResults scored_results; + if (!prevent_inline_autocomplete && input_multiple_words) { + // ScoreHistoryResults() allows autocompletion of multi-word, 1-visit + // queries if the input also has multiple words. But if we were already // autocompleting a multi-word, multi-visit query, and the current input is // still a prefix of it, then changing the autocompletion suddenly feels // wrong. To detect this case, first score as if only one word has been // typed, then check for a best result that is an autocompleted, multi-word // query. If we find one, then just keep that score set. - scored_terms = ScoreHistoryTerms(results, base_prevent_inline_autocomplete, - false, input_text, is_keyword); - if ((scored_terms[0].second < AutocompleteResult::kLowestDefaultScore) || - !HasMultipleWords(scored_terms[0].first)) - scored_terms.clear(); // Didn't detect the case above, score normally. - } - if (scored_terms.empty()) - scored_terms = ScoreHistoryTerms(results, base_prevent_inline_autocomplete, - input_multiple_words, input_text, - is_keyword); - for (ScoredTerms::const_iterator i(scored_terms.begin()); - i != scored_terms.end(); ++i) { - AddMatchToMap(i->first, input_text, i->second, + scored_results = ScoreHistoryResults(results, prevent_inline_autocomplete, + false, input_text, is_keyword); + if ((scored_results[0].relevance() < + AutocompleteResult::kLowestDefaultScore) || + !HasMultipleWords(scored_results[0].suggestion())) + scored_results.clear(); // Didn't detect the case above, score normally. + } + if (scored_results.empty()) + scored_results = ScoreHistoryResults(results, prevent_inline_autocomplete, + input_multiple_words, input_text, + is_keyword); + for (SuggestResults::const_iterator i(scored_results.begin()); + i != scored_results.end(); ++i) { + AddMatchToMap(i->suggestion(), input_text, i->relevance(), AutocompleteMatch::SEARCH_HISTORY, did_not_accept_suggestion, - is_keyword, input_.prevent_inline_autocomplete(), map); + is_keyword, map); } } -SearchProvider::ScoredTerms SearchProvider::ScoreHistoryTerms( +SearchProvider::SuggestResults SearchProvider::ScoreHistoryResults( const HistoryResults& results, bool base_prevent_inline_autocomplete, bool input_multiple_words, const string16& input_text, bool is_keyword) { AutocompleteClassifier* classifier = profile_->GetAutocompleteClassifier(); - ScoredTerms scored_terms; + SuggestResults scored_results; for (HistoryResults::const_iterator i(results.begin()); i != results.end(); ++i) { // Don't autocomplete multi-word queries that have only been seen once @@ -744,7 +746,7 @@ SearchProvider::ScoredTerms SearchProvider::ScoreHistoryTerms( int relevance = CalculateRelevanceForHistory(i->time, is_keyword, prevent_inline_autocomplete); - scored_terms.push_back(std::make_pair(i->term, relevance)); + scored_results.push_back(SuggestResult(i->term, relevance)); } // History returns results sorted for us. However, we may have docked some @@ -752,32 +754,26 @@ SearchProvider::ScoredTerms SearchProvider::ScoreHistoryTerms( // things back in order without otherwise disturbing results with equal // scores, then force the scores to be unique, so that the order in which // they're shown is deterministic. - std::stable_sort(scored_terms.begin(), scored_terms.end(), - CompareScoredTerms()); + std::stable_sort(scored_results.begin(), scored_results.end(), + CompareScoredResults()); int last_relevance = 0; - for (ScoredTerms::iterator i(scored_terms.begin()); i != scored_terms.end(); - ++i) { - if ((i != scored_terms.begin()) && (i->second >= last_relevance)) - i->second = last_relevance - 1; - last_relevance = i->second; + for (SuggestResults::iterator i(scored_results.begin()); + i != scored_results.end(); ++i) { + if ((i != scored_results.begin()) && (i->relevance() >= last_relevance)) + i->set_relevance(last_relevance - 1); + last_relevance = i->relevance(); } - return scored_terms; + return scored_results; } -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], - is_keyword ? keyword_input_text_ : input_.text(), - CalculateRelevanceForSuggestion(suggest_results.size(), i, - is_keyword), - AutocompleteMatch::SEARCH_SUGGEST, - static_cast<int>(i), is_keyword, - input_.prevent_inline_autocomplete(), map); +void SearchProvider::AddSuggestResultsToMap(const SuggestResults& results, + bool is_keyword, + MatchMap* map) { + const string16& text = is_keyword ? keyword_input_text_ : input_.text(); + for (size_t i = 0; i < results.size(); ++i) { + AddMatchToMap(results[i].suggestion(), text, results[i].relevance(), + AutocompleteMatch::SEARCH_SUGGEST, i, is_keyword, map); } } @@ -838,27 +834,13 @@ int SearchProvider::CalculateRelevanceForHistory( return std::max(0, base_score - score_discount); } -int SearchProvider::CalculateRelevanceForSuggestion(size_t num_results, - size_t result_number, - bool is_keyword) const { - DCHECK(result_number < num_results); - int base_score; - if (!providers_.is_primary_provider(is_keyword)) - base_score = 100; - else - base_score = (input_.type() == AutocompleteInput::URL) ? 300 : 600; - return base_score + - static_cast<int>(num_results - 1 - result_number); +int SearchProvider::CalculateRelevanceForSuggestion(bool for_keyword) const { + return !providers_.is_primary_provider(for_keyword) ? 100 : + ((input_.type() == AutocompleteInput::URL) ? 300 : 600); } -int SearchProvider::CalculateRelevanceForNavigation(size_t num_results, - size_t result_number, - bool is_keyword) const { - DCHECK(result_number < num_results); - // TODO(kochi): http://b/784900 Use relevance score from the NavSuggest - // server if possible. - return (providers_.is_primary_provider(is_keyword) ? 800 : 150) + - static_cast<int>(num_results - 1 - result_number); +int SearchProvider::CalculateRelevanceForNavigation(bool for_keyword) const { + return providers_.is_primary_provider(for_keyword) ? 800 : 150; } void SearchProvider::AddMatchToMap(const string16& query_string, @@ -867,7 +849,6 @@ void SearchProvider::AddMatchToMap(const string16& query_string, AutocompleteMatch::Type type, int accepted_suggestion, bool is_keyword, - bool prevent_inline_autocomplete, MatchMap* map) { AutocompleteMatch match(this, relevance, false, type); std::vector<size_t> content_param_offsets; @@ -932,7 +913,7 @@ void SearchProvider::AddMatchToMap(const string16& query_string, } match.fill_into_edit.append(query_string); // Not all suggestions start with the original input. - if (!prevent_inline_autocomplete && + 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(); @@ -966,21 +947,19 @@ void SearchProvider::AddMatchToMap(const string16& query_string, AutocompleteMatch SearchProvider::NavigationToMatch( const NavigationResult& navigation, - int relevance, bool is_keyword) { - const string16& input_text = - is_keyword ? keyword_input_text_ : input_.text(); - AutocompleteMatch match(this, relevance, false, + const string16& input_text = is_keyword ? keyword_input_text_ : input_.text(); + AutocompleteMatch match(this, navigation.relevance(), false, AutocompleteMatch::NAVSUGGEST); - match.destination_url = navigation.url; + match.destination_url = navigation.url(); match.contents = - StringForURLDisplay(navigation.url, true, !HasHTTPScheme(input_text)); + StringForURLDisplay(navigation.url(), true, !HasHTTPScheme(input_text)); AutocompleteMatch::ClassifyMatchInString(input_text, match.contents, ACMatchClassification::URL, &match.contents_class); - match.description = navigation.site_name; - AutocompleteMatch::ClassifyMatchInString(input_text, navigation.site_name, + match.description = navigation.description(); + AutocompleteMatch::ClassifyMatchInString(input_text, match.description, ACMatchClassification::NONE, &match.description_class); @@ -990,10 +969,9 @@ AutocompleteMatch SearchProvider::NavigationToMatch( if (input_.type() == AutocompleteInput::FORCED_QUERY) match.fill_into_edit.assign(ASCIIToUTF16("?")); match.fill_into_edit.append( - AutocompleteInput::FormattedStringWithEquivalentMeaning(navigation.url, + AutocompleteInput::FormattedStringWithEquivalentMeaning(navigation.url(), match.contents)); - // TODO(pkasting): http://b/1112879 These should perhaps be - // inline-autocompletable? + // TODO(pkasting|msw): Inline-autocomplete nav results; see http://b/1112879. return match; } diff --git a/chrome/browser/autocomplete/search_provider.h b/chrome/browser/autocomplete/search_provider.h index 5444a8b..856bd0b 100644 --- a/chrome/browser/autocomplete/search_provider.h +++ b/chrome/browser/autocomplete/search_provider.h @@ -134,27 +134,62 @@ class SearchProvider : public AutocompleteProvider, DISALLOW_COPY_AND_ASSIGN(Providers); }; - struct NavigationResult { - NavigationResult(const GURL& url, const string16& site_name) - : url(url), - site_name(site_name) { - } + // The Result classes are intermediate representations of AutocompleteMatches, + // simply containing relevance-ranked search and navigation suggestions. + // They may be cached to provide some synchronous matches while requests for + // new suggestions from updated input are in flight. + // TODO(msw) Extend these classes to generate their corresponding matches and + // other requisite data, in order to consolidate and simplify the + // highly fragmented SearchProvider logic for each Result type. + class Result { + public: + explicit Result(int relevance); + virtual ~Result(); + + int relevance() const { return relevance_; } + void set_relevance(int relevance) { relevance_ = relevance; } + + private: + // The relevance score. + int relevance_; + }; + + class SuggestResult : public Result { + public: + SuggestResult(const string16& suggestion, int relevance); + virtual ~SuggestResult(); + + const string16& suggestion() const { return suggestion_; } + + private: + // The search suggestion string. + string16 suggestion_; + }; + + class NavigationResult : public Result { + public: + NavigationResult(const GURL& url, + const string16& description, + int relevance); + virtual ~NavigationResult(); + + const GURL& url() const { return url_; } + const string16& description() const { return description_; } - // The URL. - GURL url; + private: + // The suggested url for navigation. + GURL url_; - // Name for the site. - string16 site_name; + // The suggested navigational result description; generally the site name. + string16 description_; }; - typedef std::vector<string16> SuggestResults; + typedef std::vector<SuggestResult> SuggestResults; typedef std::vector<NavigationResult> NavigationResults; typedef std::vector<history::KeywordSearchTermVisit> HistoryResults; typedef std::map<string16, AutocompleteMatch> MatchMap; - typedef std::pair<string16, int> ScoredTerm; - typedef std::vector<ScoredTerm> ScoredTerms; - class CompareScoredTerms; + class CompareScoredResults; // Called when timer_ expires. void Run(); @@ -177,6 +212,9 @@ class SearchProvider : public AutocompleteProvider, // NOTE: This does not update |done_|. Callers must do so. void StopSuggest(); + // Clears the current results. + void ClearResults(); + // Creates a URLFetcher requesting suggest results from the specified // |suggestions_url|. The caller owns the returned URLFetcher. content::URLFetcher* CreateSuggestFetcher( @@ -185,22 +223,21 @@ class SearchProvider : public AutocompleteProvider, const string16& text); // Parses the results from the Suggest server and stores up to kMaxMatches of - // them in server_results_. Returns whether parsing succeeded. + // them in |suggest_results|. Returns whether parsing succeeded. bool ParseSuggestResults(base::Value* root_val, bool is_keyword, const string16& input_text, SuggestResults* suggest_results); - // Converts the parsed server results in server_results_ to a set of - // AutocompleteMatches and adds them to |matches_|. This also sets |done_| - // correctly. + // Converts the parsed results to a set of AutocompleteMatches and adds them + // to |matches_|. This also sets |done_| correctly. void ConvertResultsToAutocompleteMatches(); // Converts the first navigation result in |navigation_results| to an // AutocompleteMatch and adds it to |matches_|. void AddNavigationResultsToMatches( - const NavigationResults& navigation_results, - bool is_keyword); + const NavigationResults& navigation_results, + bool is_keyword); // Adds a match for each result in |results| to |map|. |is_keyword| indicates // whether the results correspond to the keyword provider or default provider. @@ -210,18 +247,16 @@ class SearchProvider : public AutocompleteProvider, MatchMap* map); // Calculates relevance scores for all |results|. - ScoredTerms ScoreHistoryTerms(const HistoryResults& results, - bool base_prevent_inline_autocomplete, - bool input_multiple_words, - const string16& input_text, - bool is_keyword); - - // Adds a match for each result in |suggest_results| to |map|. |is_keyword| - // indicates whether the results correspond to the keyword provider or default - // provider. - void AddSuggestResultsToMap(const SuggestResults& suggest_results, + SuggestResults ScoreHistoryResults(const HistoryResults& results, + bool base_prevent_inline_autocomplete, + bool input_multiple_words, + const string16& input_text, + bool is_keyword); + + // Adds matches for |results| to |map|. |is_keyword| indicates whether the + // results correspond to the keyword provider or default provider. + void AddSuggestResultsToMap(const SuggestResults& results, bool is_keyword, - int did_not_accept_suggestion, MatchMap* map); // Determines the relevance for a particular match. We use different scoring @@ -234,17 +269,12 @@ class SearchProvider : public AutocompleteProvider, int CalculateRelevanceForHistory(const base::Time& time, bool is_keyword, bool prevent_inline_autocomplete) const; - // |result_number| is the index of the suggestion in the result set from the - // server; the best suggestion is suggestion number 0. |is_keyword| is true - // if the search is from the keyword provider. - int CalculateRelevanceForSuggestion(size_t num_results, - size_t result_number, - bool is_keyword) const; - // |result_number| is same as above. |is_keyword| is true if the navigation - // result was suggested by the keyword provider. - int CalculateRelevanceForNavigation(size_t num_results, - size_t result_number, - bool is_keyword) const; + // Calculate the relevance for search suggestion results. Set |for_keyword| to + // true for relevance values applicable to keyword provider results. + int CalculateRelevanceForSuggestion(bool for_keyword) const; + // Calculate the relevance for navigation results. Set |for_keyword| to true + // for relevance values applicable to keyword provider results. + int CalculateRelevanceForNavigation(bool for_keyword) const; // Creates an AutocompleteMatch for "Search <engine> for |query_string|" with // the supplied relevance. Adds this match to |map|; if such a match already @@ -255,12 +285,10 @@ class SearchProvider : public AutocompleteProvider, AutocompleteMatch::Type type, int accepted_suggestion, bool is_keyword, - bool prevent_inline_autocomplete, MatchMap* map); // Returns an AutocompleteMatch for a navigational suggestion. - AutocompleteMatch NavigationToMatch(const NavigationResult& query_string, - int relevance, + AutocompleteMatch NavigationToMatch(const NavigationResult& navigation, bool is_keyword); // Updates the value of |done_| from the internal state. |