diff --git a/src/field_input_monkey_patch.js b/src/field_input_monkey_patch.js new file mode 100644 index 00000000..c2d53436 --- /dev/null +++ b/src/field_input_monkey_patch.js @@ -0,0 +1,37 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from 'blockly/core'; + +function addTemporaryMarkFocusedOverrideToWorkspaceSvg() { + const oldWorkspaceSvgMarkFocused = Blockly.WorkspaceSvg.prototype.markFocused; + + Blockly.WorkspaceSvg.prototype.markFocused = function() { + oldWorkspaceSvgMarkFocused.call(this); + + // After the workspace's internal state is updated, ensure the correct + // container for keyboard navigation has focus. Note that this monkey patch is + // only overriding focus behavior for cases when a widget is being dispoed as + // there are other cases when focus needs to be correctly on the parent SVG + // (such as creating variables--see #136). + document.querySelector('.blocklyWorkspace').focus(); + Blockly.WorkspaceSvg.prototype.markFocused = oldWorkspaceSvgMarkFocused; + } +} + +const oldFieldNumberWidgetDispose = Blockly.FieldNumber.prototype.widgetDispose_; + +Blockly.FieldNumber.prototype.widgetDispose_ = function() { + oldFieldNumberWidgetDispose.call(this); + addTemporaryMarkFocusedOverrideToWorkspaceSvg(); +}; + +const oldFieldTextInputWidgetDispose = Blockly.FieldTextInput.prototype.widgetDispose_; + +Blockly.FieldTextInput.prototype.widgetDispose_ = function() { + oldFieldTextInputWidgetDispose.call(this); + addTemporaryMarkFocusedOverrideToWorkspaceSvg(); +}; diff --git a/src/index.ts b/src/index.ts index c47cc9f5..617df30c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -90,10 +90,6 @@ export class KeyboardNavigation { workspace.getSvgGroup().addEventListener('focus', this.focusListener); workspace.getSvgGroup().addEventListener('blur', this.blurListener); - // Temporary workaround for #136. - // TODO(#136): fix in core. - workspace.getParentSvg().addEventListener('focus', this.focusListener); - workspace.getParentSvg().addEventListener('blur', this.blurListener); } /** diff --git a/src/navigation_controller.ts b/src/navigation_controller.ts index 0c4affe0..99d78b5b 100644 --- a/src/navigation_controller.ts +++ b/src/navigation_controller.ts @@ -10,6 +10,7 @@ * @author aschmiedt@google.com (Abby Schmiedt) */ +import './field_input_monkey_patch'; import './gesture_monkey_patch'; import * as Blockly from 'blockly/core';