From f1ddc189adb13245141b12a3d55f7e1abd56fe39 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 15 Jul 2025 09:40:40 -0700 Subject: [PATCH 1/3] fix: Require the `FlyoutCursor` to be registered explicitly. --- src/flyout_cursor.ts | 14 ++++++++++++-- test/index.ts | 2 ++ test/webdriverio/index.ts | 2 ++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/flyout_cursor.ts b/src/flyout_cursor.ts index ee376bc6..cd1a1be3 100644 --- a/src/flyout_cursor.ts +++ b/src/flyout_cursor.ts @@ -89,8 +89,18 @@ export class FlyoutCursor extends Blockly.LineCursor { export const registrationType = Blockly.registry.Type.CURSOR; export const registrationName = 'FlyoutCursor'; -Blockly.registry.register(registrationType, registrationName, FlyoutCursor); - export const pluginInfo = { [registrationType.toString()]: registrationName, }; + +/** + * Registers the FlyoutCursor with Blockly's registry. + */ +export function registerFlyoutCursor() { + Blockly.registry.register( + registrationType, + registrationName, + FlyoutCursor, + true, + ); +} diff --git a/test/index.ts b/test/index.ts index a49c42c0..39eabf98 100644 --- a/test/index.ts +++ b/test/index.ts @@ -9,6 +9,7 @@ import * as Blockly from 'blockly'; import 'blockly/blocks'; import {installAllBlocks as installColourBlocks} from '@blockly/field-colour'; import {KeyboardNavigation} from '../src/index'; +import {registerFlyoutCursor} from '../src/flyout_cursor'; // @ts-expect-error No types in js file import {forBlock} from './blocks/p5_generators'; // @ts-expect-error No types in js file @@ -92,6 +93,7 @@ function createWorkspace(): Blockly.WorkspaceSvg { // Must be called before injection. KeyboardNavigation.registerKeyboardNavigationStyles(); + registerFlyoutCursor(); const workspace = Blockly.inject(blocklyDiv, injectOptions); Blockly.ContextMenuItems.registerCommentOptions(); diff --git a/test/webdriverio/index.ts b/test/webdriverio/index.ts index 4560ef2a..88f45135 100644 --- a/test/webdriverio/index.ts +++ b/test/webdriverio/index.ts @@ -9,6 +9,7 @@ import * as Blockly from 'blockly'; import 'blockly/blocks'; import {installAllBlocks as installColourBlocks} from '@blockly/field-colour'; import {KeyboardNavigation} from '../../src/index'; +import {registerFlyoutCursor} from '../../src/flyout_cursor'; // @ts-expect-error No types in js file import {blocks} from './../blocks/p5_blocks'; // @ts-expect-error No types in js file @@ -80,6 +81,7 @@ function createWorkspace(): Blockly.WorkspaceSvg { } // Must be called before injection. KeyboardNavigation.registerKeyboardNavigationStyles(); + registerFlyoutCursor(); const workspace = Blockly.inject(blocklyDiv, injectOptions); Blockly.ContextMenuItems.registerCommentOptions(); From 782a84ef879fbe0fc87484f9a10168158e079641 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 15 Jul 2025 11:37:12 -0700 Subject: [PATCH 2/3] fix: Use toolbox subclass instead of monkeypatch. --- src/navigation_controller.ts | 2 -- src/navigation_deferring_toolbox.ts | 23 +++++++++++++++++++++++ src/toolbox_monkey_patch.js | 12 ------------ test/index.ts | 2 ++ test/webdriverio/index.ts | 2 ++ 5 files changed, 27 insertions(+), 14 deletions(-) create mode 100644 src/navigation_deferring_toolbox.ts delete mode 100644 src/toolbox_monkey_patch.js diff --git a/src/navigation_controller.ts b/src/navigation_controller.ts index 3c29c128..de53ade4 100644 --- a/src/navigation_controller.ts +++ b/src/navigation_controller.ts @@ -10,8 +10,6 @@ * @author aschmiedt@google.com (Abby Schmiedt) */ -import './toolbox_monkey_patch'; - import * as Blockly from 'blockly/core'; import { ShortcutRegistry, diff --git a/src/navigation_deferring_toolbox.ts b/src/navigation_deferring_toolbox.ts new file mode 100644 index 00000000..85dd89a8 --- /dev/null +++ b/src/navigation_deferring_toolbox.ts @@ -0,0 +1,23 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from 'blockly/core'; + +export class NavigationDeferringToolbox extends Blockly.Toolbox { + protected override onKeyDown_(e: KeyboardEvent) { + // No-op, prevent keyboard handling by superclass in order to defer to + // global keyboard navigation. + } +} + +export function registerNavigationDeferringToolbox() { + Blockly.registry.register( + Blockly.registry.Type.TOOLBOX, + Blockly.registry.DEFAULT, + NavigationDeferringToolbox, + true, + ); +} diff --git a/src/toolbox_monkey_patch.js b/src/toolbox_monkey_patch.js deleted file mode 100644 index 2649da51..00000000 --- a/src/toolbox_monkey_patch.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * @license - * Copyright 2025 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import * as Blockly from 'blockly/core'; - -Blockly.Toolbox.prototype.onKeyDown_ = function () { - // Do nothing since keyboard functionality should be entirely handled by the - // keyboard navigation plugin. -}; diff --git a/test/index.ts b/test/index.ts index 39eabf98..4aa282a8 100644 --- a/test/index.ts +++ b/test/index.ts @@ -10,6 +10,7 @@ import 'blockly/blocks'; import {installAllBlocks as installColourBlocks} from '@blockly/field-colour'; import {KeyboardNavigation} from '../src/index'; import {registerFlyoutCursor} from '../src/flyout_cursor'; +import {registerNavigationDeferringToolbox} from '../src/navigation_deferring_toolbox'; // @ts-expect-error No types in js file import {forBlock} from './blocks/p5_generators'; // @ts-expect-error No types in js file @@ -94,6 +95,7 @@ function createWorkspace(): Blockly.WorkspaceSvg { // Must be called before injection. KeyboardNavigation.registerKeyboardNavigationStyles(); registerFlyoutCursor(); + registerNavigationDeferringToolbox(); const workspace = Blockly.inject(blocklyDiv, injectOptions); Blockly.ContextMenuItems.registerCommentOptions(); diff --git a/test/webdriverio/index.ts b/test/webdriverio/index.ts index 88f45135..f6b67963 100644 --- a/test/webdriverio/index.ts +++ b/test/webdriverio/index.ts @@ -10,6 +10,7 @@ import 'blockly/blocks'; import {installAllBlocks as installColourBlocks} from '@blockly/field-colour'; import {KeyboardNavigation} from '../../src/index'; import {registerFlyoutCursor} from '../../src/flyout_cursor'; +import {registerNavigationDeferringToolbox} from '../../src/navigation_deferring_toolbox'; // @ts-expect-error No types in js file import {blocks} from './../blocks/p5_blocks'; // @ts-expect-error No types in js file @@ -82,6 +83,7 @@ function createWorkspace(): Blockly.WorkspaceSvg { // Must be called before injection. KeyboardNavigation.registerKeyboardNavigationStyles(); registerFlyoutCursor(); + registerNavigationDeferringToolbox(); const workspace = Blockly.inject(blocklyDiv, injectOptions); Blockly.ContextMenuItems.registerCommentOptions(); From 8ac253c27f5254fcd5da382bfabe160902141b75 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 15 Jul 2025 11:51:35 -0700 Subject: [PATCH 3/3] chore: Satisfy the linter. --- src/navigation_deferring_toolbox.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/navigation_deferring_toolbox.ts b/src/navigation_deferring_toolbox.ts index 85dd89a8..b09733d2 100644 --- a/src/navigation_deferring_toolbox.ts +++ b/src/navigation_deferring_toolbox.ts @@ -6,13 +6,20 @@ import * as Blockly from 'blockly/core'; +/** + * Toolbox class that does not handle keyboard navigation. + */ export class NavigationDeferringToolbox extends Blockly.Toolbox { + // eslint-disable-next-line @typescript-eslint/naming-convention protected override onKeyDown_(e: KeyboardEvent) { // No-op, prevent keyboard handling by superclass in order to defer to // global keyboard navigation. } } +/** + * Registers the navigation-deferring toolbox with Blockly. + */ export function registerNavigationDeferringToolbox() { Blockly.registry.register( Blockly.registry.Type.TOOLBOX,