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

Side by Side Diff: chrome/common/extensions/extension.cc

Issue 10317014: Move Command class out of the Extension class and into its own location (under chrome/common/exten… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/common/extensions/extension.h" 5 #include "chrome/common/extensions/extension.h"
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/basictypes.h" 8 #include "base/basictypes.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/file_path.h" 10 #include "base/file_path.h"
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 Extension::OAuth2Info::OAuth2Info() {} 243 Extension::OAuth2Info::OAuth2Info() {}
244 Extension::OAuth2Info::~OAuth2Info() {} 244 Extension::OAuth2Info::~OAuth2Info() {}
245 245
246 ExtensionOAuth2Scopes Extension::OAuth2Info::GetScopesAsSet() { 246 ExtensionOAuth2Scopes Extension::OAuth2Info::GetScopesAsSet() {
247 ExtensionOAuth2Scopes result; 247 ExtensionOAuth2Scopes result;
248 std::copy(scopes.begin(), scopes.end(), 248 std::copy(scopes.begin(), scopes.end(),
249 std::inserter(result, result.begin())); 249 std::inserter(result, result.begin()));
250 return result; 250 return result;
251 } 251 }
252 252
253 Extension::Command::Command() {}
254 Extension::Command::~Command() {}
255
256 ui::Accelerator Extension::Command::ParseImpl(
257 const std::string& shortcut,
258 const std::string& platform_key,
259 int index,
260 string16* error) {
261 if (platform_key != values::kKeybindingPlatformWin &&
262 platform_key != values::kKeybindingPlatformMac &&
263 platform_key != values::kKeybindingPlatformChromeOs &&
264 platform_key != values::kKeybindingPlatformLinux &&
265 platform_key != values::kKeybindingPlatformDefault) {
266 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
267 errors::kInvalidKeyBindingUnknownPlatform,
268 base::IntToString(index),
269 platform_key);
270 return ui::Accelerator();
271 }
272
273 std::vector<std::string> tokens;
274 base::SplitString(shortcut, '+', &tokens);
275 if (tokens.size() < 2 || tokens.size() > 3) {
276 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
277 errors::kInvalidKeyBinding,
278 base::IntToString(index),
279 platform_key,
280 shortcut);
281 return ui::Accelerator();
282 }
283
284 // Now, parse it into an accelerator.
285 bool ctrl = false;
286 bool alt = false;
287 bool shift = false;
288 ui::KeyboardCode key = ui::VKEY_UNKNOWN;
289 for (size_t i = 0; i < tokens.size(); i++) {
290 if (tokens[i] == "Ctrl") {
291 ctrl = true;
292 } else if (tokens[i] == "Alt") {
293 alt = true;
294 } else if (tokens[i] == "Shift") {
295 shift = true;
296 } else if (tokens[i] == "Command" && platform_key == "mac") {
297 // TODO(finnur): Implement for Mac.
298 } else if (tokens[i] == "Option" && platform_key == "mac") {
299 // TODO(finnur): Implement for Mac.
300 } else if (tokens[i].size() == 1 &&
301 tokens[i][0] >= 'A' && tokens[i][0] <= 'Z') {
302 if (key != ui::VKEY_UNKNOWN) {
303 // Multiple key assignments.
304 key = ui::VKEY_UNKNOWN;
305 break;
306 }
307
308 key = static_cast<ui::KeyboardCode>(ui::VKEY_A + (tokens[i][0] - 'A'));
309 } else {
310 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
311 errors::kInvalidKeyBinding,
312 base::IntToString(index),
313 platform_key,
314 shortcut);
315 return ui::Accelerator();
316 }
317 }
318
319 // We support Ctrl+foo, Alt+foo, Ctrl+Shift+foo, Alt+Shift+foo, but not
320 // Ctrl+Alt+foo. For a more detailed reason why we don't support Ctrl+Alt+foo:
321 // http://blogs.msdn.com/b/oldnewthing/archive/2004/03/29/101121.aspx.
322 if (key == ui::VKEY_UNKNOWN || (ctrl && alt)) {
323 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
324 errors::kInvalidKeyBinding,
325 base::IntToString(index),
326 platform_key,
327 shortcut);
328 return ui::Accelerator();
329 }
330
331 return ui::Accelerator(key, shift, ctrl, alt);
332 }
333
334 // static
335 std::string Extension::Command::CommandPlatform() {
336 #if defined(OS_WIN)
337 return values::kKeybindingPlatformWin;
338 #elif defined(OS_MACOSX)
339 return values::kKeybindingPlatformMac;
340 #elif defined(OS_CHROMEOS)
341 return values::kKeybindingPlatformChromeOs;
342 #elif defined(OS_LINUX)
343 return values::kKeybindingPlatformLinux;
344 #else
345 return "";
346 #endif
347 }
348
349 bool Extension::Command::Parse(DictionaryValue* command,
350 const std::string& command_name,
351 int index,
352 string16* error) {
353 DCHECK(!command_name.empty());
354
355 // We'll build up a map of platform-to-shortcut suggestions.
356 std::map<const std::string, std::string> suggestions;
357
358 // First try to parse the |suggested_key| as a dictionary.
359 DictionaryValue* suggested_key_dict;
360 if (command->GetDictionary(keys::kSuggestedKey, &suggested_key_dict)) {
361 DictionaryValue::key_iterator iter = suggested_key_dict->begin_keys();
362 for ( ; iter != suggested_key_dict->end_keys(); ++iter) {
363 // For each item in the dictionary, extract the platforms specified.
364 std::string suggested_key_string;
365 if (suggested_key_dict->GetString(*iter, &suggested_key_string) &&
366 !suggested_key_string.empty()) {
367 // Found a platform, add it to the suggestions list.
368 suggestions[*iter] = suggested_key_string;
369 } else {
370 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
371 errors::kInvalidKeyBinding,
372 base::IntToString(index),
373 keys::kSuggestedKey,
374 "Missing");
375 return false;
376 }
377 }
378 } else {
379 // No dictionary was found, fall back to using just a string, so developers
380 // don't have to specify a dictionary if they just want to use one default
381 // for all platforms.
382 std::string suggested_key_string;
383 if (command->GetString(keys::kSuggestedKey, &suggested_key_string) &&
384 !suggested_key_string.empty()) {
385 // If only a signle string is provided, it must be default for all.
386 suggestions["default"] = suggested_key_string;
387 } else {
388 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
389 errors::kInvalidKeyBinding,
390 base::IntToString(index),
391 keys::kSuggestedKey,
392 "Missing");
393 return false;
394 }
395 }
396
397 std::string platform = CommandPlatform();
398 std::string key = platform;
399 if (suggestions.find(key) == suggestions.end())
400 key = values::kKeybindingPlatformDefault;
401 if (suggestions.find(key) == suggestions.end()) {
402 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
403 errors::kInvalidKeyBindingMissingPlatform,
404 base::IntToString(index),
405 keys::kSuggestedKey,
406 platform);
407 return false; // No platform specified and no fallback. Bail.
408 }
409
410 // For developer convenience, we parse all the suggestions (and complain about
411 // errors for platforms other than the current one) but use only what we need.
412 std::map<const std::string, std::string>::const_iterator iter =
413 suggestions.begin();
414 for ( ; iter != suggestions.end(); ++iter) {
415 // Note that we pass iter->first to pretend we are on a platform we're not
416 // on.
417 ui::Accelerator accelerator =
418 ParseImpl(iter->second, iter->first, index, error);
419 if (accelerator.key_code() == ui::VKEY_UNKNOWN) {
420 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
421 errors::kInvalidKeyBinding,
422 base::IntToString(index),
423 iter->first,
424 iter->second);
425 return false;
426 }
427
428 if (iter->first == key) {
429 // This platform is our platform, so grab this key.
430 accelerator_ = accelerator;
431 command_name_ = command_name;
432
433 if (command_name !=
434 extension_manifest_values::kPageActionKeybindingEvent &&
435 command_name !=
436 extension_manifest_values::kBrowserActionKeybindingEvent) {
437 if (!command->GetString(keys::kDescription, &description_) ||
438 description_.empty()) {
439 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
440 errors::kInvalidKeyBindingDescription,
441 base::IntToString(index));
442 return false;
443 }
444 }
445 }
446 }
447 return true;
448 }
449
450 // 253 //
451 // Extension 254 // Extension
452 // 255 //
453 256
454 // static 257 // static
455 scoped_refptr<Extension> Extension::Create(const FilePath& path, 258 scoped_refptr<Extension> Extension::Create(const FilePath& path,
456 Location location, 259 Location location,
457 const DictionaryValue& value, 260 const DictionaryValue& value,
458 int flags, 261 int flags,
459 std::string* utf8_error) { 262 std::string* utf8_error) {
(...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1587 ++command_index; 1390 ++command_index;
1588 1391
1589 DictionaryValue* command = NULL; 1392 DictionaryValue* command = NULL;
1590 if (!commands->GetDictionary(*iter, &command)) { 1393 if (!commands->GetDictionary(*iter, &command)) {
1591 *error = ExtensionErrorUtils::FormatErrorMessageUTF16( 1394 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
1592 errors::kInvalidKeyBindingDictionary, 1395 errors::kInvalidKeyBindingDictionary,
1593 base::IntToString(command_index)); 1396 base::IntToString(command_index));
1594 return false; 1397 return false;
1595 } 1398 }
1596 1399
1597 scoped_ptr<Extension::Command> binding(new Command()); 1400 scoped_ptr<extensions::Command> binding(new extensions::Command());
1598 if (!binding->Parse(command, *iter, command_index, error)) 1401 if (!binding->Parse(command, *iter, command_index, error))
1599 return false; // |error| already set. 1402 return false; // |error| already set.
1600 1403
1601 std::string command_name = binding->command_name(); 1404 std::string command_name = binding->command_name();
1602 if (command_name == values::kPageActionKeybindingEvent) { 1405 if (command_name == values::kPageActionKeybindingEvent) {
1603 page_action_command_.reset(binding.release()); 1406 page_action_command_.reset(binding.release());
1604 } else if (command_name == values::kBrowserActionKeybindingEvent) { 1407 } else if (command_name == values::kBrowserActionKeybindingEvent) {
1605 browser_action_command_.reset(binding.release()); 1408 browser_action_command_.reset(binding.release());
1606 } else { 1409 } else {
1607 if (command_name[0] != '_') // All commands w/underscore are reserved. 1410 if (command_name[0] != '_') // All commands w/underscore are reserved.
(...skipping 2120 matching lines...) Expand 10 before | Expand all | Expand 10 after
3728 already_disabled(false), 3531 already_disabled(false),
3729 extension(extension) {} 3532 extension(extension) {}
3730 3533
3731 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( 3534 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo(
3732 const Extension* extension, 3535 const Extension* extension,
3733 const ExtensionPermissionSet* permissions, 3536 const ExtensionPermissionSet* permissions,
3734 Reason reason) 3537 Reason reason)
3735 : reason(reason), 3538 : reason(reason),
3736 extension(extension), 3539 extension(extension),
3737 permissions(permissions) {} 3540 permissions(permissions) {}
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698