Chromium Code Reviews| Index: chrome/browser/autocomplete/keyword_provider.cc |
| =================================================================== |
| --- chrome/browser/autocomplete/keyword_provider.cc (revision 116848) |
| +++ chrome/browser/autocomplete/keyword_provider.cc (working copy) |
| @@ -42,21 +42,6 @@ |
| KeywordProvider* provider_; |
| }; |
| -// static |
| -string16 KeywordProvider::SplitReplacementStringFromInput( |
| - const string16& input, |
| - bool trim_leading_whitespace) { |
| - // The input may contain leading whitespace, strip it. |
| - string16 trimmed_input; |
| - TrimWhitespace(input, TRIM_LEADING, &trimmed_input); |
| - |
| - // And extract the replacement string. |
| - string16 remaining_input; |
| - SplitKeywordFromInput(trimmed_input, trim_leading_whitespace, |
| - &remaining_input); |
| - return remaining_input; |
| -} |
| - |
| KeywordProvider::KeywordProvider(ACProviderListener* listener, Profile* profile) |
| : AutocompleteProvider(listener, profile, "Keyword"), |
| model_(NULL), |
| @@ -72,6 +57,10 @@ |
| content::Source<Profile>(profile->GetOriginalProfile())); |
| registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_OMNIBOX_INPUT_ENTERED, |
| content::Source<Profile>(profile)); |
| + |
| + // Start loading the keyword DB now so it is ready by the time |
| + // the user starts typing. |
| + GetTemplateURLService(); |
|
Peter Kasting
2012/01/11 03:00:16
I'm worried about doing this. This can slow start
|
| } |
| KeywordProvider::KeywordProvider(ACProviderListener* listener, |
| @@ -107,6 +96,45 @@ |
| } // namespace |
| // static |
| +string16 KeywordProvider::SplitKeywordFromInput( |
| + const string16& input, |
| + bool trim_leading_whitespace, |
| + string16* remaining_input) { |
| + // Find end of first token. The AutocompleteController has trimmed leading |
| + // whitespace, so we need not skip over that. |
| + const size_t first_white(input.find_first_of(kWhitespaceUTF16)); |
| + DCHECK_NE(0U, first_white); |
| + if (first_white == string16::npos) |
| + return input; // Only one token provided. |
| + |
| + // Set |remaining_input| to everything after the first token. |
| + DCHECK(remaining_input != NULL); |
| + const size_t remaining_start = trim_leading_whitespace ? |
| + input.find_first_not_of(kWhitespaceUTF16, first_white) : first_white + 1; |
| + |
| + if (remaining_start < input.length()) |
| + remaining_input->assign(input.begin() + remaining_start, input.end()); |
| + |
| + // Return first token as keyword. |
| + return input.substr(0, first_white); |
| +} |
| + |
| +// static |
| +string16 KeywordProvider::SplitReplacementStringFromInput( |
| + const string16& input, |
| + bool trim_leading_whitespace) { |
| + // The input may contain leading whitespace, strip it. |
| + string16 trimmed_input; |
| + TrimWhitespace(input, TRIM_LEADING, &trimmed_input); |
| + |
| + // And extract the replacement string. |
| + string16 remaining_input; |
| + SplitKeywordFromInput(trimmed_input, trim_leading_whitespace, |
| + &remaining_input); |
| + return remaining_input; |
| +} |
| + |
| +// static |
| const TemplateURL* KeywordProvider::GetSubstitutingTemplateURLForInput( |
| Profile* profile, |
| const AutocompleteInput& input, |
| @@ -128,6 +156,45 @@ |
| return TemplateURL::SupportsReplacement(template_url) ? template_url : NULL; |
| } |
| +string16 KeywordProvider::GetKeywordForText( |
| + const string16& text) const { |
| + string16 remaining_input; |
|
Peter Kasting
2012/01/11 03:00:16
Nit: This variable is dead.
|
| + const string16 keyword(TemplateURLService::CleanUserInputKeyword(text)); |
| + |
| + if (keyword.empty()) |
| + return keyword; |
| + |
| + TemplateURLService* url_service = GetTemplateURLService(); |
| + if (!url_service) |
| + return string16(); |
| + |
| + // Don't provide a keyword if it doesn't support replacement. |
| + const TemplateURL* const template_url = |
| + url_service->GetTemplateURLForKeyword(keyword); |
| + if (!TemplateURL::SupportsReplacement(template_url)) |
| + return string16(); |
| + |
| + // Don't provide a keyword 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; |
| +} |
| + |
| +AutocompleteMatch KeywordProvider::CreateAutocompleteMatch( |
| + const string16& text, |
| + const string16& keyword, |
| + const AutocompleteInput& input) { |
| + return CreateAutocompleteMatch(GetTemplateURLService(), keyword, input, |
| + keyword.size(), SplitReplacementStringFromInput(text, true), 0); |
| +} |
| + |
| void KeywordProvider::Start(const AutocompleteInput& input, |
| bool minimal_changes) { |
| // This object ensures we end keyword mode if we exit the function without |
| @@ -161,14 +228,7 @@ |
| if (!ExtractKeywordFromInput(input, &keyword, &remaining_input)) |
| return; |
| - // Make sure the model is loaded. This is cheap and quickly bails out if |
| - // the model is already loaded. |
| - TemplateURLService* model = |
| - profile_ ? |
| - TemplateURLServiceFactory::GetForProfile(profile_) : |
| - model_; |
| - DCHECK(model); |
| - model->Load(); |
| + TemplateURLService* model = GetTemplateURLService(); |
| // Get the best matches for this keyword. |
| // |
| @@ -185,11 +245,12 @@ |
| !remaining_input.empty(), |
| &keyword_matches); |
| - // Prune any extension keywords that are disallowed in incognito mode (if |
| - // we're incognito), or disabled. |
| for (std::vector<string16>::iterator i(keyword_matches.begin()); |
| i != keyword_matches.end(); ) { |
| const TemplateURL* template_url(model->GetTemplateURLForKeyword(*i)); |
| + |
| + // Prune any extension keywords that are disallowed in incognito mode (if |
| + // we're incognito), or disabled. |
| if (profile_ && |
| input.matches_requested() == AutocompleteInput::ALL_MATCHES && |
| template_url->IsExtensionKeyword()) { |
| @@ -204,6 +265,14 @@ |
| continue; |
| } |
| } |
| + |
| + // Prune any substituting keywords if there is no substitution. |
| + if (TemplateURL::SupportsReplacement(template_url) && |
| + !input.allow_exact_keyword_match()) { |
| + i = keyword_matches.erase(i); |
| + continue; |
| + } |
| + |
| ++i; |
| } |
| if (keyword_matches.empty()) |
| @@ -294,30 +363,6 @@ |
| } |
| // static |
| -string16 KeywordProvider::SplitKeywordFromInput( |
| - const string16& input, |
| - bool trim_leading_whitespace, |
| - string16* remaining_input) { |
| - // Find end of first token. The AutocompleteController has trimmed leading |
| - // whitespace, so we need not skip over that. |
| - const size_t first_white(input.find_first_of(kWhitespaceUTF16)); |
| - DCHECK_NE(0U, first_white); |
| - if (first_white == string16::npos) |
| - return input; // Only one token provided. |
| - |
| - // Set |remaining_input| to everything after the first token. |
| - DCHECK(remaining_input != NULL); |
| - const size_t remaining_start = trim_leading_whitespace ? |
| - input.find_first_not_of(kWhitespaceUTF16, first_white) : first_white + 1; |
| - |
| - if (remaining_start < input.length()) |
| - remaining_input->assign(input.begin() + remaining_start, input.end()); |
| - |
| - // Return first token as keyword. |
| - return input.substr(0, first_white); |
| -} |
| - |
| -// static |
| void KeywordProvider::FillInURLAndContents( |
| Profile* profile, |
| const string16& remaining_input, |
| @@ -415,36 +460,36 @@ |
| supports_replacement, input.prefer_keyword(), |
| input.allow_exact_keyword_match()); |
| } |
| - AutocompleteMatch result(this, relevance, false, |
| + AutocompleteMatch match(this, relevance, false, |
| supports_replacement ? AutocompleteMatch::SEARCH_OTHER_ENGINE : |
| AutocompleteMatch::HISTORY_KEYWORD); |
| - result.fill_into_edit.assign(keyword); |
| + match.fill_into_edit.assign(keyword); |
| if (!remaining_input.empty() || !keyword_complete || supports_replacement) |
| - result.fill_into_edit.push_back(L' '); |
| - result.fill_into_edit.append(remaining_input); |
| + match.fill_into_edit.push_back(L' '); |
| + match.fill_into_edit.append(remaining_input); |
| // If we wanted to set |result.inline_autocomplete_offset| correctly, we'd |
| // need CleanUserInputKeyword() to return the amount of adjustment it's made |
| // to the user's input. Because right now inexact keyword matches can't score |
| // more highly than a "what you typed" match from one of the other providers, |
| // we just don't bother to do this, and leave inline autocompletion off. |
| - result.inline_autocomplete_offset = string16::npos; |
| + match.inline_autocomplete_offset = string16::npos; |
| // Create destination URL and popup entry content by substituting user input |
| // into keyword templates. |
| - FillInURLAndContents(profile_, remaining_input, element, &result); |
| + FillInURLAndContents(profile_, remaining_input, element, &match); |
| if (supports_replacement) |
| - result.template_url = element; |
| - result.transition = content::PAGE_TRANSITION_KEYWORD; |
| + match.template_url = element; |
| + match.keyword = keyword; |
| + match.transition = content::PAGE_TRANSITION_KEYWORD; |
| - return result; |
| + return match; |
| } |
| void KeywordProvider::Observe(int type, |
| const content::NotificationSource& source, |
| const content::NotificationDetails& details) { |
| - TemplateURLService* model = |
| - profile_ ? TemplateURLServiceFactory::GetForProfile(profile_) : model_; |
| + TemplateURLService* model = GetTemplateURLService(); |
| const AutocompleteInput& input = extension_suggest_last_input_; |
| switch (type) { |
| @@ -521,6 +566,16 @@ |
| } |
| } |
| +TemplateURLService* KeywordProvider::GetTemplateURLService() const { |
| + TemplateURLService* service = profile_ ? |
| + TemplateURLServiceFactory::GetForProfile(profile_) : model_; |
| + // Make sure the model is loaded. This is cheap and quickly bails out if |
| + // the model is already loaded. |
| + DCHECK(service); |
| + service->Load(); |
| + return service; |
| +} |
| + |
| void KeywordProvider::EnterExtensionKeywordMode( |
| const std::string& extension_id) { |
| DCHECK(current_keyword_extension_id_.empty()); |