OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/string16.h" | 10 #include "base/string16.h" |
(...skipping 24 matching lines...) Expand all Loading... | |
35 provider_->MaybeEndExtensionKeywordMode(); | 35 provider_->MaybeEndExtensionKeywordMode(); |
36 } | 36 } |
37 | 37 |
38 void StayInKeywordMode() { | 38 void StayInKeywordMode() { |
39 provider_ = NULL; | 39 provider_ = NULL; |
40 } | 40 } |
41 private: | 41 private: |
42 KeywordProvider* provider_; | 42 KeywordProvider* provider_; |
43 }; | 43 }; |
44 | 44 |
45 // static | |
46 string16 KeywordProvider::SplitReplacementStringFromInput( | |
47 const string16& input, | |
48 bool trim_leading_whitespace) { | |
49 // The input may contain leading whitespace, strip it. | |
50 string16 trimmed_input; | |
51 TrimWhitespace(input, TRIM_LEADING, &trimmed_input); | |
52 | |
53 // And extract the replacement string. | |
54 string16 remaining_input; | |
55 SplitKeywordFromInput(trimmed_input, trim_leading_whitespace, | |
56 &remaining_input); | |
57 return remaining_input; | |
58 } | |
59 | |
60 KeywordProvider::KeywordProvider(ACProviderListener* listener, Profile* profile) | 45 KeywordProvider::KeywordProvider(ACProviderListener* listener, Profile* profile) |
61 : AutocompleteProvider(listener, profile, "Keyword"), | 46 : AutocompleteProvider(listener, profile, "Keyword"), |
62 model_(NULL), | 47 model_(NULL), |
63 current_input_id_(0) { | 48 current_input_id_(0) { |
64 // Extension suggestions always come from the original profile, since that's | 49 // Extension suggestions always come from the original profile, since that's |
65 // where extensions run. We use the input ID to distinguish whether the | 50 // where extensions run. We use the input ID to distinguish whether the |
66 // suggestions are meant for us. | 51 // suggestions are meant for us. |
67 registrar_.Add(this, | 52 registrar_.Add(this, |
68 chrome::NOTIFICATION_EXTENSION_OMNIBOX_SUGGESTIONS_READY, | 53 chrome::NOTIFICATION_EXTENSION_OMNIBOX_SUGGESTIONS_READY, |
69 content::Source<Profile>(profile->GetOriginalProfile())); | 54 content::Source<Profile>(profile->GetOriginalProfile())); |
70 registrar_.Add( | 55 registrar_.Add( |
71 this, chrome::NOTIFICATION_EXTENSION_OMNIBOX_DEFAULT_SUGGESTION_CHANGED, | 56 this, chrome::NOTIFICATION_EXTENSION_OMNIBOX_DEFAULT_SUGGESTION_CHANGED, |
72 content::Source<Profile>(profile->GetOriginalProfile())); | 57 content::Source<Profile>(profile->GetOriginalProfile())); |
73 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_OMNIBOX_INPUT_ENTERED, | 58 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_OMNIBOX_INPUT_ENTERED, |
74 content::Source<Profile>(profile)); | 59 content::Source<Profile>(profile)); |
60 | |
61 // Start loading the keyword DB now so it is ready by the time | |
62 // the user starts typing. | |
63 GetTemplateURLService(); | |
Peter Kasting
2012/01/11 03:00:16
I'm worried about doing this. This can slow start
| |
75 } | 64 } |
76 | 65 |
77 KeywordProvider::KeywordProvider(ACProviderListener* listener, | 66 KeywordProvider::KeywordProvider(ACProviderListener* listener, |
78 TemplateURLService* model) | 67 TemplateURLService* model) |
79 : AutocompleteProvider(listener, NULL, "Keyword"), | 68 : AutocompleteProvider(listener, NULL, "Keyword"), |
80 model_(model), | 69 model_(model), |
81 current_input_id_(0) { | 70 current_input_id_(0) { |
82 } | 71 } |
83 | 72 |
84 | 73 |
(...skipping 15 matching lines...) Expand all Loading... | |
100 } | 89 } |
101 }; | 90 }; |
102 | 91 |
103 // We need our input IDs to be unique across all profiles, so we keep a global | 92 // We need our input IDs to be unique across all profiles, so we keep a global |
104 // UID that each provider uses. | 93 // UID that each provider uses. |
105 static int global_input_uid_; | 94 static int global_input_uid_; |
106 | 95 |
107 } // namespace | 96 } // namespace |
108 | 97 |
109 // static | 98 // static |
99 string16 KeywordProvider::SplitKeywordFromInput( | |
100 const string16& input, | |
101 bool trim_leading_whitespace, | |
102 string16* remaining_input) { | |
103 // Find end of first token. The AutocompleteController has trimmed leading | |
104 // whitespace, so we need not skip over that. | |
105 const size_t first_white(input.find_first_of(kWhitespaceUTF16)); | |
106 DCHECK_NE(0U, first_white); | |
107 if (first_white == string16::npos) | |
108 return input; // Only one token provided. | |
109 | |
110 // Set |remaining_input| to everything after the first token. | |
111 DCHECK(remaining_input != NULL); | |
112 const size_t remaining_start = trim_leading_whitespace ? | |
113 input.find_first_not_of(kWhitespaceUTF16, first_white) : first_white + 1; | |
114 | |
115 if (remaining_start < input.length()) | |
116 remaining_input->assign(input.begin() + remaining_start, input.end()); | |
117 | |
118 // Return first token as keyword. | |
119 return input.substr(0, first_white); | |
120 } | |
121 | |
122 // static | |
123 string16 KeywordProvider::SplitReplacementStringFromInput( | |
124 const string16& input, | |
125 bool trim_leading_whitespace) { | |
126 // The input may contain leading whitespace, strip it. | |
127 string16 trimmed_input; | |
128 TrimWhitespace(input, TRIM_LEADING, &trimmed_input); | |
129 | |
130 // And extract the replacement string. | |
131 string16 remaining_input; | |
132 SplitKeywordFromInput(trimmed_input, trim_leading_whitespace, | |
133 &remaining_input); | |
134 return remaining_input; | |
135 } | |
136 | |
137 // static | |
110 const TemplateURL* KeywordProvider::GetSubstitutingTemplateURLForInput( | 138 const TemplateURL* KeywordProvider::GetSubstitutingTemplateURLForInput( |
111 Profile* profile, | 139 Profile* profile, |
112 const AutocompleteInput& input, | 140 const AutocompleteInput& input, |
113 string16* remaining_input) { | 141 string16* remaining_input) { |
114 if (!input.allow_exact_keyword_match()) | 142 if (!input.allow_exact_keyword_match()) |
115 return NULL; | 143 return NULL; |
116 | 144 |
117 string16 keyword; | 145 string16 keyword; |
118 if (!ExtractKeywordFromInput(input, &keyword, remaining_input)) | 146 if (!ExtractKeywordFromInput(input, &keyword, remaining_input)) |
119 return NULL; | 147 return NULL; |
120 | 148 |
121 // Make sure the model is loaded. This is cheap and quickly bails out if | 149 // Make sure the model is loaded. This is cheap and quickly bails out if |
122 // the model is already loaded. | 150 // the model is already loaded. |
123 TemplateURLService* model = TemplateURLServiceFactory::GetForProfile(profile); | 151 TemplateURLService* model = TemplateURLServiceFactory::GetForProfile(profile); |
124 DCHECK(model); | 152 DCHECK(model); |
125 model->Load(); | 153 model->Load(); |
126 | 154 |
127 const TemplateURL* template_url = model->GetTemplateURLForKeyword(keyword); | 155 const TemplateURL* template_url = model->GetTemplateURLForKeyword(keyword); |
128 return TemplateURL::SupportsReplacement(template_url) ? template_url : NULL; | 156 return TemplateURL::SupportsReplacement(template_url) ? template_url : NULL; |
129 } | 157 } |
130 | 158 |
159 string16 KeywordProvider::GetKeywordForText( | |
160 const string16& text) const { | |
161 string16 remaining_input; | |
Peter Kasting
2012/01/11 03:00:16
Nit: This variable is dead.
| |
162 const string16 keyword(TemplateURLService::CleanUserInputKeyword(text)); | |
163 | |
164 if (keyword.empty()) | |
165 return keyword; | |
166 | |
167 TemplateURLService* url_service = GetTemplateURLService(); | |
168 if (!url_service) | |
169 return string16(); | |
170 | |
171 // Don't provide a keyword if it doesn't support replacement. | |
172 const TemplateURL* const template_url = | |
173 url_service->GetTemplateURLForKeyword(keyword); | |
174 if (!TemplateURL::SupportsReplacement(template_url)) | |
175 return string16(); | |
176 | |
177 // Don't provide a keyword for inactive/disabled extension keywords. | |
178 if (template_url->IsExtensionKeyword()) { | |
179 const Extension* extension = profile_->GetExtensionService()-> | |
180 GetExtensionById(template_url->GetExtensionId(), false); | |
181 if (!extension || | |
182 (profile_->IsOffTheRecord() && | |
183 !profile_->GetExtensionService()->IsIncognitoEnabled(extension->id()))) | |
184 return string16(); | |
185 } | |
186 | |
187 return keyword; | |
188 } | |
189 | |
190 AutocompleteMatch KeywordProvider::CreateAutocompleteMatch( | |
191 const string16& text, | |
192 const string16& keyword, | |
193 const AutocompleteInput& input) { | |
194 return CreateAutocompleteMatch(GetTemplateURLService(), keyword, input, | |
195 keyword.size(), SplitReplacementStringFromInput(text, true), 0); | |
196 } | |
197 | |
131 void KeywordProvider::Start(const AutocompleteInput& input, | 198 void KeywordProvider::Start(const AutocompleteInput& input, |
132 bool minimal_changes) { | 199 bool minimal_changes) { |
133 // This object ensures we end keyword mode if we exit the function without | 200 // This object ensures we end keyword mode if we exit the function without |
134 // toggling keyword mode to on. | 201 // toggling keyword mode to on. |
135 ScopedEndExtensionKeywordMode keyword_mode_toggle(this); | 202 ScopedEndExtensionKeywordMode keyword_mode_toggle(this); |
136 | 203 |
137 matches_.clear(); | 204 matches_.clear(); |
138 | 205 |
139 if (!minimal_changes) { | 206 if (!minimal_changes) { |
140 done_ = true; | 207 done_ = true; |
(...skipping 13 matching lines...) Expand all Loading... | |
154 // whatever we do here! | 221 // whatever we do here! |
155 // | 222 // |
156 // TODO(pkasting): http://b/1112681 If someday we remember usage frequency for | 223 // TODO(pkasting): http://b/1112681 If someday we remember usage frequency for |
157 // keywords, we might suggest keywords that haven't even been partially typed, | 224 // keywords, we might suggest keywords that haven't even been partially typed, |
158 // if the user uses them enough and isn't obviously typing something else. In | 225 // if the user uses them enough and isn't obviously typing something else. In |
159 // this case we'd consider all input here to be query input. | 226 // this case we'd consider all input here to be query input. |
160 string16 keyword, remaining_input; | 227 string16 keyword, remaining_input; |
161 if (!ExtractKeywordFromInput(input, &keyword, &remaining_input)) | 228 if (!ExtractKeywordFromInput(input, &keyword, &remaining_input)) |
162 return; | 229 return; |
163 | 230 |
164 // Make sure the model is loaded. This is cheap and quickly bails out if | 231 TemplateURLService* model = GetTemplateURLService(); |
165 // the model is already loaded. | |
166 TemplateURLService* model = | |
167 profile_ ? | |
168 TemplateURLServiceFactory::GetForProfile(profile_) : | |
169 model_; | |
170 DCHECK(model); | |
171 model->Load(); | |
172 | 232 |
173 // Get the best matches for this keyword. | 233 // Get the best matches for this keyword. |
174 // | 234 // |
175 // NOTE: We could cache the previous keywords and reuse them here in the | 235 // NOTE: We could cache the previous keywords and reuse them here in the |
176 // |minimal_changes| case, but since we'd still have to recalculate their | 236 // |minimal_changes| case, but since we'd still have to recalculate their |
177 // relevances and we can just recreate the results synchronously anyway, we | 237 // relevances and we can just recreate the results synchronously anyway, we |
178 // don't bother. | 238 // don't bother. |
179 // | 239 // |
180 // TODO(pkasting): http://b/893701 We should remember the user's use of a | 240 // TODO(pkasting): http://b/893701 We should remember the user's use of a |
181 // search query both from the autocomplete popup and from web pages | 241 // search query both from the autocomplete popup and from web pages |
182 // themselves. | 242 // themselves. |
183 std::vector<string16> keyword_matches; | 243 std::vector<string16> keyword_matches; |
184 model->FindMatchingKeywords(keyword, | 244 model->FindMatchingKeywords(keyword, |
185 !remaining_input.empty(), | 245 !remaining_input.empty(), |
186 &keyword_matches); | 246 &keyword_matches); |
187 | 247 |
188 // Prune any extension keywords that are disallowed in incognito mode (if | |
189 // we're incognito), or disabled. | |
190 for (std::vector<string16>::iterator i(keyword_matches.begin()); | 248 for (std::vector<string16>::iterator i(keyword_matches.begin()); |
191 i != keyword_matches.end(); ) { | 249 i != keyword_matches.end(); ) { |
192 const TemplateURL* template_url(model->GetTemplateURLForKeyword(*i)); | 250 const TemplateURL* template_url(model->GetTemplateURLForKeyword(*i)); |
251 | |
252 // Prune any extension keywords that are disallowed in incognito mode (if | |
253 // we're incognito), or disabled. | |
193 if (profile_ && | 254 if (profile_ && |
194 input.matches_requested() == AutocompleteInput::ALL_MATCHES && | 255 input.matches_requested() == AutocompleteInput::ALL_MATCHES && |
195 template_url->IsExtensionKeyword()) { | 256 template_url->IsExtensionKeyword()) { |
196 ExtensionService* service = profile_->GetExtensionService(); | 257 ExtensionService* service = profile_->GetExtensionService(); |
197 const Extension* extension = service->GetExtensionById( | 258 const Extension* extension = service->GetExtensionById( |
198 template_url->GetExtensionId(), false); | 259 template_url->GetExtensionId(), false); |
199 bool enabled = | 260 bool enabled = |
200 extension && (!profile_->IsOffTheRecord() || | 261 extension && (!profile_->IsOffTheRecord() || |
201 service->IsIncognitoEnabled(extension->id())); | 262 service->IsIncognitoEnabled(extension->id())); |
202 if (!enabled) { | 263 if (!enabled) { |
203 i = keyword_matches.erase(i); | 264 i = keyword_matches.erase(i); |
204 continue; | 265 continue; |
205 } | 266 } |
206 } | 267 } |
268 | |
269 // Prune any substituting keywords if there is no substitution. | |
270 if (TemplateURL::SupportsReplacement(template_url) && | |
271 !input.allow_exact_keyword_match()) { | |
272 i = keyword_matches.erase(i); | |
273 continue; | |
274 } | |
275 | |
207 ++i; | 276 ++i; |
208 } | 277 } |
209 if (keyword_matches.empty()) | 278 if (keyword_matches.empty()) |
210 return; | 279 return; |
211 std::sort(keyword_matches.begin(), keyword_matches.end(), CompareQuality()); | 280 std::sort(keyword_matches.begin(), keyword_matches.end(), CompareQuality()); |
212 | 281 |
213 // Limit to one exact or three inexact matches, and mark them up for display | 282 // Limit to one exact or three inexact matches, and mark them up for display |
214 // in the autocomplete popup. | 283 // in the autocomplete popup. |
215 // Any exact match is going to be the highest quality match, and thus at the | 284 // Any exact match is going to be the highest quality match, and thus at the |
216 // front of our vector. | 285 // front of our vector. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
287 return false; | 356 return false; |
288 | 357 |
289 string16 trimmed_input; | 358 string16 trimmed_input; |
290 TrimWhitespace(input.text(), TRIM_TRAILING, &trimmed_input); | 359 TrimWhitespace(input.text(), TRIM_TRAILING, &trimmed_input); |
291 *keyword = TemplateURLService::CleanUserInputKeyword( | 360 *keyword = TemplateURLService::CleanUserInputKeyword( |
292 SplitKeywordFromInput(trimmed_input, true, remaining_input)); | 361 SplitKeywordFromInput(trimmed_input, true, remaining_input)); |
293 return !keyword->empty(); | 362 return !keyword->empty(); |
294 } | 363 } |
295 | 364 |
296 // static | 365 // static |
297 string16 KeywordProvider::SplitKeywordFromInput( | |
298 const string16& input, | |
299 bool trim_leading_whitespace, | |
300 string16* remaining_input) { | |
301 // Find end of first token. The AutocompleteController has trimmed leading | |
302 // whitespace, so we need not skip over that. | |
303 const size_t first_white(input.find_first_of(kWhitespaceUTF16)); | |
304 DCHECK_NE(0U, first_white); | |
305 if (first_white == string16::npos) | |
306 return input; // Only one token provided. | |
307 | |
308 // Set |remaining_input| to everything after the first token. | |
309 DCHECK(remaining_input != NULL); | |
310 const size_t remaining_start = trim_leading_whitespace ? | |
311 input.find_first_not_of(kWhitespaceUTF16, first_white) : first_white + 1; | |
312 | |
313 if (remaining_start < input.length()) | |
314 remaining_input->assign(input.begin() + remaining_start, input.end()); | |
315 | |
316 // Return first token as keyword. | |
317 return input.substr(0, first_white); | |
318 } | |
319 | |
320 // static | |
321 void KeywordProvider::FillInURLAndContents( | 366 void KeywordProvider::FillInURLAndContents( |
322 Profile* profile, | 367 Profile* profile, |
323 const string16& remaining_input, | 368 const string16& remaining_input, |
324 const TemplateURL* element, | 369 const TemplateURL* element, |
325 AutocompleteMatch* match) { | 370 AutocompleteMatch* match) { |
326 DCHECK(!element->short_name().empty()); | 371 DCHECK(!element->short_name().empty()); |
327 DCHECK(element->url()); | 372 DCHECK(element->url()); |
328 DCHECK(element->url()->IsValid()); | 373 DCHECK(element->url()->IsValid()); |
329 int message_id = element->IsExtensionKeyword() ? | 374 int message_id = element->IsExtensionKeyword() ? |
330 IDS_EXTENSION_KEYWORD_COMMAND : IDS_KEYWORD_SEARCH; | 375 IDS_EXTENSION_KEYWORD_COMMAND : IDS_KEYWORD_SEARCH; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
408 const bool keyword_complete = (prefix_length == keyword.length()); | 453 const bool keyword_complete = (prefix_length == keyword.length()); |
409 if (relevance < 0) { | 454 if (relevance < 0) { |
410 relevance = | 455 relevance = |
411 CalculateRelevance(input.type(), keyword_complete, | 456 CalculateRelevance(input.type(), keyword_complete, |
412 // When the user wants keyword matches to take | 457 // When the user wants keyword matches to take |
413 // preference, score them highly regardless of | 458 // preference, score them highly regardless of |
414 // whether the input provides query text. | 459 // whether the input provides query text. |
415 supports_replacement, input.prefer_keyword(), | 460 supports_replacement, input.prefer_keyword(), |
416 input.allow_exact_keyword_match()); | 461 input.allow_exact_keyword_match()); |
417 } | 462 } |
418 AutocompleteMatch result(this, relevance, false, | 463 AutocompleteMatch match(this, relevance, false, |
419 supports_replacement ? AutocompleteMatch::SEARCH_OTHER_ENGINE : | 464 supports_replacement ? AutocompleteMatch::SEARCH_OTHER_ENGINE : |
420 AutocompleteMatch::HISTORY_KEYWORD); | 465 AutocompleteMatch::HISTORY_KEYWORD); |
421 result.fill_into_edit.assign(keyword); | 466 match.fill_into_edit.assign(keyword); |
422 if (!remaining_input.empty() || !keyword_complete || supports_replacement) | 467 if (!remaining_input.empty() || !keyword_complete || supports_replacement) |
423 result.fill_into_edit.push_back(L' '); | 468 match.fill_into_edit.push_back(L' '); |
424 result.fill_into_edit.append(remaining_input); | 469 match.fill_into_edit.append(remaining_input); |
425 // If we wanted to set |result.inline_autocomplete_offset| correctly, we'd | 470 // If we wanted to set |result.inline_autocomplete_offset| correctly, we'd |
426 // need CleanUserInputKeyword() to return the amount of adjustment it's made | 471 // need CleanUserInputKeyword() to return the amount of adjustment it's made |
427 // to the user's input. Because right now inexact keyword matches can't score | 472 // to the user's input. Because right now inexact keyword matches can't score |
428 // more highly than a "what you typed" match from one of the other providers, | 473 // more highly than a "what you typed" match from one of the other providers, |
429 // we just don't bother to do this, and leave inline autocompletion off. | 474 // we just don't bother to do this, and leave inline autocompletion off. |
430 result.inline_autocomplete_offset = string16::npos; | 475 match.inline_autocomplete_offset = string16::npos; |
431 | 476 |
432 // Create destination URL and popup entry content by substituting user input | 477 // Create destination URL and popup entry content by substituting user input |
433 // into keyword templates. | 478 // into keyword templates. |
434 FillInURLAndContents(profile_, remaining_input, element, &result); | 479 FillInURLAndContents(profile_, remaining_input, element, &match); |
435 | 480 |
436 if (supports_replacement) | 481 if (supports_replacement) |
437 result.template_url = element; | 482 match.template_url = element; |
438 result.transition = content::PAGE_TRANSITION_KEYWORD; | 483 match.keyword = keyword; |
484 match.transition = content::PAGE_TRANSITION_KEYWORD; | |
439 | 485 |
440 return result; | 486 return match; |
441 } | 487 } |
442 | 488 |
443 void KeywordProvider::Observe(int type, | 489 void KeywordProvider::Observe(int type, |
444 const content::NotificationSource& source, | 490 const content::NotificationSource& source, |
445 const content::NotificationDetails& details) { | 491 const content::NotificationDetails& details) { |
446 TemplateURLService* model = | 492 TemplateURLService* model = GetTemplateURLService(); |
447 profile_ ? TemplateURLServiceFactory::GetForProfile(profile_) : model_; | |
448 const AutocompleteInput& input = extension_suggest_last_input_; | 493 const AutocompleteInput& input = extension_suggest_last_input_; |
449 | 494 |
450 switch (type) { | 495 switch (type) { |
451 case chrome::NOTIFICATION_EXTENSION_OMNIBOX_INPUT_ENTERED: | 496 case chrome::NOTIFICATION_EXTENSION_OMNIBOX_INPUT_ENTERED: |
452 // Input has been accepted, so we're done with this input session. Ensure | 497 // Input has been accepted, so we're done with this input session. Ensure |
453 // we don't send the OnInputCancelled event, or handle any more stray | 498 // we don't send the OnInputCancelled event, or handle any more stray |
454 // suggestions_ready events. | 499 // suggestions_ready events. |
455 current_keyword_extension_id_.clear(); | 500 current_keyword_extension_id_.clear(); |
456 current_input_id_ = 0; | 501 current_input_id_ = 0; |
457 return; | 502 return; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
514 listener_->OnProviderUpdate(!extension_suggest_matches_.empty()); | 559 listener_->OnProviderUpdate(!extension_suggest_matches_.empty()); |
515 return; | 560 return; |
516 } | 561 } |
517 | 562 |
518 default: | 563 default: |
519 NOTREACHED(); | 564 NOTREACHED(); |
520 return; | 565 return; |
521 } | 566 } |
522 } | 567 } |
523 | 568 |
569 TemplateURLService* KeywordProvider::GetTemplateURLService() const { | |
570 TemplateURLService* service = profile_ ? | |
571 TemplateURLServiceFactory::GetForProfile(profile_) : model_; | |
572 // Make sure the model is loaded. This is cheap and quickly bails out if | |
573 // the model is already loaded. | |
574 DCHECK(service); | |
575 service->Load(); | |
576 return service; | |
577 } | |
578 | |
524 void KeywordProvider::EnterExtensionKeywordMode( | 579 void KeywordProvider::EnterExtensionKeywordMode( |
525 const std::string& extension_id) { | 580 const std::string& extension_id) { |
526 DCHECK(current_keyword_extension_id_.empty()); | 581 DCHECK(current_keyword_extension_id_.empty()); |
527 current_keyword_extension_id_ = extension_id; | 582 current_keyword_extension_id_ = extension_id; |
528 | 583 |
529 ExtensionOmniboxEventRouter::OnInputStarted( | 584 ExtensionOmniboxEventRouter::OnInputStarted( |
530 profile_, current_keyword_extension_id_); | 585 profile_, current_keyword_extension_id_); |
531 } | 586 } |
532 | 587 |
533 void KeywordProvider::MaybeEndExtensionKeywordMode() { | 588 void KeywordProvider::MaybeEndExtensionKeywordMode() { |
534 if (!current_keyword_extension_id_.empty()) { | 589 if (!current_keyword_extension_id_.empty()) { |
535 ExtensionOmniboxEventRouter::OnInputCancelled( | 590 ExtensionOmniboxEventRouter::OnInputCancelled( |
536 profile_, current_keyword_extension_id_); | 591 profile_, current_keyword_extension_id_); |
537 | 592 |
538 current_keyword_extension_id_.clear(); | 593 current_keyword_extension_id_.clear(); |
539 } | 594 } |
540 } | 595 } |
OLD | NEW |