| Index: chrome/browser/autocomplete/search_provider.cc
|
| diff --git a/chrome/browser/autocomplete/search_provider.cc b/chrome/browser/autocomplete/search_provider.cc
|
| index 80f8648c574d0198e373d5f657c241a230546478..d399f6d2c7de593d3d7e9b82c3c1669b293e1c7c 100644
|
| --- a/chrome/browser/autocomplete/search_provider.cc
|
| +++ b/chrome/browser/autocomplete/search_provider.cc
|
| @@ -102,53 +102,6 @@ bool HasMultipleWords(const base::string16& text) {
|
| return false;
|
| }
|
|
|
| -// Builds the match contents and classification for the contents, and updates
|
| -// the given |AutocompleteMatch|.
|
| -void SetAndClassifyMatchContents(const base::string16& query_string,
|
| - const base::string16& input_text,
|
| - const base::string16& match_contents,
|
| - AutocompleteMatch* match) {
|
| - match->contents = match_contents.empty() ? query_string : match_contents;
|
| -
|
| - // We do intra-string highlighting for suggestions - the suggested segment
|
| - // will be highlighted, e.g. for input_text = "you" the suggestion may be
|
| - // "youtube", so we'll bold the "tube" section: you*tube*.
|
| - if (input_text != match_contents) {
|
| - size_t input_position = match->contents.find(input_text);
|
| - if (input_position == base::string16::npos) {
|
| - // The input text is not a substring of the query string, e.g. input
|
| - // text is "slasdot" and the query string is "slashdot", so we bold the
|
| - // whole thing.
|
| - match->contents_class.push_back(ACMatchClassification(
|
| - 0, ACMatchClassification::MATCH));
|
| - } else {
|
| - // TODO(beng): ACMatchClassification::MATCH now seems to just mean
|
| - // "bold" this. Consider modifying the terminology.
|
| - // We don't iterate over the string here annotating all matches because
|
| - // it looks odd to have every occurrence of a substring that may be as
|
| - // short as a single character highlighted in a query suggestion result,
|
| - // e.g. for input text "s" and query string "southwest airlines", it
|
| - // looks odd if both the first and last s are highlighted.
|
| - if (input_position != 0) {
|
| - match->contents_class.push_back(ACMatchClassification(
|
| - 0, ACMatchClassification::MATCH));
|
| - }
|
| - match->contents_class.push_back(
|
| - ACMatchClassification(input_position, ACMatchClassification::NONE));
|
| - size_t next_fragment_position = input_position + input_text.length();
|
| - if (next_fragment_position < query_string.length()) {
|
| - match->contents_class.push_back(ACMatchClassification(
|
| - next_fragment_position, ACMatchClassification::MATCH));
|
| - }
|
| - }
|
| - } else {
|
| - // Otherwise, |match| is a verbatim (what-you-typed) match, either for the
|
| - // default provider or a keyword search provider.
|
| - match->contents_class.push_back(ACMatchClassification(
|
| - 0, ACMatchClassification::NONE));
|
| - }
|
| -}
|
| -
|
| AutocompleteMatchType::Type GetAutocompleteMatchType(const std::string& type) {
|
| if (type == "ENTITY")
|
| return AutocompleteMatchType::SEARCH_SUGGEST_ENTITY;
|
| @@ -262,7 +215,8 @@ SearchProvider::SuggestResult::SuggestResult(
|
| bool from_keyword_provider,
|
| int relevance,
|
| bool relevance_from_server,
|
| - bool should_prefetch)
|
| + bool should_prefetch,
|
| + const base::string16& input_text)
|
| : Result(from_keyword_provider, relevance, relevance_from_server),
|
| suggestion_(suggestion),
|
| type_(type),
|
| @@ -271,11 +225,60 @@ SearchProvider::SuggestResult::SuggestResult(
|
| suggest_query_params_(suggest_query_params),
|
| deletion_url_(deletion_url),
|
| should_prefetch_(should_prefetch) {
|
| + DCHECK(!match_contents_.empty());
|
| + ClassifyMatchContents(true, input_text);
|
| }
|
|
|
| SearchProvider::SuggestResult::~SuggestResult() {
|
| }
|
|
|
| +void SearchProvider::SuggestResult::ClassifyMatchContents(
|
| + const bool allow_bolding_all,
|
| + const base::string16& input_text) {
|
| + size_t input_position = match_contents_.find(input_text);
|
| + if (!allow_bolding_all && (input_position == base::string16::npos)) {
|
| + // Bail if the code below to update the bolding would bold the whole
|
| + // string. Note that the string may already be entirely bolded; if
|
| + // so, leave it as is.
|
| + return;
|
| + }
|
| + match_contents_class_.clear();
|
| + // We do intra-string highlighting for suggestions - the suggested segment
|
| + // will be highlighted, e.g. for input_text = "you" the suggestion may be
|
| + // "youtube", so we'll bold the "tube" section: you*tube*.
|
| + if (input_text != match_contents_) {
|
| + if (input_position == base::string16::npos) {
|
| + // The input text is not a substring of the query string, e.g. input
|
| + // text is "slasdot" and the query string is "slashdot", so we bold the
|
| + // whole thing.
|
| + match_contents_class_.push_back(ACMatchClassification(
|
| + 0, ACMatchClassification::MATCH));
|
| + } else {
|
| + // We don't iterate over the string here annotating all matches because
|
| + // it looks odd to have every occurrence of a substring that may be as
|
| + // short as a single character highlighted in a query suggestion result,
|
| + // e.g. for input text "s" and query string "southwest airlines", it
|
| + // looks odd if both the first and last s are highlighted.
|
| + if (input_position != 0) {
|
| + match_contents_class_.push_back(ACMatchClassification(
|
| + 0, ACMatchClassification::MATCH));
|
| + }
|
| + match_contents_class_.push_back(
|
| + ACMatchClassification(input_position, ACMatchClassification::NONE));
|
| + size_t next_fragment_position = input_position + input_text.length();
|
| + if (next_fragment_position < match_contents_.length()) {
|
| + match_contents_class_.push_back(ACMatchClassification(
|
| + next_fragment_position, ACMatchClassification::MATCH));
|
| + }
|
| + }
|
| + } else {
|
| + // Otherwise, match_contents_ is a verbatim (what-you-typed) match, either
|
| + // for the default provider or a keyword search provider.
|
| + match_contents_class_.push_back(ACMatchClassification(
|
| + 0, ACMatchClassification::NONE));
|
| + }
|
| +}
|
| +
|
| bool SearchProvider::SuggestResult::IsInlineable(
|
| const base::string16& input) const {
|
| return StartsWith(suggestion_, input, false);
|
| @@ -410,9 +413,8 @@ AutocompleteMatch SearchProvider::CreateSearchSuggestion(
|
| if (!template_url)
|
| return match;
|
| match.keyword = template_url->keyword();
|
| -
|
| - SetAndClassifyMatchContents(suggestion.suggestion(), input_text,
|
| - suggestion.match_contents(), &match);
|
| + match.contents = suggestion.match_contents();
|
| + match.contents_class = suggestion.match_contents_class();
|
|
|
| if (!suggestion.annotation().empty())
|
| match.description = suggestion.annotation();
|
| @@ -570,6 +572,15 @@ void SearchProvider::RemoveStaleResults(const base::string16& input,
|
| }
|
|
|
| // static
|
| +void SearchProvider::UpdateMatchContentsClass(const base::string16& input_text,
|
| + SuggestResults* suggest_results) {
|
| + for (SuggestResults::iterator sug_it = suggest_results->begin();
|
| + sug_it != suggest_results->end(); ++sug_it) {
|
| + sug_it->ClassifyMatchContents(false, input_text);
|
| + }
|
| +}
|
| +
|
| +// static
|
| int SearchProvider::CalculateRelevanceForKeywordVerbatim(
|
| AutocompleteInput::Type type,
|
| bool prefer_keyword) {
|
| @@ -875,6 +886,14 @@ void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes) {
|
| // Remove existing results that cannot inline autocomplete the new input.
|
| RemoveAllStaleResults();
|
|
|
| + // Update the content classifications of remaining results so they look good
|
| + // against the current input.
|
| + UpdateMatchContentsClass(input_.text(), &default_results_.suggest_results);
|
| + if (!keyword_input_.text().empty()) {
|
| + UpdateMatchContentsClass(keyword_input_.text(),
|
| + &keyword_results_.suggest_results);
|
| + }
|
| +
|
| // We can't start a new query if we're only allowed synchronous results.
|
| if (input_.matches_requested() != AutocompleteInput::ALL_MATCHES)
|
| return;
|
| @@ -1196,6 +1215,9 @@ bool SearchProvider::ParseSuggestResults(base::Value* root_val,
|
| suggestion_detail->GetString("du", &deletion_url);
|
| suggestion_detail->GetString("title", &match_contents) ||
|
| suggestion_detail->GetString("t", &match_contents);
|
| + // Error correction for bad data from server.
|
| + if (match_contents.empty())
|
| + match_contents = suggestion;
|
| suggestion_detail->GetString("annotation", &annotation) ||
|
| suggestion_detail->GetString("a", &annotation);
|
| suggestion_detail->GetString("query_params", &suggest_query_params) ||
|
| @@ -1207,7 +1229,7 @@ bool SearchProvider::ParseSuggestResults(base::Value* root_val,
|
| results->suggest_results.push_back(SuggestResult(
|
| suggestion, match_type, match_contents, annotation,
|
| suggest_query_params, deletion_url, is_keyword, relevance, true,
|
| - should_prefetch));
|
| + should_prefetch, input_text));
|
| }
|
| }
|
|
|
| @@ -1257,8 +1279,8 @@ void SearchProvider::ConvertResultsToAutocompleteMatches() {
|
| if (verbatim_relevance > 0) {
|
| SuggestResult verbatim(
|
| input_.text(), AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
|
| - input_.text(), base::string16(), std::string(), std::string(),
|
| - false, verbatim_relevance, relevance_from_server, false);
|
| + input_.text(), base::string16(), std::string(), std::string(), false,
|
| + verbatim_relevance, relevance_from_server, false, input_.text());
|
| AddMatchToMap(verbatim, input_.text(), std::string(),
|
| did_not_accept_default_suggestion, &map);
|
| }
|
| @@ -1280,7 +1302,7 @@ void SearchProvider::ConvertResultsToAutocompleteMatches() {
|
| keyword_input_.text(), AutocompleteMatchType::SEARCH_OTHER_ENGINE,
|
| keyword_input_.text(), base::string16(), std::string(),
|
| std::string(), true, keyword_verbatim_relevance,
|
| - keyword_relevance_from_server, false);
|
| + keyword_relevance_from_server, false, keyword_input_.text());
|
| AddMatchToMap(verbatim, keyword_input_.text(), std::string(),
|
| did_not_accept_keyword_suggestion, &map);
|
| }
|
| @@ -1630,7 +1652,7 @@ SearchProvider::SuggestResults SearchProvider::ScoreHistoryResults(
|
| scored_results.push_back(SuggestResult(
|
| i->term, AutocompleteMatchType::SEARCH_HISTORY, i->term,
|
| base::string16(), std::string(), std::string(), is_keyword, relevance,
|
| - false, false));
|
| + false, false, input_text));
|
| }
|
|
|
| // History returns results sorted for us. However, we may have docked some
|
|
|