Chromium Code Reviews| Index: chrome/browser/autocomplete/autocomplete.cc |
| =================================================================== |
| --- chrome/browser/autocomplete/autocomplete.cc (revision 80563) |
| +++ chrome/browser/autocomplete/autocomplete.cc (working copy) |
| @@ -5,6 +5,8 @@ |
| #include "chrome/browser/autocomplete/autocomplete.h" |
| #include <algorithm> |
| +#include <set> |
| +#include <utility> |
| #include "base/basictypes.h" |
| #include "base/command_line.h" |
| @@ -22,10 +24,13 @@ |
| #include "chrome/browser/autocomplete/keyword_provider.h" |
| #include "chrome/browser/autocomplete/search_provider.h" |
| #include "chrome/browser/bookmarks/bookmark_model.h" |
| +#include "chrome/browser/extensions/extension_service.h" |
| #include "chrome/browser/external_protocol_handler.h" |
| #include "chrome/browser/net/url_fixer_upper.h" |
| #include "chrome/browser/prefs/pref_service.h" |
| #include "chrome/browser/profiles/profile.h" |
| +#include "chrome/browser/search_engines/template_url.h" |
| +#include "chrome/browser/search_engines/template_url_model.h" |
| #include "chrome/browser/ui/webui/history_ui.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/pref_names.h" |
| @@ -641,6 +646,9 @@ |
| } |
| void AutocompleteResult::SortAndCull(const AutocompleteInput& input) { |
| + for (ACMatches::iterator i = matches_.begin(); i != matches_.end(); ++i) |
| + i->ComputeStrippedDestinationURL(); |
| + |
| // Remove duplicates. |
| std::sort(matches_.begin(), matches_.end(), |
| &AutocompleteMatch::DestinationSortFunc); |
| @@ -784,7 +792,8 @@ |
| AutocompleteControllerDelegate* delegate) |
| : delegate_(delegate), |
| done_(true), |
| - in_start_(false) { |
| + in_start_(false), |
| + profile_(profile) { |
| search_provider_ = new SearchProvider(this, profile); |
| providers_.push_back(search_provider_); |
| if (!CommandLine::ForCurrentProcess()->HasSwitch( |
| @@ -818,6 +827,7 @@ |
| void AutocompleteController::SetProfile(Profile* profile) { |
| Stop(true); |
| + profile_ = profile; |
| for (ACProviders::iterator i(providers_.begin()); i != providers_.end(); ++i) |
| (*i)->SetProfile(profile); |
| input_.Clear(); // Ensure we don't try to do a "minimal_changes" query on a |
| @@ -930,6 +940,24 @@ |
| // Sort the matches and trim to a small number of "best" matches. |
| result_.SortAndCull(input_); |
| + std::set<string16> keywords; |
| + for (ACMatches::iterator match(result_.begin()); match != result_.end(); |
| + ++match) { |
| + GetKeywordForMatch(&*match); |
| + |
| + if (match->keyword.get()) { |
| + std::pair<std::set<string16>::iterator, bool> result = |
| + keywords.insert(match->keyword->text); |
| + |
| + // If the match has a duplicate keyword with a |
| + // more relevant match, don't show a hint. |
| + if (match->keyword->is_keyword_hint && !result.second) { |
| + match->keyword->is_keyword_hint = false; |
| + match->keyword->text.clear(); |
| + } |
| + } |
| + } |
| + |
| // Need to validate before invoking CopyOldMatches as the old matches are not |
| // valid against the current input. |
| #ifndef NDEBUG |
| @@ -988,3 +1016,60 @@ |
| expire_timer_.Start(base::TimeDelta::FromMilliseconds(kExpireTimeMS), |
| this, &AutocompleteController::ExpireCopiedEntries); |
| } |
| + |
|
Peter Kasting
2011/04/07 20:19:21
Nit: Extra newline
|
| + |
| +void AutocompleteController::GetKeywordForMatch(AutocompleteMatch* match) const { |
|
Peter Kasting
2011/04/07 20:19:21
Nit: Line too long; wrap after '('
|
| + // If the current match is a keyword, return that as the selected keyword. |
| + if (TemplateURL::SupportsReplacement(match->template_url)) { |
| + AutocompleteMatch::Keyword* keyword = new AutocompleteMatch::Keyword(); |
| + keyword->text.assign(match->template_url->keyword()); |
| + keyword->is_keyword_mode = true; |
| + match->keyword = keyword; |
| + return; |
| + } |
| + |
| + // See if the current match's fill_into_edit corresponds to a keyword. |
| + string16 keyword_text; |
| + if (GetKeywordForText(match->fill_into_edit, &keyword_text)) { |
| + AutocompleteMatch::Keyword* keyword = new AutocompleteMatch::Keyword(); |
| + keyword->is_keyword_hint = true; |
| + keyword->text = keyword_text; |
| + keyword->template_url = |
| + profile_->GetTemplateURLModel()->GetTemplateURLForKeyword(keyword_text); |
| + match->keyword = keyword; |
| + } |
| +} |
| + |
| +bool AutocompleteController::GetKeywordForText(const string16& text, |
| + string16* keyword) const { |
| + // Creates keyword_hint first in case |keyword| is a pointer to |text|. |
| + const string16 keyword_hint(TemplateURLModel::CleanUserInputKeyword(text)); |
| + |
| + // Assume we have no keyword until we find otherwise. |
| + keyword->clear(); |
| + |
| + if (keyword_hint.empty()) |
| + return false; |
| + if (!profile_->GetTemplateURLModel()) |
| + return false; |
| + profile_->GetTemplateURLModel()->Load(); |
| + |
| + // Don't provide a hint if this keyword doesn't support replacement. |
| + const TemplateURL* const template_url = |
| + profile_->GetTemplateURLModel()->GetTemplateURLForKeyword(keyword_hint); |
| + if (!TemplateURL::SupportsReplacement(template_url)) |
| + return false; |
| + |
| + // Don't provide a hint for inactive/disabled extension keywords. |
| + if (template_url->IsExtensionKeyword()) { |
| + const Extension* extension = profile_->GetExtensionService()-> |
| + GetExtensionById(template_url->GetExtensionId(), false); |
| + if (!extension || |
|
Peter Kasting
2011/04/07 20:19:21
Nit: Indenting is one space short
|
| + (profile_->IsOffTheRecord() && |
| + !profile_->GetExtensionService()->IsIncognitoEnabled(extension->id()))) |
| + return false; |
| + } |
| + |
| + keyword->assign(keyword_hint); |
| + return true; |
| +} |
|
Peter Kasting
2011/04/07 20:19:21
Nit: Make sure there's a newline character at the
|