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

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.
Evan Stade 2012/06/06 23:04:45 @type doc for these they should all be member var
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) {
Evan Stade 2012/06/06 23:04:45 doesn't need to be a member function
107 var output = '';
108 if (event.ctrlKey)
109 output = 'Ctrl + ';
110 if (!event.ctrlKey && event.altKey)
111 output += 'Alt + ';
Evan Stade 2012/06/06 23:04:45 indent wrong here and L109
112 if (event.shiftKey)
113 output += 'Shift + ';
114 if (this.validChar_(event.keyCode))
115 output += String.fromCharCode('A'.charCodeAt(0) + event.keyCode - 65);
116 return output;
117 },
118
119 /**
120 * Returns whether the passed in |keyCode| is a valid extension command
121 * char or not. This is restricted to A-Z and 0-9 (ignoring modifiers) at
122 * the moment.
123 * @param {int} keyCode The keycode to consider.
124 * @private
125 */
126 validChar_: function(keyCode) {
Evan Stade 2012/06/06 23:04:45 doesn't need to be a member function
127 return (keyCode >= 'A'.charCodeAt(0) && keyCode <= 'Z'.charCodeAt(0)) ||
128 (keyCode >= '0'.charCodeAt(0) && keyCode <= '9'.charCodeAt(0));
129 },
130
131 /**
132 * Starts keystroke capture to determine which key to use for a particular
133 * extension command.
134 * @param {Event} event The keyboard event to consider.
135 * @private
136 */
137 startCapture_: function(event) {
138 if (capturingElement)
139 return; // Already capturing.
140
141 chrome.send('setShortcutHandlingSuspended', [true]);
142
143 oldValue = event.target.textContent;
144 event.target.textContent =
145 loadTimeData.getString('extensionCommandsStartTyping');
146 event.target.classList.add('capturing');
147
148 capturingElement = event.target;
149 },
150
151 /**
152 * Ends keystroke capture and either restores the old value or (if valid
153 * value) sets the new value as active..
154 * @param {Event} event The keyboard event to consider.
155 * @private
156 */
157 endCapture_: function(event) {
158 if (!capturingElement)
159 return; // Not capturing.
160
161 chrome.send('setShortcutHandlingSuspended', [false]);
162
163 capturingElement.classList.remove('capturing');
164 capturingElement.classList.remove('contains-chars');
165 if (!currentKeyEvent || !this.validChar_(currentKeyEvent.keyCode))
166 capturingElement.textContent = oldValue;
167
168 if (oldValue == '')
169 capturingElement.classList.remove('clearable');
170 else
171 capturingElement.classList.add('clearable');
172
173 oldValue = '';
174 capturingElement = null;
175 currentKeyEvent = null;
176 },
177
178 /**
179 * The KeyDown handler.
180 * @param {Event} event The keyboard event to consider.
181 * @private
182 */
183 handleKeyDown_: function(event) {
184 if (!capturingElement)
185 this.startCapture_(event);
186
187 this.handleKey_(event);
188 },
189
190 /**
191 * The KeyUp handler.
192 * @param {Event} event The keyboard event to consider.
193 * @private
194 */
195 handleKeyUp_: function(event) {
196 // We want to make it easy to change from Ctrl+Shift+ to just Ctrl+ by
197 // releasing Shift, but we also don't want it to be easy to loose for
Evan Stade 2012/06/06 23:04:45 lose
198 // example Ctrl+Shift+F to Ctrl+ just because you didn't release Ctrl
199 // as fast as the other two keys. Therefore, we process KeyUp until you
200 // have a valid combination and then stop processing it (meaning that once
201 // you have a valid combination, we won't change it until the next
202 // KeyDown message arrives).
203 if (!currentKeyEvent || !this.validChar_(currentKeyEvent.keyCode)) {
204 if (!event.ctrlKey && !event.altKey) {
205 // If neither Ctrl nor Alt is pressed then it is not a valid shortcut.
206 // That means we're back at the starting point so we should restart
207 // capture.
208 this.endCapture_(event);
209 this.startCapture_(event);
210 } else {
211 this.handleKey_(event);
212 }
213 }
214 },
215
216 /**
217 * A general key handler (used for both KeyDown and KeyUp).
218 * @param {Event} event The keyboard event to consider.
219 * @private
220 */
221 handleKey_: function(event) {
222 // While capturing, we prevent all events from bubbling, to prevent
223 // shortcuts lacking the right modifier (F3 for example) from activating
224 // and ending capture prematurely.
225 event.preventDefault();
Evan Stade 2012/06/06 23:04:45 I think what you want is stopPropagation (or perha
Finnur 2012/06/07 12:41:02 I've added stopPropagation. I found that stopPropa
226
227 if (!event.ctrlKey && !event.altKey)
228 return; // Ctrl or Alt is a must.
229
230 var keystroke = this.keystrokeToString_(event);
231 event.target.textContent = keystroke;
232 event.target.classList.add('contains-chars');
233
234 if (this.validChar_(event.keyCode)) {
235 oldValue = keystroke; // Forget what the old value was.
236 chrome.send('setExtensionCommandShortcut', ['id', keystroke]);
237 this.endCapture_(event);
238 }
239
240 currentKeyEvent = event;
Finnur 2012/06/06 15:39:51 This needs to happen after endCapture because endC
241 },
73 }; 242 };
74 243
75 return { 244 return {
76 ExtensionCommandList: ExtensionCommandList 245 ExtensionCommandList: ExtensionCommandList
77 }; 246 };
78 }); 247 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698