From 82140d31bbecc5d184af87b5ca35c663e28f18c4 Mon Sep 17 00:00:00 2001 From: Mike Harvey <43474485+mikeharv@users.noreply.github.com> Date: Thu, 27 Aug 2026 11:52:07 -0400 Subject: [PATCH] fix: scroll field into view after window resize instead of bumping block --- packages/blockly/core/field_input.ts | 31 +++++++++++++++++--------- packages/blockly/core/inject.ts | 2 +- packages/blockly/core/workspace_svg.ts | 9 +++++--- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/packages/blockly/core/field_input.ts b/packages/blockly/core/field_input.ts index f9619bf838c..ba43097bb61 100644 --- a/packages/blockly/core/field_input.ts +++ b/packages/blockly/core/field_input.ts @@ -14,7 +14,6 @@ import {computeAriaLabel, getBeginStackLabel} from './block_aria_composer.js'; import {BlockSvg} from './block_svg.js'; import * as browserEvents from './browser_events.js'; -import * as bumpObjects from './bump_objects.js'; import * as css from './css.js'; import * as dialog from './dialog.js'; import * as dropDownDiv from './dropdowndiv.js'; @@ -33,8 +32,10 @@ import * as renderManagement from './render_management.js'; import * as aria from './utils/aria.js'; import {Verbosity} from './utils/aria.js'; import * as dom from './utils/dom.js'; +import {Rect} from './utils/rect.js'; import {Size} from './utils/size.js'; import {Svg} from './utils/svg.js'; +import * as svgMath from './utils/svg_math.js'; import * as userAgent from './utils/useragent.js'; import * as WidgetDiv from './widgetdiv.js'; import type {WorkspaceSvg} from './workspace_svg.js'; @@ -842,26 +843,34 @@ export abstract class FieldInput extends Field< /** * Handles repositioning the WidgetDiv used for input fields when the - * workspace is resized. Will bump the block into the viewport and update the - * position of the text input if necessary. + * workspace is resized. Scrolls this field into view, then updates the + * position of the text input. * * @returns True for rendered workspaces, as we never want to hide the widget * div. */ override repositionForWindowResize(): boolean { - const block = this.getSourceBlock()?.getRootBlock(); + const block = this.getSourceBlock(); + const workspace = this.workspace_; // This shouldn't be possible. We should never have a WidgetDiv if not using // rendered blocks. if (!(block instanceof BlockSvg)) return false; - const bumped = bumpObjects.bumpIntoBounds( - this.workspace_!, - this.workspace_!.getMetricsManager().getViewMetrics(true), - block, - ); - - if (!bumped) this.resizeEditor_(); + this.resizeEditor_(); + const element = this.getClickTarget_(); + if (!element || !workspace) return true; + + const bbox = Rect.from(element.getBoundingClientRect()); + const origin = svgMath.screenToWsCoordinates(workspace, bbox.getOrigin()); + const scale = workspace.scale; + workspace.scrollBoundsIntoView( + Rect.createFromPoint( + origin, + bbox.getWidth() / scale, + bbox.getHeight() / scale, + ), + ); return true; } diff --git a/packages/blockly/core/inject.ts b/packages/blockly/core/inject.ts index cc6165fe914..f8440ad89de 100644 --- a/packages/blockly/core/inject.ts +++ b/packages/blockly/core/inject.ts @@ -235,9 +235,9 @@ function init(mainWorkspace: WorkspaceSvg) { // possible. Tooltip.hide(); mainWorkspace.hideComponents(true); + common.svgResize(mainWorkspace); dropDownDiv.repositionForWindowResize(); WidgetDiv.repositionForWindowResize(); - common.svgResize(mainWorkspace); bumpObjects.bumpTopObjectsIntoBounds(mainWorkspace); }, ); diff --git a/packages/blockly/core/workspace_svg.ts b/packages/blockly/core/workspace_svg.ts index 67e60fc1891..21fa37dc028 100644 --- a/packages/blockly/core/workspace_svg.ts +++ b/packages/blockly/core/workspace_svg.ts @@ -2236,9 +2236,12 @@ export class WorkspaceSvg * * @param x Target X to scroll to. * @param y Target Y to scroll to. + * @param shouldHidePopups Whether to hide popups. Defaults to true. */ - scroll(x: number, y: number) { - this.hideChaff(/* opt_onlyClosePopups= */ true); + scroll(x: number, y: number, shouldHidePopups = true) { + if (shouldHidePopups) { + this.hideChaff(/* opt_onlyClosePopups= */ true); + } // Keep scrolling within the bounds of the content. const metrics = this.getMetrics(); @@ -2770,7 +2773,7 @@ export class WorkspaceSvg deltaX *= scale; deltaY *= scale; - this.scroll(this.scrollX + deltaX, this.scrollY + deltaY); + this.scroll(this.scrollX + deltaX, this.scrollY + deltaY, false); } /** See IFocusableNode.getFocusableElement. */