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

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

Issue 2962283002: MD Bookmarks: Add 'show in folder' command to search result context menu (Closed)
Patch Set: Add MenuSource to CommandManager. Created 3 years, 5 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
« no previous file with comments | « no previous file | chrome/browser/resources/md_bookmarks/constants.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
11 var CommandManager = Polymer({ 11 var CommandManager = Polymer({
12 is: 'bookmarks-command-manager', 12 is: 'bookmarks-command-manager',
13 13
14 behaviors: [ 14 behaviors: [
15 bookmarks.StoreClient, 15 bookmarks.StoreClient,
16 ], 16 ],
17 17
18 properties: { 18 properties: {
19 /** @private {!Array<Command>} */ 19 /** @private {!Array<Command>} */
20 menuCommands_: { 20 menuCommands_: {
21 type: Array, 21 type: Array,
22 value: function() { 22 value: function() {
23 return [ 23 return [
24 Command.EDIT, 24 Command.EDIT,
25 Command.COPY_URL, 25 Command.COPY_URL,
26 Command.SHOW_IN_FOLDER,
26 Command.DELETE, 27 Command.DELETE,
27 // <hr> 28 // <hr>
28 Command.OPEN_NEW_TAB, 29 Command.OPEN_NEW_TAB,
29 Command.OPEN_NEW_WINDOW, 30 Command.OPEN_NEW_WINDOW,
30 Command.OPEN_INCOGNITO, 31 Command.OPEN_INCOGNITO,
31 ]; 32 ];
32 }, 33 },
33 }, 34 },
34 35
35 /** @private {Set<string>} */ 36 /** @private {Set<string>} */
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 /** @private {function()} */ 68 /** @private {function()} */
68 this.boundOnCommandUndo_ = function() { 69 this.boundOnCommandUndo_ = function() {
69 this.handle(Command.UNDO, new Set()); 70 this.handle(Command.UNDO, new Set());
70 }.bind(this); 71 }.bind(this);
71 document.addEventListener('command-undo', this.boundOnCommandUndo_); 72 document.addEventListener('command-undo', this.boundOnCommandUndo_);
72 73
73 /** @private {function(!Event)} */ 74 /** @private {function(!Event)} */
74 this.boundOnKeydown_ = this.onKeydown_.bind(this); 75 this.boundOnKeydown_ = this.onKeydown_.bind(this);
75 document.addEventListener('keydown', this.boundOnKeydown_); 76 document.addEventListener('keydown', this.boundOnKeydown_);
76 77
78 /**
79 * Indicates where the context menu was opened from. Will be NONE if
80 * menu is not open, indicating that commands are from keyboard shortcuts
81 * or elsewhere in the UI.
82 * @private {MenuSource}
83 */
84 this.menuSource_ = MenuSource.NONE;
85
77 /** @private {Object<Command, cr.ui.KeyboardShortcutList>} */ 86 /** @private {Object<Command, cr.ui.KeyboardShortcutList>} */
78 this.shortcuts_ = {}; 87 this.shortcuts_ = {};
79 88
80 this.addShortcut_(Command.EDIT, 'F2', 'Enter'); 89 this.addShortcut_(Command.EDIT, 'F2', 'Enter');
81 this.addShortcut_(Command.DELETE, 'Delete', 'Delete Backspace'); 90 this.addShortcut_(Command.DELETE, 'Delete', 'Delete Backspace');
82 91
83 this.addShortcut_(Command.OPEN, 'Enter', 'Meta|ArrowDown Meta|o'); 92 this.addShortcut_(Command.OPEN, 'Enter', 'Meta|ArrowDown Meta|o');
84 this.addShortcut_(Command.OPEN_NEW_TAB, 'Ctrl|Enter', 'Meta|Enter'); 93 this.addShortcut_(Command.OPEN_NEW_TAB, 'Ctrl|Enter', 'Meta|Enter');
85 this.addShortcut_(Command.OPEN_NEW_WINDOW, 'Shift|Enter'); 94 this.addShortcut_(Command.OPEN_NEW_WINDOW, 'Shift|Enter');
86 95
(...skipping 14 matching lines...) Expand all
101 document.removeEventListener('command-undo', this.boundOnCommandUndo_); 110 document.removeEventListener('command-undo', this.boundOnCommandUndo_);
102 document.removeEventListener('keydown', this.boundOnKeydown_); 111 document.removeEventListener('keydown', this.boundOnKeydown_);
103 }, 112 },
104 113
105 /** 114 /**
106 * Display the command context menu at (|x|, |y|) in window co-ordinates. 115 * Display the command context menu at (|x|, |y|) in window co-ordinates.
107 * Commands will execute on |items| if given, or on the currently selected 116 * Commands will execute on |items| if given, or on the currently selected
108 * items. 117 * items.
109 * @param {number} x 118 * @param {number} x
110 * @param {number} y 119 * @param {number} y
120 * @param {MenuSource} source
111 * @param {Set<string>=} items 121 * @param {Set<string>=} items
112 */ 122 */
113 openCommandMenuAtPosition: function(x, y, items) { 123 openCommandMenuAtPosition: function(x, y, source, items) {
124 this.menuSource_ = source;
114 this.menuIds_ = items || this.getState().selection.items; 125 this.menuIds_ = items || this.getState().selection.items;
115 126
116 var dropdown = 127 var dropdown =
117 /** @type {!CrActionMenuElement} */ (this.$.dropdown.get()); 128 /** @type {!CrActionMenuElement} */ (this.$.dropdown.get());
118 // Ensure that the menu is fully rendered before trying to position it. 129 // Ensure that the menu is fully rendered before trying to position it.
119 Polymer.dom.flush(); 130 Polymer.dom.flush();
120 bookmarks.DialogFocusManager.getInstance().showDialog( 131 bookmarks.DialogFocusManager.getInstance().showDialog(
121 dropdown, function() { 132 dropdown, function() {
122 dropdown.showAtPosition({top: y, left: x}); 133 dropdown.showAtPosition({top: y, left: x});
123 }); 134 });
124 }, 135 },
125 136
126 /** 137 /**
127 * Display the command context menu positioned to cover the |target| 138 * Display the command context menu positioned to cover the |target|
128 * element. Commands will execute on the currently selected items. 139 * element. Commands will execute on the currently selected items.
129 * @param {!Element} target 140 * @param {!Element} target
141 * @param {MenuSource} source
130 */ 142 */
131 openCommandMenuAtElement: function(target) { 143 openCommandMenuAtElement: function(target, source) {
144 this.menuSource_ = source;
132 this.menuIds_ = this.getState().selection.items; 145 this.menuIds_ = this.getState().selection.items;
133 146
134 var dropdown = 147 var dropdown =
135 /** @type {!CrActionMenuElement} */ (this.$.dropdown.get()); 148 /** @type {!CrActionMenuElement} */ (this.$.dropdown.get());
136 // Ensure that the menu is fully rendered before trying to position it. 149 // Ensure that the menu is fully rendered before trying to position it.
137 Polymer.dom.flush(); 150 Polymer.dom.flush();
138 bookmarks.DialogFocusManager.getInstance().showDialog( 151 bookmarks.DialogFocusManager.getInstance().showDialog(
139 dropdown, function() { 152 dropdown, function() {
140 dropdown.showAt(target); 153 dropdown.showAt(target);
141 }); 154 });
142 }, 155 },
143 156
144 closeCommandMenu: function() { 157 closeCommandMenu: function() {
145 this.menuIds_ = new Set(); 158 this.menuIds_ = new Set();
159 this.menuSource_ = MenuSource.NONE;
146 /** @type {!CrActionMenuElement} */ (this.$.dropdown.get()).close(); 160 /** @type {!CrActionMenuElement} */ (this.$.dropdown.get()).close();
147 }, 161 },
148 162
149 //////////////////////////////////////////////////////////////////////////// 163 ////////////////////////////////////////////////////////////////////////////
150 // Command handlers: 164 // Command handlers:
151 165
152 /** 166 /**
153 * Determine if the |command| can be executed with the given |itemIds|. 167 * Determine if the |command| can be executed with the given |itemIds|.
154 * Commands which appear in the context menu should be implemented 168 * Commands which appear in the context menu should be implemented
155 * separately using `isCommandVisible_` and `isCommandEnabled_`. 169 * separately using `isCommandVisible_` and `isCommandEnabled_`.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 * menu. 205 * menu.
192 */ 206 */
193 isCommandVisible_: function(command, itemIds) { 207 isCommandVisible_: function(command, itemIds) {
194 switch (command) { 208 switch (command) {
195 case Command.EDIT: 209 case Command.EDIT:
196 return itemIds.size == 1 && this.globalCanEdit_; 210 return itemIds.size == 1 && this.globalCanEdit_;
197 case Command.COPY_URL: 211 case Command.COPY_URL:
198 return this.isSingleBookmark_(itemIds); 212 return this.isSingleBookmark_(itemIds);
199 case Command.DELETE: 213 case Command.DELETE:
200 return itemIds.size > 0 && this.globalCanEdit_; 214 return itemIds.size > 0 && this.globalCanEdit_;
215 case Command.SHOW_IN_FOLDER:
216 return this.menuSource_ == MenuSource.LIST && itemIds.size == 1 &&
217 this.getState().search.term != '' &&
218 !this.containsMatchingNode_(itemIds, function(node) {
219 return !node.parentId || node.parentId == ROOT_NODE_ID;
220 });
201 case Command.OPEN_NEW_TAB: 221 case Command.OPEN_NEW_TAB:
202 case Command.OPEN_NEW_WINDOW: 222 case Command.OPEN_NEW_WINDOW:
203 case Command.OPEN_INCOGNITO: 223 case Command.OPEN_INCOGNITO:
204 return itemIds.size > 0; 224 return itemIds.size > 0;
205 default: 225 default:
206 return false; 226 return false;
207 } 227 }
208 }, 228 },
209 229
210 /** 230 /**
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 Promise.resolve(loadTimeData.getString('toastUrlCopied')); 275 Promise.resolve(loadTimeData.getString('toastUrlCopied'));
256 } else { 276 } else {
257 labelPromise = cr.sendWithPromise( 277 labelPromise = cr.sendWithPromise(
258 'getPluralString', 'toastItemsCopied', idList.length); 278 'getPluralString', 'toastItemsCopied', idList.length);
259 } 279 }
260 280
261 this.showTitleToast_( 281 this.showTitleToast_(
262 labelPromise, state.nodes[idList[0]].title, false); 282 labelPromise, state.nodes[idList[0]].title, false);
263 }.bind(this)); 283 }.bind(this));
264 break; 284 break;
285 case Command.SHOW_IN_FOLDER:
286 var id = Array.from(itemIds)[0];
287 this.dispatch(bookmarks.actions.selectFolder(
288 assert(state.nodes[id].parentId), state.nodes));
289 break;
265 case Command.DELETE: 290 case Command.DELETE:
266 var idList = Array.from(this.minimizeDeletionSet_(itemIds)); 291 var idList = Array.from(this.minimizeDeletionSet_(itemIds));
267 var title = state.nodes[idList[0]].title; 292 var title = state.nodes[idList[0]].title;
268 var labelPromise = cr.sendWithPromise( 293 var labelPromise = cr.sendWithPromise(
269 'getPluralString', 'toastItemsDeleted', idList.length); 294 'getPluralString', 'toastItemsDeleted', idList.length);
270 chrome.bookmarkManagerPrivate.removeTrees(idList, function() { 295 chrome.bookmarkManagerPrivate.removeTrees(idList, function() {
271 this.showTitleToast_(labelPromise, title, true); 296 this.showTitleToast_(labelPromise, title, true);
272 }.bind(this)); 297 }.bind(this));
273 break; 298 break;
274 case Command.UNDO: 299 case Command.UNDO:
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 var id = Array.from(this.menuIds_)[0]; 520 var id = Array.from(this.menuIds_)[0];
496 var itemUrl = this.getState().nodes[id].url; 521 var itemUrl = this.getState().nodes[id].url;
497 label = itemUrl ? 'menuEdit' : 'menuRename'; 522 label = itemUrl ? 'menuEdit' : 'menuRename';
498 break; 523 break;
499 case Command.COPY_URL: 524 case Command.COPY_URL:
500 label = 'menuCopyURL'; 525 label = 'menuCopyURL';
501 break; 526 break;
502 case Command.DELETE: 527 case Command.DELETE:
503 label = 'menuDelete'; 528 label = 'menuDelete';
504 break; 529 break;
530 case Command.SHOW_IN_FOLDER:
531 label = 'menuShowInFolder';
532 break;
505 case Command.OPEN_NEW_TAB: 533 case Command.OPEN_NEW_TAB:
506 label = multipleNodes ? 'menuOpenAllNewTab' : 'menuOpenNewTab'; 534 label = multipleNodes ? 'menuOpenAllNewTab' : 'menuOpenNewTab';
507 break; 535 break;
508 case Command.OPEN_NEW_WINDOW: 536 case Command.OPEN_NEW_WINDOW:
509 label = multipleNodes ? 'menuOpenAllNewWindow' : 'menuOpenNewWindow'; 537 label = multipleNodes ? 'menuOpenAllNewWindow' : 'menuOpenNewWindow';
510 break; 538 break;
511 case Command.OPEN_INCOGNITO: 539 case Command.OPEN_INCOGNITO:
512 label = multipleNodes ? 'menuOpenAllIncognito' : 'menuOpenIncognito'; 540 label = multipleNodes ? 'menuOpenAllIncognito' : 'menuOpenIncognito';
513 break; 541 break;
514 } 542 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 608
581 //////////////////////////////////////////////////////////////////////////// 609 ////////////////////////////////////////////////////////////////////////////
582 // Event handlers: 610 // Event handlers:
583 611
584 /** 612 /**
585 * @param {Event} e 613 * @param {Event} e
586 * @private 614 * @private
587 */ 615 */
588 onOpenItemMenu_: function(e) { 616 onOpenItemMenu_: function(e) {
589 if (e.detail.targetElement) { 617 if (e.detail.targetElement) {
590 this.openCommandMenuAtElement(e.detail.targetElement); 618 this.openCommandMenuAtElement(e.detail.targetElement, e.detail.source);
591 } else { 619 } else {
592 this.openCommandMenuAtPosition(e.detail.x, e.detail.y); 620 this.openCommandMenuAtPosition(e.detail.x, e.detail.y, e.detail.source);
593 } 621 }
594 }, 622 },
595 623
596 /** 624 /**
597 * @param {Event} e 625 * @param {Event} e
598 * @private 626 * @private
599 */ 627 */
600 onCommandClick_: function(e) { 628 onCommandClick_: function(e) {
601 this.handle( 629 this.handle(
602 e.currentTarget.getAttribute('command'), assert(this.menuIds_)); 630 e.currentTarget.getAttribute('command'), assert(this.menuIds_));
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 672
645 /** @return {!bookmarks.CommandManager} */ 673 /** @return {!bookmarks.CommandManager} */
646 CommandManager.getInstance = function() { 674 CommandManager.getInstance = function() {
647 return assert(CommandManager.instance_); 675 return assert(CommandManager.instance_);
648 }; 676 };
649 677
650 return { 678 return {
651 CommandManager: CommandManager, 679 CommandManager: CommandManager,
652 }; 680 };
653 }); 681 });
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/resources/md_bookmarks/constants.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698