OLD | NEW |
---|---|
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" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
54 | 54 |
55 KeywordProvider::KeywordProvider(ACProviderListener* listener, Profile* profile) | 55 KeywordProvider::KeywordProvider(ACProviderListener* listener, Profile* profile) |
56 : AutocompleteProvider(listener, profile, "Keyword"), | 56 : AutocompleteProvider(listener, profile, "Keyword"), |
57 model_(NULL), | 57 model_(NULL), |
58 current_input_id_(0) { | 58 current_input_id_(0) { |
59 // Extension suggestions always come from the original profile, since that's | 59 // Extension suggestions always come from the original profile, since that's |
60 // where extensions run. We use the input ID to distinguish whether the | 60 // where extensions run. We use the input ID to distinguish whether the |
61 // suggestions are meant for us. | 61 // suggestions are meant for us. |
62 registrar_.Add(this, NotificationType::EXTENSION_OMNIBOX_SUGGESTIONS_READY, | 62 registrar_.Add(this, NotificationType::EXTENSION_OMNIBOX_SUGGESTIONS_READY, |
63 Source<Profile>(profile->GetOriginalProfile())); | 63 Source<Profile>(profile->GetOriginalProfile())); |
64 registrar_.Add(this, | |
65 NotificationType::EXTENSION_OMNIBOX_DEFAULT_SUGGESTION_CHANGED, | |
66 Source<Profile>(profile->GetOriginalProfile())); | |
64 registrar_.Add(this, NotificationType::EXTENSION_OMNIBOX_INPUT_ENTERED, | 67 registrar_.Add(this, NotificationType::EXTENSION_OMNIBOX_INPUT_ENTERED, |
65 Source<Profile>(profile)); | 68 Source<Profile>(profile)); |
66 } | 69 } |
67 | 70 |
68 KeywordProvider::KeywordProvider(ACProviderListener* listener, | 71 KeywordProvider::KeywordProvider(ACProviderListener* listener, |
69 TemplateURLModel* model) | 72 TemplateURLModel* model) |
70 : AutocompleteProvider(listener, NULL, "Keyword"), | 73 : AutocompleteProvider(listener, NULL, "Keyword"), |
71 model_(model), | 74 model_(model), |
72 current_input_id_(0) { | 75 current_input_id_(0) { |
73 } | 76 } |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
426 ACMatchClassification::DIM, | 429 ACMatchClassification::DIM, |
427 &result.description_class); | 430 &result.description_class); |
428 } | 431 } |
429 | 432 |
430 return result; | 433 return result; |
431 } | 434 } |
432 | 435 |
433 void KeywordProvider::Observe(NotificationType type, | 436 void KeywordProvider::Observe(NotificationType type, |
434 const NotificationSource& source, | 437 const NotificationSource& source, |
435 const NotificationDetails& details) { | 438 const NotificationDetails& details) { |
436 if (type == NotificationType::EXTENSION_OMNIBOX_INPUT_ENTERED) { | 439 TemplateURLModel* model = profile_ ? profile_->GetTemplateURLModel() : model_; |
437 // Input has been accepted, so we're done with this input session. Ensure | 440 const AutocompleteInput& input = extension_suggest_last_input_; |
438 // we don't send the OnInputCancelled event. | 441 |
439 current_keyword_extension_id_.clear(); | 442 switch (type.value) { |
440 return; | 443 case NotificationType::EXTENSION_OMNIBOX_INPUT_ENTERED: |
444 // Input has been accepted, so we're done with this input session. Ensure | |
445 // we don't send the OnInputCancelled event. | |
446 current_keyword_extension_id_.clear(); | |
447 break; | |
Peter Kasting
2010/12/06 20:05:53
Nit: Using "return" instead of "break" makes life
Matt Perry
2010/12/07 00:10:18
Done.
| |
448 | |
449 case NotificationType::EXTENSION_OMNIBOX_DEFAULT_SUGGESTION_CHANGED: { | |
450 // It's possible to change the default suggestion while not in an editing | |
451 // session. | |
452 std::wstring keyword, remaining_input; | |
453 if (matches_.empty() || current_keyword_extension_id_.empty() || | |
454 !ExtractKeywordFromInput(input, &keyword, &remaining_input)) | |
Peter Kasting
2010/12/06 20:05:53
Is ExtractKeywordFromInput() supposed to guarantee
Matt Perry
2010/12/07 00:10:18
I *think* it should as long as the first 2 clauses
| |
455 return; | |
456 | |
457 const TemplateURL* template_url(model->GetTemplateURLForKeyword(keyword)); | |
458 ApplyDefaultSuggestionForExtensionKeyword(profile_, template_url, | |
459 WideToUTF16(remaining_input), | |
460 &matches_[0]); | |
461 listener_->OnProviderUpdate(true); | |
462 break; | |
463 } | |
464 | |
465 case NotificationType::EXTENSION_OMNIBOX_SUGGESTIONS_READY: { | |
466 const ExtensionOmniboxSuggestions& suggestions = | |
467 *Details<ExtensionOmniboxSuggestions>(details).ptr(); | |
468 if (suggestions.request_id != current_input_id_) | |
469 return; // This is an old result. Just ignore. | |
470 | |
471 // TODO(mpcomplete): consider clamping the number of suggestions to | |
Peter Kasting
2010/12/06 20:05:53
Nit: Doesn't this TODO belong on the next block?
Matt Perry
2010/12/07 00:10:18
I've moved the TODO. I think I'm going to wait unt
| |
472 // AutocompleteProvider::kMaxMatches. | |
473 std::wstring keyword, remaining_input; | |
474 if (!ExtractKeywordFromInput(input, &keyword, &remaining_input)) { | |
475 NOTREACHED(); | |
476 return; | |
477 } | |
478 | |
479 for (size_t i = 0; i < suggestions.suggestions.size(); ++i) { | |
480 const ExtensionOmniboxSuggestion& suggestion = | |
481 suggestions.suggestions[i]; | |
Peter Kasting
2010/12/06 20:05:53
Nit: You could probably avoid this temp by using a
Matt Perry
2010/12/07 00:10:18
I also need the index for the relevance calculatio
| |
482 // We want to order these suggestions in descending order, so start with | |
483 // the relevance of the first result (added synchronously in Start()), | |
484 // and subtract 1 for each subsequent suggestion from the extension. | |
485 // We know that |complete| is true, because we wouldn't get results from | |
486 // the extension unless the full keyword had been typed. | |
487 int first_relevance = CalculateRelevance(input.type(), true, | |
488 input.prefer_keyword(), input.allow_exact_keyword_match()); | |
489 extension_suggest_matches_.push_back(CreateAutocompleteMatch( | |
490 model, keyword, input, keyword.length(), | |
491 UTF16ToWide(suggestion.content), first_relevance - (i + 1))); | |
492 | |
493 AutocompleteMatch* match = &extension_suggest_matches_.back(); | |
494 match->contents.assign(UTF16ToWide(suggestion.description)); | |
495 match->contents_class = suggestion.description_styles; | |
496 match->description.clear(); | |
497 match->description_class.clear(); | |
498 } | |
499 | |
500 done_ = true; | |
501 matches_.insert(matches_.end(), extension_suggest_matches_.begin(), | |
502 extension_suggest_matches_.end()); | |
503 listener_->OnProviderUpdate(!extension_suggest_matches_.empty()); | |
504 break; | |
505 } | |
506 | |
507 default: | |
508 NOTREACHED(); | |
509 break; | |
441 } | 510 } |
442 | |
443 // TODO(mpcomplete): consider clamping the number of suggestions to | |
444 // AutocompleteProvider::kMaxMatches. | |
445 DCHECK(type == NotificationType::EXTENSION_OMNIBOX_SUGGESTIONS_READY); | |
446 | |
447 const ExtensionOmniboxSuggestions& suggestions = | |
448 *Details<ExtensionOmniboxSuggestions>(details).ptr(); | |
449 if (suggestions.request_id != current_input_id_) | |
450 return; // This is an old result. Just ignore. | |
451 | |
452 const AutocompleteInput& input = extension_suggest_last_input_; | |
453 std::wstring keyword, remaining_input; | |
454 if (!ExtractKeywordFromInput(input, &keyword, &remaining_input)) { | |
455 NOTREACHED(); | |
456 return; | |
457 } | |
458 | |
459 TemplateURLModel* model = | |
460 profile_ ? profile_->GetTemplateURLModel() : model_; | |
461 | |
462 for (size_t i = 0; i < suggestions.suggestions.size(); ++i) { | |
463 const ExtensionOmniboxSuggestion& suggestion = suggestions.suggestions[i]; | |
464 // We want to order these suggestions in descending order, so start with | |
465 // the relevance of the first result (added synchronously in Start()), | |
466 // and subtract 1 for each subsequent suggestion from the extension. | |
467 // We know that |complete| is true, because we wouldn't get results from | |
468 // the extension unless the full keyword had been typed. | |
469 int first_relevance = CalculateRelevance(input.type(), true, | |
470 input.prefer_keyword(), input.allow_exact_keyword_match()); | |
471 extension_suggest_matches_.push_back(CreateAutocompleteMatch( | |
472 model, keyword, input, keyword.length(), | |
473 UTF16ToWide(suggestion.content), first_relevance - (i + 1))); | |
474 | |
475 AutocompleteMatch* match = &extension_suggest_matches_.back(); | |
476 match->contents.assign(UTF16ToWide(suggestion.description)); | |
477 match->contents_class = suggestion.description_styles; | |
478 match->description.clear(); | |
479 match->description_class.clear(); | |
480 } | |
481 | |
482 done_ = true; | |
483 matches_.insert(matches_.end(), extension_suggest_matches_.begin(), | |
484 extension_suggest_matches_.end()); | |
485 listener_->OnProviderUpdate(!extension_suggest_matches_.empty()); | |
486 } | 511 } |
487 | 512 |
488 void KeywordProvider::EnterExtensionKeywordMode( | 513 void KeywordProvider::EnterExtensionKeywordMode( |
489 const std::string& extension_id) { | 514 const std::string& extension_id) { |
490 DCHECK(current_keyword_extension_id_.empty()); | 515 DCHECK(current_keyword_extension_id_.empty()); |
491 current_keyword_extension_id_ = extension_id; | 516 current_keyword_extension_id_ = extension_id; |
492 | 517 |
493 ExtensionOmniboxEventRouter::OnInputStarted( | 518 ExtensionOmniboxEventRouter::OnInputStarted( |
494 profile_, current_keyword_extension_id_); | 519 profile_, current_keyword_extension_id_); |
495 } | 520 } |
496 | 521 |
497 void KeywordProvider::MaybeEndExtensionKeywordMode() { | 522 void KeywordProvider::MaybeEndExtensionKeywordMode() { |
498 if (!current_keyword_extension_id_.empty()) { | 523 if (!current_keyword_extension_id_.empty()) { |
499 ExtensionOmniboxEventRouter::OnInputCancelled( | 524 ExtensionOmniboxEventRouter::OnInputCancelled( |
500 profile_, current_keyword_extension_id_); | 525 profile_, current_keyword_extension_id_); |
501 | 526 |
502 current_keyword_extension_id_.clear(); | 527 current_keyword_extension_id_.clear(); |
503 } | 528 } |
504 } | 529 } |
OLD | NEW |