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

Side by Side Diff: chrome/browser/resources/md_bookmarks/command_manager.js

Issue 2939873004: MD Bookmarks: Fix issue where keyboard shortcuts could fire incorrectly (Closed)
Patch Set: Fix mac test? Created 3 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
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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 /** 5 /**
6 * @fileoverview Element which shows context menus and handles keyboard 6 * @fileoverview Element which shows context menus and handles keyboard
7 * shortcuts. 7 * shortcuts.
8 */ 8 */
9 cr.define('bookmarks', function() { 9 cr.define('bookmarks', function() {
10 10
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 /** @private {function()} */ 55 /** @private {function()} */
56 this.boundOnCommandUndo_ = function() { 56 this.boundOnCommandUndo_ = function() {
57 this.handle(Command.UNDO, new Set()); 57 this.handle(Command.UNDO, new Set());
58 }.bind(this); 58 }.bind(this);
59 document.addEventListener('command-undo', this.boundOnCommandUndo_); 59 document.addEventListener('command-undo', this.boundOnCommandUndo_);
60 60
61 /** @private {function(!Event)} */ 61 /** @private {function(!Event)} */
62 this.boundOnKeydown_ = this.onKeydown_.bind(this); 62 this.boundOnKeydown_ = this.onKeydown_.bind(this);
63 document.addEventListener('keydown', this.boundOnKeydown_); 63 document.addEventListener('keydown', this.boundOnKeydown_);
64 64
65 /** @private {Object<Command, string>} */ 65 /** @private {Object<Command, cr.ui.KeyboardShortcutList>} */
66 this.shortcuts_ = {}; 66 this.shortcuts_ = {};
67 this.shortcuts_[Command.EDIT] = cr.isMac ? 'enter' : 'f2'; 67
68 this.shortcuts_[Command.COPY] = cr.isMac ? 'meta+c' : 'ctrl+c'; 68 this.addShortcut_(Command.EDIT, 'F2', 'Enter');
69 this.shortcuts_[Command.DELETE] = 69 this.addShortcut_(Command.COPY, 'Ctrl|c', 'Meta|c');
70 cr.isMac ? 'delete backspace' : 'delete'; 70 this.addShortcut_(Command.DELETE, 'Delete', 'Delete Backspace');
71 this.shortcuts_[Command.OPEN_NEW_TAB] = 71
72 cr.isMac ? 'meta+enter' : 'ctrl+enter'; 72 this.addShortcut_(Command.OPEN, 'Enter', 'Meta|ArrowDown Meta|o');
73 this.shortcuts_[Command.OPEN_NEW_WINDOW] = 'shift+enter'; 73 this.addShortcut_(Command.OPEN_NEW_TAB, 'Ctrl|Enter', 'Meta|Enter');
74 this.shortcuts_[Command.OPEN] = cr.isMac ? 'meta+down' : 'enter'; 74 this.addShortcut_(Command.OPEN_NEW_WINDOW, 'Shift|Enter');
75 this.shortcuts_[Command.UNDO] = cr.isMac ? 'meta+z' : 'ctrl+z'; 75
76 this.shortcuts_[Command.REDO] = 76 this.addShortcut_(Command.UNDO, 'Ctrl|z', 'Meta|z');
77 cr.isMac ? 'meta+shift+z' : 'ctrl+y ctrl+shift+z'; 77 this.addShortcut_(Command.REDO, 'Ctrl|y Ctrl|Shift|Z', 'Meta|Shift|Z');
78 }, 78 },
79 79
80 detached: function() { 80 detached: function() {
81 CommandManager.instance_ = null; 81 CommandManager.instance_ = null;
82 document.removeEventListener('open-item-menu', this.boundOnOpenItemMenu_); 82 document.removeEventListener('open-item-menu', this.boundOnOpenItemMenu_);
83 document.removeEventListener('command-undo', this.boundOnCommandUndo_); 83 document.removeEventListener('command-undo', this.boundOnCommandUndo_);
84 document.removeEventListener('keydown', this.boundOnKeydown_); 84 document.removeEventListener('keydown', this.boundOnKeydown_);
85 }, 85 },
86 86
87 /** 87 /**
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 default: 182 default:
183 return true; 183 return true;
184 } 184 }
185 }, 185 },
186 186
187 /** 187 /**
188 * @param {Command} command 188 * @param {Command} command
189 * @param {!Set<string>} itemIds 189 * @param {!Set<string>} itemIds
190 */ 190 */
191 handle: function(command, itemIds) { 191 handle: function(command, itemIds) {
192 var state = this.getState();
192 switch (command) { 193 switch (command) {
193 case Command.EDIT: 194 case Command.EDIT:
194 var id = Array.from(itemIds)[0]; 195 var id = Array.from(itemIds)[0];
195 /** @type {!BookmarksEditDialogElement} */ (this.$.editDialog.get()) 196 /** @type {!BookmarksEditDialogElement} */ (this.$.editDialog.get())
196 .showEditDialog(this.getState().nodes[id]); 197 .showEditDialog(state.nodes[id]);
197 break; 198 break;
198 case Command.COPY: 199 case Command.COPY:
199 var idList = Array.from(itemIds); 200 var idList = Array.from(itemIds);
200 chrome.bookmarkManagerPrivate.copy(idList, function() { 201 chrome.bookmarkManagerPrivate.copy(idList, function() {
201 bookmarks.ToastManager.getInstance().show( 202 bookmarks.ToastManager.getInstance().show(
202 loadTimeData.getString('toastUrlCopied'), false); 203 loadTimeData.getString('toastUrlCopied'), false);
203 }); 204 });
204 break; 205 break;
205 case Command.DELETE: 206 case Command.DELETE:
206 var idList = Array.from(this.minimizeDeletionSet_(itemIds)); 207 var idList = Array.from(this.minimizeDeletionSet_(itemIds));
207 var title = this.getState().nodes[idList[0]].title; 208 var title = state.nodes[idList[0]].title;
208 var labelPromise = cr.sendWithPromise( 209 var labelPromise = cr.sendWithPromise(
209 'getPluralString', 'toastItemsDeleted', idList.length); 210 'getPluralString', 'toastItemsDeleted', idList.length);
210 chrome.bookmarkManagerPrivate.removeTrees(idList, function() { 211 chrome.bookmarkManagerPrivate.removeTrees(idList, function() {
211 labelPromise.then(function(label) { 212 labelPromise.then(function(label) {
212 var pieces = loadTimeData.getSubstitutedStringPieces(label, title) 213 var pieces = loadTimeData.getSubstitutedStringPieces(label, title)
213 .map(function(p) { 214 .map(function(p) {
214 // Make the bookmark name collapsible. 215 // Make the bookmark name collapsible.
215 p.collapsible = !!p.arg; 216 p.collapsible = !!p.arg;
216 return p; 217 return p;
217 }); 218 });
(...skipping 14 matching lines...) Expand all
232 case Command.OPEN_INCOGNITO: 233 case Command.OPEN_INCOGNITO:
233 this.openUrls_(this.expandUrls_(itemIds), command); 234 this.openUrls_(this.expandUrls_(itemIds), command);
234 break; 235 break;
235 case Command.OPEN: 236 case Command.OPEN:
236 var isFolder = itemIds.size == 1 && 237 var isFolder = itemIds.size == 1 &&
237 this.containsMatchingNode_(itemIds, function(node) { 238 this.containsMatchingNode_(itemIds, function(node) {
238 return !node.url; 239 return !node.url;
239 }); 240 });
240 if (isFolder) { 241 if (isFolder) {
241 var folderId = Array.from(itemIds)[0]; 242 var folderId = Array.from(itemIds)[0];
242 this.dispatch(bookmarks.actions.selectFolder( 243 this.dispatch(
243 folderId, this.getState().nodes)); 244 bookmarks.actions.selectFolder(folderId, state.nodes));
244 } else { 245 } else {
245 this.openUrls_(this.expandUrls_(itemIds), command); 246 this.openUrls_(this.expandUrls_(itemIds), command);
246 } 247 }
247 break; 248 break;
248 default: 249 default:
249 assert(false); 250 assert(false);
250 } 251 }
251 }, 252 },
252 253
253 /** 254 /**
254 * @param {Event} e 255 * @param {!Event} e
255 * @param {!Set<string>} itemIds 256 * @param {!Set<string>} itemIds
256 * @return {boolean} True if the event was handled, triggering a keyboard 257 * @return {boolean} True if the event was handled, triggering a keyboard
257 * shortcut. 258 * shortcut.
258 */ 259 */
259 handleKeyEvent: function(e, itemIds) { 260 handleKeyEvent: function(e, itemIds) {
260 for (var commandName in this.shortcuts_) { 261 for (var commandName in this.shortcuts_) {
261 var shortcut = this.shortcuts_[commandName]; 262 var shortcut = this.shortcuts_[commandName];
262 if (Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys( 263 if (shortcut.matchesEvent(e) && this.canExecute(commandName, itemIds)) {
263 e, shortcut) &&
264 this.canExecute(commandName, itemIds)) {
265 this.handle(commandName, itemIds); 264 this.handle(commandName, itemIds);
266 265
267 e.stopPropagation(); 266 e.stopPropagation();
268 e.preventDefault(); 267 e.preventDefault();
269 return true; 268 return true;
270 } 269 }
271 } 270 }
272 271
273 return false; 272 return false;
274 }, 273 },
275 274
276 //////////////////////////////////////////////////////////////////////////// 275 ////////////////////////////////////////////////////////////////////////////
277 // Private functions: 276 // Private functions:
278 277
279 /** 278 /**
279 * Register a keyboard shortcut for a command.
280 * @param {Command} command Command that the shortcut will trigger.
281 * @param {string} shortcut Keyboard shortcut, using the syntax of
282 * cr/ui/command.js.
283 * @param {string=} macShortcut If set, enables a replacement shortcut for
284 * Mac.
285 */
286 addShortcut_: function(command, shortcut, macShortcut) {
287 var shortcut = (cr.isMac && macShortcut) ? macShortcut : shortcut;
288 this.shortcuts_[command] = new cr.ui.KeyboardShortcutList(shortcut);
289 },
290
291 /**
280 * Minimize the set of |itemIds| by removing any node which has an ancestor 292 * Minimize the set of |itemIds| by removing any node which has an ancestor
281 * node already in the set. This ensures that instead of trying to delete 293 * node already in the set. This ensures that instead of trying to delete
282 * both a node and its descendant, we will only try to delete the topmost 294 * both a node and its descendant, we will only try to delete the topmost
283 * node, preventing an error in the bookmarkManagerPrivate.removeTrees API 295 * node, preventing an error in the bookmarkManagerPrivate.removeTrees API
284 * call. 296 * call.
285 * @param {!Set<string>} itemIds 297 * @param {!Set<string>} itemIds
286 * @return {!Set<string>} 298 * @return {!Set<string>}
287 */ 299 */
288 minimizeDeletionSet_: function(itemIds) { 300 minimizeDeletionSet_: function(itemIds) {
289 var minimizedSet = new Set(); 301 var minimizedSet = new Set();
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 494
483 /** @return {!bookmarks.CommandManager} */ 495 /** @return {!bookmarks.CommandManager} */
484 CommandManager.getInstance = function() { 496 CommandManager.getInstance = function() {
485 return assert(CommandManager.instance_); 497 return assert(CommandManager.instance_);
486 }; 498 };
487 499
488 return { 500 return {
489 CommandManager: CommandManager, 501 CommandManager: CommandManager,
490 }; 502 };
491 }); 503 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698