Index: chrome/common/extensions/extension.cc |
=================================================================== |
--- chrome/common/extensions/extension.cc (revision 122745) |
+++ chrome/common/extensions/extension.cc (working copy) |
@@ -42,6 +42,7 @@ |
#include "grit/theme_resources.h" |
#include "net/base/registry_controlled_domain.h" |
#include "third_party/skia/include/core/SkBitmap.h" |
+#include "ui/base/keycodes/keyboard_codes.h" |
#include "ui/base/l10n/l10n_util.h" |
#include "ui/base/resource/resource_bundle.h" |
#include "webkit/glue/image_decoder.h" |
@@ -219,6 +220,105 @@ |
Extension::TtsVoice::TtsVoice() {} |
Extension::TtsVoice::~TtsVoice() {} |
+Extension::ExtensionKeybinding::ExtensionKeybinding() {} |
+Extension::ExtensionKeybinding::~ExtensionKeybinding() {} |
+ |
+bool Extension::ExtensionKeybinding::Parse(DictionaryValue* command, |
+ const std::string& event_name, |
+ string16* error, |
+ int index) { |
Matt Perry
2012/02/21 23:13:39
outparams (error) should go last
|
+ std::string key_binding; |
+ if (!command->GetString(keys::kKey, &key_binding)) { |
+ *error = ExtensionErrorUtils::FormatErrorMessageUTF16( |
+ errors::kInvalidKeyBinding, |
+ base::IntToString(index), |
+ "Missing"); |
+ return false; |
+ } |
+ |
+ std::string original_keybinding = key_binding; |
+ // Normalize '-' to '+'. |
+ for (size_t pos = key_binding.find('-'); |
+ pos != std::string::npos; |
+ pos = key_binding.find('-')) { |
+ key_binding.replace(pos, 1, "+"); |
+ } |
+ // Remove all spaces. |
+ for (size_t pos = key_binding.find(' '); |
+ pos != std::string::npos; |
+ pos = key_binding.find(' ')) { |
+ key_binding.replace(pos, 1, ""); |
+ } |
Matt Perry
2012/02/21 23:13:39
base::ReplaceSubstringsAfterOffset(&key_binding, 0
|
+ // And finally, lower-case it. |
+ key_binding = StringToLowerASCII(key_binding); |
+ |
+ // Now, parse it into an accelerator. |
+ bool ctrl = false; |
+ bool alt = false; |
+ bool shift = false; |
+ ui::KeyboardCode key = ui::VKEY_UNKNOWN; |
+ // We support Ctrl+foo, Alt+foo, Ctrl+Shift+foo, Alt+Shift+foo, but not |
+ // Ctrl+Alt+foo. For a more detailed reason why we don't support Ctrl+Alt+foo: |
+ // http://blogs.msdn.com/b/oldnewthing/archive/2004/03/29/101121.aspx. |
+ size_t position; |
Matt Perry
2012/02/21 23:13:39
Should we support Shift+Alt+foo? If so, it might b
Finnur
2012/02/22 23:45:22
Good idea.
On 2012/02/21 23:13:39, Matt Perry wro
|
+ if ((position = key_binding.find("ctrl+")) != std::string::npos) { |
+ ctrl = true; |
+ key_binding = key_binding.replace(position, 5, ""); |
+ } else if ((position = key_binding.find("alt+")) != std::string::npos) { |
+ alt = true; |
+ key_binding = key_binding.replace(position, 4, ""); |
+ } |
+ if ((position = key_binding.find("shift+")) != std::string::npos) { |
+ shift = true; |
+ key_binding = key_binding.replace(position, 6, ""); |
+ } |
+ // We've stripped everything from the string but the letter. |
+ if (key_binding.size() != 1) { |
+ *error = ExtensionErrorUtils::FormatErrorMessageUTF16( |
+ errors::kInvalidKeyBinding, |
+ base::IntToString(index), |
+ original_keybinding); |
+ return false; |
+ } |
+ |
+ if (key_binding.compare("a") == 0) key = ui::VKEY_A; |
Matt Perry
2012/02/21 23:13:39
Are we guaranteed for VKEY_A through _Z to be cont
|
+ else if (key_binding.compare("b") == 0) key = ui::VKEY_B; |
+ else if (key_binding.compare("c") == 0) key = ui::VKEY_C; |
+ else if (key_binding.compare("d") == 0) key = ui::VKEY_D; |
+ else if (key_binding.compare("e") == 0) key = ui::VKEY_E; |
+ else if (key_binding.compare("f") == 0) key = ui::VKEY_F; |
+ else if (key_binding.compare("g") == 0) key = ui::VKEY_G; |
+ else if (key_binding.compare("h") == 0) key = ui::VKEY_H; |
+ else if (key_binding.compare("i") == 0) key = ui::VKEY_I; |
+ else if (key_binding.compare("j") == 0) key = ui::VKEY_J; |
+ else if (key_binding.compare("k") == 0) key = ui::VKEY_K; |
+ else if (key_binding.compare("l") == 0) key = ui::VKEY_L; |
+ else if (key_binding.compare("m") == 0) key = ui::VKEY_M; |
+ else if (key_binding.compare("n") == 0) key = ui::VKEY_N; |
+ else if (key_binding.compare("o") == 0) key = ui::VKEY_O; |
+ else if (key_binding.compare("p") == 0) key = ui::VKEY_P; |
+ else if (key_binding.compare("q") == 0) key = ui::VKEY_Q; |
+ else if (key_binding.compare("r") == 0) key = ui::VKEY_R; |
+ else if (key_binding.compare("s") == 0) key = ui::VKEY_S; |
+ else if (key_binding.compare("t") == 0) key = ui::VKEY_T; |
+ else if (key_binding.compare("u") == 0) key = ui::VKEY_U; |
+ else if (key_binding.compare("v") == 0) key = ui::VKEY_V; |
+ else if (key_binding.compare("x") == 0) key = ui::VKEY_X; |
+ else if (key_binding.compare("y") == 0) key = ui::VKEY_Y; |
+ else if (key_binding.compare("z") == 0) key = ui::VKEY_Z; |
+ |
+ accelerator_ = ui::Accelerator(key, shift, ctrl, alt); |
+ if (!command->GetString(keys::kDescription, &description_)) { |
+ *error = ExtensionErrorUtils::FormatErrorMessageUTF16( |
+ errors::kInvalidKeyBindingDescription, |
+ base::IntToString(index)); |
+ return false; |
+ } |
+ |
+ event_name_ = event_name; |
+ return true; |
+} |
+ |
// |
// Extension |
// |
@@ -858,7 +958,7 @@ |
// Read the file browser action |default_icon| (optional). |
if (file_browser_handler->HasKey(keys::kPageActionDefaultIcon)) { |
if (!file_browser_handler->GetString( |
- keys::kPageActionDefaultIcon,&default_icon) || |
+ keys::kPageActionDefaultIcon, &default_icon) || |
default_icon.empty()) { |
*error = ASCIIToUTF16(errors::kInvalidPageActionIconPath); |
return NULL; |
@@ -1162,7 +1262,7 @@ |
!one_service->GetList(keys::kIntentType, &mime_types) || |
mime_types->GetSize() == 0) { |
*error = ExtensionErrorUtils::FormatErrorMessageUTF16( |
- errors::kInvalidIntentType,*iter); |
+ errors::kInvalidIntentType, *iter); |
return false; |
} |
@@ -1177,7 +1277,7 @@ |
if (!service_url.is_valid() || |
!(web_extent().MatchesURL(service_url))) { |
*error = ExtensionErrorUtils::FormatErrorMessageUTF16( |
- errors::kInvalidIntentPageInHostedApp,*iter); |
+ errors::kInvalidIntentPageInHostedApp, *iter); |
return false; |
} |
service.service_url = service_url; |
@@ -1185,7 +1285,7 @@ |
// We do not allow absolute intent URLs in non-hosted apps. |
if (GURL(value).is_valid()) { |
*error =ExtensionErrorUtils::FormatErrorMessageUTF16( |
- errors::kCannotAccessPage,value.c_str()); |
+ errors::kCannotAccessPage, value.c_str()); |
return false; |
} |
service.service_url = GetResourceURL(value); |
@@ -1719,6 +1819,35 @@ |
manifest->GetBoolean(keys::kConvertedFromUserScript, |
&converted_from_user_script_); |
+ // Initialize commands (if present). |
+ if (manifest->HasKey(keys::kCommands)) { |
+ DictionaryValue* commands = NULL; |
+ if (!manifest->GetDictionary(keys::kCommands, &commands)) { |
+ *error = ASCIIToUTF16(errors::kInvalidCommandsKey); |
+ return false; |
+ } |
+ |
+ int command_index = 0; |
+ for (DictionaryValue::key_iterator iter = commands->begin_keys(); |
+ iter != commands->end_keys(); ++iter) { |
+ ++command_index; |
+ |
+ DictionaryValue* command = NULL; |
+ if (!commands->GetDictionary(*iter, &command)) { |
+ *error = ExtensionErrorUtils::FormatErrorMessageUTF16( |
+ errors::kInvalidKeyBindingDictionary, |
+ base::IntToString(command_index)); |
+ return false; |
+ } |
+ |
+ ExtensionKeybinding binding; |
+ if (!binding.Parse(command, *iter, error, command_index)) |
+ return false; // |error| already set. |
+ |
+ commands_.push_back(binding); |
+ } |
+ } |
+ |
// Initialize icons (if present). |
if (manifest->HasKey(keys::kIcons)) { |
DictionaryValue* icons_value = NULL; |
@@ -2882,7 +3011,7 @@ |
bool supports_type = false; |
switch (GetType()) { |
- case TYPE_USER_SCRIPT: // Pass through. |
+ case TYPE_USER_SCRIPT: // Pass through. |
case TYPE_EXTENSION: |
supports_type = permission->supports_extensions(); |
break; |
@@ -3038,7 +3167,6 @@ |
// their positions should sync. |
return location_ == Extension::INTERNAL || |
ShouldDisplayInLauncher(); |
- |
} |
bool Extension::ShouldDisplayInLauncher() const { |