diff --git a/README.md b/README.md index 6f19520..974a310 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,12 @@ options = { disabledIcon: 'https://github.com/mit-cml/workspace-multiselect/raw/main/test/media/unselect.svg', }, + // Keys for multi-selection mode switch. Any key value is possible (see MDN docs). + // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key + // The best support (default) is given for Shift. Provide an empty array [] + // will revert to the default key. + multiSelectKeys: ['Shift', 'Control'], + multiselectCopyPaste: { // Enable the copy/paste accross tabs feature (true by default). crossTab: true, diff --git a/src/multiselect.js b/src/multiselect.js index f8802e3..9639a1b 100644 --- a/src/multiselect.js +++ b/src/multiselect.js @@ -36,6 +36,7 @@ export class Multiselect { this.useCopyPasteCrossTab_ = true; this.useCopyPasteMenu_ = true; this.multiFieldUpdate_ = true; + this.multiSelectKeys_ = ['shift']; } /** @@ -44,6 +45,11 @@ export class Multiselect { * to set. */ init(options) { + if (options.multiSelectKeys && options.multiSelectKeys.length > 0) { + this.multiSelectKeys_ = options.multiSelectKeys.map((key) => { + return key.toLocaleLowerCase(); + }); + } const injectionDiv = this.workspace_.getInjectionDiv(); this.onKeyDownWrapper_ = Blockly.browserEvents.conditionalBind( injectionDiv, 'keydown', this, this.onKeyDown_); @@ -87,7 +93,7 @@ export class Multiselect { } this.controls_ = new MultiselectControls( - this.workspace_, options.multiselectIcon, this); + this.workspace_, options.multiselectIcon, this.multiSelectKeys_); multiselectControlsList.add(this.controls_); if (!options.multiselectIcon || !options.multiselectIcon.hideIcon) { const svgControls = this.controls_.createDom(); @@ -329,7 +335,7 @@ export class Multiselect { * @private */ onKeyDown_(e) { - if (e.keyCode === Blockly.utils.KeyCodes.SHIFT && + if (this.multiSelectKeys_.indexOf(e.key.toLocaleLowerCase()) > -1 && !inMultipleSelectionModeWeakMap.get(this.workspace_)) { this.controls_.enableMultiselect(); } @@ -341,7 +347,7 @@ export class Multiselect { * @private */ onKeyUp_(e) { - if (e.keyCode === Blockly.utils.KeyCodes.SHIFT) { + if (this.multiSelectKeys_.indexOf(e.key.toLocaleLowerCase()) > -1) { this.controls_.disableMultiselect(); } } diff --git a/src/multiselect_controls.js b/src/multiselect_controls.js index 25feefc..4945f24 100644 --- a/src/multiselect_controls.js +++ b/src/multiselect_controls.js @@ -49,8 +49,10 @@ export class MultiselectControls { /** * @param {!Blockly.WorkspaceSvg} workspace The workspace to sit in. * @param {Object} options The icons configuration. + * @param {!Array} multiSelectKeys The key codes for + * switching between multi select mode. */ - constructor(workspace, options) { + constructor(workspace, options, multiSelectKeys) { /** * Icon path of the multi select controls when enabled. * @type {string} @@ -86,6 +88,13 @@ export class MultiselectControls { */ this.id = 'multiselectControls'; + /** + * The key codes for switching between multi select. + * @type {!Array} + * @private + */ + this.multiSelectKeys_ = multiSelectKeys; + /** * A handle to use to unbind the mouse down event handler for multi select * button. Opaque data returned from browserEvents.conditionalBind. @@ -371,6 +380,7 @@ export class MultiselectControls { multiselectMode: true, draggability: false, usePointerEvents: true, + multiSelectKeys: this.multiSelectKeys_, }); // Filter out the parent block when selecting child blocks // to mitigate the invisible rectangles issue. @@ -423,9 +433,7 @@ export class MultiselectControls { }); if (byIcon) { document.dispatchEvent( - new KeyboardEvent('keydown', {'key': 'shift'})); - this.workspace_.getInjectionDiv().dispatchEvent( - new KeyboardEvent('keydown', {'key': 'meta'})); + new KeyboardEvent('keydown', {'key': this.multiSelectKeys_[0]})); } this.updateMultiselectIcon(true); inMultipleSelectionModeWeakMap.set(this.workspace_, true); @@ -439,10 +447,8 @@ export class MultiselectControls { inMultipleSelectionModeWeakMap.set(this.workspace_, false); if (this.dragSelect_) { if (byIcon) { - this.workspace_.getInjectionDiv().dispatchEvent( - new KeyboardEvent('keyup', {'key': 'meta'})); document.dispatchEvent( - new KeyboardEvent('keyup', {'key': 'shift'})); + new KeyboardEvent('keyup', {'key': this.multiSelectKeys_[0]})); } this.dragSelect_.stop(); this.dragSelect_ = null; diff --git a/test/index.js b/test/index.js index a36a251..aa78358 100644 --- a/test/index.js +++ b/test/index.js @@ -44,6 +44,7 @@ document.addEventListener('DOMContentLoaded', function() { enabledIcon: 'media/select.svg', disabledIcon: 'media/unselect.svg', }, + multiSelectKeys: ['Shift', 'Control'], multiselectCopyPaste: { crossTab: true, menu: true,