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

Side by Side Diff: chrome/browser/resources/extensions/extension_command_list.js

Issue 10514003: Config UI for Extension Commands (part 1). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 6 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 cr.define('options', function() { 5 cr.define('options', function() {
6 'use strict'; 6 'use strict';
7 7
8 /** 8 /**
9 * Creates a new list of extension commands. 9 * Creates a new list of extension commands.
10 * @param {Object=} opt_propertyBag Optional properties. 10 * @param {Object=} opt_propertyBag Optional properties.
11 * @constructor 11 * @constructor
12 * @extends {cr.ui.div} 12 * @extends {cr.ui.div}
13 */ 13 */
14 var ExtensionCommandList = cr.ui.define('div'); 14 var ExtensionCommandList = cr.ui.define('div');
15 15
16 /**
17 * While capturing, this records the current (last) keyboard event generated
18 * by the user. Will be |null| after capture and during capture when no
19 * keyboard event has been generated.
20 */
21 var currentKeyEvent = null;
22
23 /**
24 * While capturing, this keeps track of the previous selection so we can
25 * revert back to if no valid assignment is made during capture.
26 */
27 var oldValue = '';
28
29 /**
30 * While capturing, this keeps track of which element the user asked to
31 * change.
32 */
33 var capturingElement = null;
34
16 ExtensionCommandList.prototype = { 35 ExtensionCommandList.prototype = {
17 __proto__: HTMLDivElement.prototype, 36 __proto__: HTMLDivElement.prototype,
18 37
19 /** @inheritDoc */ 38 /** @inheritDoc */
20 decorate: function() { 39 decorate: function() {
21 this.textContent = ''; 40 this.textContent = '';
22 41
23 // Iterate over the extension data and add each item to the list. 42 // Iterate over the extension data and add each item to the list.
24 this.data_.commands.forEach(this.createNodeForExtension_.bind(this)); 43 this.data_.commands.forEach(this.createNodeForExtension_.bind(this));
25 }, 44 },
(...skipping 26 matching lines...) Expand all
52 * @private 71 * @private
53 */ 72 */
54 createNodeForCommand_: function(command) { 73 createNodeForCommand_: function(command) {
55 var template = $('template-collection-extension-commands').querySelector( 74 var template = $('template-collection-extension-commands').querySelector(
56 '.extension-command-list-command-item-wrapper'); 75 '.extension-command-list-command-item-wrapper');
57 var node = template.cloneNode(true); 76 var node = template.cloneNode(true);
58 77
59 var description = node.querySelector('.command-description'); 78 var description = node.querySelector('.command-description');
60 description.textContent = command.description; 79 description.textContent = command.description;
61 80
62 var shortcut = node.querySelector('.command-shortcut'); 81 var command_shortcut = node.querySelector('.command-shortcut');
82 command_shortcut.addEventListener('mouseup',
83 this.startCapture_.bind(this));
84 command_shortcut.addEventListener('blur', this.endCapture_.bind(this));
85 command_shortcut.addEventListener('keydown',
86 this.handleKeyDown_.bind(this));
87 command_shortcut.addEventListener('keyup', this.handleKeyUp_.bind(this));
88
63 if (!command.active) { 89 if (!command.active) {
64 shortcut.textContent = 90 command_shortcut.textContent =
65 loadTimeData.getString('extensionCommandsInactive'); 91 loadTimeData.getString('extensionCommandsInactive');
66 shortcut.classList.add('inactive-keybinding'); 92 command_shortcut.classList.add('inactive-keybinding');
67 } else { 93 } else {
68 shortcut.textContent = command.keybinding; 94 command_shortcut.textContent = command.keybinding;
69 } 95 }
70 96
71 this.appendChild(node); 97 this.appendChild(node);
72 }, 98 },
99
100 /**
101 * Convert a keystroke event to string form, while taking into account
102 * (ignoring) invalid extension commands.
103 * @param {Event} event The keyboard event to convert.
104 * @private
105 */
106 keystrokeToString_: function(event) {
107 var output = '';
108 if (event.ctrlKey)
109 output = 'Ctrl + ';
110 if (!event.ctrlKey) {
111 if (event.altKey)
Evan Stade 2012/06/05 21:25:52 if (!event.ctrlKey && event.altKey)
112 output += 'Alt + ';
113 }
114 if (event.shiftKey)
115 output += 'Shift + ';
116 if (this.validChar_(event.keyCode))
117 output += String.fromCharCode('A'.charCodeAt(0) + event.keyCode - 65);
118 return output;
119 },
120
121 /**
122 * Returns whether the passed in |keyCode| is a valid extension command
123 * char or not. This is restricted to A-Z and 0-9 (ignoring modifiers) at
124 * the moment.
125 * @param {int} keyCode The keycode to consider.
126 * @private
127 */
128 validChar_: function(keyCode) {
129 return (keyCode >= 'A'.charCodeAt(0) && keyCode <= 'Z'.charCodeAt(0)) ||
130 (keyCode >= '0'.charCodeAt(0) && keyCode <= '9'.charCodeAt(0));
131 },
132
133 /**
134 * Starts keystroke capture to determine which key to use for a particular
135 * extension command.
136 * @param {Event} event The keyboard event to consider.
137 * @private
138 */
139 startCapture_: function(event) {
140 if (capturingElement !== null)
Evan Stade 2012/06/05 21:25:52 just if (capturingElement)
141 return; // Already capturing.
142
143 chrome.send('setShortcutHandlingSuspended', [true]);
144
145 oldValue = event.target.textContent;
146 event.target.textContent =
147 loadTimeData.getString('extensionCommandsStartTyping');
148 event.target.classList.add('capturing');
149
150 capturingElement = event.target;
151 },
152
153 /**
154 * Ends keystroke capture and either restores the old value or (if valid
155 * value) sets the new value as active..
156 * @param {Event} event The keyboard event to consider.
157 * @private
158 */
159 endCapture_: function(event) {
160 if (capturingElement === null)
Evan Stade 2012/06/05 21:25:52 ditto
161 return; // Not capturing.
162
163 chrome.send('setShortcutHandlingSuspended', [false]);
164
165 capturingElement.classList.remove('capturing');
166 capturingElement.classList.remove('contains-chars');
167 if (currentKeyEvent == null ||
Evan Stade 2012/06/05 21:25:52 no need to wrap
168 !this.validChar_(currentKeyEvent.keyCode))
169 capturingElement.textContent = oldValue;
170
171 if (oldValue == '')
172 capturingElement.classList.remove('clearable');
173 else
174 capturingElement.classList.add('clearable');
175
176 oldValue = '';
177 capturingElement = null;
178 currentKeyEvent = null;
179 },
180
181 /**
182 * The KeyDown handler.
183 * @param {Event} event The keyboard event to consider.
184 * @private
185 */
186 handleKeyDown_: function(event) {
187 if (capturingElement === null)
Evan Stade 2012/06/05 21:25:52 ditto
188 this.startCapture_(event);
189
190 this.handleKey_(event);
191 },
192
193 /**
194 * The KeyUp handler.
195 * @param {Event} event The keyboard event to consider.
196 * @private
197 */
198 handleKeyUp_: function(event) {
199 // We want to make it easy to change from Ctrl+Shift+ to just Ctrl+ by
200 // releasing Shift, but we also don't want it to be easy to loose for
201 // example Ctrl+Shift+F to Ctrl+ just because you didn't release Ctrl
202 // as fast as the other two keys. Therefore, we process KeyUp until you
203 // have a valid combination and then stop processing it (meaning that once
204 // you have a valid combination, we won't change it until the next
205 // KeyDown message arrives).
206 if (currentKeyEvent === null ||
207 !this.validChar_(currentKeyEvent.keyCode)) {
208 if (!event.ctrlKey && !event.altKey) {
209 // If neither Ctrl nor Alt is pressed then it is not a valid shortcut.
210 // That means we're back at the starting point so we should restart
211 // capture.
212 this.endCapture_(event);
213 this.startCapture_(event);
214 } else {
215 this.handleKey_(event);
216 }
217 }
218 },
219
220 /**
221 * A general key handler (used for both KeyDown and KeyUp).
222 * @param {Event} event The keyboard event to consider.
223 * @private
224 */
Evan Stade 2012/06/05 21:25:52 document return type and meaning
Finnur 2012/06/06 15:39:50 This shouldn't be returning anything. Thanks for r
225 handleKey_: function(event) {
226 // While capturing, we prevent all events from bubbling, to prevent
227 // shortcuts lacking the right modifier (F3 for example) from activating
228 // and ending capture prematurely.
229 event.preventDefault();
230
231 if (!event.ctrlKey && !event.altKey)
232 return true; // Ctrl or Alt is a must.
233
234 var keystroke = this.keystrokeToString_(event);
235 event.target.textContent = keystroke;
236 event.target.classList.add('contains-chars');
237 currentKeyEvent = event;
238
239 if (this.validChar_(event.keyCode)) {
240 oldValue = keystroke; // Forget what the old value was.
241 chrome.send('setExtensionCommandShortcut', ['id', keystroke]);
242 this.endCapture_(event);
243 }
244
245 return false;
246 },
73 }; 247 };
74 248
75 return { 249 return {
76 ExtensionCommandList: ExtensionCommandList 250 ExtensionCommandList: ExtensionCommandList
77 }; 251 };
78 }); 252 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698