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

Unified Diff: chrome/common/extensions/extension.cc

Issue 9402018: Experimental Extension Keybinding (first cut). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 10 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 side-by-side diff with in-line comments
Download patch
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 {

Powered by Google App Engine
This is Rietveld 408576698