Chromium Code Reviews| Index: chrome/browser/resources/md_bookmarks/command_manager.js |
| diff --git a/chrome/browser/resources/md_bookmarks/command_manager.js b/chrome/browser/resources/md_bookmarks/command_manager.js |
| index a21c9c471868ec0e2bdcb6484d27bb132b9670f8..6e9565b8ae30c7e6017619bdd0a23d14df25d646 100644 |
| --- a/chrome/browser/resources/md_bookmarks/command_manager.js |
| +++ b/chrome/browser/resources/md_bookmarks/command_manager.js |
| @@ -10,6 +10,22 @@ Polymer({ |
| ], |
| properties: { |
| + /** @private {!Array<Command>} */ |
| + menuCommands_: { |
| + type: Array, |
| + value: function() { |
| + return [ |
| + Command.EDIT, |
| + Command.COPY, |
| + Command.DELETE, |
| + // <hr> |
| + Command.OPEN_NEW_TAB, |
| + Command.OPEN_NEW_WINDOW, |
| + Command.OPEN_INCOGNITO, |
| + ]; |
| + }, |
| + }, |
| + |
| /** @type {Set<string>} */ |
| menuIds_: Object, |
| }, |
| @@ -28,6 +44,9 @@ Polymer({ |
| this.shortcuts_[Command.EDIT] = cr.isMac ? 'enter' : 'f2'; |
| this.shortcuts_[Command.COPY] = cr.isMac ? 'meta+c' : 'ctrl+c'; |
| this.shortcuts_[Command.DELETE] = cr.isMac ? 'delete backspace' : 'delete'; |
| + this.shortcuts_[Command.OPEN_NEW_TAB] = |
| + cr.isMac ? 'meta+enter' : 'ctrl+enter'; |
| + this.shortcuts_[Command.OPEN_NEW_WINDOW] = 'shift+enter'; |
| }, |
| detached: function() { |
| @@ -65,11 +84,25 @@ Polymer({ |
| // Command handlers: |
| /** |
| + * Determine if the |command| can be executed with the given |itemIds|. |
| + * Commands which appear in the context menu should be implemented separately |
| + * using `isCommandVisible_` and `isCommandEnabled_`. |
| * @param {Command} command |
| * @param {!Set<string>} itemIds |
| * @return {boolean} |
| */ |
| canExecute: function(command, itemIds) { |
| + return this.isCommandVisible_(command, itemIds) && |
| + this.isCommandEnabled_(command, itemIds); |
| + }, |
| + |
| + /** |
| + * @param {Command} command |
| + * @param {!Set<string>} itemIds |
| + * @return {boolean} True if the command should be visible in the context |
| + * menu. |
| + */ |
| + isCommandVisible_: function(command, itemIds) { |
| switch (command) { |
| case Command.EDIT: |
| return itemIds.size == 1; |
| @@ -79,12 +112,32 @@ Polymer({ |
| return !!node.url; |
| }); |
| case Command.DELETE: |
| + case Command.OPEN_NEW_TAB: |
| + case Command.OPEN_NEW_WINDOW: |
| + case Command.OPEN_INCOGNITO: |
| return itemIds.size > 0; |
| default: |
| return false; |
| } |
| }, |
| + /** |
| + * @param {Command} command |
| + * @param {!Set<string>} itemIds |
| + * @return {boolean} True if the command should be clickable in the context |
| + * menu. |
| + */ |
| + isCommandEnabled_: function(command, itemIds) { |
| + switch (command) { |
| + case Command.OPEN_NEW_TAB: |
| + case Command.OPEN_NEW_WINDOW: |
| + case Command.OPEN_INCOGNITO: |
| + return this.expandUrls_(itemIds).length > 0; |
| + default: |
| + return true; |
| + } |
| + }, |
| + |
| /** |
| * @param {Command} command |
| * @param {!Set<string>} itemIds |
| @@ -108,6 +161,11 @@ Polymer({ |
| // TODO(jiaxi): Add toast later. |
| }); |
| break; |
| + case Command.OPEN_NEW_TAB: |
| + case Command.OPEN_NEW_WINDOW: |
| + case Command.OPEN_INCOGNITO: |
| + this.openUrls_(this.expandUrls_(itemIds), command); |
| + break; |
| } |
| }, |
| @@ -137,6 +195,56 @@ Polymer({ |
| return minimizedSet; |
| }, |
| + /** |
| + * @param {!Array<string>} urls |
| + * @param {Command} command |
| + * @private |
| + */ |
| + openUrls_: function(urls, command) { |
| + assert( |
| + command == Command.OPEN_NEW_TAB || command == Command.OPEN_NEW_WINDOW || |
| + command == Command.OPEN_INCOGNITO); |
| + |
| + if (urls.length == 0) |
| + return; |
| + |
| + var incognito = command == Command.OPEN_INCOGNITO; |
| + if (command == Command.OPEN_NEW_WINDOW || incognito) { |
| + chrome.windows.create({url: urls, incognito: incognito}); |
| + } else { |
| + urls.forEach(function(url) { |
| + chrome.tabs.create({url: url, active: false}); |
| + }); |
| + } |
| + }, |
| + |
| + /** |
| + * Returns all URLs in the given set of nodes and their immediate children. |
| + * Note that these will be ordered by insertion order into the |itemIds| set. |
|
calamity
2017/05/12 03:22:52
Mention that this assumes itemIds are all at the s
tsergeant
2017/05/12 05:15:27
As discussed, it doesn't assume that, but I've exp
|
| + * @param {!Set<string>} itemIds |
| + * @return {!Array<string>} |
| + * @private |
| + */ |
| + expandUrls_: function(itemIds) { |
| + var urls = []; |
| + var nodes = this.getState().nodes; |
| + |
| + itemIds.forEach(function(id) { |
| + var node = nodes[id]; |
| + if (node.url) { |
| + urls.push(node.url); |
| + } else { |
| + node.children.forEach(function(childId) { |
| + var childNode = nodes[childId]; |
| + if (childNode.url) |
| + urls.push(childNode.url); |
| + }); |
| + } |
| + }); |
| + |
| + return urls; |
| + }, |
| + |
| /** |
| * @param {!Set<string>} itemIds |
| * @param {function(BookmarkNode):boolean} predicate |
| @@ -207,14 +315,52 @@ Polymer({ |
| this.$.dropdown.close(); |
| }, |
| - /** @private */ |
| - getEditActionLabel_: function() { |
| - if (this.menuIds_.size > 1) |
| - return; |
| + /** |
| + * @param {Command} command |
| + * @return {string} |
| + * @private |
| + */ |
| + getCommandLabel_: function(command) { |
| + var multipleNodes = this.menuIds_.size > 1 || |
| + this.containsMatchingNode_(this.menuIds_, function(node) { |
| + return !node.url; |
| + }); |
| + var label; |
| + switch (command) { |
| + case Command.EDIT: |
| + if (this.menuIds_.size > 1) |
| + return ''; |
| + |
| + var id = Array.from(this.menuIds_)[0]; |
| + var itemUrl = this.getState().nodes[id].url; |
| + label = itemUrl ? 'menuEdit' : 'menuRename'; |
| + break; |
| + case Command.COPY: |
| + label = 'menuCopyURL'; |
| + break; |
| + case Command.DELETE: |
| + label = 'menuDelete'; |
| + break; |
| + case Command.OPEN_NEW_TAB: |
| + label = multipleNodes ? 'menuOpenAllNewTab' : 'menuOpenNewTab'; |
| + break; |
| + case Command.OPEN_NEW_WINDOW: |
| + label = multipleNodes ? 'menuOpenAllNewWindow' : 'menuOpenNewWindow'; |
| + break; |
| + case Command.OPEN_INCOGNITO: |
| + label = multipleNodes ? 'menuOpenAllIncognito' : 'menuOpenIncognito'; |
| + break; |
| + } |
| + |
| + return loadTimeData.getString(assert(label)); |
| + }, |
| - var id = Array.from(this.menuIds_)[0]; |
| - var itemUrl = this.getState().nodes[id].url; |
| - var label = itemUrl ? 'menuEdit' : 'menuRename'; |
| - return loadTimeData.getString(label); |
| + /** |
| + * @param {Command} command |
| + * @return {boolean} |
| + * @private |
| + */ |
| + showDividerAfter_: function(command) { |
| + return command == Command.DELETE; |
| }, |
| }); |