| Index: chrome/browser/autocomplete/autocomplete.cc
|
| ===================================================================
|
| --- chrome/browser/autocomplete/autocomplete.cc (revision 81359)
|
| +++ 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"
|
| @@ -23,10 +25,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"
|
| @@ -642,6 +647,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);
|
| @@ -785,7 +793,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(
|
| @@ -820,6 +829,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
|
| @@ -932,6 +942,26 @@
|
| // 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) {
|
| + if (match->keyword_state == AutocompleteMatch::KEYWORD) {
|
| + keywords.insert(match->keyword);
|
| + } else {
|
| + string16 keyword = GetKeywordForText(match->fill_into_edit);
|
| +
|
| + // Only add the keyword if the match does not have a duplicate keyword
|
| + // with a more relevant match.
|
| + if (!keyword.empty() && !keywords.count(keyword)) {
|
| + match->keyword.assign(keyword);
|
| + match->keyword_state = AutocompleteMatch::DUAL_SHOWING_NON_KEYWORD;
|
| + match->keyword_url = profile_->GetTemplateURLModel()->
|
| + GetTemplateURLForKeyword(keyword);
|
| + keywords.insert(keyword);
|
| + }
|
| + }
|
| + }
|
| +
|
| // Need to validate before invoking CopyOldMatches as the old matches are not
|
| // valid against the current input.
|
| #ifndef NDEBUG
|
| @@ -990,3 +1020,33 @@
|
| expire_timer_.Start(base::TimeDelta::FromMilliseconds(kExpireTimeMS),
|
| this, &AutocompleteController::ExpireCopiedEntries);
|
| }
|
| +
|
| +string16 AutocompleteController::GetKeywordForText(
|
| + const string16& text) const {
|
| + const string16 keyword(TemplateURLModel::CleanUserInputKeyword(text));
|
| +
|
| + if (keyword.empty())
|
| + return keyword;
|
| + if (!profile_->GetTemplateURLModel())
|
| + return string16();
|
| + profile_->GetTemplateURLModel()->Load();
|
| +
|
| + // Don't provide a hint if this keyword doesn't support replacement.
|
| + const TemplateURL* const template_url =
|
| + profile_->GetTemplateURLModel()->GetTemplateURLForKeyword(keyword);
|
| + if (!TemplateURL::SupportsReplacement(template_url))
|
| + return string16();
|
| +
|
| + // 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 ||
|
| + (profile_->IsOffTheRecord() &&
|
| + !profile_->GetExtensionService()->IsIncognitoEnabled(extension->id())))
|
| + return string16();
|
| + }
|
| +
|
| + return keyword;
|
| +}
|
| +
|
|
|