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

Side by Side Diff: chrome/browser/autocomplete/keyword_provider.cc

Issue 2807033: Add support for omnibox.onInputStarted and onInputCancelled. (Closed)
Patch Set: fix Stop Created 10 years, 5 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/autocomplete/keyword_provider.h" 5 #include "chrome/browser/autocomplete/keyword_provider.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "app/l10n_util.h" 10 #include "app/l10n_util.h"
11 #include "base/string16.h" 11 #include "base/string16.h"
12 #include "base/utf_string_conversions.h" 12 #include "base/utf_string_conversions.h"
13 #include "chrome/browser/extensions/extension_omnibox_api.h" 13 #include "chrome/browser/extensions/extension_omnibox_api.h"
14 #include "chrome/browser/extensions/extensions_service.h" 14 #include "chrome/browser/extensions/extensions_service.h"
15 #include "chrome/browser/profile.h" 15 #include "chrome/browser/profile.h"
16 #include "chrome/browser/search_engines/template_url.h" 16 #include "chrome/browser/search_engines/template_url.h"
17 #include "chrome/browser/search_engines/template_url_model.h" 17 #include "chrome/browser/search_engines/template_url_model.h"
18 #include "chrome/common/notification_service.h" 18 #include "chrome/common/notification_service.h"
19 #include "grit/generated_resources.h" 19 #include "grit/generated_resources.h"
20 #include "net/base/escape.h" 20 #include "net/base/escape.h"
21 #include "net/base/net_util.h" 21 #include "net/base/net_util.h"
22 22
23 // Helper functor for Start(), for ending keyword mode unless explicitly told
24 // otherwise.
25 class KeywordProvider::ScopedEndExtensionKeywordMode {
26 public:
27 ScopedEndExtensionKeywordMode(KeywordProvider* provider)
28 : provider_(provider) { }
29 ~ScopedEndExtensionKeywordMode() {
30 if (provider_)
31 provider_->MaybeEndExtensionKeywordMode();
32 }
33
34 void StayInKeywordMode() {
35 provider_ = NULL;
36 }
37 private:
38 KeywordProvider* provider_;
39 };
40
23 // static 41 // static
24 std::wstring KeywordProvider::SplitReplacementStringFromInput( 42 std::wstring KeywordProvider::SplitReplacementStringFromInput(
25 const std::wstring& input) { 43 const std::wstring& input) {
26 // The input may contain leading whitespace, strip it. 44 // The input may contain leading whitespace, strip it.
27 std::wstring trimmed_input; 45 std::wstring trimmed_input;
28 TrimWhitespace(input, TRIM_LEADING, &trimmed_input); 46 TrimWhitespace(input, TRIM_LEADING, &trimmed_input);
29 47
30 // And extract the replacement string. 48 // And extract the replacement string.
31 std::wstring remaining_input; 49 std::wstring remaining_input;
32 SplitKeywordFromInput(trimmed_input, &remaining_input); 50 SplitKeywordFromInput(trimmed_input, &remaining_input);
33 return remaining_input; 51 return remaining_input;
34 } 52 }
35 53
36 KeywordProvider::KeywordProvider(ACProviderListener* listener, Profile* profile) 54 KeywordProvider::KeywordProvider(ACProviderListener* listener, Profile* profile)
37 : AutocompleteProvider(listener, profile, "Keyword"), 55 : AutocompleteProvider(listener, profile, "Keyword"),
38 model_(NULL), 56 model_(NULL),
39 current_input_id_(0) { 57 current_input_id_(0) {
40 // Extension suggestions always come from the original profile, since that's 58 // Extension suggestions always come from the original profile, since that's
41 // where extensions run. We use the input ID to distinguish whether the 59 // where extensions run. We use the input ID to distinguish whether the
42 // suggestions are meant for us. 60 // suggestions are meant for us.
43 registrar_.Add(this, NotificationType::EXTENSION_OMNIBOX_SUGGESTIONS_READY, 61 registrar_.Add(this, NotificationType::EXTENSION_OMNIBOX_SUGGESTIONS_READY,
44 Source<Profile>(profile->GetOriginalProfile())); 62 Source<Profile>(profile->GetOriginalProfile()));
63 registrar_.Add(this, NotificationType::EXTENSION_OMNIBOX_INPUT_ENTERED,
64 Source<Profile>(profile));
45 } 65 }
46 66
47 KeywordProvider::KeywordProvider(ACProviderListener* listener, 67 KeywordProvider::KeywordProvider(ACProviderListener* listener,
48 TemplateURLModel* model) 68 TemplateURLModel* model)
49 : AutocompleteProvider(listener, NULL, "Keyword"), 69 : AutocompleteProvider(listener, NULL, "Keyword"),
50 model_(model), 70 model_(model),
51 current_input_id_(0) { 71 current_input_id_(0) {
52 } 72 }
53 73
54 74
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 TemplateURLModel* model = profile->GetTemplateURLModel(); 110 TemplateURLModel* model = profile->GetTemplateURLModel();
91 DCHECK(model); 111 DCHECK(model);
92 model->Load(); 112 model->Load();
93 113
94 const TemplateURL* template_url = model->GetTemplateURLForKeyword(keyword); 114 const TemplateURL* template_url = model->GetTemplateURLForKeyword(keyword);
95 return TemplateURL::SupportsReplacement(template_url) ? template_url : NULL; 115 return TemplateURL::SupportsReplacement(template_url) ? template_url : NULL;
96 } 116 }
97 117
98 void KeywordProvider::Start(const AutocompleteInput& input, 118 void KeywordProvider::Start(const AutocompleteInput& input,
99 bool minimal_changes) { 119 bool minimal_changes) {
120 // This object ensures we end keyword mode if we exit the function without
121 // toggling keyword mode to on.
122 ScopedEndExtensionKeywordMode keyword_mode_toggle(this);
123
100 matches_.clear(); 124 matches_.clear();
101 125
102 if (!minimal_changes) { 126 if (!minimal_changes) {
103 done_ = true; 127 done_ = true;
104 128
105 // Input has changed. Increment the input ID so that we can discard any 129 // Input has changed. Increment the input ID so that we can discard any
106 // stale extension suggestions that may be incoming. 130 // stale extension suggestions that may be incoming.
107 current_input_id_ = ++global_input_uid_; 131 current_input_id_ = ++global_input_uid_;
108 } 132 }
109 133
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 // If this extension keyword is disabled, make sure we don't add any 182 // If this extension keyword is disabled, make sure we don't add any
159 // matches (including the synchronous one below). 183 // matches (including the synchronous one below).
160 ExtensionsService* service = profile_->GetExtensionsService(); 184 ExtensionsService* service = profile_->GetExtensionsService();
161 Extension* extension = service->GetExtensionById( 185 Extension* extension = service->GetExtensionById(
162 template_url->GetExtensionId(), false); 186 template_url->GetExtensionId(), false);
163 bool enabled = extension && (!profile_->IsOffTheRecord() || 187 bool enabled = extension && (!profile_->IsOffTheRecord() ||
164 service->IsIncognitoEnabled(extension)); 188 service->IsIncognitoEnabled(extension));
165 if (!enabled) 189 if (!enabled)
166 return; 190 return;
167 191
192 if (extension->id() != current_keyword_extension_id_)
193 MaybeEndExtensionKeywordMode();
194 if (current_keyword_extension_id_.empty())
195 EnterExtensionKeywordMode(extension->id());
196 keyword_mode_toggle.StayInKeywordMode();
197
168 if (minimal_changes) { 198 if (minimal_changes) {
169 // If the input hasn't significantly changed, we can just use the 199 // If the input hasn't significantly changed, we can just use the
170 // suggestions from last time. We need to readjust the relevance to 200 // suggestions from last time. We need to readjust the relevance to
171 // ensure it is less than the main match's relevance. 201 // ensure it is less than the main match's relevance.
172 for (size_t i = 0; i < extension_suggest_matches_.size(); ++i) { 202 for (size_t i = 0; i < extension_suggest_matches_.size(); ++i) {
173 matches_.push_back(extension_suggest_matches_[i]); 203 matches_.push_back(extension_suggest_matches_[i]);
174 matches_.back().relevance = matches_[0].relevance - (i + 1); 204 matches_.back().relevance = matches_[0].relevance - (i + 1);
175 } 205 }
176 } else { 206 } else {
177 extension_suggest_last_input_ = input; 207 extension_suggest_last_input_ = input;
(...skipping 20 matching lines...) Expand all
198 } 228 }
199 for (std::vector<std::wstring>::const_iterator i(keyword_matches.begin()); 229 for (std::vector<std::wstring>::const_iterator i(keyword_matches.begin());
200 i != keyword_matches.end(); ++i) { 230 i != keyword_matches.end(); ++i) {
201 matches_.push_back(CreateAutocompleteMatch(model, *i, input, 231 matches_.push_back(CreateAutocompleteMatch(model, *i, input,
202 keyword.length(), 232 keyword.length(),
203 remaining_input, -1)); 233 remaining_input, -1));
204 } 234 }
205 } 235 }
206 } 236 }
207 237
238 void KeywordProvider::Stop() {
239 done_ = true;
240 MaybeEndExtensionKeywordMode();
241 }
242
208 // static 243 // static
209 bool KeywordProvider::ExtractKeywordFromInput(const AutocompleteInput& input, 244 bool KeywordProvider::ExtractKeywordFromInput(const AutocompleteInput& input,
210 std::wstring* keyword, 245 std::wstring* keyword,
211 std::wstring* remaining_input) { 246 std::wstring* remaining_input) {
212 if ((input.type() == AutocompleteInput::INVALID) || 247 if ((input.type() == AutocompleteInput::INVALID) ||
213 (input.type() == AutocompleteInput::FORCED_QUERY)) 248 (input.type() == AutocompleteInput::FORCED_QUERY))
214 return false; 249 return false;
215 250
216 *keyword = TemplateURLModel::CleanUserInputKeyword( 251 *keyword = TemplateURLModel::CleanUserInputKeyword(
217 SplitKeywordFromInput(input.text(), remaining_input)); 252 SplitKeywordFromInput(input.text(), remaining_input));
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 ACMatchClassification::DIM, 393 ACMatchClassification::DIM,
359 &result.description_class); 394 &result.description_class);
360 } 395 }
361 396
362 return result; 397 return result;
363 } 398 }
364 399
365 void KeywordProvider::Observe(NotificationType type, 400 void KeywordProvider::Observe(NotificationType type,
366 const NotificationSource& source, 401 const NotificationSource& source,
367 const NotificationDetails& details) { 402 const NotificationDetails& details) {
403 if (type == NotificationType::EXTENSION_OMNIBOX_INPUT_ENTERED) {
404 // Input has been accepted, so we're done with this input session. Ensure
405 // we don't send the OnInputCancelled event.
406 current_keyword_extension_id_.clear();
407 return;
408 }
409
368 // TODO(mpcomplete): consider clamping the number of suggestions to 410 // TODO(mpcomplete): consider clamping the number of suggestions to
369 // AutocompleteProvider::kMaxMatches. 411 // AutocompleteProvider::kMaxMatches.
370 DCHECK(type == NotificationType::EXTENSION_OMNIBOX_SUGGESTIONS_READY); 412 DCHECK(type == NotificationType::EXTENSION_OMNIBOX_SUGGESTIONS_READY);
371 413
372 const ExtensionOmniboxSuggestions& suggestions = 414 const ExtensionOmniboxSuggestions& suggestions =
373 *Details<ExtensionOmniboxSuggestions>(details).ptr(); 415 *Details<ExtensionOmniboxSuggestions>(details).ptr();
374 if (suggestions.request_id != current_input_id_) 416 if (suggestions.request_id != current_input_id_)
375 return; // This is an old result. Just ignore. 417 return; // This is an old result. Just ignore.
376 418
377 const AutocompleteInput& input = extension_suggest_last_input_; 419 const AutocompleteInput& input = extension_suggest_last_input_;
(...skipping 24 matching lines...) Expand all
402 match->contents_class = suggestion.description_styles; 444 match->contents_class = suggestion.description_styles;
403 match->description.clear(); 445 match->description.clear();
404 match->description_class.clear(); 446 match->description_class.clear();
405 } 447 }
406 448
407 done_ = true; 449 done_ = true;
408 matches_.insert(matches_.end(), extension_suggest_matches_.begin(), 450 matches_.insert(matches_.end(), extension_suggest_matches_.begin(),
409 extension_suggest_matches_.end()); 451 extension_suggest_matches_.end());
410 listener_->OnProviderUpdate(!extension_suggest_matches_.empty()); 452 listener_->OnProviderUpdate(!extension_suggest_matches_.empty());
411 } 453 }
454
455 void KeywordProvider::EnterExtensionKeywordMode(
456 const std::string& extension_id) {
457 DCHECK(current_keyword_extension_id_.empty());
458 current_keyword_extension_id_ = extension_id;
459
460 ExtensionOmniboxEventRouter::OnInputStarted(
461 profile_, current_keyword_extension_id_);
462 }
463
464 void KeywordProvider::MaybeEndExtensionKeywordMode() {
465 if (!current_keyword_extension_id_.empty()) {
466 ExtensionOmniboxEventRouter::OnInputCancelled(
467 profile_, current_keyword_extension_id_);
468
469 current_keyword_extension_id_.clear();
470 }
471 }
OLDNEW
« no previous file with comments | « chrome/browser/autocomplete/keyword_provider.h ('k') | chrome/browser/extensions/extension_browser_event_router.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698