Chromium Code Reviews| OLD | NEW |
|---|---|
| 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, | 25 Command.COPY_URL, |
| 26 Command.DELETE, | 26 Command.DELETE, |
| 27 // <hr> | 27 // <hr> |
| 28 Command.OPEN_NEW_TAB, | 28 Command.OPEN_NEW_TAB, |
| 29 Command.OPEN_NEW_WINDOW, | 29 Command.OPEN_NEW_WINDOW, |
| 30 Command.OPEN_INCOGNITO, | 30 Command.OPEN_INCOGNITO, |
| 31 ]; | 31 ]; |
| 32 }, | 32 }, |
| 33 }, | 33 }, |
| 34 | 34 |
| 35 /** @private {Set<string>} */ | 35 /** @private {Set<string>} */ |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 71 document.addEventListener('command-undo', this.boundOnCommandUndo_); | 71 document.addEventListener('command-undo', this.boundOnCommandUndo_); |
| 72 | 72 |
| 73 /** @private {function(!Event)} */ | 73 /** @private {function(!Event)} */ |
| 74 this.boundOnKeydown_ = this.onKeydown_.bind(this); | 74 this.boundOnKeydown_ = this.onKeydown_.bind(this); |
| 75 document.addEventListener('keydown', this.boundOnKeydown_); | 75 document.addEventListener('keydown', this.boundOnKeydown_); |
| 76 | 76 |
| 77 /** @private {Object<Command, cr.ui.KeyboardShortcutList>} */ | 77 /** @private {Object<Command, cr.ui.KeyboardShortcutList>} */ |
| 78 this.shortcuts_ = {}; | 78 this.shortcuts_ = {}; |
| 79 | 79 |
| 80 this.addShortcut_(Command.EDIT, 'F2', 'Enter'); | 80 this.addShortcut_(Command.EDIT, 'F2', 'Enter'); |
| 81 this.addShortcut_(Command.COPY, 'Ctrl|c', 'Meta|c'); | |
| 82 this.addShortcut_(Command.DELETE, 'Delete', 'Delete Backspace'); | 81 this.addShortcut_(Command.DELETE, 'Delete', 'Delete Backspace'); |
| 83 | 82 |
| 84 this.addShortcut_(Command.OPEN, 'Enter', 'Meta|ArrowDown Meta|o'); | 83 this.addShortcut_(Command.OPEN, 'Enter', 'Meta|ArrowDown Meta|o'); |
| 85 this.addShortcut_(Command.OPEN_NEW_TAB, 'Ctrl|Enter', 'Meta|Enter'); | 84 this.addShortcut_(Command.OPEN_NEW_TAB, 'Ctrl|Enter', 'Meta|Enter'); |
| 86 this.addShortcut_(Command.OPEN_NEW_WINDOW, 'Shift|Enter'); | 85 this.addShortcut_(Command.OPEN_NEW_WINDOW, 'Shift|Enter'); |
| 87 | 86 |
| 88 this.addShortcut_(Command.UNDO, 'Ctrl|z', 'Meta|z'); | 87 this.addShortcut_(Command.UNDO, 'Ctrl|z', 'Meta|z'); |
| 89 this.addShortcut_(Command.REDO, 'Ctrl|y Ctrl|Shift|Z', 'Meta|Shift|Z'); | 88 this.addShortcut_(Command.REDO, 'Ctrl|y Ctrl|Shift|Z', 'Meta|Shift|Z'); |
| 90 | 89 |
| 91 this.addShortcut_(Command.SELECT_ALL, 'Ctrl|a', 'Meta|a'); | 90 this.addShortcut_(Command.SELECT_ALL, 'Ctrl|a', 'Meta|a'); |
| 92 this.addShortcut_(Command.DESELECT_ALL, 'Escape'); | 91 this.addShortcut_(Command.DESELECT_ALL, 'Escape'); |
| 92 | |
| 93 this.addShortcut_(Command.CUT, 'Ctrl|x', 'Meta|x'); | |
| 94 this.addShortcut_(Command.COPY, 'Ctrl|c', 'Meta|c'); | |
| 95 this.addShortcut_(Command.PASTE, 'Ctrl|v', 'Meta|v'); | |
| 93 }, | 96 }, |
| 94 | 97 |
| 95 detached: function() { | 98 detached: function() { |
| 96 CommandManager.instance_ = null; | 99 CommandManager.instance_ = null; |
| 97 document.removeEventListener('open-item-menu', this.boundOnOpenItemMenu_); | 100 document.removeEventListener('open-item-menu', this.boundOnOpenItemMenu_); |
| 98 document.removeEventListener('command-undo', this.boundOnCommandUndo_); | 101 document.removeEventListener('command-undo', this.boundOnCommandUndo_); |
| 99 document.removeEventListener('keydown', this.boundOnKeydown_); | 102 document.removeEventListener('keydown', this.boundOnKeydown_); |
| 100 }, | 103 }, |
| 101 | 104 |
| 102 /** | 105 /** |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 140 | 143 |
| 141 /** | 144 /** |
| 142 * Determine if the |command| can be executed with the given |itemIds|. | 145 * Determine if the |command| can be executed with the given |itemIds|. |
| 143 * Commands which appear in the context menu should be implemented | 146 * Commands which appear in the context menu should be implemented |
| 144 * separately using `isCommandVisible_` and `isCommandEnabled_`. | 147 * separately using `isCommandVisible_` and `isCommandEnabled_`. |
| 145 * @param {Command} command | 148 * @param {Command} command |
| 146 * @param {!Set<string>} itemIds | 149 * @param {!Set<string>} itemIds |
| 147 * @return {boolean} | 150 * @return {boolean} |
| 148 */ | 151 */ |
| 149 canExecute: function(command, itemIds) { | 152 canExecute: function(command, itemIds) { |
| 153 var state = this.getState(); | |
| 150 switch (command) { | 154 switch (command) { |
| 151 case Command.OPEN: | 155 case Command.OPEN: |
| 152 return itemIds.size > 0; | 156 return itemIds.size > 0; |
| 153 case Command.UNDO: | 157 case Command.UNDO: |
| 154 case Command.REDO: | 158 case Command.REDO: |
| 155 return this.globalCanEdit_; | 159 return this.globalCanEdit_; |
| 156 case Command.SELECT_ALL: | 160 case Command.SELECT_ALL: |
| 157 case Command.DESELECT_ALL: | 161 case Command.DESELECT_ALL: |
| 158 return true; | 162 return true; |
| 163 case Command.COPY: | |
| 164 return itemIds.size > 0; | |
| 165 case Command.CUT: | |
| 166 return itemIds.size > 0 && | |
| 167 !this.containsMatchingNode_(itemIds, function(node) { | |
| 168 return !bookmarks.util.canEditNode(state, node.id); | |
| 169 }); | |
| 170 case Command.PASTE: | |
| 171 return state.search.term == '' && | |
| 172 bookmarks.util.canReorderChildren(state, state.selectedFolder); | |
| 159 default: | 173 default: |
| 160 return this.isCommandVisible_(command, itemIds) && | 174 return this.isCommandVisible_(command, itemIds) && |
| 161 this.isCommandEnabled_(command, itemIds); | 175 this.isCommandEnabled_(command, itemIds); |
| 162 } | 176 } |
| 163 }, | 177 }, |
| 164 | 178 |
| 165 /** | 179 /** |
| 166 * @param {Command} command | 180 * @param {Command} command |
| 167 * @param {!Set<string>} itemIds | 181 * @param {!Set<string>} itemIds |
| 168 * @return {boolean} True if the command should be visible in the context | 182 * @return {boolean} True if the command should be visible in the context |
| 169 * menu. | 183 * menu. |
| 170 */ | 184 */ |
| 171 isCommandVisible_: function(command, itemIds) { | 185 isCommandVisible_: function(command, itemIds) { |
| 172 switch (command) { | 186 switch (command) { |
| 173 case Command.EDIT: | 187 case Command.EDIT: |
| 174 return itemIds.size == 1 && this.globalCanEdit_; | 188 return itemIds.size == 1 && this.globalCanEdit_; |
| 175 case Command.COPY: | 189 case Command.COPY_URL: |
| 176 return this.isSingleBookmark_(itemIds); | 190 return this.isSingleBookmark_(itemIds); |
| 177 case Command.DELETE: | 191 case Command.DELETE: |
| 178 return itemIds.size > 0 && this.globalCanEdit_; | 192 return itemIds.size > 0 && this.globalCanEdit_; |
| 179 case Command.OPEN_NEW_TAB: | 193 case Command.OPEN_NEW_TAB: |
| 180 case Command.OPEN_NEW_WINDOW: | 194 case Command.OPEN_NEW_WINDOW: |
| 181 case Command.OPEN_INCOGNITO: | 195 case Command.OPEN_INCOGNITO: |
| 182 return itemIds.size > 0; | 196 return itemIds.size > 0; |
| 183 default: | 197 default: |
| 184 return false; | 198 return false; |
| 185 } | 199 } |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 216 * @param {!Set<string>} itemIds | 230 * @param {!Set<string>} itemIds |
| 217 */ | 231 */ |
| 218 handle: function(command, itemIds) { | 232 handle: function(command, itemIds) { |
| 219 var state = this.getState(); | 233 var state = this.getState(); |
| 220 switch (command) { | 234 switch (command) { |
| 221 case Command.EDIT: | 235 case Command.EDIT: |
| 222 var id = Array.from(itemIds)[0]; | 236 var id = Array.from(itemIds)[0]; |
| 223 /** @type {!BookmarksEditDialogElement} */ (this.$.editDialog.get()) | 237 /** @type {!BookmarksEditDialogElement} */ (this.$.editDialog.get()) |
| 224 .showEditDialog(state.nodes[id]); | 238 .showEditDialog(state.nodes[id]); |
| 225 break; | 239 break; |
| 240 case Command.COPY_URL: | |
| 226 case Command.COPY: | 241 case Command.COPY: |
| 227 var idList = Array.from(itemIds); | 242 var idList = Array.from(itemIds); |
| 228 chrome.bookmarkManagerPrivate.copy(idList, function() { | 243 chrome.bookmarkManagerPrivate.copy(idList, function() { |
| 229 bookmarks.ToastManager.getInstance().show( | 244 var labelPromise; |
| 230 loadTimeData.getString('toastUrlCopied'), false); | 245 if (command == Command.COPY_URL) { |
| 231 }); | 246 labelPromise = |
| 247 Promise.resolve(loadTimeData.getString('toastUrlCopied')); | |
| 248 } else { | |
| 249 labelPromise = cr.sendWithPromise( | |
| 250 'getPluralString', 'toastItemsCopied', idList.length); | |
| 251 } | |
| 252 | |
| 253 this.showTitleToast_( | |
| 254 labelPromise, state.nodes[idList[0]].title, false); | |
| 255 }.bind(this)); | |
| 232 break; | 256 break; |
| 233 case Command.DELETE: | 257 case Command.DELETE: |
| 234 var idList = Array.from(this.minimizeDeletionSet_(itemIds)); | 258 var idList = Array.from(this.minimizeDeletionSet_(itemIds)); |
| 235 var title = state.nodes[idList[0]].title; | 259 var title = state.nodes[idList[0]].title; |
| 236 var labelPromise = cr.sendWithPromise( | 260 var labelPromise = cr.sendWithPromise( |
| 237 'getPluralString', 'toastItemsDeleted', idList.length); | 261 'getPluralString', 'toastItemsDeleted', idList.length); |
| 238 chrome.bookmarkManagerPrivate.removeTrees(idList, function() { | 262 chrome.bookmarkManagerPrivate.removeTrees(idList, function() { |
| 239 labelPromise.then(function(label) { | 263 this.showTitleToast_(labelPromise, title, true); |
| 240 var pieces = loadTimeData.getSubstitutedStringPieces(label, title) | |
| 241 .map(function(p) { | |
| 242 // Make the bookmark name collapsible. | |
| 243 p.collapsible = !!p.arg; | |
| 244 return p; | |
| 245 }); | |
| 246 bookmarks.ToastManager.getInstance().showForStringPieces( | |
| 247 pieces, true); | |
| 248 }.bind(this)); | |
| 249 }.bind(this)); | 264 }.bind(this)); |
| 250 break; | 265 break; |
| 251 case Command.UNDO: | 266 case Command.UNDO: |
| 252 chrome.bookmarkManagerPrivate.undo(); | 267 chrome.bookmarkManagerPrivate.undo(); |
| 253 bookmarks.ToastManager.getInstance().hide(); | 268 bookmarks.ToastManager.getInstance().hide(); |
| 254 break; | 269 break; |
| 255 case Command.REDO: | 270 case Command.REDO: |
| 256 chrome.bookmarkManagerPrivate.redo(); | 271 chrome.bookmarkManagerPrivate.redo(); |
| 257 break; | 272 break; |
| 258 case Command.OPEN_NEW_TAB: | 273 case Command.OPEN_NEW_TAB: |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 273 this.openUrls_(this.expandUrls_(itemIds), command); | 288 this.openUrls_(this.expandUrls_(itemIds), command); |
| 274 } | 289 } |
| 275 break; | 290 break; |
| 276 case Command.SELECT_ALL: | 291 case Command.SELECT_ALL: |
| 277 var displayedIds = bookmarks.util.getDisplayedList(state); | 292 var displayedIds = bookmarks.util.getDisplayedList(state); |
| 278 this.dispatch(bookmarks.actions.selectAll(displayedIds, state)); | 293 this.dispatch(bookmarks.actions.selectAll(displayedIds, state)); |
| 279 break; | 294 break; |
| 280 case Command.DESELECT_ALL: | 295 case Command.DESELECT_ALL: |
| 281 this.dispatch(bookmarks.actions.deselectItems()); | 296 this.dispatch(bookmarks.actions.deselectItems()); |
| 282 break; | 297 break; |
| 298 case Command.CUT: | |
| 299 var idList = Array.from(itemIds); | |
| 300 chrome.bookmarkManagerPrivate.cut(idList); | |
|
calamity
2017/07/03 03:40:05
nit: inline var.
tsergeant
2017/07/03 05:28:29
Done.
| |
| 301 break; | |
| 302 case Command.PASTE: | |
| 303 var selectedFolder = state.selectedFolder; | |
| 304 var selectedItems = state.selection.items; | |
| 305 chrome.bookmarkManagerPrivate.paste( | |
| 306 selectedFolder, Array.from(selectedItems)); | |
|
calamity
2017/07/03 03:40:05
We should scroll to the pasted node here.
tsergeant
2017/07/03 05:28:29
This little comment reveals a slightly unkempt yak
tsergeant
2017/07/04 01:32:11
Filed https://crbug.com/738958
| |
| 307 break; | |
| 283 default: | 308 default: |
| 284 assert(false); | 309 assert(false); |
| 285 } | 310 } |
| 286 }, | 311 }, |
| 287 | 312 |
| 288 /** | 313 /** |
| 289 * @param {!Event} e | 314 * @param {!Event} e |
| 290 * @param {!Set<string>} itemIds | 315 * @param {!Set<string>} itemIds |
| 291 * @return {boolean} True if the event was handled, triggering a keyboard | 316 * @return {boolean} True if the event was handled, triggering a keyboard |
| 292 * shortcut. | 317 * shortcut. |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 436 * node. | 461 * node. |
| 437 */ | 462 */ |
| 438 isSingleBookmark_: function(itemIds) { | 463 isSingleBookmark_: function(itemIds) { |
| 439 return itemIds.size == 1 && | 464 return itemIds.size == 1 && |
| 440 this.containsMatchingNode_(itemIds, function(node) { | 465 this.containsMatchingNode_(itemIds, function(node) { |
| 441 return !!node.url; | 466 return !!node.url; |
| 442 }); | 467 }); |
| 443 }, | 468 }, |
| 444 | 469 |
| 445 /** | 470 /** |
| 446 * @param {Event} e | |
| 447 * @private | |
| 448 */ | |
| 449 onOpenItemMenu_: function(e) { | |
| 450 if (e.detail.targetElement) { | |
| 451 this.openCommandMenuAtElement(e.detail.targetElement); | |
| 452 } else { | |
| 453 this.openCommandMenuAtPosition(e.detail.x, e.detail.y); | |
| 454 } | |
| 455 }, | |
| 456 | |
| 457 /** | |
| 458 * @param {Event} e | |
| 459 * @private | |
| 460 */ | |
| 461 onCommandClick_: function(e) { | |
| 462 this.handle( | |
| 463 e.currentTarget.getAttribute('command'), assert(this.menuIds_)); | |
| 464 this.closeCommandMenu(); | |
| 465 }, | |
| 466 | |
| 467 /** | |
| 468 * @param {!Event} e | |
| 469 * @private | |
| 470 */ | |
| 471 onKeydown_: function(e) { | |
| 472 var selection = this.getState().selection.items; | |
| 473 if (e.target == document.body) | |
| 474 this.handleKeyEvent(e, selection); | |
| 475 }, | |
| 476 | |
| 477 /** | |
| 478 * Close the menu on mousedown so clicks can propagate to the underlying UI. | |
| 479 * This allows the user to right click the list while a context menu is | |
| 480 * showing and get another context menu. | |
| 481 * @param {Event} e | |
| 482 * @private | |
| 483 */ | |
| 484 onMenuMousedown_: function(e) { | |
| 485 if (e.path[0] != this.$.dropdown.getIfExists()) | |
| 486 return; | |
| 487 | |
| 488 this.closeCommandMenu(); | |
| 489 }, | |
| 490 | |
| 491 /** @private */ | |
| 492 onOpenCancelTap_: function() { | |
| 493 this.$.openDialog.get().cancel(); | |
| 494 }, | |
| 495 | |
| 496 /** @private */ | |
| 497 onOpenConfirmTap_: function() { | |
| 498 this.confirmOpenCallback_(); | |
| 499 this.$.openDialog.get().close(); | |
| 500 }, | |
| 501 | |
| 502 /** | |
| 503 * @param {Command} command | 471 * @param {Command} command |
| 504 * @return {string} | 472 * @return {string} |
| 505 * @private | 473 * @private |
| 506 */ | 474 */ |
| 507 getCommandLabel_: function(command) { | 475 getCommandLabel_: function(command) { |
| 508 var multipleNodes = this.menuIds_.size > 1 || | 476 var multipleNodes = this.menuIds_.size > 1 || |
| 509 this.containsMatchingNode_(this.menuIds_, function(node) { | 477 this.containsMatchingNode_(this.menuIds_, function(node) { |
| 510 return !node.url; | 478 return !node.url; |
| 511 }); | 479 }); |
| 512 var label; | 480 var label; |
| 513 switch (command) { | 481 switch (command) { |
| 514 case Command.EDIT: | 482 case Command.EDIT: |
| 515 if (this.menuIds_.size != 1) | 483 if (this.menuIds_.size != 1) |
| 516 return ''; | 484 return ''; |
| 517 | 485 |
| 518 var id = Array.from(this.menuIds_)[0]; | 486 var id = Array.from(this.menuIds_)[0]; |
| 519 var itemUrl = this.getState().nodes[id].url; | 487 var itemUrl = this.getState().nodes[id].url; |
| 520 label = itemUrl ? 'menuEdit' : 'menuRename'; | 488 label = itemUrl ? 'menuEdit' : 'menuRename'; |
| 521 break; | 489 break; |
| 522 case Command.COPY: | 490 case Command.COPY_URL: |
| 523 label = 'menuCopyURL'; | 491 label = 'menuCopyURL'; |
| 524 break; | 492 break; |
| 525 case Command.DELETE: | 493 case Command.DELETE: |
| 526 label = 'menuDelete'; | 494 label = 'menuDelete'; |
| 527 break; | 495 break; |
| 528 case Command.OPEN_NEW_TAB: | 496 case Command.OPEN_NEW_TAB: |
| 529 label = multipleNodes ? 'menuOpenAllNewTab' : 'menuOpenNewTab'; | 497 label = multipleNodes ? 'menuOpenAllNewTab' : 'menuOpenNewTab'; |
| 530 break; | 498 break; |
| 531 case Command.OPEN_NEW_WINDOW: | 499 case Command.OPEN_NEW_WINDOW: |
| 532 label = multipleNodes ? 'menuOpenAllNewWindow' : 'menuOpenNewWindow'; | 500 label = multipleNodes ? 'menuOpenAllNewWindow' : 'menuOpenNewWindow'; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 570 | 538 |
| 571 /** | 539 /** |
| 572 * @param {Command} command | 540 * @param {Command} command |
| 573 * @return {boolean} | 541 * @return {boolean} |
| 574 * @private | 542 * @private |
| 575 */ | 543 */ |
| 576 showDividerAfter_: function(command, itemIds) { | 544 showDividerAfter_: function(command, itemIds) { |
| 577 return command == Command.DELETE && | 545 return command == Command.DELETE && |
| 578 (this.globalCanEdit_ || this.isSingleBookmark_(itemIds)); | 546 (this.globalCanEdit_ || this.isSingleBookmark_(itemIds)); |
| 579 }, | 547 }, |
| 548 | |
| 549 /** | |
| 550 * Show a toast with a bookmark |title| inserted into a label, with the | |
| 551 * title ellipsised if necessary. | |
| 552 * @param {!Promise<string>} labelPromise Promise which resolves with the | |
| 553 * label for the toast. | |
| 554 * @param {string} title Bookmark title to insert. | |
| 555 * @param {boolean} canUndo If true, shows an undo button in the toast. | |
| 556 * @private | |
| 557 */ | |
| 558 showTitleToast_: function(labelPromise, title, canUndo) { | |
| 559 labelPromise.then(function(label) { | |
| 560 var pieces = loadTimeData.getSubstitutedStringPieces(label, title) | |
| 561 .map(function(p) { | |
| 562 // Make the bookmark name collapsible. | |
| 563 p.collapsible = !!p.arg; | |
| 564 return p; | |
| 565 }); | |
| 566 | |
| 567 bookmarks.ToastManager.getInstance().showForStringPieces( | |
| 568 pieces, canUndo); | |
| 569 }); | |
| 570 }, | |
| 571 | |
| 572 //////////////////////////////////////////////////////////////////////////// | |
| 573 // Event handlers: | |
| 574 | |
| 575 /** | |
| 576 * @param {Event} e | |
| 577 * @private | |
| 578 */ | |
| 579 onOpenItemMenu_: function(e) { | |
| 580 if (e.detail.targetElement) { | |
| 581 this.openCommandMenuAtElement(e.detail.targetElement); | |
| 582 } else { | |
| 583 this.openCommandMenuAtPosition(e.detail.x, e.detail.y); | |
| 584 } | |
| 585 }, | |
| 586 | |
| 587 /** | |
| 588 * @param {Event} e | |
| 589 * @private | |
| 590 */ | |
| 591 onCommandClick_: function(e) { | |
| 592 this.handle( | |
| 593 e.currentTarget.getAttribute('command'), assert(this.menuIds_)); | |
| 594 this.closeCommandMenu(); | |
| 595 }, | |
| 596 | |
| 597 /** | |
| 598 * @param {!Event} e | |
| 599 * @private | |
| 600 */ | |
| 601 onKeydown_: function(e) { | |
| 602 var selection = this.getState().selection.items; | |
| 603 if (e.target == document.body) | |
| 604 this.handleKeyEvent(e, selection); | |
| 605 }, | |
| 606 | |
| 607 /** | |
| 608 * Close the menu on mousedown so clicks can propagate to the underlying UI. | |
| 609 * This allows the user to right click the list while a context menu is | |
| 610 * showing and get another context menu. | |
| 611 * @param {Event} e | |
| 612 * @private | |
| 613 */ | |
| 614 onMenuMousedown_: function(e) { | |
| 615 if (e.path[0] != this.$.dropdown.getIfExists()) | |
| 616 return; | |
| 617 | |
| 618 this.closeCommandMenu(); | |
| 619 }, | |
| 620 | |
| 621 /** @private */ | |
| 622 onOpenCancelTap_: function() { | |
| 623 this.$.openDialog.get().cancel(); | |
| 624 }, | |
| 625 | |
| 626 /** @private */ | |
| 627 onOpenConfirmTap_: function() { | |
| 628 this.confirmOpenCallback_(); | |
| 629 this.$.openDialog.get().close(); | |
| 630 }, | |
| 580 }); | 631 }); |
| 581 | 632 |
| 582 /** @private {bookmarks.CommandManager} */ | 633 /** @private {bookmarks.CommandManager} */ |
| 583 CommandManager.instance_ = null; | 634 CommandManager.instance_ = null; |
| 584 | 635 |
| 585 /** @return {!bookmarks.CommandManager} */ | 636 /** @return {!bookmarks.CommandManager} */ |
| 586 CommandManager.getInstance = function() { | 637 CommandManager.getInstance = function() { |
| 587 return assert(CommandManager.instance_); | 638 return assert(CommandManager.instance_); |
| 588 }; | 639 }; |
| 589 | 640 |
| 590 return { | 641 return { |
| 591 CommandManager: CommandManager, | 642 CommandManager: CommandManager, |
| 592 }; | 643 }; |
| 593 }); | 644 }); |
| OLD | NEW |