| 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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 // |minimal_changes| case, but since we'd still have to recalculate their | 161 // |minimal_changes| case, but since we'd still have to recalculate their |
| 162 // relevances and we can just recreate the results synchronously anyway, we | 162 // relevances and we can just recreate the results synchronously anyway, we |
| 163 // don't bother. | 163 // don't bother. |
| 164 // | 164 // |
| 165 // TODO(pkasting): http://b/893701 We should remember the user's use of a | 165 // TODO(pkasting): http://b/893701 We should remember the user's use of a |
| 166 // search query both from the autocomplete popup and from web pages | 166 // search query both from the autocomplete popup and from web pages |
| 167 // themselves. | 167 // themselves. |
| 168 std::vector<std::wstring> keyword_matches; | 168 std::vector<std::wstring> keyword_matches; |
| 169 model->FindMatchingKeywords(keyword, !remaining_input.empty(), | 169 model->FindMatchingKeywords(keyword, !remaining_input.empty(), |
| 170 &keyword_matches); | 170 &keyword_matches); |
| 171 |
| 172 // Prune any extension keywords that are disallowed in incognito mode (if |
| 173 // we're incognito), or disabled. |
| 174 for (std::vector<std::wstring>::iterator i(keyword_matches.begin()); |
| 175 i != keyword_matches.end(); ) { |
| 176 const TemplateURL* template_url(model->GetTemplateURLForKeyword(*i)); |
| 177 if (profile_ && |
| 178 !input.synchronous_only() && template_url->IsExtensionKeyword()) { |
| 179 ExtensionsService* service = profile_->GetExtensionsService(); |
| 180 const Extension* extension = service->GetExtensionById( |
| 181 template_url->GetExtensionId(), false); |
| 182 bool enabled = extension && (!profile_->IsOffTheRecord() || |
| 183 service->IsIncognitoEnabled(extension)); |
| 184 if (!enabled) { |
| 185 i = keyword_matches.erase(i); |
| 186 continue; |
| 187 } |
| 188 } |
| 189 ++i; |
| 190 } |
| 171 if (keyword_matches.empty()) | 191 if (keyword_matches.empty()) |
| 172 return; | 192 return; |
| 173 std::sort(keyword_matches.begin(), keyword_matches.end(), CompareQuality()); | 193 std::sort(keyword_matches.begin(), keyword_matches.end(), CompareQuality()); |
| 174 | 194 |
| 175 // Limit to one exact or three inexact matches, and mark them up for display | 195 // Limit to one exact or three inexact matches, and mark them up for display |
| 176 // in the autocomplete popup. | 196 // in the autocomplete popup. |
| 177 // Any exact match is going to be the highest quality match, and thus at the | 197 // Any exact match is going to be the highest quality match, and thus at the |
| 178 // front of our vector. | 198 // front of our vector. |
| 179 if (keyword_matches.front() == keyword) { | 199 if (keyword_matches.front() == keyword) { |
| 180 const TemplateURL* template_url(model->GetTemplateURLForKeyword(keyword)); | 200 const TemplateURL* template_url(model->GetTemplateURLForKeyword(keyword)); |
| 181 // TODO(pkasting): We should probably check that if the user explicitly | 201 // TODO(pkasting): We should probably check that if the user explicitly |
| 182 // typed a scheme, that scheme matches the one in |template_url|. | 202 // typed a scheme, that scheme matches the one in |template_url|. |
| 203 matches_.push_back(CreateAutocompleteMatch(model, keyword, input, |
| 204 keyword.length(), |
| 205 remaining_input, -1)); |
| 183 | 206 |
| 184 if (profile_ && | 207 if (profile_ && |
| 185 !input.synchronous_only() && template_url->IsExtensionKeyword()) { | 208 !input.synchronous_only() && template_url->IsExtensionKeyword()) { |
| 186 // If this extension keyword is disabled, make sure we don't add any | 209 if (template_url->GetExtensionId() != current_keyword_extension_id_) |
| 187 // matches (including the synchronous one below). | |
| 188 ExtensionsService* service = profile_->GetExtensionsService(); | |
| 189 const Extension* extension = service->GetExtensionById( | |
| 190 template_url->GetExtensionId(), false); | |
| 191 bool enabled = extension && (!profile_->IsOffTheRecord() || | |
| 192 service->IsIncognitoEnabled(extension)); | |
| 193 if (!enabled) | |
| 194 return; | |
| 195 | |
| 196 if (extension->id() != current_keyword_extension_id_) | |
| 197 MaybeEndExtensionKeywordMode(); | 210 MaybeEndExtensionKeywordMode(); |
| 198 if (current_keyword_extension_id_.empty()) | 211 if (current_keyword_extension_id_.empty()) |
| 199 EnterExtensionKeywordMode(extension->id()); | 212 EnterExtensionKeywordMode(template_url->GetExtensionId()); |
| 200 keyword_mode_toggle.StayInKeywordMode(); | 213 keyword_mode_toggle.StayInKeywordMode(); |
| 201 | 214 |
| 202 if (minimal_changes) { | 215 if (minimal_changes) { |
| 203 // If the input hasn't significantly changed, we can just use the | 216 // If the input hasn't significantly changed, we can just use the |
| 204 // suggestions from last time. We need to readjust the relevance to | 217 // suggestions from last time. We need to readjust the relevance to |
| 205 // ensure it is less than the main match's relevance. | 218 // ensure it is less than the main match's relevance. |
| 206 for (size_t i = 0; i < extension_suggest_matches_.size(); ++i) { | 219 for (size_t i = 0; i < extension_suggest_matches_.size(); ++i) { |
| 207 matches_.push_back(extension_suggest_matches_[i]); | 220 matches_.push_back(extension_suggest_matches_[i]); |
| 208 matches_.back().relevance = matches_[0].relevance - (i + 1); | 221 matches_.back().relevance = matches_[0].relevance - (i + 1); |
| 209 } | 222 } |
| 210 } else { | 223 } else { |
| 211 extension_suggest_last_input_ = input; | 224 extension_suggest_last_input_ = input; |
| 212 extension_suggest_matches_.clear(); | 225 extension_suggest_matches_.clear(); |
| 213 | 226 |
| 214 bool have_listeners = ExtensionOmniboxEventRouter::OnInputChanged( | 227 bool have_listeners = ExtensionOmniboxEventRouter::OnInputChanged( |
| 215 profile_, template_url->GetExtensionId(), | 228 profile_, template_url->GetExtensionId(), |
| 216 WideToUTF8(remaining_input), current_input_id_); | 229 WideToUTF8(remaining_input), current_input_id_); |
| 217 | 230 |
| 218 // We only have to wait for suggest results if there are actually | 231 // We only have to wait for suggest results if there are actually |
| 219 // extensions listening for input changes. | 232 // extensions listening for input changes. |
| 220 if (have_listeners) | 233 if (have_listeners) |
| 221 done_ = false; | 234 done_ = false; |
| 222 } | 235 } |
| 223 } | 236 } |
| 224 | |
| 225 matches_.push_back(CreateAutocompleteMatch(model, keyword, input, | |
| 226 keyword.length(), | |
| 227 remaining_input, -1)); | |
| 228 } else { | 237 } else { |
| 229 if (keyword_matches.size() > kMaxMatches) { | 238 if (keyword_matches.size() > kMaxMatches) { |
| 230 keyword_matches.erase(keyword_matches.begin() + kMaxMatches, | 239 keyword_matches.erase(keyword_matches.begin() + kMaxMatches, |
| 231 keyword_matches.end()); | 240 keyword_matches.end()); |
| 232 } | 241 } |
| 233 for (std::vector<std::wstring>::const_iterator i(keyword_matches.begin()); | 242 for (std::vector<std::wstring>::const_iterator i(keyword_matches.begin()); |
| 234 i != keyword_matches.end(); ++i) { | 243 i != keyword_matches.end(); ++i) { |
| 235 matches_.push_back(CreateAutocompleteMatch(model, *i, input, | 244 matches_.push_back(CreateAutocompleteMatch(model, *i, input, |
| 236 keyword.length(), | 245 keyword.length(), |
| 237 remaining_input, -1)); | 246 remaining_input, -1)); |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 } | 480 } |
| 472 | 481 |
| 473 void KeywordProvider::MaybeEndExtensionKeywordMode() { | 482 void KeywordProvider::MaybeEndExtensionKeywordMode() { |
| 474 if (!current_keyword_extension_id_.empty()) { | 483 if (!current_keyword_extension_id_.empty()) { |
| 475 ExtensionOmniboxEventRouter::OnInputCancelled( | 484 ExtensionOmniboxEventRouter::OnInputCancelled( |
| 476 profile_, current_keyword_extension_id_); | 485 profile_, current_keyword_extension_id_); |
| 477 | 486 |
| 478 current_keyword_extension_id_.clear(); | 487 current_keyword_extension_id_.clear(); |
| 479 } | 488 } |
| 480 } | 489 } |
| OLD | NEW |