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

Unified Diff: components/omnibox/browser/keyword_provider.cc

Issue 1411543011: Omnibox: Make Keyword Provide More Generous with Matching (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: == -> >= Created 5 years, 1 month 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: components/omnibox/browser/keyword_provider.cc
diff --git a/components/omnibox/browser/keyword_provider.cc b/components/omnibox/browser/keyword_provider.cc
index 8992f02f8717f4d795f9b93b76d03ee8866442e9..fe7084138ac875adcde589fdd07d24dfe1ba7eda 100644
--- a/components/omnibox/browser/keyword_provider.cc
+++ b/components/omnibox/browser/keyword_provider.cc
@@ -15,6 +15,7 @@
#include "components/omnibox/browser/autocomplete_provider_client.h"
#include "components/omnibox/browser/autocomplete_provider_listener.h"
#include "components/omnibox/browser/keyword_extensions_delegate.h"
+#include "components/omnibox/browser/omnibox_field_trial.h"
#include "components/search_engines/template_url.h"
#include "components/search_engines/template_url_service.h"
#include "grit/components_strings.h"
@@ -27,15 +28,20 @@ namespace {
// Helper functor for Start(), for sorting keyword matches by quality.
class CompareQuality {
public:
- // A keyword is of higher quality when a greater fraction of it has been
- // typed, that is, when it is shorter.
+ // A keyword is of higher quality when a greater fraction of the important
+ // part of it has been typed, that is, when the effective keyword length is
+ // shorter.
//
// TODO(pkasting): Most recent and most frequent keywords are probably
// better rankings than the fraction of the keyword typed. We should
// always put any exact matches first no matter what, since the code in
// Start() assumes this (and it makes sense).
- bool operator()(const TemplateURL* t_url1, const TemplateURL* t_url2) const {
- return t_url1->keyword().length() < t_url2->keyword().length();
+ bool operator()(
+ const TemplateURLService::TemplateURLAndEffectiveKeywordLength
+ t_url_match1,
+ const TemplateURLService::TemplateURLAndEffectiveKeywordLength
+ t_url_match2) const {
+ return t_url_match1.second < t_url_match2.second;
}
};
@@ -196,8 +202,9 @@ AutocompleteMatch KeywordProvider::CreateVerbatimMatch(
const AutocompleteInput& input) {
// A verbatim match is allowed to be the default match.
return CreateAutocompleteMatch(
- GetTemplateURLService()->GetTemplateURLForKeyword(keyword), input,
- keyword.length(), SplitReplacementStringFromInput(text, true), true, 0);
+ GetTemplateURLService()->GetTemplateURLForKeyword(keyword),
+ keyword.length(), input, keyword.length(),
+ SplitReplacementStringFromInput(text, true), true, 0);
}
void KeywordProvider::Start(const AutocompleteInput& input,
@@ -243,13 +250,17 @@ void KeywordProvider::Start(const AutocompleteInput& input,
// |minimal_changes| case, but since we'd still have to recalculate their
// relevances and we can just recreate the results synchronously anyway, we
// don't bother.
- TemplateURLService::TemplateURLVector matches;
+ TemplateURLService::TemplateURLMatchesVector matches;
GetTemplateURLService()->FindMatchingKeywords(
keyword, !remaining_input.empty(), &matches);
+ if (!OmniboxFieldTrial::KeywordRequiresPrefixBeforeDomain()) {
+ GetTemplateURLService()->FindMatchingDomainKeywords(
+ keyword, !remaining_input.empty(), &matches);
Peter Kasting 2015/11/09 23:11:14 As written this seems to imply that the functions
Mark P 2015/11/11 07:40:59 Revised to AddMatching...() and changed all commen
+ }
- for (TemplateURLService::TemplateURLVector::iterator i(matches.begin());
- i != matches.end(); ) {
- const TemplateURL* template_url = *i;
+ for (TemplateURLService::TemplateURLMatchesVector::iterator
+ i(matches.begin()); i != matches.end(); ) {
+ const TemplateURL* template_url = i->first;
// Prune any extension keywords that are disallowed in incognito mode (if
// we're incognito), or disabled.
@@ -280,8 +291,9 @@ void KeywordProvider::Start(const AutocompleteInput& input,
// in the autocomplete popup.
// Any exact match is going to be the highest quality match, and thus at the
// front of our vector.
- if (matches.front()->keyword() == keyword) {
- const TemplateURL* template_url = matches.front();
+ if (matches.front().first->keyword() == keyword) {
+ const TemplateURL* template_url = matches.front().first;
+ const size_t effective_keyword_length = matches.front().second;
const bool is_extension_keyword =
template_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION;
@@ -300,7 +312,8 @@ void KeywordProvider::Start(const AutocompleteInput& input,
// remaining query or an extension keyword, possibly with remaining
// input), allow the match to be the default match.
matches_.push_back(CreateAutocompleteMatch(
- template_url, input, keyword.length(), remaining_input, true, -1));
+ template_url, effective_keyword_length, input, keyword.length(),
+ remaining_input, true, -1));
if (is_extension_keyword && extensions_delegate_) {
if (extensions_delegate_->Start(input, minimal_changes, template_url,
@@ -308,12 +321,24 @@ void KeywordProvider::Start(const AutocompleteInput& input,
keyword_mode_toggle.StayInKeywordMode();
}
} else {
- if (matches.size() > kMaxMatches)
- matches.erase(matches.begin() + kMaxMatches, matches.end());
- for (TemplateURLService::TemplateURLVector::const_iterator i(
- matches.begin()); i != matches.end(); ++i) {
- matches_.push_back(CreateAutocompleteMatch(
- *i, input, keyword.length(), remaining_input, false, -1));
+ for (TemplateURLService::TemplateURLMatchesVector::const_iterator i(
+ matches.begin());
+ (i != matches.end()) && (matches.size() <= kMaxMatches); ++i) {
+ // Skip keywords that we've already added. It's possible we may have
+ // retrieved the same keyword twice. For example, the keyword'
Peter Kasting 2015/11/09 23:11:14 Nit: Mismatched '
Mark P 2015/11/11 07:40:59 Done.
+ // abc.abc.com, may be retrieved for the input abc from the full keyword
Peter Kasting 2015/11/09 23:11:14 Nit: No comma (but consider adding quotes around k
Mark P 2015/11/11 07:40:59 Did both.
+ // matching and the domain matching passes.
+ bool found_duplicate = false;
+ for (ACMatches::const_iterator j = matches_.begin();
+ (j != matches_.end()) && !found_duplicate; ++j) {
+ if (j->keyword == i->first->keyword())
+ found_duplicate = true;
+ }
Peter Kasting 2015/11/09 23:11:14 Nit: Use std::find_if() with a lambda instead of t
Mark P 2015/11/11 07:41:00 Done.
+ if (!found_duplicate) {
+ matches_.push_back(CreateAutocompleteMatch(
+ i->first, i->second, input, keyword.length(), remaining_input,
+ false, -1));
+ }
}
}
}
@@ -346,6 +371,7 @@ bool KeywordProvider::ExtractKeywordFromInput(const AutocompleteInput& input,
// static
int KeywordProvider::CalculateRelevance(metrics::OmniboxInputType::Type type,
bool complete,
+ bool nearly_complete,
bool supports_replacement,
bool prefer_keyword,
bool allow_exact_keyword_match) {
@@ -353,13 +379,22 @@ int KeywordProvider::CalculateRelevance(metrics::OmniboxInputType::Type type,
// themselves and the suggestion of the verbatim query on an
// extension keyword. SearchProvider::CalculateRelevanceForKeywordVerbatim()
// scores verbatim query suggestions for non-extension keywords.
- // These two functions are currently in sync, but there's no reason
- // we couldn't decide in the future to score verbatim matches
+ // These two functions are currently in sync except for the code at the
+ // beginning for this function that handles scoring not-fully-typed keywords.
+ // (SearchProvider does not make such suggestions and so has no need to
+ // score them.) Other than that, they're currently in sync. There's no
+ // reason we couldn't decide in the future to score verbatim matches
// differently for extension and non-extension keywords. If you
// make such a change, however, you should update this comment to
// describe it, so it's clear why the functions diverge.
Peter Kasting 2015/11/09 23:11:14 Instead of this long comment about what's in sync
Mark P 2015/11/11 07:41:00 Done. Now search_provider.{cc,h} is part of this
- if (!complete)
+ if (!complete) {
+ const int nearly_complete_score =
+ OmniboxFieldTrial::KeywordScoreForNearlyCompleteMatch();
+ // If we have a special score to apply for nearly-complete matches, do so.
+ if (nearly_complete && (nearly_complete_score > -1))
+ return nearly_complete_score;
return (type == metrics::OmniboxInputType::URL) ? 700 : 450;
+ }
if (!supports_replacement || (allow_exact_keyword_match && prefer_keyword))
return 1500;
return (allow_exact_keyword_match &&
@@ -369,6 +404,7 @@ int KeywordProvider::CalculateRelevance(metrics::OmniboxInputType::Type type,
AutocompleteMatch KeywordProvider::CreateAutocompleteMatch(
const TemplateURL* template_url,
+ const size_t effective_keyword_length,
const AutocompleteInput& input,
size_t prefix_length,
const base::string16& remaining_input,
@@ -384,9 +420,10 @@ AutocompleteMatch KeywordProvider::CreateAutocompleteMatch(
// choice and immediately begin typing in query input.
const base::string16& keyword = template_url->keyword();
const bool keyword_complete = (prefix_length == keyword.length());
+ const bool nearly_complete = (prefix_length >= effective_keyword_length);
if (relevance < 0) {
relevance =
- CalculateRelevance(input.type(), keyword_complete,
+ CalculateRelevance(input.type(), keyword_complete, nearly_complete,
// When the user wants keyword matches to take
// preference, score them highly regardless of
// whether the input provides query text.

Powered by Google App Engine
This is Rietveld 408576698