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

Side by Side Diff: chrome/common/extensions/extension_commands.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
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/common/extensions/extension_commands.h"
6
7 #include "base/logging.h"
8 #include "base/string_number_conversions.h"
9 #include "base/string_split.h"
10 #include "base/values.h"
11 #include "chrome/common/extensions/extension_error_utils.h"
12 #include "chrome/common/extensions/extension_manifest_constants.h"
13
14 namespace errors = extension_manifest_errors;
15 namespace keys = extension_manifest_keys;
16 namespace values = extension_manifest_values;
17
18 namespace extensions {
19
20 Command::Command() {}
21
22 Command::~Command() {}
23
24 ui::Accelerator Command::ParseImpl(
25 const std::string& shortcut,
26 const std::string& platform_key,
27 int index,
28 string16* error) {
29 if (platform_key != values::kKeybindingPlatformWin &&
30 platform_key != values::kKeybindingPlatformMac &&
31 platform_key != values::kKeybindingPlatformChromeOs &&
32 platform_key != values::kKeybindingPlatformLinux &&
33 platform_key != values::kKeybindingPlatformDefault) {
34 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
35 errors::kInvalidKeyBindingUnknownPlatform,
36 base::IntToString(index),
37 platform_key);
38 return ui::Accelerator();
39 }
40
41 std::vector<std::string> tokens;
42 base::SplitString(shortcut, '+', &tokens);
43 if (tokens.size() < 2 || tokens.size() > 3) {
44 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
45 errors::kInvalidKeyBinding,
46 base::IntToString(index),
47 platform_key,
48 shortcut);
49 return ui::Accelerator();
50 }
51
52 // Now, parse it into an accelerator.
53 bool ctrl = false;
54 bool alt = false;
55 bool shift = false;
56 ui::KeyboardCode key = ui::VKEY_UNKNOWN;
57 for (size_t i = 0; i < tokens.size(); i++) {
58 if (tokens[i] == "Ctrl") {
59 ctrl = true;
60 } else if (tokens[i] == "Alt") {
61 alt = true;
62 } else if (tokens[i] == "Shift") {
63 shift = true;
64 } else if (tokens[i] == "Command" && platform_key == "mac") {
65 // TODO(finnur): Implement for Mac.
66 } else if (tokens[i] == "Option" && platform_key == "mac") {
67 // TODO(finnur): Implement for Mac.
68 } else if (tokens[i].size() == 1 &&
69 tokens[i][0] >= 'A' && tokens[i][0] <= 'Z') {
70 if (key != ui::VKEY_UNKNOWN) {
71 // Multiple key assignments.
72 key = ui::VKEY_UNKNOWN;
73 break;
74 }
75
76 key = static_cast<ui::KeyboardCode>(ui::VKEY_A + (tokens[i][0] - 'A'));
77 } else {
78 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
79 errors::kInvalidKeyBinding,
80 base::IntToString(index),
81 platform_key,
82 shortcut);
83 return ui::Accelerator();
84 }
85 }
86
87 // We support Ctrl+foo, Alt+foo, Ctrl+Shift+foo, Alt+Shift+foo, but not
88 // Ctrl+Alt+foo. For a more detailed reason why we don't support Ctrl+Alt+foo:
89 // http://blogs.msdn.com/b/oldnewthing/archive/2004/03/29/101121.aspx.
90 if (key == ui::VKEY_UNKNOWN || (ctrl && alt)) {
91 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
92 errors::kInvalidKeyBinding,
93 base::IntToString(index),
94 platform_key,
95 shortcut);
96 return ui::Accelerator();
97 }
98
99 return ui::Accelerator(key, shift, ctrl, alt);
100 }
101
102 // static
103 std::string Command::CommandPlatform() {
104 #if defined(OS_WIN)
105 return values::kKeybindingPlatformWin;
106 #elif defined(OS_MACOSX)
107 return values::kKeybindingPlatformMac;
108 #elif defined(OS_CHROMEOS)
109 return values::kKeybindingPlatformChromeOs;
110 #elif defined(OS_LINUX)
111 return values::kKeybindingPlatformLinux;
112 #else
113 return "";
114 #endif
115 }
116
117 bool Command::Parse(DictionaryValue* command,
118 const std::string& command_name,
119 int index,
120 string16* error) {
121 DCHECK(!command_name.empty());
122
123 // We'll build up a map of platform-to-shortcut suggestions.
124 std::map<const std::string, std::string> suggestions;
125
126 // First try to parse the |suggested_key| as a dictionary.
127 DictionaryValue* suggested_key_dict;
128 if (command->GetDictionary(keys::kSuggestedKey, &suggested_key_dict)) {
129 DictionaryValue::key_iterator iter = suggested_key_dict->begin_keys();
130 for ( ; iter != suggested_key_dict->end_keys(); ++iter) {
131 // For each item in the dictionary, extract the platforms specified.
132 std::string suggested_key_string;
133 if (suggested_key_dict->GetString(*iter, &suggested_key_string) &&
134 !suggested_key_string.empty()) {
135 // Found a platform, add it to the suggestions list.
136 suggestions[*iter] = suggested_key_string;
137 } else {
138 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
139 errors::kInvalidKeyBinding,
140 base::IntToString(index),
141 keys::kSuggestedKey,
142 "Missing");
143 return false;
144 }
145 }
146 } else {
147 // No dictionary was found, fall back to using just a string, so developers
148 // don't have to specify a dictionary if they just want to use one default
149 // for all platforms.
150 std::string suggested_key_string;
151 if (command->GetString(keys::kSuggestedKey, &suggested_key_string) &&
152 !suggested_key_string.empty()) {
153 // If only a signle string is provided, it must be default for all.
154 suggestions["default"] = suggested_key_string;
155 } else {
156 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
157 errors::kInvalidKeyBinding,
158 base::IntToString(index),
159 keys::kSuggestedKey,
160 "Missing");
161 return false;
162 }
163 }
164
165 std::string platform = CommandPlatform();
166 std::string key = platform;
167 if (suggestions.find(key) == suggestions.end())
168 key = values::kKeybindingPlatformDefault;
169 if (suggestions.find(key) == suggestions.end()) {
170 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
171 errors::kInvalidKeyBindingMissingPlatform,
172 base::IntToString(index),
173 keys::kSuggestedKey,
174 platform);
175 return false; // No platform specified and no fallback. Bail.
176 }
177
178 // For developer convenience, we parse all the suggestions (and complain about
179 // errors for platforms other than the current one) but use only what we need.
180 std::map<const std::string, std::string>::const_iterator iter =
181 suggestions.begin();
182 for ( ; iter != suggestions.end(); ++iter) {
183 // Note that we pass iter->first to pretend we are on a platform we're not
184 // on.
185 ui::Accelerator accelerator =
186 ParseImpl(iter->second, iter->first, index, error);
187 if (accelerator.key_code() == ui::VKEY_UNKNOWN) {
188 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
189 errors::kInvalidKeyBinding,
190 base::IntToString(index),
191 iter->first,
192 iter->second);
193 return false;
194 }
195
196 if (iter->first == key) {
197 // This platform is our platform, so grab this key.
198 accelerator_ = accelerator;
199 command_name_ = command_name;
200
201 if (command_name !=
202 extension_manifest_values::kPageActionKeybindingEvent &&
203 command_name !=
204 extension_manifest_values::kBrowserActionKeybindingEvent) {
205 if (!command->GetString(keys::kDescription, &description_) ||
206 description_.empty()) {
207 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
208 errors::kInvalidKeyBindingDescription,
209 base::IntToString(index));
210 return false;
211 }
212 }
213 }
214 }
215 return true;
216 }
217
218 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698