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

Unified Diff: chrome/browser/autocomplete/search_provider.cc

Issue 23164011: Omnibox: Reduce Bolding Flicker in SearchProvider (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/autocomplete/search_provider.cc
diff --git a/chrome/browser/autocomplete/search_provider.cc b/chrome/browser/autocomplete/search_provider.cc
index c561490ad1301b5468d61b353253b4df8253852d..f3177907132d62702a393154909df72437d1b8e9 100644
--- a/chrome/browser/autocomplete/search_provider.cc
+++ b/chrome/browser/autocomplete/search_provider.cc
@@ -133,12 +133,55 @@ SearchProvider::Result::~Result() {
// SearchProvider::SuggestResult ----------------------------------------------
-SearchProvider::SuggestResult::SuggestResult(const string16& suggestion,
- bool from_keyword_provider,
- int relevance,
- bool relevance_from_server)
+SearchProvider::SuggestResult::SuggestResult(
+ const string16& suggestion,
+ bool from_keyword_provider,
+ int relevance,
+ bool relevance_from_server,
+ const string16& input_text)
: Result(from_keyword_provider, relevance, relevance_from_server),
suggestion_(suggestion) {
+ contents_.assign(suggestion_);
Mark P 2013/08/15 18:34:23 This whole blob was moved from CreateSearchSuggest
+ 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 != suggestion_) {
+ size_t input_position = contents_.find(input_text);
+ if (input_position == 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.
+ 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) {
+ contents_class_.push_back(
+ ACMatchClassification(0, ACMatchClassification::MATCH));
+ }
+ contents_class_.push_back(
+ ACMatchClassification(input_position, ACMatchClassification::NONE));
+ size_t next_fragment_position = input_position + input_text.length();
+ if (next_fragment_position < suggestion_.length()) {
+ 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.
+ contents_class_.push_back(
+ ACMatchClassification(0, ACMatchClassification::NONE));
+
+ }
}
SearchProvider::SuggestResult::~SuggestResult() {
@@ -165,13 +208,37 @@ SearchProvider::NavigationResult::NavigationResult(
const string16& description,
bool from_keyword_provider,
int relevance,
- bool relevance_from_server)
+ bool relevance_from_server,
+ const string16& input_text,
+ const std::string& languages)
: Result(from_keyword_provider, relevance, relevance_from_server),
url_(url),
formatted_url_(AutocompleteInput::FormattedStringWithEquivalentMeaning(
url, provider.StringForURLDisplay(url, true, false))),
description_(description) {
DCHECK(url_.is_valid());
+ // First look for the user's input inside the fill_into_edit as it would be
Mark P 2013/08/15 18:34:23 This whole section is the necessary parts from Nav
msw 2013/08/15 18:51:03 Can we reduce more duplication between the two?
Mark P 2013/08/15 19:28:15 I can't figure out how. Here's the problem: inlin
msw 2013/08/15 19:48:30 I was thinking of a helper function, but only if w
+ // without trimming the scheme, so we can find matches at the beginning of the
+ // scheme.
+ const string16& untrimmed_fill_into_edit = formatted_url_;
+ const URLPrefix* prefix =
+ URLPrefix::BestURLPrefix(untrimmed_fill_into_edit, input_text);
+ size_t match_start = (prefix == NULL) ?
+ untrimmed_fill_into_edit.find(input_text) : prefix->prefix.length();
+ bool trim_http = !HasHTTPScheme(input_text) && (!prefix || (match_start != 0));
+ const net::FormatUrlTypes format_types =
+ net::kFormatUrlOmitAll & ~(trim_http ? 0 : net::kFormatUrlOmitHTTP);
+ contents_ = net::FormatUrl(url_, languages,
+ format_types, net::UnescapeRule::SPACES, NULL, NULL, &match_start);
+ // If the first match in the untrimmed string was inside a scheme that we
+ // trimmed, look for a subsequent match.
+ if (match_start == string16::npos)
+ match_start = contents_.find(input_text);
+ // Safe if |match_start| is npos; also safe if the input is longer than the
+ // remaining contents after |match_start|.
+ AutocompleteMatch::ClassifyLocationInString(match_start, input_text.length(),
+ contents_.length(), ACMatchClassification::URL,
+ &contents_class_);
}
SearchProvider::NavigationResult::~NavigationResult() {
@@ -259,81 +326,45 @@ SearchProvider::SearchProvider(AutocompleteProviderListener* listener,
// static
AutocompleteMatch SearchProvider::CreateSearchSuggestion(
AutocompleteProvider* autocomplete_provider,
- int relevance,
+ const SuggestResult& result,
AutocompleteMatch::Type type,
const TemplateURL* template_url,
- const string16& query_string,
const string16& input_text,
const AutocompleteInput& input,
- bool is_keyword,
int accepted_suggestion,
int omnibox_start_margin,
bool append_extra_query_params) {
- AutocompleteMatch match(autocomplete_provider, relevance, false, type);
+ AutocompleteMatch match(
+ autocomplete_provider, result.relevance(), false, type);
if (!template_url)
return match;
match.keyword = template_url->keyword();
- match.contents.assign(query_string);
- // 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 != query_string) {
- size_t input_position = match.contents.find(input_text);
- if (input_position == 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));
+ match.contents = result.contents();
+ match.contents_class = result.contents_class();
+ if (input_text == result.suggestion())
match.allowed_to_be_default_match = true;
- }
// When the user forced a query, we need to make sure all the fill_into_edit
// values preserve that property. Otherwise, if the user starts editing a
// suggestion, non-Search results will suddenly appear.
if (input.type() == AutocompleteInput::FORCED_QUERY)
match.fill_into_edit.assign(ASCIIToUTF16("?"));
- if (is_keyword)
+ if (result.from_keyword_provider())
match.fill_into_edit.append(match.keyword + char16(' '));
if (!input.prevent_inline_autocomplete() &&
- StartsWith(query_string, input_text, false)) {
- match.inline_autocompletion = query_string.substr(input_text.length());
+ StartsWith(result.suggestion(), input_text, false)) {
+ match.inline_autocompletion =
+ result.suggestion().substr(input_text.length());
match.allowed_to_be_default_match = true;
}
- match.fill_into_edit.append(query_string);
+ match.fill_into_edit.append(result.suggestion());
const TemplateURLRef& search_url = template_url->url_ref();
DCHECK(search_url.SupportsReplacement());
match.search_terms_args.reset(
- new TemplateURLRef::SearchTermsArgs(query_string));
+ new TemplateURLRef::SearchTermsArgs(result.suggestion()));
match.search_terms_args->original_query = input_text;
match.search_terms_args->accepted_suggestion = accepted_suggestion;
match.search_terms_args->omnibox_start_margin = omnibox_start_margin;
@@ -346,7 +377,7 @@ AutocompleteMatch SearchProvider::CreateSearchSuggestion(
GURL(search_url.ReplaceSearchTerms(*match.search_terms_args.get()));
// Search results don't look like URLs.
- match.transition = is_keyword ?
+ match.transition = result.from_keyword_provider() ?
content::PAGE_TRANSITION_KEYWORD : content::PAGE_TRANSITION_GENERATED;
return match;
@@ -906,6 +937,8 @@ bool SearchProvider::ParseSuggestResults(Value* root_val, bool is_keyword) {
string16 result, title;
std::string type;
int relevance = -1;
+ const std::string& languages =
+ profile_->GetPrefs()->GetString(prefs::kAcceptLanguages);
for (size_t index = 0; results_list->GetString(index, &result); ++index) {
// Google search may return empty suggestions for weird input characters,
// they make no sense at all and can cause problems in our code.
@@ -915,6 +948,8 @@ bool SearchProvider::ParseSuggestResults(Value* root_val, bool is_keyword) {
// Apply valid suggested relevance scores; discard invalid lists.
if (relevances != NULL && !relevances->GetInteger(index, &relevance))
relevances = NULL;
+ string16 contents;
+ ACMatchClassifications contents_class;
Mark P 2013/08/15 18:34:23 Forgot to delete those two lines, sorry.
if (types && types->GetString(index, &type) && (type == "NAVIGATION")) {
// Do not blindly trust the URL coming from the server to be valid.
GURL url(URLFixerUpper::FixupURL(UTF16ToUTF8(result), std::string()));
@@ -922,12 +957,12 @@ bool SearchProvider::ParseSuggestResults(Value* root_val, bool is_keyword) {
if (descriptions != NULL)
descriptions->GetString(index, &title);
results->navigation_results.push_back(NavigationResult(
- *this, url, title, is_keyword, relevance, true));
+ *this, url, title, is_keyword, relevance, true, input_text, languages));
}
} else {
// TODO(kochi): Improve calculator result presentation.
results->suggest_results.push_back(
- SuggestResult(result, is_keyword, relevance, true));
+ SuggestResult(result, is_keyword, relevance, true, input_text));
}
}
@@ -964,10 +999,11 @@ void SearchProvider::ConvertResultsToAutocompleteMatches() {
TemplateURLRef::NO_SUGGESTIONS_AVAILABLE :
TemplateURLRef::NO_SUGGESTION_CHOSEN;
if (verbatim_relevance > 0) {
- AddMatchToMap(input_.text(), input_.text(), verbatim_relevance,
- relevance_from_server,
+ SuggestResult verbatim(
+ input_.text(), false, verbatim_relevance, relevance_from_server, input_.text());
+ AddMatchToMap(verbatim, input_.text(),
AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
- did_not_accept_default_suggestion, false, &map);
+ did_not_accept_default_suggestion, &map);
}
if (!keyword_input_.text().empty()) {
const TemplateURL* keyword_url = providers_.GetKeywordProviderURL();
@@ -982,10 +1018,12 @@ void SearchProvider::ConvertResultsToAutocompleteMatches() {
const int keyword_verbatim_relevance =
GetKeywordVerbatimRelevance(&keyword_relevance_from_server);
if (keyword_verbatim_relevance > 0) {
- AddMatchToMap(keyword_input_.text(), keyword_input_.text(),
- keyword_verbatim_relevance, keyword_relevance_from_server,
+ SuggestResult keyword_verbatim(
+ keyword_input_.text(), true, keyword_verbatim_relevance,
+ keyword_relevance_from_server, keyword_input_.text());
+ AddMatchToMap(keyword_verbatim, keyword_input_.text(),
AutocompleteMatchType::SEARCH_OTHER_ENGINE,
- did_not_accept_keyword_suggestion, true, &map);
+ did_not_accept_keyword_suggestion, &map);
}
}
}
@@ -1208,10 +1246,9 @@ void SearchProvider::AddHistoryResultsToMap(const HistoryResults& results,
is_keyword);
for (SuggestResults::const_iterator i(scored_results.begin());
i != scored_results.end(); ++i) {
- AddMatchToMap(i->suggestion(), input_text, i->relevance(), false,
+ AddMatchToMap(*i, input_text,
AutocompleteMatchType::SEARCH_HISTORY,
- did_not_accept_suggestion,
- is_keyword, map);
+ did_not_accept_suggestion, map);
}
}
@@ -1258,7 +1295,7 @@ SearchProvider::SuggestResults SearchProvider::ScoreHistoryResults(
i->time, is_keyword, !prevent_inline_autocomplete,
prevent_search_history_inlining);
scored_results.push_back(
- SuggestResult(i->term, is_keyword, relevance, false));
+ SuggestResult(i->term, is_keyword, relevance, false, input_text));
}
// History returns results sorted for us. However, we may have docked some
@@ -1282,11 +1319,10 @@ SearchProvider::SuggestResults SearchProvider::ScoreHistoryResults(
void SearchProvider::AddSuggestResultsToMap(const SuggestResults& results,
MatchMap* map) {
for (size_t i = 0; i < results.size(); ++i) {
- const bool is_keyword = results[i].from_keyword_provider();
- const string16& input = is_keyword ? keyword_input_.text() : input_.text();
- AddMatchToMap(results[i].suggestion(), input, results[i].relevance(),
- results[i].relevance_from_server(),
- AutocompleteMatchType::SEARCH_SUGGEST, i, is_keyword, map);
+ const string16& input = results[i].from_keyword_provider() ?
+ keyword_input_.text() : input_.text();
+ AddMatchToMap(results[i], input,
+ AutocompleteMatchType::SEARCH_SUGGEST, i, map);
}
}
@@ -1398,13 +1434,10 @@ int SearchProvider::CalculateRelevanceForHistory(
return std::max(0, base_score - score_discount);
}
-void SearchProvider::AddMatchToMap(const string16& query_string,
+void SearchProvider::AddMatchToMap(const SuggestResult& result,
const string16& input_text,
- int relevance,
- bool relevance_from_server,
AutocompleteMatch::Type type,
int accepted_suggestion,
- bool is_keyword,
MatchMap* map) {
// On non-mobile, ask the instant controller for the appropriate start margin.
// On mobile the start margin is unused, so leave the value as default there.
@@ -1421,22 +1454,22 @@ void SearchProvider::AddMatchToMap(const string16& query_string,
}
#endif // !defined(OS_ANDROID) && !defined(IOS)
- const TemplateURL* template_url = is_keyword ?
+ const TemplateURL* template_url = result.from_keyword_provider() ?
providers_.GetKeywordProviderURL() : providers_.GetDefaultProviderURL();
- AutocompleteMatch match = CreateSearchSuggestion(this, relevance, type,
- template_url, query_string, input_text, input_, is_keyword,
- accepted_suggestion, omnibox_start_margin,
- !is_keyword || providers_.default_provider().empty());
+ AutocompleteMatch match = CreateSearchSuggestion(this, result,
+ type, template_url, input_text, input_, accepted_suggestion,
+ omnibox_start_margin,
+ !result.from_keyword_provider() || providers_.default_provider().empty());
if (!match.destination_url.is_valid())
return;
match.RecordAdditionalInfo(kRelevanceFromServerKey,
- relevance_from_server ? kTrue : kFalse);
+ result.relevance_from_server() ? kTrue : kFalse);
// Try to add |match| to |map|. If a match for |query_string| is already in
// |map|, replace it if |match| is more relevant.
// NOTE: Keep this ToLower() call in sync with url_database.cc.
- const std::pair<MatchMap::iterator, bool> i(
- map->insert(std::make_pair(base::i18n::ToLower(query_string), match)));
+ const std::pair<MatchMap::iterator, bool> i(map->insert(std::make_pair(
+ base::i18n::ToLower(result.suggestion()), match)));
// NOTE: We purposefully do a direct relevance comparison here instead of
// using AutocompleteMatch::MoreRelevant(), so that we'll prefer "items added
// first" rather than "items alphabetically first" when the scores are equal.
@@ -1494,18 +1527,8 @@ AutocompleteMatch SearchProvider::NavigationToMatch(
match.fill_into_edit.substr(inline_autocomplete_offset);
}
- match.contents = net::FormatUrl(navigation.url(), languages,
- format_types, net::UnescapeRule::SPACES, NULL, NULL, &match_start);
- // If the first match in the untrimmed string was inside a scheme that we
- // trimmed, look for a subsequent match.
- if (match_start == string16::npos)
- match_start = match.contents.find(input);
- // Safe if |match_start| is npos; also safe if the input is longer than the
- // remaining contents after |match_start|.
- AutocompleteMatch::ClassifyLocationInString(match_start, input.length(),
- match.contents.length(), ACMatchClassification::URL,
- &match.contents_class);
-
+ match.contents = navigation.contents();
+ match.contents_class = navigation.contents_class();
match.description = navigation.description();
AutocompleteMatch::ClassifyMatchInString(input, match.description,
ACMatchClassification::NONE, &match.description_class);

Powered by Google App Engine
This is Rietveld 408576698