diff --git a/packages/blockly/core/shortcut_items.ts b/packages/blockly/core/shortcut_items.ts index 92a0ea6e507..a87c0899168 100644 --- a/packages/blockly/core/shortcut_items.ts +++ b/packages/blockly/core/shortcut_items.ts @@ -558,7 +558,8 @@ export function registerMovementShortcuts() { } /** - * Keyboard shortcut to show the context menu on ctrl/cmd+Enter. + * Keyboard shortcut to show the context menu on ctrl/cmd+Enter, shift+F10, and + * the menu key. */ export function registerShowContextMenu() { const ctrlEnter = ShortcutRegistry.registry.createSerializedKey( @@ -566,6 +567,10 @@ export function registerShowContextMenu() { [KeyCodes.CTRL_CMD], ); + const shiftF10 = ShortcutRegistry.registry.createSerializedKey(KeyCodes.F10, [ + KeyCodes.SHIFT, + ]); + const contextMenuShortcut: KeyboardShortcut = { name: names.MENU, preconditionFn: (workspace) => { @@ -582,7 +587,7 @@ export function registerShowContextMenu() { } return false; }, - keyCodes: [ctrlEnter], + keyCodes: [ctrlEnter, shiftF10, KeyCodes.CONTEXT_MENU], displayText: () => Msg['SHORTCUTS_SHOW_CONTEXT_MENU'], }; ShortcutRegistry.registry.register(contextMenuShortcut); diff --git a/packages/blockly/tests/mocha/shortcut_items_test.js b/packages/blockly/tests/mocha/shortcut_items_test.js index 90dfe32b616..6655d21794b 100644 --- a/packages/blockly/tests/mocha/shortcut_items_test.js +++ b/packages/blockly/tests/mocha/shortcut_items_test.js @@ -468,13 +468,21 @@ suite('Keyboard Shortcut Items', function () { ); }); - suite('Show context menu (Ctrl/Cmd+Enter)', function () { + suite('Show context menu', function () { const contextMenuKeyEvent = createKeyDownEvent( Blockly.utils.KeyCodes.ENTER, [Blockly.utils.KeyCodes.CTRL_CMD], ); - test('Displays context menu on a block using the keyboard shortcut', function () { + const shiftF10KeyEvent = createKeyDownEvent(Blockly.utils.KeyCodes.F10, [ + Blockly.utils.KeyCodes.SHIFT, + ]); + + const menuKeyEvent = createKeyDownEvent( + Blockly.utils.KeyCodes.CONTEXT_MENU, + ); + + test('Displays context menu on a block using Ctrl/Cmd+Enter', function () { const block = setSelectedBlock(this.workspace); this.injectionDiv.dispatchEvent(contextMenuKeyEvent); @@ -491,7 +499,7 @@ suite('Keyboard Shortcut Items', function () { } }); - test('Displays context menu on the workspace using the keyboard shortcut', function () { + test('Displays context menu on the workspace using Ctrl/Cmd+Enter', function () { Blockly.getFocusManager().focusNode(this.workspace); this.injectionDiv.dispatchEvent(contextMenuKeyEvent); @@ -507,7 +515,7 @@ suite('Keyboard Shortcut Items', function () { } }); - test('Displays context menu on a workspace comment using the keyboard shortcut', function () { + test('Displays context menu on a workspace comment using Ctrl/Cmd+Enter', function () { Blockly.ContextMenuItems.registerCommentOptions(); const comment = setSelectedComment(this.workspace); this.injectionDiv.dispatchEvent(contextMenuKeyEvent); @@ -524,6 +532,106 @@ suite('Keyboard Shortcut Items', function () { } }); + test('Displays context menu on a block using Shift+F10', function () { + const block = setSelectedBlock(this.workspace); + this.injectionDiv.dispatchEvent(shiftF10KeyEvent); + + const menu = Blockly.ContextMenu.getMenu(); + assert.instanceOf(menu, Blockly.Menu, 'Context menu should be shown'); + + const menuOptions = + Blockly.ContextMenuRegistry.registry.getContextMenuOptions( + {block, focusedNode: block}, + shiftF10KeyEvent, + ); + for (const option of menuOptions) { + assert.include(menu.getElement().textContent, option.text); + } + }); + + test('Displays context menu on the workspace using Shift+F10', function () { + Blockly.getFocusManager().focusNode(this.workspace); + this.injectionDiv.dispatchEvent(shiftF10KeyEvent); + + const menu = Blockly.ContextMenu.getMenu(); + assert.instanceOf(menu, Blockly.Menu, 'Context menu should be shown'); + const menuOptions = + Blockly.ContextMenuRegistry.registry.getContextMenuOptions( + {workspace: this.workspace, focusedNode: this.workspace}, + shiftF10KeyEvent, + ); + for (const option of menuOptions) { + assert.include(menu.getElement().textContent, option.text); + } + }); + + test('Displays context menu on a workspace comment using Shift+F10', function () { + Blockly.ContextMenuItems.registerCommentOptions(); + const comment = setSelectedComment(this.workspace); + this.injectionDiv.dispatchEvent(shiftF10KeyEvent); + + const menu = Blockly.ContextMenu.getMenu(); + assert.instanceOf(menu, Blockly.Menu, 'Context menu should be shown'); + const menuOptions = + Blockly.ContextMenuRegistry.registry.getContextMenuOptions( + {comment, focusedNode: comment}, + shiftF10KeyEvent, + ); + for (const option of menuOptions) { + assert.include(menu.getElement().textContent, option.text); + } + }); + + test('Displays context menu on a block using the menu button', function () { + const block = setSelectedBlock(this.workspace); + this.injectionDiv.dispatchEvent(menuKeyEvent); + + const menu = Blockly.ContextMenu.getMenu(); + assert.instanceOf(menu, Blockly.Menu, 'Context menu should be shown'); + + const menuOptions = + Blockly.ContextMenuRegistry.registry.getContextMenuOptions( + {block, focusedNode: block}, + menuKeyEvent, + ); + for (const option of menuOptions) { + assert.include(menu.getElement().textContent, option.text); + } + }); + + test('Displays context menu on the workspace using the menu button', function () { + Blockly.getFocusManager().focusNode(this.workspace); + this.injectionDiv.dispatchEvent(menuKeyEvent); + + const menu = Blockly.ContextMenu.getMenu(); + assert.instanceOf(menu, Blockly.Menu, 'Context menu should be shown'); + const menuOptions = + Blockly.ContextMenuRegistry.registry.getContextMenuOptions( + {workspace: this.workspace, focusedNode: this.workspace}, + menuKeyEvent, + ); + for (const option of menuOptions) { + assert.include(menu.getElement().textContent, option.text); + } + }); + + test('Displays context menu on a workspace comment using the menu button', function () { + Blockly.ContextMenuItems.registerCommentOptions(); + const comment = setSelectedComment(this.workspace); + this.injectionDiv.dispatchEvent(menuKeyEvent); + + const menu = Blockly.ContextMenu.getMenu(); + assert.instanceOf(menu, Blockly.Menu, 'Context menu should be shown'); + const menuOptions = + Blockly.ContextMenuRegistry.registry.getContextMenuOptions( + {comment, focusedNode: comment}, + menuKeyEvent, + ); + for (const option of menuOptions) { + assert.include(menu.getElement().textContent, option.text); + } + }); + test('First menu item is highlighted when context menu is shown via keyboard shortcut', function () { setSelectedBlock(this.workspace); this.injectionDiv.dispatchEvent(contextMenuKeyEvent);