From 86da7dcbfab72a84182f633295ce0e904b1bb9bd Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 21 Aug 2025 14:21:02 -0700 Subject: [PATCH 01/19] release: Update version number to 12.3.0-beta.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e03f6d24d..c7f681f2e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "blockly", - "version": "12.2.0", + "version": "12.3.0-beta.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "blockly", - "version": "12.2.0", + "version": "12.3.0-beta.0", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index e7a496b31..c122a32fe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blockly", - "version": "12.2.0", + "version": "12.3.0-beta.0", "description": "Blockly is a library for building visual programming editors.", "keywords": [ "blockly" From 84933b9119b0d874d80a9e7f0fa0b34d6d10fa71 Mon Sep 17 00:00:00 2001 From: Maribeth Moffatt Date: Tue, 19 Aug 2025 11:22:17 -0400 Subject: [PATCH 02/19] chore: lint error on only in mocha tests (#9300) --- eslint.config.mjs | 5 +++++ package-lock.json | 26 ++++++++++++++++++++++++++ package.json | 1 + 3 files changed, 32 insertions(+) diff --git a/eslint.config.mjs b/eslint.config.mjs index f018e525d..0560586cb 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,6 +1,7 @@ import eslint from '@eslint/js'; import googleStyle from 'eslint-config-google'; import jsdoc from 'eslint-plugin-jsdoc'; +import mochaPlugin from 'eslint-plugin-mocha'; import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; import globals from 'globals'; import tseslint from 'typescript-eslint'; @@ -200,6 +201,9 @@ export default [ }, { files: ['tests/**'], + plugins: { + mocha: mochaPlugin, + }, languageOptions: { globals: { 'Blockly': true, @@ -219,6 +223,7 @@ export default [ 'jsdoc/check-tag-names': ['warn', {'definedTags': ['record']}], 'jsdoc/tag-lines': ['off'], 'jsdoc/no-defaults': ['off'], + 'mocha/no-exclusive-tests': 'error', }, }, { diff --git a/package-lock.json b/package-lock.json index c7f681f2e..d30a69df6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "eslint-config-google": "^0.14.0", "eslint-config-prettier": "^10.1.1", "eslint-plugin-jsdoc": "^52.0.2", + "eslint-plugin-mocha": "^11.1.0", "eslint-plugin-prettier": "^5.2.1", "glob": "^11.0.1", "globals": "^16.0.0", @@ -4137,6 +4138,31 @@ "spdx-license-ids": "^3.0.0" } }, + "node_modules/eslint-plugin-mocha": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-11.1.0.tgz", + "integrity": "sha512-rKntVWRsQFPbf8OkSgVNRVRrcVAPaGTyEgWCEyXaPDJkTl0v5/lwu1vTk5sWiUJU8l2sxwvGUZzSNrEKdVMeQw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.1", + "globals": "^15.14.0" + }, + "peerDependencies": { + "eslint": ">=9.0.0" + } + }, + "node_modules/eslint-plugin-mocha/node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint-plugin-prettier": { "version": "5.5.1", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.1.tgz", diff --git a/package.json b/package.json index c122a32fe..6cfd025c7 100644 --- a/package.json +++ b/package.json @@ -115,6 +115,7 @@ "eslint-config-google": "^0.14.0", "eslint-config-prettier": "^10.1.1", "eslint-plugin-jsdoc": "^52.0.2", + "eslint-plugin-mocha": "^11.1.0", "eslint-plugin-prettier": "^5.2.1", "glob": "^11.0.1", "globals": "^16.0.0", From 29d5b43cd3ba1d210472c064c16e9a1c9dd7cddb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Aug 2025 08:28:11 -0700 Subject: [PATCH 03/19] chore(deps): bump actions/checkout from 4 to 5 (#9320) Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/appengine_deploy.yml | 2 +- .github/workflows/browser_test.yml | 2 +- .github/workflows/build.yml | 6 +++--- .github/workflows/keyboard_plugin_test.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/appengine_deploy.yml b/.github/workflows/appengine_deploy.yml index 50afec240..efc6fe941 100644 --- a/.github/workflows/appengine_deploy.yml +++ b/.github/workflows/appengine_deploy.yml @@ -15,7 +15,7 @@ jobs: steps: # Checks-out the repository under $GITHUB_WORKSPACE. # When running manually this checks out the master branch. - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Prepare demo files # Install all dependencies, then copy all the files needed for demos. diff --git a/.github/workflows/browser_test.yml b/.github/workflows/browser_test.yml index 51ac0dffa..c2ce99136 100644 --- a/.github/workflows/browser_test.yml +++ b/.github/workflows/browser_test.yml @@ -26,7 +26,7 @@ jobs: # https://nodejs.org/en/about/releases/ steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: persist-credentials: false diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c4ab688f8..d7a4e786c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,7 +23,7 @@ jobs: # https://nodejs.org/en/about/releases/ steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: persist-credentials: false @@ -54,7 +54,7 @@ jobs: timeout-minutes: 5 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Use Node.js 20.x uses: actions/setup-node@v4 @@ -71,7 +71,7 @@ jobs: timeout-minutes: 5 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Use Node.js 20.x uses: actions/setup-node@v4 diff --git a/.github/workflows/keyboard_plugin_test.yml b/.github/workflows/keyboard_plugin_test.yml index 753d31dda..3d7d3d5d4 100644 --- a/.github/workflows/keyboard_plugin_test.yml +++ b/.github/workflows/keyboard_plugin_test.yml @@ -25,12 +25,12 @@ jobs: steps: - name: Checkout core Blockly - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: path: core-blockly - name: Checkout keyboard navigation plugin - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: 'google/blockly-keyboard-experimentation' ref: 'main' From 10b1d1e848239ee6eff6fb6a1dd3e2cf2ead590f Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 19 Aug 2025 08:32:31 -0700 Subject: [PATCH 04/19] fix: Fix positioning of pasted blocks and comments in RTL. (#9302) * fix: Fix positioning of pasted blocks in RTL. * fix: Clean up after temporarily making the workspace RTL. * fix: Remove .only. * fix: Fix positioning of pasted comments in RTL. * fix: Fix positioning of text preview on collapsed comments in RTL. --- core/clipboard/block_paster.ts | 3 ++ core/comments/comment_view.ts | 5 +++- core/xml.ts | 2 +- tests/mocha/clipboard_test.js | 51 ++++++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/core/clipboard/block_paster.ts b/core/clipboard/block_paster.ts index 750cedca1..e782cc0b0 100644 --- a/core/clipboard/block_paster.ts +++ b/core/clipboard/block_paster.ts @@ -83,6 +83,9 @@ export function moveBlockToNotConflict( block: BlockSvg, originalPosition: Coordinate, ) { + if (block.workspace.RTL) { + originalPosition.x = block.workspace.getWidth() - originalPosition.x; + } const workspace = block.workspace; const snapRadius = config.snapRadius; const bumpOffset = Coordinate.difference( diff --git a/core/comments/comment_view.ts b/core/comments/comment_view.ts index ca0c261c3..b1cd628f8 100644 --- a/core/comments/comment_view.ts +++ b/core/comments/comment_view.ts @@ -368,7 +368,10 @@ export class CommentView implements IRenderedElement { const textPreviewWidth = size.width - foldoutSize.getWidth() - deleteSize.getWidth(); - this.textPreview.setAttribute('x', `${foldoutSize.getWidth()}`); + this.textPreview.setAttribute( + 'x', + `${(this.workspace.RTL ? -1 : 1) * foldoutSize.getWidth()}`, + ); this.textPreview.setAttribute( 'y', `${textPreviewMargin + textPreviewSize.height / 2}`, diff --git a/core/xml.ts b/core/xml.ts index cc26d8c8a..362a59ab2 100644 --- a/core/xml.ts +++ b/core/xml.ts @@ -68,7 +68,7 @@ export function saveWorkspaceComment( if (!skipId) elem.setAttribute('id', comment.id); const workspace = comment.workspace; - const loc = comment.getRelativeToSurfaceXY(); + const loc = comment.getRelativeToSurfaceXY().clone(); loc.x = workspace.RTL ? workspace.getWidth() - loc.x : loc.x; elem.setAttribute('x', `${loc.x}`); elem.setAttribute('y', `${loc.y}`); diff --git a/tests/mocha/clipboard_test.js b/tests/mocha/clipboard_test.js index d58f78b9b..5a513b44a 100644 --- a/tests/mocha/clipboard_test.js +++ b/tests/mocha/clipboard_test.js @@ -157,6 +157,34 @@ suite('Clipboard', function () { ); }); + test('pasted blocks are bumped to not overlap in RTL', function () { + this.workspace.dispose(); + this.workspace = Blockly.inject('blocklyDiv', {rtl: true}); + const block = Blockly.serialization.blocks.append( + { + 'type': 'controls_if', + 'x': 38, + 'y': 13, + }, + this.workspace, + ); + const data = block.toCopyData(); + + const newBlock = Blockly.clipboard.paste(data, this.workspace); + const oldBlockXY = block.getRelativeToSurfaceXY(); + assert.deepEqual( + newBlock.getRelativeToSurfaceXY(), + new Blockly.utils.Coordinate( + oldBlockXY.x - Blockly.config.snapRadius, + oldBlockXY.y + Blockly.config.snapRadius * 2, + ), + ); + + // Restore an LTR workspace. + this.workspace.dispose(); + this.workspace = Blockly.inject('blocklyDiv'); + }); + test('pasted blocks are bumped to be outside the connection snap radius', function () { Blockly.serialization.workspaces.load( { @@ -208,5 +236,28 @@ suite('Clipboard', function () { new Blockly.utils.Coordinate(40, 40), ); }); + + test('pasted comments are bumped to not overlap in RTL', function () { + this.workspace.dispose(); + this.workspace = Blockly.inject('blocklyDiv', {rtl: true}); + Blockly.Xml.domToWorkspace( + Blockly.utils.xml.textToDom( + '', + ), + this.workspace, + ); + const comment = this.workspace.getTopComments(false)[0]; + const data = comment.toCopyData(); + + const newComment = Blockly.clipboard.paste(data, this.workspace); + const oldCommentXY = comment.getRelativeToSurfaceXY(); + assert.deepEqual( + newComment.getRelativeToSurfaceXY(), + new Blockly.utils.Coordinate(oldCommentXY.x - 30, oldCommentXY.y + 30), + ); + // Restore an LTR workspace. + this.workspace.dispose(); + this.workspace = Blockly.inject('blocklyDiv'); + }); }); }); From 9e1db9e332b6b2c609c22fff27cede7bb8b3acc7 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 19 Aug 2025 14:56:59 -0700 Subject: [PATCH 05/19] chore: Fix documentation generation warnings. (#9325) * chore: Replace @yields with @returns. * fix: Update the ESLint config to not require @yields. * chore: Move docs onto getters. --- core/block.ts | 2 +- core/field.ts | 3 --- core/field_input.ts | 6 ++---- eslint.config.mjs | 3 ++- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/core/block.ts b/core/block.ts index d15700a7e..af44facda 100644 --- a/core/block.ts +++ b/core/block.ts @@ -1126,7 +1126,7 @@ export class Block { /** * Returns a generator that provides every field on the block. * - * @yields A generator that can be used to iterate the fields on the block. + * @returns A generator that can be used to iterate the fields on the block. */ *getFields(): Generator { for (const input of this.inputList) { diff --git a/core/field.ts b/core/field.ts index fdcb2d693..3d12880a9 100644 --- a/core/field.ts +++ b/core/field.ts @@ -119,9 +119,6 @@ export abstract class Field return this.size; } - /** - * Sets the size of this field. - */ protected set size_(newValue: Size) { this.size = newValue; } diff --git a/core/field_input.ts b/core/field_input.ts index b68530918..97ad0e959 100644 --- a/core/field_input.ts +++ b/core/field_input.ts @@ -102,11 +102,9 @@ export abstract class FieldInput extends Field< */ override SERIALIZABLE = true; - /** - * Sets the size of this field. Although this appears to be a no-op, it must - * exist since the getter is overridden below. - */ protected override set size_(newValue: Size) { + // Although this appears to be a no-op, it must exist since the getter is + // overridden below. super.size_ = newValue; } diff --git a/eslint.config.mjs b/eslint.config.mjs index 0560586cb..744e02b45 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -89,7 +89,8 @@ function buildTSOverride({files, tsconfig}) { '@typescript-eslint/no-explicit-any': ['off'], // We use this pattern extensively for block (e.g. controls_if) interfaces. '@typescript-eslint/no-empty-object-type': ['off'], - + // TSDoc doesn't support @yields, so don't require that we use it. + 'jsdoc/require-yields': ['off'], // params and returns docs are optional. 'jsdoc/require-param-description': ['off'], 'jsdoc/require-returns': ['off'], From 4a0b710f7c2f7e5f9596e1476f0dc9ffe168344b Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 20 Aug 2025 11:26:45 -0700 Subject: [PATCH 06/19] fix: Show the delete cursor when dragging a block by an editable field. (#9326) --- core/css.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/css.ts b/core/css.ts index 30ee47fc5..503b6362b 100644 --- a/core/css.ts +++ b/core/css.ts @@ -181,7 +181,8 @@ let content = ` cursor: -webkit-grabbing; } -.blocklyDragging.blocklyDraggingDelete { +.blocklyDragging.blocklyDraggingDelete, +.blocklyDragging.blocklyDraggingDelete .blocklyField { cursor: url("<<>>/handdelete.cur"), auto; } From cf93f0721b244e206c3b5287a65dae4cc0fd1eda Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 21 Aug 2025 11:05:43 -0700 Subject: [PATCH 07/19] fix: Correct the alignment of narrow text in input fields. (#9327) * fix: Correct the alignment of narrow text in input fields. * chore: Clarify purpose of first argument to positionTextElement_(). --- core/field.ts | 3 +-- core/field_dropdown.ts | 7 +++---- core/field_input.ts | 26 ++++++++++++++++++++++++-- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/core/field.ts b/core/field.ts index 3d12880a9..d993e197d 100644 --- a/core/field.ts +++ b/core/field.ts @@ -849,8 +849,7 @@ export abstract class Field totalHeight = Math.max(totalHeight, constants!.FIELD_BORDER_RECT_HEIGHT); } - this.size_.height = totalHeight; - this.size_.width = totalWidth; + this.size_ = new Size(totalWidth, totalHeight); this.positionTextElement_(xOffset, contentWidth); this.positionBorderRect_(); diff --git a/core/field_dropdown.ts b/core/field_dropdown.ts index 8b01ccdda..3be5c94c3 100644 --- a/core/field_dropdown.ts +++ b/core/field_dropdown.ts @@ -29,6 +29,7 @@ import * as aria from './utils/aria.js'; import {Coordinate} from './utils/coordinate.js'; import * as dom from './utils/dom.js'; import * as parsing from './utils/parsing.js'; +import {Size} from './utils/size.js'; import * as utilsString from './utils/string.js'; import {Svg} from './utils/svg.js'; @@ -553,8 +554,7 @@ export class FieldDropdown extends Field { } else { arrowWidth = dom.getTextWidth(this.arrow as SVGTSpanElement); } - this.size_.width = imageWidth + arrowWidth + xPadding * 2; - this.size_.height = height; + this.size_ = new Size(imageWidth + arrowWidth + xPadding * 2, height); let arrowX = 0; if (block.RTL) { @@ -595,8 +595,7 @@ export class FieldDropdown extends Field { height / 2 - this.getConstants()!.FIELD_DROPDOWN_SVG_ARROW_SIZE / 2, ); } - this.size_.width = textWidth + arrowWidth + xPadding * 2; - this.size_.height = height; + this.size_ = new Size(textWidth + arrowWidth + xPadding * 2, height); this.positionTextElement_(xPadding, textWidth); } diff --git a/core/field_input.ts b/core/field_input.ts index 97ad0e959..55383a4c1 100644 --- a/core/field_input.ts +++ b/core/field_input.ts @@ -45,6 +45,11 @@ import type {WorkspaceSvg} from './workspace_svg.js'; */ type InputTypes = string | number; +/** + * The minimum width of an input field. + */ +const MINIMUM_WIDTH = 14; + /** * Abstract class for an editable input field. * @@ -113,8 +118,8 @@ export abstract class FieldInput extends Field< */ protected override get size_() { const s = super.size_; - if (s.width < 14) { - s.width = 14; + if (s.width < MINIMUM_WIDTH) { + s.width = MINIMUM_WIDTH; } return s; @@ -730,6 +735,23 @@ export abstract class FieldInput extends Field< return true; } + /** + * Position a field's text element after a size change. This handles both LTR + * and RTL positioning. + * + * @param xMargin x offset to use when positioning the text element. + * @param contentWidth The content width. + */ + protected override positionTextElement_( + xMargin: number, + contentWidth: number, + ) { + const effectiveWidth = xMargin * 2 + contentWidth; + const delta = + effectiveWidth < MINIMUM_WIDTH ? (MINIMUM_WIDTH - effectiveWidth) / 2 : 0; + super.positionTextElement_(xMargin + delta, contentWidth); + } + /** * Use the `getText_` developer hook to override the field's text * representation. When we're currently editing, return the current HTML value From 4891659d6e6ff8c82ec09dfc36ecf0d5b5cfe7be Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 21 Aug 2025 11:15:07 -0700 Subject: [PATCH 08/19] fix: Fix bug that caused inadvertent scrolling when the `WidgetDiv` was shown. (#9291) * fix: Fix bug that caused inadvertent scrolling when the `WidgetDiv` was shown. * chore: Add test to verify that displaying the context menu does not scroll the page. * chore: Clarify comments. * fix: Remove errant `.only`. * chore: Add test to verify that actively focusing a node does not scroll the page. * fix: Remove inadvertent `.only`. --- core/focus_manager.ts | 8 +++- core/interfaces/i_focusable_node.ts | 3 ++ tests/browser/test/basic_playground_test.mjs | 39 ++++++++++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/core/focus_manager.ts b/core/focus_manager.ts index 02e059107..47e432454 100644 --- a/core/focus_manager.ts +++ b/core/focus_manager.ts @@ -309,6 +309,8 @@ export class FocusManager { * Note that this may update the specified node's element's tabindex to ensure * that it can be properly read out by screenreaders while focused. * + * The focused node will not be automatically scrolled into view. + * * @param focusableNode The node that should receive active focus. */ focusNode(focusableNode: IFocusableNode): void { @@ -423,6 +425,8 @@ export class FocusManager { * the returned lambda is called. Additionally, only 1 ephemeral focus context * can be active at any given time (attempting to activate more than one * simultaneously will result in an error being thrown). + * + * This method does not scroll the ephemerally focused element into view. */ takeEphemeralFocus( focusableElement: HTMLElement | SVGElement, @@ -439,7 +443,7 @@ export class FocusManager { if (this.focusedNode) { this.passivelyFocusNode(this.focusedNode, null); } - focusableElement.focus(); + focusableElement.focus({preventScroll: true}); let hasFinishedEphemeralFocus = false; return () => { @@ -574,7 +578,7 @@ export class FocusManager { } this.setNodeToVisualActiveFocus(node); - elem.focus(); + elem.focus({preventScroll: true}); } /** diff --git a/core/interfaces/i_focusable_node.ts b/core/interfaces/i_focusable_node.ts index 24833328d..57ec1a126 100644 --- a/core/interfaces/i_focusable_node.ts +++ b/core/interfaces/i_focusable_node.ts @@ -59,6 +59,9 @@ export interface IFocusableNode { * they should avoid the following: * - Creating or removing DOM elements (including via the renderer or drawer). * - Affecting focus via DOM focus() calls or the FocusManager. + * + * Implementations may consider scrolling themselves into view here; that is + * not handled by the focus manager. */ onNodeFocus(): void; diff --git a/tests/browser/test/basic_playground_test.mjs b/tests/browser/test/basic_playground_test.mjs index 4c54523bd..c7c8a5a37 100644 --- a/tests/browser/test/basic_playground_test.mjs +++ b/tests/browser/test/basic_playground_test.mjs @@ -101,6 +101,45 @@ suite('Right Clicking on Blocks', function () { await contextMenuSelect(this.browser, this.block, 'Remove Comment'); chai.assert.isNull(await getCommentText(this.browser, this.block.id)); }); + + test('does not scroll the page when node is ephemerally focused', async function () { + const initialScroll = await this.browser.execute(() => { + return window.scrollY; + }); + // This left-right-left sequence was necessary to reproduce unintended + // scrolling; regardless of the number of clicks/context menu activations, + // the page should not scroll. + this.block.click({button: 2}); + this.block.click({button: 0}); + this.block.click({button: 2}); + await this.browser.pause(250); + const finalScroll = await this.browser.execute(() => { + return window.scrollY; + }); + + chai.assert.equal(initialScroll, finalScroll); + }); + + test('does not scroll the page when node is actively focused', async function () { + await this.browser.setWindowSize(500, 300); + await this.browser.setViewport({width: 500, height: 300}); + const initialScroll = await this.browser.execute((blockId) => { + window.scrollTo(0, document.body.scrollHeight); + return window.scrollY; + }, this.block.id); + await this.browser.execute(() => { + Blockly.getFocusManager().focusNode( + Blockly.getMainWorkspace().getToolbox(), + ); + }); + const finalScroll = await this.browser.execute(() => { + return window.scrollY; + }); + + chai.assert.equal(initialScroll, finalScroll); + await this.browser.setWindowSize(800, 600); + await this.browser.setViewport({width: 800, height: 600}); + }); }); suite('Disabling', function () { From c32f6db02287e0140350f7693fc15888ffae656e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Aug 2025 12:06:10 -0700 Subject: [PATCH 09/19] chore(deps): bump eslint-plugin-prettier from 5.5.1 to 5.5.4 (#9319) Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 5.5.1 to 5.5.4. - [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases) - [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v5.5.1...v5.5.4) --- updated-dependencies: - dependency-name: eslint-plugin-prettier dependency-version: 5.5.4 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d30a69df6..285fbba58 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4164,10 +4164,11 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.1.tgz", - "integrity": "sha512-dobTkHT6XaEVOo8IO90Q4DOSxnm3Y151QxPJlM/vKC0bVy+d6cVWQZLlFiuZPP0wS6vZwSKeJgKkcS+KfMBlRw==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.4.tgz", + "integrity": "sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==", "dev": true, + "license": "MIT", "dependencies": { "prettier-linter-helpers": "^1.0.0", "synckit": "^0.11.7" From be5f5a2a0a3d8271c15eaf6ece4c73023a184d88 Mon Sep 17 00:00:00 2001 From: Ennis Nian Date: Fri, 22 Aug 2025 04:59:09 +0800 Subject: [PATCH 10/19] fix: pointercancel event is not handled (#9250) --- core/touch.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/core/touch.ts b/core/touch.ts index 8fb2cd229..9af3b1f94 100644 --- a/core/touch.ts +++ b/core/touch.ts @@ -46,6 +46,7 @@ export const TOUCH_MAP: {[key: string]: string[]} = { 'mouseup': ['pointerup', 'pointercancel'], 'touchend': ['pointerup'], 'touchcancel': ['pointercancel'], + 'pointerup': ['pointerup', 'pointercancel'], }; /** PID of queued long-press task. */ From e358f4e7eeeffe93b995d6d5df0d83523a5a388d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Aug 2025 20:01:03 +0100 Subject: [PATCH 11/19] chore(deps): bump eslint-config-prettier from 10.1.5 to 10.1.8 (#9321) Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 10.1.5 to 10.1.8. - [Release notes](https://github.com/prettier/eslint-config-prettier/releases) - [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/eslint-config-prettier/compare/v10.1.5...v10.1.8) --- updated-dependencies: - dependency-name: eslint-config-prettier dependency-version: 10.1.8 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 285fbba58..0f8f34104 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4076,10 +4076,11 @@ } }, "node_modules/eslint-config-prettier": { - "version": "10.1.5", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.5.tgz", - "integrity": "sha512-zc1UmCpNltmVY34vuLRV61r1K27sWuX39E+uyUnY8xS2Bex88VV9cugG+UZbRSRGtGyFboj+D8JODyme1plMpw==", + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", + "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, + "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, From cb698928251738e2c912b197479813c535c2f57f Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 22 Aug 2025 14:55:07 -0700 Subject: [PATCH 12/19] fix: Allow reregistering fields. (#9290) --- core/field_registry.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/field_registry.ts b/core/field_registry.ts index 06bb9acd0..e02ece75c 100644 --- a/core/field_registry.ts +++ b/core/field_registry.ts @@ -56,11 +56,11 @@ export interface RegistrableField { * @param type The field type name as used in the JSON definition. * @param fieldClass The field class containing a fromJson function that can * construct an instance of the field. - * @throws {Error} if the type name is empty, the field is already registered, - * or the fieldClass is not an object containing a fromJson function. + * @throws {Error} if the type name is empty or the fieldClass is not an object + * containing a fromJson function. */ export function register(type: string, fieldClass: RegistrableField) { - registry.register(registry.Type.FIELD, type, fieldClass); + registry.register(registry.Type.FIELD, type, fieldClass, true); } /** From aeb3e5e1435e0fc5769cea62170de35c2b8e84a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Aug 2025 09:08:01 -0700 Subject: [PATCH 13/19] chore(deps): bump chai from 5.2.1 to 6.0.1 (#9330) * chore(deps): bump chai from 5.2.1 to 6.0.1 Bumps [chai](https://github.com/chaijs/chai) from 5.2.1 to 6.0.1. - [Release notes](https://github.com/chaijs/chai/releases) - [Changelog](https://github.com/chaijs/chai/blob/main/History.md) - [Commits](https://github.com/chaijs/chai/compare/v5.2.1...v6.0.1) --- updated-dependencies: - dependency-name: chai dependency-version: 6.0.1 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * fix: Fix Chai import path. --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Aaron Dodson --- package-lock.json | 60 ++----------------- package.json | 2 +- tests/mocha/block_json_test.js | 2 +- tests/mocha/block_test.js | 2 +- tests/mocha/blocks/lists_test.js | 2 +- tests/mocha/blocks/logic_ternary_test.js | 2 +- tests/mocha/blocks/loops_test.js | 2 +- tests/mocha/blocks/procedures_test.js | 2 +- tests/mocha/blocks/variables_test.js | 2 +- tests/mocha/clipboard_test.js | 2 +- tests/mocha/comment_deserialization_test.js | 2 +- tests/mocha/comment_test.js | 2 +- tests/mocha/comment_view_test.js | 2 +- tests/mocha/connection_checker_test.js | 2 +- tests/mocha/connection_db_test.js | 2 +- tests/mocha/connection_test.js | 2 +- tests/mocha/contextmenu_items_test.js | 2 +- tests/mocha/contextmenu_test.js | 2 +- tests/mocha/cursor_test.js | 2 +- tests/mocha/dialog_test.js | 2 +- tests/mocha/dropdowndiv_test.js | 2 +- tests/mocha/event_block_change_test.js | 2 +- tests/mocha/event_block_create_test.js | 2 +- tests/mocha/event_block_delete_test.js | 2 +- tests/mocha/event_block_drag_test.js | 2 +- ...nt_block_field_intermediate_change_test.js | 2 +- tests/mocha/event_block_move_test.js | 2 +- tests/mocha/event_bubble_open_test.js | 2 +- tests/mocha/event_click_test.js | 2 +- tests/mocha/event_comment_change_test.js | 2 +- tests/mocha/event_comment_collapse_test.js | 2 +- tests/mocha/event_comment_create_test.js | 2 +- tests/mocha/event_comment_delete_test.js | 2 +- tests/mocha/event_comment_drag_test.js | 2 +- tests/mocha/event_comment_move_test.js | 2 +- tests/mocha/event_comment_resize_test.js | 2 +- tests/mocha/event_selected_test.js | 2 +- tests/mocha/event_test.js | 2 +- tests/mocha/event_theme_change_test.js | 2 +- tests/mocha/event_toolbox_item_select_test.js | 2 +- tests/mocha/event_trashcan_open_test.js | 2 +- tests/mocha/event_var_create_test.js | 2 +- tests/mocha/event_var_delete_test.js | 2 +- tests/mocha/event_var_rename_test.js | 2 +- tests/mocha/event_var_type_change_test.js | 2 +- tests/mocha/event_viewport_test.js | 2 +- tests/mocha/extensions_test.js | 2 +- tests/mocha/field_checkbox_test.js | 2 +- tests/mocha/field_colour_test.js | 2 +- tests/mocha/field_dropdown_test.js | 2 +- tests/mocha/field_image_test.js | 2 +- tests/mocha/field_label_serializable_test.js | 2 +- tests/mocha/field_label_test.js | 2 +- tests/mocha/field_number_test.js | 2 +- tests/mocha/field_registry_test.js | 2 +- tests/mocha/field_test.js | 2 +- tests/mocha/field_textinput_test.js | 2 +- tests/mocha/field_variable_test.js | 2 +- tests/mocha/flyout_test.js | 2 +- tests/mocha/focus_manager_test.js | 2 +- tests/mocha/focusable_tree_traverser_test.js | 2 +- tests/mocha/generator_test.js | 2 +- tests/mocha/gesture_test.js | 2 +- tests/mocha/icon_test.js | 2 +- tests/mocha/input_test.js | 2 +- tests/mocha/insertion_marker_test.js | 2 +- tests/mocha/jso_deserialization_test.js | 2 +- tests/mocha/jso_serialization_test.js | 2 +- tests/mocha/json_test.js | 2 +- .../keyboard_navigation_controller_test.js | 2 +- tests/mocha/layering_test.js | 2 +- tests/mocha/metrics_test.js | 2 +- tests/mocha/mutator_test.js | 2 +- tests/mocha/names_test.js | 2 +- tests/mocha/navigation_test.js | 2 +- tests/mocha/old_workspace_comment_test.js | 2 +- tests/mocha/procedure_map_test.js | 2 +- tests/mocha/rect_test.js | 2 +- tests/mocha/registry_test.js | 2 +- tests/mocha/render_management_test.js | 2 +- tests/mocha/serializer_test.js | 2 +- tests/mocha/shortcut_items_test.js | 2 +- tests/mocha/shortcut_registry_test.js | 2 +- tests/mocha/test_helpers/code_generation.js | 2 +- tests/mocha/test_helpers/events.js | 2 +- tests/mocha/test_helpers/fields.js | 2 +- tests/mocha/test_helpers/procedures.js | 2 +- tests/mocha/test_helpers/serialization.js | 2 +- tests/mocha/test_helpers/variables.js | 2 +- tests/mocha/test_helpers/warnings.js | 2 +- tests/mocha/test_helpers/workspace.js | 2 +- tests/mocha/theme_test.js | 2 +- tests/mocha/toast_test.js | 2 +- tests/mocha/toolbox_test.js | 2 +- tests/mocha/tooltip_test.js | 2 +- tests/mocha/touch_test.js | 2 +- tests/mocha/trashcan_test.js | 2 +- tests/mocha/utils_test.js | 2 +- tests/mocha/variable_map_test.js | 2 +- tests/mocha/variable_model_test.js | 2 +- tests/mocha/widget_div_test.js | 2 +- tests/mocha/workspace_comment_test.js | 2 +- tests/mocha/workspace_svg_test.js | 2 +- tests/mocha/xml_test.js | 2 +- tests/mocha/zoom_controls_test.js | 2 +- 105 files changed, 108 insertions(+), 160 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0f8f34104..f7a8f9426 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "@microsoft/api-extractor": "^7.29.5", "ajv": "^8.17.1", "async-done": "^2.0.0", - "chai": "^5.1.1", + "chai": "^6.0.1", "concurrently": "^9.0.1", "eslint": "^9.15.0", "eslint-config-google": "^0.14.0", @@ -2489,15 +2489,6 @@ "node": ">=0.10.0" } }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, "node_modules/assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -2882,18 +2873,11 @@ } }, "node_modules/chai": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.1.tgz", - "integrity": "sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.0.1.tgz", + "integrity": "sha512-/JOoU2//6p5vCXh00FpNgtlw0LjvhGttaWc+y7wpW9yjBm3ys0dI8tSKZxIOgNruz5J0RleccatSIC3uxEZP0g==", "dev": true, "license": "MIT", - "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - }, "engines": { "node": ">=18" } @@ -2914,15 +2898,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/check-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", - "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", - "dev": true, - "engines": { - "node": ">= 16" - } - }, "node_modules/cheerio": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", @@ -3586,15 +3561,6 @@ "node": ">=0.10" } }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -6794,15 +6760,6 @@ "dev": true, "license": "MIT" }, - "node_modules/loupe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", - "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.1" - } - }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -7731,15 +7688,6 @@ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, - "node_modules/pathval": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", - "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", - "dev": true, - "engines": { - "node": ">= 14.16" - } - }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", diff --git a/package.json b/package.json index 6cfd025c7..c52a79003 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,7 @@ "@microsoft/api-extractor": "^7.29.5", "ajv": "^8.17.1", "async-done": "^2.0.0", - "chai": "^5.1.1", + "chai": "^6.0.1", "concurrently": "^9.0.1", "eslint": "^9.15.0", "eslint-config-google": "^0.14.0", diff --git a/tests/mocha/block_json_test.js b/tests/mocha/block_json_test.js index 4baccef6b..31abd6e34 100644 --- a/tests/mocha/block_json_test.js +++ b/tests/mocha/block_json_test.js @@ -5,7 +5,7 @@ */ import {Align} from '../../build/src/core/inputs/align.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/block_test.js b/tests/mocha/block_test.js index e3bd47090..1f8f9b1ee 100644 --- a/tests/mocha/block_test.js +++ b/tests/mocha/block_test.js @@ -11,7 +11,7 @@ import {IconType} from '../../build/src/core/icons/icon_types.js'; import {EndRowInput} from '../../build/src/core/inputs/end_row_input.js'; import {isCommentIcon} from '../../build/src/core/interfaces/i_comment_icon.js'; import {Size} from '../../build/src/core/utils/size.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {createRenderedBlock} from './test_helpers/block_definitions.js'; import { createChangeListenerSpy, diff --git a/tests/mocha/blocks/lists_test.js b/tests/mocha/blocks/lists_test.js index 490109d22..e749fae90 100644 --- a/tests/mocha/blocks/lists_test.js +++ b/tests/mocha/blocks/lists_test.js @@ -5,7 +5,7 @@ */ import {ConnectionType} from '../../../build/src/core/connection_type.js'; -import {assert} from '../../../node_modules/chai/chai.js'; +import {assert} from '../../../node_modules/chai/index.js'; import {defineStatementBlock} from '../test_helpers/block_definitions.js'; import {runSerializationTestSuite} from '../test_helpers/serialization.js'; import { diff --git a/tests/mocha/blocks/logic_ternary_test.js b/tests/mocha/blocks/logic_ternary_test.js index 719209359..3d343a7ca 100644 --- a/tests/mocha/blocks/logic_ternary_test.js +++ b/tests/mocha/blocks/logic_ternary_test.js @@ -5,7 +5,7 @@ */ import * as eventUtils from '../../../build/src/core/events/utils.js'; -import {assert} from '../../../node_modules/chai/chai.js'; +import {assert} from '../../../node_modules/chai/index.js'; import {runSerializationTestSuite} from '../test_helpers/serialization.js'; import { sharedTestSetup, diff --git a/tests/mocha/blocks/loops_test.js b/tests/mocha/blocks/loops_test.js index f8d74916c..eb040c884 100644 --- a/tests/mocha/blocks/loops_test.js +++ b/tests/mocha/blocks/loops_test.js @@ -5,7 +5,7 @@ */ import * as Blockly from '../../../build/src/core/blockly.js'; -import {assert} from '../../../node_modules/chai/chai.js'; +import {assert} from '../../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/blocks/procedures_test.js b/tests/mocha/blocks/procedures_test.js index 4b20662cf..5ac651fe4 100644 --- a/tests/mocha/blocks/procedures_test.js +++ b/tests/mocha/blocks/procedures_test.js @@ -5,7 +5,7 @@ */ import * as Blockly from '../../../build/src/core/blockly.js'; -import {assert} from '../../../node_modules/chai/chai.js'; +import {assert} from '../../../node_modules/chai/index.js'; import {defineRowBlock} from '../test_helpers/block_definitions.js'; import { assertCallBlockStructure, diff --git a/tests/mocha/blocks/variables_test.js b/tests/mocha/blocks/variables_test.js index d12691dd4..a317fe11b 100644 --- a/tests/mocha/blocks/variables_test.js +++ b/tests/mocha/blocks/variables_test.js @@ -5,7 +5,7 @@ */ import {nameUsedWithConflictingParam} from '../../../build/src/core/variables.js'; -import {assert} from '../../../node_modules/chai/chai.js'; +import {assert} from '../../../node_modules/chai/index.js'; import { MockParameterModelWithVar, MockProcedureModel, diff --git a/tests/mocha/clipboard_test.js b/tests/mocha/clipboard_test.js index 5a513b44a..ff49c0e30 100644 --- a/tests/mocha/clipboard_test.js +++ b/tests/mocha/clipboard_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { assertEventFired, createChangeListenerSpy, diff --git a/tests/mocha/comment_deserialization_test.js b/tests/mocha/comment_deserialization_test.js index 54ee0b2ff..f834eb0f3 100644 --- a/tests/mocha/comment_deserialization_test.js +++ b/tests/mocha/comment_deserialization_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/comment_test.js b/tests/mocha/comment_test.js index 0ff1c239e..1f52df8fd 100644 --- a/tests/mocha/comment_test.js +++ b/tests/mocha/comment_test.js @@ -5,7 +5,7 @@ */ import {EventType} from '../../build/src/core/events/type.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {assertEventFired} from './test_helpers/events.js'; import { sharedTestSetup, diff --git a/tests/mocha/comment_view_test.js b/tests/mocha/comment_view_test.js index 57a247424..a60a7a973 100644 --- a/tests/mocha/comment_view_test.js +++ b/tests/mocha/comment_view_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/connection_checker_test.js b/tests/mocha/connection_checker_test.js index fee2966d7..bdbcb70a6 100644 --- a/tests/mocha/connection_checker_test.js +++ b/tests/mocha/connection_checker_test.js @@ -5,7 +5,7 @@ */ import {ConnectionType} from '../../build/src/core/connection_type.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/connection_db_test.js b/tests/mocha/connection_db_test.js index 04f685124..459c59e3a 100644 --- a/tests/mocha/connection_db_test.js +++ b/tests/mocha/connection_db_test.js @@ -6,7 +6,7 @@ import {ConnectionType} from '../../build/src/core/connection_type.js'; import * as idGenerator from '../../build/src/core/utils/idgenerator.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/connection_test.js b/tests/mocha/connection_test.js index cefea1784..b36f358ea 100644 --- a/tests/mocha/connection_test.js +++ b/tests/mocha/connection_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { defineRowBlock, defineStackBlock, diff --git a/tests/mocha/contextmenu_items_test.js b/tests/mocha/contextmenu_items_test.js index d9044ec7e..08ab5d526 100644 --- a/tests/mocha/contextmenu_items_test.js +++ b/tests/mocha/contextmenu_items_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/contextmenu_test.js b/tests/mocha/contextmenu_test.js index 65896112b..df5bf79dc 100644 --- a/tests/mocha/contextmenu_test.js +++ b/tests/mocha/contextmenu_test.js @@ -6,7 +6,7 @@ import {callbackFactory} from '../../build/src/core/contextmenu.js'; import * as xmlUtils from '../../build/src/core/utils/xml.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/cursor_test.js b/tests/mocha/cursor_test.js index 6f841ae09..02426ae26 100644 --- a/tests/mocha/cursor_test.js +++ b/tests/mocha/cursor_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {createRenderedBlock} from './test_helpers/block_definitions.js'; import { sharedTestSetup, diff --git a/tests/mocha/dialog_test.js b/tests/mocha/dialog_test.js index f250ff0f8..7d4147d83 100644 --- a/tests/mocha/dialog_test.js +++ b/tests/mocha/dialog_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/dropdowndiv_test.js b/tests/mocha/dropdowndiv_test.js index fc792fbaf..495237f18 100644 --- a/tests/mocha/dropdowndiv_test.js +++ b/tests/mocha/dropdowndiv_test.js @@ -6,7 +6,7 @@ import {Rect} from '../../build/src/core/utils/rect.js'; import * as style from '../../build/src/core/utils/style.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/event_block_change_test.js b/tests/mocha/event_block_change_test.js index 7de0a23b6..9e1f9c310 100644 --- a/tests/mocha/event_block_change_test.js +++ b/tests/mocha/event_block_change_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {defineMutatorBlocks} from './test_helpers/block_definitions.js'; import { sharedTestSetup, diff --git a/tests/mocha/event_block_create_test.js b/tests/mocha/event_block_create_test.js index f59f9435e..1672b56bb 100644 --- a/tests/mocha/event_block_create_test.js +++ b/tests/mocha/event_block_create_test.js @@ -5,7 +5,7 @@ */ import {EventType} from '../../build/src/core/events/type.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {defineRowBlock} from './test_helpers/block_definitions.js'; import {assertEventFired} from './test_helpers/events.js'; import { diff --git a/tests/mocha/event_block_delete_test.js b/tests/mocha/event_block_delete_test.js index d74b6aa06..e2fb5b8ce 100644 --- a/tests/mocha/event_block_delete_test.js +++ b/tests/mocha/event_block_delete_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {defineRowBlock} from './test_helpers/block_definitions.js'; import { sharedTestSetup, diff --git a/tests/mocha/event_block_drag_test.js b/tests/mocha/event_block_drag_test.js index 9b0f2031a..cc71e3bf0 100644 --- a/tests/mocha/event_block_drag_test.js +++ b/tests/mocha/event_block_drag_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {defineRowBlock} from './test_helpers/block_definitions.js'; import { sharedTestSetup, diff --git a/tests/mocha/event_block_field_intermediate_change_test.js b/tests/mocha/event_block_field_intermediate_change_test.js index 0ff4e1bbf..d917dadcd 100644 --- a/tests/mocha/event_block_field_intermediate_change_test.js +++ b/tests/mocha/event_block_field_intermediate_change_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/event_block_move_test.js b/tests/mocha/event_block_move_test.js index b93457e14..6d1890eeb 100644 --- a/tests/mocha/event_block_move_test.js +++ b/tests/mocha/event_block_move_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {defineRowBlock} from './test_helpers/block_definitions.js'; import { sharedTestSetup, diff --git a/tests/mocha/event_bubble_open_test.js b/tests/mocha/event_bubble_open_test.js index 099a625f6..a445a6a78 100644 --- a/tests/mocha/event_bubble_open_test.js +++ b/tests/mocha/event_bubble_open_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {defineMutatorBlocks} from './test_helpers/block_definitions.js'; import { sharedTestSetup, diff --git a/tests/mocha/event_click_test.js b/tests/mocha/event_click_test.js index 6e1876948..5c4afbcad 100644 --- a/tests/mocha/event_click_test.js +++ b/tests/mocha/event_click_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {defineRowBlock} from './test_helpers/block_definitions.js'; import { sharedTestSetup, diff --git a/tests/mocha/event_comment_change_test.js b/tests/mocha/event_comment_change_test.js index ed5f4d9f6..edb539ef5 100644 --- a/tests/mocha/event_comment_change_test.js +++ b/tests/mocha/event_comment_change_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/event_comment_collapse_test.js b/tests/mocha/event_comment_collapse_test.js index e2d275307..5c3f61054 100644 --- a/tests/mocha/event_comment_collapse_test.js +++ b/tests/mocha/event_comment_collapse_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/event_comment_create_test.js b/tests/mocha/event_comment_create_test.js index df919541d..71ef8ed1b 100644 --- a/tests/mocha/event_comment_create_test.js +++ b/tests/mocha/event_comment_create_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/event_comment_delete_test.js b/tests/mocha/event_comment_delete_test.js index 2e2bb45c4..dd9f0dd22 100644 --- a/tests/mocha/event_comment_delete_test.js +++ b/tests/mocha/event_comment_delete_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/event_comment_drag_test.js b/tests/mocha/event_comment_drag_test.js index d214e0adb..f6685cc5b 100644 --- a/tests/mocha/event_comment_drag_test.js +++ b/tests/mocha/event_comment_drag_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/event_comment_move_test.js b/tests/mocha/event_comment_move_test.js index aae3fdfe6..b3acea990 100644 --- a/tests/mocha/event_comment_move_test.js +++ b/tests/mocha/event_comment_move_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/event_comment_resize_test.js b/tests/mocha/event_comment_resize_test.js index b74e1abb2..bed3e733a 100644 --- a/tests/mocha/event_comment_resize_test.js +++ b/tests/mocha/event_comment_resize_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/event_selected_test.js b/tests/mocha/event_selected_test.js index 1ce8306db..8731099ec 100644 --- a/tests/mocha/event_selected_test.js +++ b/tests/mocha/event_selected_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {defineRowBlock} from './test_helpers/block_definitions.js'; import { sharedTestSetup, diff --git a/tests/mocha/event_test.js b/tests/mocha/event_test.js index 7423f22f7..a5019c8a9 100644 --- a/tests/mocha/event_test.js +++ b/tests/mocha/event_test.js @@ -6,7 +6,7 @@ import * as Blockly from '../../build/src/core/blockly.js'; import * as eventUtils from '../../build/src/core/events/utils.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { assertEventEquals, assertNthCallEventArgEquals, diff --git a/tests/mocha/event_theme_change_test.js b/tests/mocha/event_theme_change_test.js index f20f745b6..396347c9e 100644 --- a/tests/mocha/event_theme_change_test.js +++ b/tests/mocha/event_theme_change_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/event_toolbox_item_select_test.js b/tests/mocha/event_toolbox_item_select_test.js index bf6a9a462..02484c35b 100644 --- a/tests/mocha/event_toolbox_item_select_test.js +++ b/tests/mocha/event_toolbox_item_select_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/event_trashcan_open_test.js b/tests/mocha/event_trashcan_open_test.js index 2c809f2df..47da09a07 100644 --- a/tests/mocha/event_trashcan_open_test.js +++ b/tests/mocha/event_trashcan_open_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/event_var_create_test.js b/tests/mocha/event_var_create_test.js index e374c4965..79af41281 100644 --- a/tests/mocha/event_var_create_test.js +++ b/tests/mocha/event_var_create_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/event_var_delete_test.js b/tests/mocha/event_var_delete_test.js index b06943d9a..93d9ef0ba 100644 --- a/tests/mocha/event_var_delete_test.js +++ b/tests/mocha/event_var_delete_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/event_var_rename_test.js b/tests/mocha/event_var_rename_test.js index 7fbd185ab..b6d77cb35 100644 --- a/tests/mocha/event_var_rename_test.js +++ b/tests/mocha/event_var_rename_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/event_var_type_change_test.js b/tests/mocha/event_var_type_change_test.js index d19b0421a..066c145a3 100644 --- a/tests/mocha/event_var_type_change_test.js +++ b/tests/mocha/event_var_type_change_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/event_viewport_test.js b/tests/mocha/event_viewport_test.js index edacc0da6..cd11079fa 100644 --- a/tests/mocha/event_viewport_test.js +++ b/tests/mocha/event_viewport_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/extensions_test.js b/tests/mocha/extensions_test.js index 66772cbea..8c41861d5 100644 --- a/tests/mocha/extensions_test.js +++ b/tests/mocha/extensions_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/field_checkbox_test.js b/tests/mocha/field_checkbox_test.js index 08190fed8..74357338a 100644 --- a/tests/mocha/field_checkbox_test.js +++ b/tests/mocha/field_checkbox_test.js @@ -5,7 +5,7 @@ */ import * as Blockly from '../../build/src/core/blockly.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {defineRowBlock} from './test_helpers/block_definitions.js'; import { assertFieldValue, diff --git a/tests/mocha/field_colour_test.js b/tests/mocha/field_colour_test.js index 262f978f2..975d5a01d 100644 --- a/tests/mocha/field_colour_test.js +++ b/tests/mocha/field_colour_test.js @@ -5,7 +5,7 @@ */ import * as Blockly from '../../build/src/core/blockly.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { createTestBlock, defineRowBlock, diff --git a/tests/mocha/field_dropdown_test.js b/tests/mocha/field_dropdown_test.js index e9bc15914..a1731e812 100644 --- a/tests/mocha/field_dropdown_test.js +++ b/tests/mocha/field_dropdown_test.js @@ -5,7 +5,7 @@ */ import * as Blockly from '../../build/src/core/blockly.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { createTestBlock, defineRowBlock, diff --git a/tests/mocha/field_image_test.js b/tests/mocha/field_image_test.js index a02b3f6b6..f0358703b 100644 --- a/tests/mocha/field_image_test.js +++ b/tests/mocha/field_image_test.js @@ -5,7 +5,7 @@ */ import * as Blockly from '../../build/src/core/blockly.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { assertFieldValue, runConstructorSuiteTests, diff --git a/tests/mocha/field_label_serializable_test.js b/tests/mocha/field_label_serializable_test.js index a83171341..443cc6d17 100644 --- a/tests/mocha/field_label_serializable_test.js +++ b/tests/mocha/field_label_serializable_test.js @@ -5,7 +5,7 @@ */ import * as Blockly from '../../build/src/core/blockly.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { createTestBlock, defineRowBlock, diff --git a/tests/mocha/field_label_test.js b/tests/mocha/field_label_test.js index cf5b49044..bae600aff 100644 --- a/tests/mocha/field_label_test.js +++ b/tests/mocha/field_label_test.js @@ -5,7 +5,7 @@ */ import * as Blockly from '../../build/src/core/blockly.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {createTestBlock} from './test_helpers/block_definitions.js'; import { assertFieldValue, diff --git a/tests/mocha/field_number_test.js b/tests/mocha/field_number_test.js index 768766bf0..3c12fed82 100644 --- a/tests/mocha/field_number_test.js +++ b/tests/mocha/field_number_test.js @@ -5,7 +5,7 @@ */ import * as Blockly from '../../build/src/core/blockly.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {defineRowBlock} from './test_helpers/block_definitions.js'; import {runTestCases} from './test_helpers/common.js'; import { diff --git a/tests/mocha/field_registry_test.js b/tests/mocha/field_registry_test.js index 26b33c16c..1f19477de 100644 --- a/tests/mocha/field_registry_test.js +++ b/tests/mocha/field_registry_test.js @@ -5,7 +5,7 @@ */ import * as Blockly from '../../build/src/core/blockly.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/field_test.js b/tests/mocha/field_test.js index 38f9662d6..422b04734 100644 --- a/tests/mocha/field_test.js +++ b/tests/mocha/field_test.js @@ -5,7 +5,7 @@ */ import * as Blockly from '../../build/src/core/blockly.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { addBlockTypeToCleanup, addMessageToCleanup, diff --git a/tests/mocha/field_textinput_test.js b/tests/mocha/field_textinput_test.js index 7dc105f72..7cafd00d9 100644 --- a/tests/mocha/field_textinput_test.js +++ b/tests/mocha/field_textinput_test.js @@ -5,7 +5,7 @@ */ import * as Blockly from '../../build/src/core/blockly.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { createTestBlock, defineRowBlock, diff --git a/tests/mocha/field_variable_test.js b/tests/mocha/field_variable_test.js index 2dc8d35a5..58a209775 100644 --- a/tests/mocha/field_variable_test.js +++ b/tests/mocha/field_variable_test.js @@ -5,7 +5,7 @@ */ import * as Blockly from '../../build/src/core/blockly.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { createTestBlock, defineRowBlock, diff --git a/tests/mocha/flyout_test.js b/tests/mocha/flyout_test.js index f6d3019df..998279a08 100644 --- a/tests/mocha/flyout_test.js +++ b/tests/mocha/flyout_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/focus_manager_test.js b/tests/mocha/focus_manager_test.js index 26dcb8dbe..490fa4301 100644 --- a/tests/mocha/focus_manager_test.js +++ b/tests/mocha/focus_manager_test.js @@ -8,7 +8,7 @@ import { FocusManager, getFocusManager, } from '../../build/src/core/focus_manager.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/focusable_tree_traverser_test.js b/tests/mocha/focusable_tree_traverser_test.js index 0f88e1106..a384dd4be 100644 --- a/tests/mocha/focusable_tree_traverser_test.js +++ b/tests/mocha/focusable_tree_traverser_test.js @@ -6,7 +6,7 @@ import {FocusManager} from '../../build/src/core/focus_manager.js'; import {FocusableTreeTraverser} from '../../build/src/core/utils/focusable_tree_traverser.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/generator_test.js b/tests/mocha/generator_test.js index 527448eac..3c377e7c1 100644 --- a/tests/mocha/generator_test.js +++ b/tests/mocha/generator_test.js @@ -10,7 +10,7 @@ import {JavascriptGenerator} from '../../build/src/generators/javascript/javascr import {LuaGenerator} from '../../build/src/generators/lua/lua_generator.js'; import {PhpGenerator} from '../../build/src/generators/php/php_generator.js'; import {PythonGenerator} from '../../build/src/generators/python/python_generator.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/gesture_test.js b/tests/mocha/gesture_test.js index 3f53b8894..af4c599fe 100644 --- a/tests/mocha/gesture_test.js +++ b/tests/mocha/gesture_test.js @@ -5,7 +5,7 @@ */ import {EventType} from '../../build/src/core/events/type.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {defineBasicBlockWithField} from './test_helpers/block_definitions.js'; import {assertEventFired, assertEventNotFired} from './test_helpers/events.js'; import { diff --git a/tests/mocha/icon_test.js b/tests/mocha/icon_test.js index 5855fcfc5..ba1b71160 100644 --- a/tests/mocha/icon_test.js +++ b/tests/mocha/icon_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {defineEmptyBlock} from './test_helpers/block_definitions.js'; import {MockIcon, MockSerializableIcon} from './test_helpers/icon_mocks.js'; import { diff --git a/tests/mocha/input_test.js b/tests/mocha/input_test.js index 0c2b0973e..dfa30858e 100644 --- a/tests/mocha/input_test.js +++ b/tests/mocha/input_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/insertion_marker_test.js b/tests/mocha/insertion_marker_test.js index 9ccf8a00b..f8215a847 100644 --- a/tests/mocha/insertion_marker_test.js +++ b/tests/mocha/insertion_marker_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/jso_deserialization_test.js b/tests/mocha/jso_deserialization_test.js index dfd3e62b7..f6b47d7de 100644 --- a/tests/mocha/jso_deserialization_test.js +++ b/tests/mocha/jso_deserialization_test.js @@ -5,7 +5,7 @@ */ import {EventType} from '../../build/src/core/events/type.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {assertEventFired} from './test_helpers/events.js'; import { MockParameterModel, diff --git a/tests/mocha/jso_serialization_test.js b/tests/mocha/jso_serialization_test.js index 7cf415e67..4a7d5e9e1 100644 --- a/tests/mocha/jso_serialization_test.js +++ b/tests/mocha/jso_serialization_test.js @@ -5,7 +5,7 @@ */ import * as Blockly from '../../build/src/core/blockly.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { defineRowBlock, defineStackBlock, diff --git a/tests/mocha/json_test.js b/tests/mocha/json_test.js index 471d2fb97..2e4b68df9 100644 --- a/tests/mocha/json_test.js +++ b/tests/mocha/json_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { addMessageToCleanup, sharedTestSetup, diff --git a/tests/mocha/keyboard_navigation_controller_test.js b/tests/mocha/keyboard_navigation_controller_test.js index c7abd863e..dd81e9e4b 100644 --- a/tests/mocha/keyboard_navigation_controller_test.js +++ b/tests/mocha/keyboard_navigation_controller_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/layering_test.js b/tests/mocha/layering_test.js index 1ef0ee697..b84f23252 100644 --- a/tests/mocha/layering_test.js +++ b/tests/mocha/layering_test.js @@ -3,7 +3,7 @@ * Copyright 2023 Google LLC * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/metrics_test.js b/tests/mocha/metrics_test.js index 860e80255..de9a5641a 100644 --- a/tests/mocha/metrics_test.js +++ b/tests/mocha/metrics_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/mutator_test.js b/tests/mocha/mutator_test.js index fb6d8caf0..72b17d0a4 100644 --- a/tests/mocha/mutator_test.js +++ b/tests/mocha/mutator_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { createRenderedBlock, defineMutatorBlocks, diff --git a/tests/mocha/names_test.js b/tests/mocha/names_test.js index 732e28cd5..e449a59fd 100644 --- a/tests/mocha/names_test.js +++ b/tests/mocha/names_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/navigation_test.js b/tests/mocha/navigation_test.js index 5bed2aaab..38dc88894 100644 --- a/tests/mocha/navigation_test.js +++ b/tests/mocha/navigation_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/old_workspace_comment_test.js b/tests/mocha/old_workspace_comment_test.js index 08a2523f5..5038d67ba 100644 --- a/tests/mocha/old_workspace_comment_test.js +++ b/tests/mocha/old_workspace_comment_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/procedure_map_test.js b/tests/mocha/procedure_map_test.js index eebd5a9f3..5e29c6ca0 100644 --- a/tests/mocha/procedure_map_test.js +++ b/tests/mocha/procedure_map_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {MockProcedureModel} from './test_helpers/procedures.js'; import { sharedTestSetup, diff --git a/tests/mocha/rect_test.js b/tests/mocha/rect_test.js index 37712dff3..652837eae 100644 --- a/tests/mocha/rect_test.js +++ b/tests/mocha/rect_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/registry_test.js b/tests/mocha/registry_test.js index 6bcb8b5b0..2d5e22543 100644 --- a/tests/mocha/registry_test.js +++ b/tests/mocha/registry_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/render_management_test.js b/tests/mocha/render_management_test.js index 4de063539..94fa48805 100644 --- a/tests/mocha/render_management_test.js +++ b/tests/mocha/render_management_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/serializer_test.js b/tests/mocha/serializer_test.js index a3a3761e9..efd1f308b 100644 --- a/tests/mocha/serializer_test.js +++ b/tests/mocha/serializer_test.js @@ -5,7 +5,7 @@ */ import * as Blockly from '../../build/src/core/blockly.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { TestCase, TestSuite, diff --git a/tests/mocha/shortcut_items_test.js b/tests/mocha/shortcut_items_test.js index d96ddbfea..dfbae3f09 100644 --- a/tests/mocha/shortcut_items_test.js +++ b/tests/mocha/shortcut_items_test.js @@ -5,7 +5,7 @@ */ import * as Blockly from '../../build/src/core/blockly.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {defineStackBlock} from './test_helpers/block_definitions.js'; import { sharedTestSetup, diff --git a/tests/mocha/shortcut_registry_test.js b/tests/mocha/shortcut_registry_test.js index 5641e17c7..a06f01b9c 100644 --- a/tests/mocha/shortcut_registry_test.js +++ b/tests/mocha/shortcut_registry_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {createTestBlock} from './test_helpers/block_definitions.js'; import { sharedTestSetup, diff --git a/tests/mocha/test_helpers/code_generation.js b/tests/mocha/test_helpers/code_generation.js index 95bd902cd..e61a45653 100644 --- a/tests/mocha/test_helpers/code_generation.js +++ b/tests/mocha/test_helpers/code_generation.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../../node_modules/chai/chai.js'; +import {assert} from '../../../node_modules/chai/index.js'; import {runTestSuites} from './common.js'; /** diff --git a/tests/mocha/test_helpers/events.js b/tests/mocha/test_helpers/events.js index c074bdd77..3e0b1e95d 100644 --- a/tests/mocha/test_helpers/events.js +++ b/tests/mocha/test_helpers/events.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../../node_modules/chai/chai.js'; +import {assert} from '../../../node_modules/chai/index.js'; /** * Creates spy for workspace fireChangeListener diff --git a/tests/mocha/test_helpers/fields.js b/tests/mocha/test_helpers/fields.js index e082abb4c..ab304a808 100644 --- a/tests/mocha/test_helpers/fields.js +++ b/tests/mocha/test_helpers/fields.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../../node_modules/chai/chai.js'; +import {assert} from '../../../node_modules/chai/index.js'; import {runTestCases, TestCase} from './common.js'; /** diff --git a/tests/mocha/test_helpers/procedures.js b/tests/mocha/test_helpers/procedures.js index ecf8c13ad..16ef97335 100644 --- a/tests/mocha/test_helpers/procedures.js +++ b/tests/mocha/test_helpers/procedures.js @@ -6,7 +6,7 @@ import {ConnectionType} from '../../../build/src/core/connection_type.js'; import {VariableModel} from '../../../build/src/core/variable_model.js'; -import {assert} from '../../../node_modules/chai/chai.js'; +import {assert} from '../../../node_modules/chai/index.js'; /** * Asserts that the procedure definition or call block has the expected var diff --git a/tests/mocha/test_helpers/serialization.js b/tests/mocha/test_helpers/serialization.js index c99f508d4..c476eae3d 100644 --- a/tests/mocha/test_helpers/serialization.js +++ b/tests/mocha/test_helpers/serialization.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../../node_modules/chai/chai.js'; +import {assert} from '../../../node_modules/chai/index.js'; import {runTestCases} from './common.js'; /** diff --git a/tests/mocha/test_helpers/variables.js b/tests/mocha/test_helpers/variables.js index 83f175f63..dd19b4904 100644 --- a/tests/mocha/test_helpers/variables.js +++ b/tests/mocha/test_helpers/variables.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../../node_modules/chai/chai.js'; +import {assert} from '../../../node_modules/chai/index.js'; /** * Check if a variable with the given values exists. diff --git a/tests/mocha/test_helpers/warnings.js b/tests/mocha/test_helpers/warnings.js index 0e07f846c..d718a25c1 100644 --- a/tests/mocha/test_helpers/warnings.js +++ b/tests/mocha/test_helpers/warnings.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../../node_modules/chai/chai.js'; +import {assert} from '../../../node_modules/chai/index.js'; /** * Captures the strings sent to console.warn() when calling a function. diff --git a/tests/mocha/test_helpers/workspace.js b/tests/mocha/test_helpers/workspace.js index 917ce6f62..b5f3cadab 100644 --- a/tests/mocha/test_helpers/workspace.js +++ b/tests/mocha/test_helpers/workspace.js @@ -5,7 +5,7 @@ */ import * as eventUtils from '../../../build/src/core/events/utils.js'; -import {assert} from '../../../node_modules/chai/chai.js'; +import {assert} from '../../../node_modules/chai/index.js'; import {workspaceTeardown} from './setup_teardown.js'; import {assertVariableValues} from './variables.js'; import {assertWarnings} from './warnings.js'; diff --git a/tests/mocha/theme_test.js b/tests/mocha/theme_test.js index 1f425dca6..f54641a34 100644 --- a/tests/mocha/theme_test.js +++ b/tests/mocha/theme_test.js @@ -5,7 +5,7 @@ */ import {EventType} from '../../build/src/core/events/type.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {assertEventFired} from './test_helpers/events.js'; import { sharedTestSetup, diff --git a/tests/mocha/toast_test.js b/tests/mocha/toast_test.js index 45e02ad5d..afb7f7f6c 100644 --- a/tests/mocha/toast_test.js +++ b/tests/mocha/toast_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/toolbox_test.js b/tests/mocha/toolbox_test.js index 4e92cd28f..480fdfdc6 100644 --- a/tests/mocha/toolbox_test.js +++ b/tests/mocha/toolbox_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {defineStackBlock} from './test_helpers/block_definitions.js'; import { sharedTestSetup, diff --git a/tests/mocha/tooltip_test.js b/tests/mocha/tooltip_test.js index 1edc8ad6e..0695b9ebe 100644 --- a/tests/mocha/tooltip_test.js +++ b/tests/mocha/tooltip_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/touch_test.js b/tests/mocha/touch_test.js index 775665643..30a9fe727 100644 --- a/tests/mocha/touch_test.js +++ b/tests/mocha/touch_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/trashcan_test.js b/tests/mocha/trashcan_test.js index 5486326f1..d96e00f3a 100644 --- a/tests/mocha/trashcan_test.js +++ b/tests/mocha/trashcan_test.js @@ -6,7 +6,7 @@ import {EventType} from '../../build/src/core/events/type.js'; import * as eventUtils from '../../build/src/core/events/utils.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { defineBasicBlockWithField, defineMutatorBlocks, diff --git a/tests/mocha/utils_test.js b/tests/mocha/utils_test.js index b6228448d..accf164b7 100644 --- a/tests/mocha/utils_test.js +++ b/tests/mocha/utils_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/variable_map_test.js b/tests/mocha/variable_map_test.js index 2d6cee0b9..76dffbe9d 100644 --- a/tests/mocha/variable_map_test.js +++ b/tests/mocha/variable_map_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { assertEventFired, assertEventNotFired, diff --git a/tests/mocha/variable_model_test.js b/tests/mocha/variable_model_test.js index cd2a89db4..eee7ea9bf 100644 --- a/tests/mocha/variable_model_test.js +++ b/tests/mocha/variable_model_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/widget_div_test.js b/tests/mocha/widget_div_test.js index 61c942471..4ad31f96c 100644 --- a/tests/mocha/widget_div_test.js +++ b/tests/mocha/widget_div_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { sharedTestSetup, sharedTestTeardown, diff --git a/tests/mocha/workspace_comment_test.js b/tests/mocha/workspace_comment_test.js index 3ce276e85..bb87ad82a 100644 --- a/tests/mocha/workspace_comment_test.js +++ b/tests/mocha/workspace_comment_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { assertEventFired, createChangeListenerSpy, diff --git a/tests/mocha/workspace_svg_test.js b/tests/mocha/workspace_svg_test.js index 207cad45d..6193dda2d 100644 --- a/tests/mocha/workspace_svg_test.js +++ b/tests/mocha/workspace_svg_test.js @@ -5,7 +5,7 @@ */ import {EventType} from '../../build/src/core/events/type.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {defineStackBlock} from './test_helpers/block_definitions.js'; import { assertEventFired, diff --git a/tests/mocha/xml_test.js b/tests/mocha/xml_test.js index 218324197..cd1bce128 100644 --- a/tests/mocha/xml_test.js +++ b/tests/mocha/xml_test.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import { addBlockTypeToCleanup, createGenUidStubWithReturns, diff --git a/tests/mocha/zoom_controls_test.js b/tests/mocha/zoom_controls_test.js index dedc36b75..d9bb0f91e 100644 --- a/tests/mocha/zoom_controls_test.js +++ b/tests/mocha/zoom_controls_test.js @@ -5,7 +5,7 @@ */ import {EventType} from '../../build/src/core/events/type.js'; -import {assert} from '../../node_modules/chai/chai.js'; +import {assert} from '../../node_modules/chai/index.js'; import {assertEventFired, assertEventNotFired} from './test_helpers/events.js'; import { sharedTestSetup, From 90580a8655f754b0c158be917b04925a1e83690d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Aug 2025 19:12:06 +0100 Subject: [PATCH 14/19] chore(deps): bump eslint from 9.30.0 to 9.34.0 (#9329) Bumps [eslint](https://github.com/eslint/eslint) from 9.30.0 to 9.34.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v9.30.0...v9.34.0) --- updated-dependencies: - dependency-name: eslint dependency-version: 9.34.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 60 +++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/package-lock.json b/package-lock.json index f7a8f9426..847c0d795 100644 --- a/package-lock.json +++ b/package-lock.json @@ -445,19 +445,21 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz", - "integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", + "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/core": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz", - "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", + "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@types/json-schema": "^7.0.15" }, @@ -527,10 +529,11 @@ "license": "MIT" }, "node_modules/@eslint/js": { - "version": "9.30.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.30.0.tgz", - "integrity": "sha512-Wzw3wQwPvc9sHM+NjakWTcPx11mbZyiYHuwWa/QfZ7cIRX7WK54PSk7bdyXDaoaopUcMatv1zaQvOAAO8hCdww==", + "version": "9.34.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.34.0.tgz", + "integrity": "sha512-EoyvqQnBNsV1CWaEJ559rxXL4c8V92gxirbawSmVUOWXlsRxxQXl6LmCpdUblgxgSkDIqKnhzba2SjRTI/A5Rw==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -548,30 +551,19 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.3.tgz", - "integrity": "sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", + "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.15.1", + "@eslint/core": "^0.15.2", "levn": "^0.4.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz", - "integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, "node_modules/@gulp-sourcemaps/identity-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz", @@ -1528,7 +1520,8 @@ "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { "version": "20.16.3", @@ -3970,19 +3963,20 @@ } }, "node_modules/eslint": { - "version": "9.30.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.30.0.tgz", - "integrity": "sha512-iN/SiPxmQu6EVkf+m1qpBxzUhE12YqFLOSySuOyVLJLEF9nzTf+h/1AJYc1JWzCnktggeNrjvQGLngDzXirU6g==", + "version": "9.34.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.34.0.tgz", + "integrity": "sha512-RNCHRX5EwdrESy3Jc9o8ie8Bog+PeYvvSR8sDGoZxNFTvZ4dlxUB3WzQ3bQMztFrSRODGrLLj8g6OFuGY/aiQg==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.0", - "@eslint/config-helpers": "^0.3.0", - "@eslint/core": "^0.14.0", + "@eslint/config-helpers": "^0.3.1", + "@eslint/core": "^0.15.2", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.30.0", - "@eslint/plugin-kit": "^0.3.1", + "@eslint/js": "9.34.0", + "@eslint/plugin-kit": "^0.3.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", From f10454cb360321f3b9d64c2769e7bff4cc976756 Mon Sep 17 00:00:00 2001 From: Christopher Allen Date: Wed, 27 Aug 2025 19:18:20 +0100 Subject: [PATCH 15/19] chore: Add node.js v24 to CI build matrix (#9219) Node.js v24 has now been released, so add it to our build matrix. Node v18 is no longer in LTS but we want to continue to test on it until it is removed from package.json engines. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d7a4e786c..cdec53082 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,7 +18,7 @@ jobs: # TODO (#2114): re-enable osx build. # os: [ubuntu-latest, macos-latest] os: [ubuntu-latest] - node-version: [18.x, 20.x, 22.x] + node-version: [18.x, 20.x, 22.x, 24.x] # See supported Node.js release schedule at # https://nodejs.org/en/about/releases/ From b0569c4a576e3918d8f8c646947331ba7bdb99ad Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 27 Aug 2025 12:28:06 -0700 Subject: [PATCH 16/19] fix: Prevent mocha tests failures when window does not have focus. (#9332) * chore: Add puppeteer-core as a dev dependency. * fix: Make mocha tests run in a fake-focused window. * fix: Make `test:mocha:interactive` use the same gulp codepath as `test`. --- gulpfile.mjs | 7 ++- package-lock.json | 89 +++++++++++++++++++++++++++----- package.json | 3 +- scripts/gulpfiles/test_tasks.mjs | 12 ++++- tests/mocha/webdriver.js | 18 ++++++- 5 files changed, 111 insertions(+), 18 deletions(-) diff --git a/gulpfile.mjs b/gulpfile.mjs index fd3de3bde..ad61bcb51 100644 --- a/gulpfile.mjs +++ b/gulpfile.mjs @@ -45,7 +45,11 @@ import { publishBeta, recompile, } from './scripts/gulpfiles/release_tasks.mjs'; -import {generators, test} from './scripts/gulpfiles/test_tasks.mjs'; +import { + generators, + interactiveMocha, + test, +} from './scripts/gulpfiles/test_tasks.mjs'; const clean = parallel(cleanBuildDir, cleanReleaseDir); @@ -80,6 +84,7 @@ export { clean, test, generators as testGenerators, + interactiveMocha, buildAdvancedCompilationTest, createRC as gitCreateRC, docs, diff --git a/package-lock.json b/package-lock.json index 847c0d795..08c105c69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,6 +51,7 @@ "patch-package": "^8.0.0", "prettier": "^3.3.3", "prettier-plugin-organize-imports": "^4.0.0", + "puppeteer-core": "^24.17.0", "readline-sync": "^1.4.10", "rimraf": "^5.0.0", "typescript": "^5.3.3", @@ -1282,18 +1283,18 @@ } }, "node_modules/@puppeteer/browsers": { - "version": "2.10.4", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.10.4.tgz", - "integrity": "sha512-9DxbZx+XGMNdjBynIs4BRSz+M3iRDeB7qRcAr6UORFLphCIM2x3DXgOucvADiifcqCE4XePFUKcnaAMyGbrDlQ==", + "version": "2.10.7", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.10.7.tgz", + "integrity": "sha512-wHWLkQWBjHtajZeqCB74nsa/X70KheyOhySYBRmVQDJiNj0zjZR/naPCvdWjMhcG1LmjaMV/9WtTo5mpe8qWLw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "debug": "^4.4.0", + "debug": "^4.4.1", "extract-zip": "^2.0.1", "progress": "^2.0.3", "proxy-agent": "^6.5.0", - "semver": "^7.7.1", - "tar-fs": "^3.0.8", + "semver": "^7.7.2", + "tar-fs": "^3.1.0", "yargs": "^17.7.2" }, "bin": { @@ -2960,6 +2961,20 @@ "fsevents": "~2.3.2" } }, + "node_modules/chromium-bidi": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-8.0.0.tgz", + "integrity": "sha512-d1VmE0FD7lxZQHzcDUCKZSNRtRwISXDsdg4HjdTR5+Ll5nQ/vzU12JeNmupD6VWffrPSlrnGhEWlLESKH3VO+g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "mitt": "^3.0.1", + "zod": "^3.24.1" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, "node_modules/ci-info": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", @@ -3612,6 +3627,13 @@ "node": ">=0.10.0" } }, + "node_modules/devtools-protocol": { + "version": "0.0.1475386", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1475386.tgz", + "integrity": "sha512-RQ809ykTfJ+dgj9bftdeL2vRVxASAuGU+I9LEx9Ij5TXU5HrgAQVmzi72VA+mkzscE12uzlRv5/tWWv9R9J1SA==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/diff": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", @@ -6895,6 +6917,13 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true, + "license": "MIT" + }, "node_modules/mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -7925,6 +7954,24 @@ "node": ">=6" } }, + "node_modules/puppeteer-core": { + "version": "24.17.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.17.0.tgz", + "integrity": "sha512-RYOBKFiF+3RdwIZTEacqNpD567gaFcBAOKTT7742FdB1icXudrPI7BlZbYTYWK2wgGQUXt9Zi1Yn+D5PmCs4CA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@puppeteer/browsers": "2.10.7", + "chromium-bidi": "8.0.0", + "debug": "^4.4.1", + "devtools-protocol": "0.0.1475386", + "typed-query-selector": "^2.12.0", + "ws": "^8.18.3" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/qs": { "version": "6.14.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", @@ -8993,9 +9040,9 @@ } }, "node_modules/tar-fs": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.9.tgz", - "integrity": "sha512-XF4w9Xp+ZQgifKakjZYmFdkLoSWd34VGKcsTCwlNWM7QG3ZbaxnTsaBwnjFZqHRf/rROxaR8rXnbtwdvaDI+lA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", + "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", "dev": true, "license": "MIT", "dependencies": { @@ -9212,6 +9259,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typed-query-selector": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz", + "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==", + "dev": true, + "license": "MIT" + }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -9773,9 +9827,10 @@ "dev": true }, "node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -10029,6 +10084,16 @@ "dependencies": { "safe-buffer": "~5.2.0" } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index c52a79003..9ba8ebe61 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "test": "gulp test", "test:browser": "cd tests/browser && npx mocha", "test:generators": "gulp testGenerators", - "test:mocha:interactive": "npm run build && concurrently -n tsc,server \"tsc --watch --preserveWatchOutput --outDir \"build/src\" --declarationDir \"build/declarations\"\" \"http-server ./ -o /tests/mocha/index.html -c-1\"", + "test:mocha:interactive": "npm run build && concurrently -n tsc,server \"tsc --watch --preserveWatchOutput --outDir \"build/src\" --declarationDir \"build/declarations\"\" \"gulp interactiveMocha\"", "test:compile:advanced": "gulp buildAdvancedCompilationTest --debug", "updateGithubPages": "npm ci && gulp gitUpdateGithubPages" }, @@ -138,6 +138,7 @@ "patch-package": "^8.0.0", "prettier": "^3.3.3", "prettier-plugin-organize-imports": "^4.0.0", + "puppeteer-core": "^24.17.0", "readline-sync": "^1.4.10", "rimraf": "^5.0.0", "typescript": "^5.3.3", diff --git a/scripts/gulpfiles/test_tasks.mjs b/scripts/gulpfiles/test_tasks.mjs index d4b73cdb3..37f988444 100644 --- a/scripts/gulpfiles/test_tasks.mjs +++ b/scripts/gulpfiles/test_tasks.mjs @@ -257,9 +257,9 @@ async function metadata() { * Run Mocha tests inside a browser. * @return {Promise} Asynchronous result. */ -async function mocha() { +async function mocha(exitOnCompletion = true) { return runTestTask('mocha', async () => { - const result = await runMochaTestsInBrowser().catch(e => { + const result = await runMochaTestsInBrowser(exitOnCompletion).catch(e => { throw e; }); if (result) { @@ -269,6 +269,14 @@ async function mocha() { }); } +/** + * Run Mocha tests inside a browser and keep the browser open upon completion. + * @return {Promise} Asynchronous result. + */ +export async function interactiveMocha() { + return mocha(false); +} + /** * Helper method for comparison file. * @param {string} file1 First target file. diff --git a/tests/mocha/webdriver.js b/tests/mocha/webdriver.js index 207917c5e..06e7a3e65 100644 --- a/tests/mocha/webdriver.js +++ b/tests/mocha/webdriver.js @@ -15,9 +15,12 @@ const {posixPath} = require('../../scripts/helpers'); * Runs the Mocha tests in this directory in Chrome. It uses webdriverio to * launch Chrome and load index.html. Outputs a summary of the test results * to the console. + * + * @param {boolean} exitOnCompletetion True if the browser should automatically + * quit after tests have finished running. * @return {number} 0 on success, 1 on failure. */ -async function runMochaTestsInBrowser() { +async function runMochaTestsInBrowser(exitOnCompletion = true) { const options = { capabilities: { browserName: 'chrome', @@ -45,6 +48,17 @@ async function runMochaTestsInBrowser() { console.log('Loading URL: ' + url); await browser.url(url); + // Toggle the devtools setting to emulate focus, so that the window will + // always act as if it has focus regardless of the state of the window manager + // or operating system. This improves the reliability of FocusManager-related + // tests. + const puppeteer = await browser.getPuppeteer(); + await browser.call(async () => { + const page = (await puppeteer.pages())[0]; + const session = await page.createCDPSession(); + await session.send('Emulation.setFocusEmulationEnabled', { enabled: true }); + }); + await browser.waitUntil(async() => { const elem = await browser.$('#failureCount'); const text = await elem.getAttribute('tests_failed'); @@ -74,7 +88,7 @@ async function runMochaTestsInBrowser() { if (parseInt(numOfFailure) !== 0) { return 1; } - await browser.deleteSession(); + if (exitOnCompletion) await browser.deleteSession(); return 0; } From e51efe4855f96554fd552b175e8ae10d15f912bf Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 28 Aug 2025 10:06:52 -0700 Subject: [PATCH 17/19] fix: Fix bug that could cause errant line when rendering. (#9333) --- core/renderers/common/drawer.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core/renderers/common/drawer.ts b/core/renderers/common/drawer.ts index 7046406ad..c474bc8c3 100644 --- a/core/renderers/common/drawer.ts +++ b/core/renderers/common/drawer.ts @@ -122,9 +122,12 @@ export class Drawer { } else if (Types.isSpacer(elem)) { this.outlinePath_ += svgPaths.lineOnAxis('h', elem.width); } + // No branch for a square corner, because it's a no-op. } - // No branch for a square corner, because it's a no-op. - this.outlinePath_ += svgPaths.lineOnAxis('v', topRow.height); + this.outlinePath_ += svgPaths.lineOnAxis( + 'v', + topRow.height - topRow.ascenderHeight, + ); } /** From 5afc0d6692f1a2403dc9a6024920111f23e25487 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 28 Aug 2025 11:28:40 -0700 Subject: [PATCH 18/19] refactor: Make focusable elements responsible for scrolling themselves into bounds. (#9288) * refactor: Make focusable elements responsible for scrolling themselves into bounds. * chore: Add tests for scrolling focused elements into view. * fix: Removed inadvertent `.only`. * fix: Scroll parent block of connections into bounds on focus. --- core/block_svg.ts | 3 + core/bubbles/bubble.ts | 4 + core/comments/comment_bar_button.ts | 8 +- core/comments/comment_editor.ts | 13 +- core/comments/rendered_workspace_comment.ts | 1 + core/field.ts | 7 +- core/flyout_button.ts | 6 +- core/icons/icon.ts | 12 +- core/keyboard_nav/line_cursor.ts | 30 +-- core/rendered_connection.ts | 7 +- tests/browser/test/basic_playground_test.mjs | 221 +++++++++++++++++++ 11 files changed, 276 insertions(+), 36 deletions(-) diff --git a/core/block_svg.ts b/core/block_svg.ts index c6065282a..b3fdeb2d6 100644 --- a/core/block_svg.ts +++ b/core/block_svg.ts @@ -1844,6 +1844,9 @@ export class BlockSvg /** See IFocusableNode.onNodeFocus. */ onNodeFocus(): void { this.select(); + this.workspace.scrollBoundsIntoView( + this.getBoundingRectangleWithoutChildren(), + ); } /** See IFocusableNode.onNodeBlur. */ diff --git a/core/bubbles/bubble.ts b/core/bubbles/bubble.ts index c42e60254..742d300ad 100644 --- a/core/bubbles/bubble.ts +++ b/core/bubbles/bubble.ts @@ -707,6 +707,10 @@ export abstract class Bubble implements IBubble, ISelectable, IFocusableNode { onNodeFocus(): void { this.select(); this.bringToFront(); + const xy = this.getRelativeToSurfaceXY(); + const size = this.getSize(); + const bounds = new Rect(xy.y, xy.y + size.height, xy.x, xy.x + size.width); + this.workspace.scrollBoundsIntoView(bounds); } /** See IFocusableNode.onNodeBlur. */ diff --git a/core/comments/comment_bar_button.ts b/core/comments/comment_bar_button.ts index 24a084ad2..be130b0e3 100644 --- a/core/comments/comment_bar_button.ts +++ b/core/comments/comment_bar_button.ts @@ -87,7 +87,13 @@ export abstract class CommentBarButton implements IFocusableNode { } /** Called when this button's focusable DOM element gains focus. */ - onNodeFocus() {} + onNodeFocus() { + const commentView = this.getCommentView(); + const xy = commentView.getRelativeToSurfaceXY(); + const size = commentView.getSize(); + const bounds = new Rect(xy.y, xy.y + size.height, xy.x, xy.x + size.width); + commentView.workspace.scrollBoundsIntoView(bounds); + } /** Called when this button's focusable DOM element loses focus. */ onNodeBlur() {} diff --git a/core/comments/comment_editor.ts b/core/comments/comment_editor.ts index ac1559c4b..b4c741ba1 100644 --- a/core/comments/comment_editor.ts +++ b/core/comments/comment_editor.ts @@ -10,8 +10,10 @@ import {IFocusableNode} from '../interfaces/i_focusable_node.js'; import {IFocusableTree} from '../interfaces/i_focusable_tree.js'; import * as touch from '../touch.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 {WorkspaceSvg} from '../workspace_svg.js'; /** @@ -188,7 +190,16 @@ export class CommentEditor implements IFocusableNode { getFocusableTree(): IFocusableTree { return this.workspace; } - onNodeFocus(): void {} + onNodeFocus(): void { + const bbox = Rect.from(this.foreignObject.getBoundingClientRect()); + this.workspace.scrollBoundsIntoView( + Rect.createFromPoint( + svgMath.screenToWsCoordinates(this.workspace, bbox.getOrigin()), + bbox.getWidth(), + bbox.getHeight(), + ), + ); + } onNodeBlur(): void {} canBeFocused(): boolean { if (this.id) return true; diff --git a/core/comments/rendered_workspace_comment.ts b/core/comments/rendered_workspace_comment.ts index 49c75e608..2903bff4b 100644 --- a/core/comments/rendered_workspace_comment.ts +++ b/core/comments/rendered_workspace_comment.ts @@ -347,6 +347,7 @@ export class RenderedWorkspaceComment this.select(); // Ensure that the comment is always at the top when focused. this.workspace.getLayerManager()?.append(this, layers.BLOCK); + this.workspace.scrollBoundsIntoView(this.getBoundingRectangle()); } /** See IFocusableNode.onNodeBlur. */ diff --git a/core/field.ts b/core/field.ts index d993e197d..e025efab7 100644 --- a/core/field.ts +++ b/core/field.ts @@ -1380,7 +1380,12 @@ export abstract class Field } /** See IFocusableNode.onNodeFocus. */ - onNodeFocus(): void {} + onNodeFocus(): void { + const block = this.getSourceBlock() as BlockSvg; + block.workspace.scrollBoundsIntoView( + block.getBoundingRectangleWithoutChildren(), + ); + } /** See IFocusableNode.onNodeBlur. */ onNodeBlur(): void {} diff --git a/core/flyout_button.ts b/core/flyout_button.ts index c9afb8b01..5a066a23b 100644 --- a/core/flyout_button.ts +++ b/core/flyout_button.ts @@ -398,7 +398,11 @@ export class FlyoutButton } /** See IFocusableNode.onNodeFocus. */ - onNodeFocus(): void {} + onNodeFocus(): void { + const xy = this.getPosition(); + const bounds = new Rect(xy.y, xy.y + this.height, xy.x, xy.x + this.width); + this.workspace.scrollBoundsIntoView(bounds); + } /** See IFocusableNode.onNodeBlur. */ onNodeBlur(): void {} diff --git a/core/icons/icon.ts b/core/icons/icon.ts index 8f8ff70fc..f5f766038 100644 --- a/core/icons/icon.ts +++ b/core/icons/icon.ts @@ -14,6 +14,7 @@ import * as tooltip from '../tooltip.js'; import {Coordinate} from '../utils/coordinate.js'; import * as dom from '../utils/dom.js'; import * as idGenerator from '../utils/idgenerator.js'; +import {Rect} from '../utils/rect.js'; import {Size} from '../utils/size.js'; import {Svg} from '../utils/svg.js'; import type {WorkspaceSvg} from '../workspace_svg.js'; @@ -168,7 +169,16 @@ export abstract class Icon implements IIcon { } /** See IFocusableNode.onNodeFocus. */ - onNodeFocus(): void {} + onNodeFocus(): void { + const blockBounds = (this.sourceBlock as BlockSvg).getBoundingRectangle(); + const bounds = new Rect( + blockBounds.top + this.offsetInBlock.y, + blockBounds.top + this.offsetInBlock.y + this.getSize().height, + blockBounds.left + this.offsetInBlock.x, + blockBounds.left + this.offsetInBlock.x + this.getSize().width, + ); + (this.sourceBlock as BlockSvg).workspace.scrollBoundsIntoView(bounds); + } /** See IFocusableNode.onNodeBlur. */ onNodeBlur(): void {} diff --git a/core/keyboard_nav/line_cursor.ts b/core/keyboard_nav/line_cursor.ts index 13e5a729d..30770e47d 100644 --- a/core/keyboard_nav/line_cursor.ts +++ b/core/keyboard_nav/line_cursor.ts @@ -14,14 +14,11 @@ */ import {BlockSvg} from '../block_svg.js'; -import {CommentBarButton} from '../comments/comment_bar_button.js'; import {RenderedWorkspaceComment} from '../comments/rendered_workspace_comment.js'; -import {Field} from '../field.js'; import {getFocusManager} from '../focus_manager.js'; import type {IFocusableNode} from '../interfaces/i_focusable_node.js'; import * as registry from '../registry.js'; -import {Rect} from '../utils/rect.js'; -import {WorkspaceSvg} from '../workspace_svg.js'; +import type {WorkspaceSvg} from '../workspace_svg.js'; import {Marker} from './marker.js'; /** @@ -392,31 +389,6 @@ export class LineCursor extends Marker { */ setCurNode(newNode: IFocusableNode) { getFocusManager().focusNode(newNode); - - // Try to scroll cursor into view. - if (newNode instanceof BlockSvg) { - newNode.workspace.scrollBoundsIntoView( - newNode.getBoundingRectangleWithoutChildren(), - ); - } else if (newNode instanceof Field) { - const block = newNode.getSourceBlock() as BlockSvg; - block.workspace.scrollBoundsIntoView( - block.getBoundingRectangleWithoutChildren(), - ); - } else if (newNode instanceof RenderedWorkspaceComment) { - newNode.workspace.scrollBoundsIntoView(newNode.getBoundingRectangle()); - } else if (newNode instanceof CommentBarButton) { - const commentView = newNode.getCommentView(); - const xy = commentView.getRelativeToSurfaceXY(); - const size = commentView.getSize(); - const bounds = new Rect( - xy.y, - xy.y + size.height, - xy.x, - xy.x + size.width, - ); - commentView.workspace.scrollBoundsIntoView(bounds); - } } /** diff --git a/core/rendered_connection.ts b/core/rendered_connection.ts index 84905eecc..4a53048bc 100644 --- a/core/rendered_connection.ts +++ b/core/rendered_connection.ts @@ -644,6 +644,9 @@ export class RenderedConnection /** See IFocusableNode.onNodeFocus. */ onNodeFocus(): void { this.highlight(); + this.getSourceBlock().workspace.scrollBoundsIntoView( + this.getSourceBlock().getBoundingRectangleWithoutChildren(), + ); } /** See IFocusableNode.onNodeBlur. */ @@ -656,12 +659,12 @@ export class RenderedConnection return true; } - private findHighlightSvg(): SVGElement | null { + private findHighlightSvg(): SVGPathElement | null { // This cast is valid as TypeScript's definition is wrong. See: // https://github.com/microsoft/TypeScript/issues/60996. return document.getElementById(this.id) as | unknown - | null as SVGElement | null; + | null as SVGPathElement | null; } } diff --git a/tests/browser/test/basic_playground_test.mjs b/tests/browser/test/basic_playground_test.mjs index c7c8a5a37..72b3894a6 100644 --- a/tests/browser/test/basic_playground_test.mjs +++ b/tests/browser/test/basic_playground_test.mjs @@ -238,3 +238,224 @@ suite('Disabling', function () { }, ); }); + +suite('Focused nodes are scrolled into bounds', function () { + // Setting timeout to unlimited as the webdriver takes a longer time to run + // than most mocha tests. + this.timeout(0); + + // Setup Selenium for all of the tests + suiteSetup(async function () { + this.browser = await testSetup(testFileLocations.PLAYGROUND); + await this.browser.execute(() => { + window.focusScrollTest = async (testcase) => { + const workspace = Blockly.getMainWorkspace(); + const metrics = workspace.getMetricsManager(); + const initialViewport = metrics.getViewMetrics(true); + const elementBounds = await testcase(workspace); + await Blockly.renderManagement.finishQueuedRenders(); + const scrolledViewport = metrics.getViewMetrics(true); + const workspaceBounds = new Blockly.utils.Rect( + scrolledViewport.top, + scrolledViewport.top + scrolledViewport.height, + scrolledViewport.left, + scrolledViewport.left + scrolledViewport.width, + ); + return { + changed: + JSON.stringify(initialViewport) !== + JSON.stringify(scrolledViewport), + intersects: elementBounds.intersects(workspaceBounds), + contains: workspaceBounds.contains( + elementBounds.getOrigin().x, + elementBounds.getOrigin().y, + ), + elementBounds, + workspaceBounds, + }; + }; + }); + }); + + setup(async function () { + await this.browser.execute(() => { + Blockly.serialization.blocks.append( + { + 'type': 'text', + 'x': -500, + 'y': -500, + }, + Blockly.getMainWorkspace(), + ); + Blockly.serialization.blocks.append( + { + 'type': 'controls_if', + 'x': 500, + 'y': 500, + }, + Blockly.getMainWorkspace(), + ); + Blockly.getMainWorkspace().zoomCenter(1); + }); + }); + + test('Focused blocks scroll into bounds', async function () { + const result = await this.browser.execute(async () => { + return await window.focusScrollTest(async (workspace) => { + const block = workspace.getTopBlocks()[0]; + Blockly.getFocusManager().focusNode(block); + return block.getBoundingRectangleWithoutChildren(); + }); + }); + chai.assert.isTrue(result.intersects); + chai.assert.isTrue(result.contains); + chai.assert.isTrue(result.changed); + }); + + test('Focused bubbles scroll into bounds', async function () { + const result = await this.browser.execute(async () => { + return await window.focusScrollTest(async (workspace) => { + const block = workspace.getTopBlocks()[0]; + block.setCommentText('hello world'); + const icon = block.getIcon(Blockly.icons.IconType.COMMENT); + icon.setBubbleVisible(true); + await Blockly.renderManagement.finishQueuedRenders(); + icon.setBubbleLocation(new Blockly.utils.Coordinate(-510, -510)); + Blockly.getFocusManager().focusNode(icon.getBubble()); + const xy = icon.getBubble().getRelativeToSurfaceXY(); + const size = icon.getBubble().getSize(); + return new Blockly.utils.Rect( + xy.y, + xy.y + size.height, + xy.x, + xy.x + size.width, + ); + }); + }); + + chai.assert.isTrue(result.intersects); + chai.assert.isTrue(result.contains); + chai.assert.isTrue(result.changed); + }); + + test('Comment bar buttons scroll into bounds', async function () { + const result = await this.browser.execute(async () => { + return await window.focusScrollTest(async (workspace) => { + const comment = new Blockly.comments.RenderedWorkspaceComment( + workspace, + ); + comment.moveTo(new Blockly.utils.Coordinate(-300, 500)); + const commentBarButton = comment.view.getCommentBarButtons()[0]; + Blockly.getFocusManager().focusNode(commentBarButton); + const xy = comment.view.getRelativeToSurfaceXY(); + const size = comment.view.getSize(); + // Comment bar buttons scroll their parent comment view into view. + return new Blockly.utils.Rect( + xy.y, + xy.y + size.height, + xy.x, + xy.x + size.width, + ); + }); + }); + + chai.assert.isTrue(result.intersects); + chai.assert.isTrue(result.contains); + chai.assert.isTrue(result.changed); + }); + + test('Comment editors scroll into bounds', async function () { + const result = await this.browser.execute(async () => { + return await window.focusScrollTest(async (workspace) => { + const comment = new Blockly.comments.RenderedWorkspaceComment( + workspace, + ); + comment.moveTo(new Blockly.utils.Coordinate(-300, 500)); + const commentEditor = comment.view.getEditorFocusableNode(); + Blockly.getFocusManager().focusNode(commentEditor); + // Comment editor bounds can't be calculated externally since they + // depend on private properties, but the comment view is a reasonable + // proxy. + const xy = comment.view.getRelativeToSurfaceXY(); + const size = comment.view.getSize(); + return new Blockly.utils.Rect( + xy.y, + xy.y + size.height, + xy.x, + xy.x + size.width, + ); + }); + }); + + chai.assert.isTrue(result.intersects); + chai.assert.isTrue(result.contains); + chai.assert.isTrue(result.changed); + }); + + test('Workspace comments scroll into bounds', async function () { + const result = await this.browser.execute(async () => { + return await window.focusScrollTest(async (workspace) => { + const comment = new Blockly.comments.RenderedWorkspaceComment( + workspace, + ); + comment.moveTo(new Blockly.utils.Coordinate(-500, 500)); + Blockly.getFocusManager().focusNode(comment); + return comment.getBoundingRectangle(); + }); + }); + + chai.assert.isTrue(result.intersects); + chai.assert.isTrue(result.contains); + chai.assert.isTrue(result.changed); + }); + + test('Icons scroll into bounds', async function () { + const result = await this.browser.execute(async () => { + return await window.focusScrollTest(async (workspace) => { + const block = workspace.getTopBlocks()[0]; + block.setWarningText('this is bad'); + const icon = block.getIcon(Blockly.icons.IconType.WARNING); + Blockly.getFocusManager().focusNode(icon); + // Icon bounds can't be calculated externally since they depend on + // protected properties, but the parent block is a reasonable proxy. + return block.getBoundingRectangleWithoutChildren(); + }); + }); + + chai.assert.isTrue(result.intersects); + chai.assert.isTrue(result.contains); + chai.assert.isTrue(result.changed); + }); + + test('Fields scroll into bounds', async function () { + const result = await this.browser.execute(async () => { + return await window.focusScrollTest(async (workspace) => { + const block = workspace.getTopBlocks()[0]; + const field = block.getField('TEXT'); + Blockly.getFocusManager().focusNode(field); + // Fields scroll their source block into view. + return block.getBoundingRectangleWithoutChildren(); + }); + }); + + chai.assert.isTrue(result.intersects); + chai.assert.isTrue(result.contains); + chai.assert.isTrue(result.changed); + }); + + test('Connections scroll into bounds', async function () { + const result = await this.browser.execute(async () => { + return await window.focusScrollTest(async (workspace) => { + const block = workspace.getBlocksByType('controls_if')[0]; + Blockly.getFocusManager().focusNode(block.nextConnection); + // Connection bounds can't be calculated externally since they depend on + // protected properties, but the parent block is a reasonable proxy. + return block.getBoundingRectangleWithoutChildren(); + }); + }); + + chai.assert.isTrue(result.intersects); + chai.assert.isTrue(result.contains); + chai.assert.isTrue(result.changed); + }); +}); From 5f21e9b15430c43dad8e139c7c09a0ff2537329d Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 28 Aug 2025 15:46:39 -0700 Subject: [PATCH 19/19] release: Update version number to 12.3.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 08c105c69..afd057ce6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "blockly", - "version": "12.3.0-beta.0", + "version": "12.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "blockly", - "version": "12.3.0-beta.0", + "version": "12.3.0", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 9ba8ebe61..7b639a872 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blockly", - "version": "12.3.0-beta.0", + "version": "12.3.0", "description": "Blockly is a library for building visual programming editors.", "keywords": [ "blockly"