diff --git a/packages/blockly/core/clipboard/block_paster.ts b/packages/blockly/core/clipboard/block_paster.ts index dade36479c0..2fe4baefb0b 100644 --- a/packages/blockly/core/clipboard/block_paster.ts +++ b/packages/blockly/core/clipboard/block_paster.ts @@ -61,9 +61,10 @@ export class BlockPaster implements IPaster { // Sometimes there's a delay before the block is fully created and ready for // focusing, so wait slightly before focusing the newly pasted block. const nodeToFocus: IFocusableNode = block; - renderManagement - .finishQueuedRenders() - .then(() => getFocusManager().focusNode(nodeToFocus)); + renderManagement.finishQueuedRenders().then(() => { + if (block.isDeadOrDying()) return; + getFocusManager().focusNode(nodeToFocus); + }); return block; } } diff --git a/packages/blockly/core/field_input.ts b/packages/blockly/core/field_input.ts index f9619bf838c..042d1d63050 100644 --- a/packages/blockly/core/field_input.ts +++ b/packages/blockly/core/field_input.ts @@ -819,9 +819,10 @@ export abstract class FieldInput extends Field< const block = this.getSourceBlock(); if (!block) throw new UnattachedFieldError(); const div = WidgetDiv.getDiv(); + if (!div) return; const bBox = this.getScaledBBox(); - div!.style.width = bBox.right - bBox.left + 'px'; - div!.style.height = bBox.bottom - bBox.top + 'px'; + div.style.width = bBox.right - bBox.left + 'px'; + div.style.height = bBox.bottom - bBox.top + 'px'; // In RTL mode block fields and LTR input fields the left edge moves, // whereas the right edge is fixed. Reposition the editor. @@ -835,8 +836,8 @@ export abstract class FieldInput extends Field< y -= bounds.top + window.scrollY; } - div!.style.left = `${x}px`; - div!.style.top = `${y}px`; + div.style.left = `${x}px`; + div.style.top = `${y}px`; }); } diff --git a/packages/blockly/core/workspace_audio.ts b/packages/blockly/core/workspace_audio.ts index ecb1f84c823..63df5110411 100644 --- a/packages/blockly/core/workspace_audio.ts +++ b/packages/blockly/core/workspace_audio.ts @@ -90,6 +90,7 @@ export class WorkspaceAudio { const sound = this.sounds.get(name); if (sound) { await this.prepareToPlay(); + if (this.context.state !== 'running') return; const source = this.context.createBufferSource(); const gainNode = this.context.createGain(); @@ -122,6 +123,7 @@ export class WorkspaceAudio { async beep(tone: number, duration = 0.2) { if (!this.isPlayingAllowed()) return; await this.prepareToPlay(); + if (this.context.state !== 'running') return; const oscillator = this.context.createOscillator(); oscillator.type = 'sine'; @@ -209,7 +211,10 @@ export class WorkspaceAudio { ) { this.lastSound = new Date(); - if (this.context.state === 'suspended') { + if ( + this.context.state === 'suspended' && + navigator.userActivation.hasBeenActive + ) { await this.context.resume(); } } diff --git a/packages/blockly/tests/mocha/block_test.js b/packages/blockly/tests/mocha/block_test.js index 659894bc31b..0b7867dfe2b 100644 --- a/packages/blockly/tests/mocha/block_test.js +++ b/packages/blockly/tests/mocha/block_test.js @@ -1500,9 +1500,16 @@ suite('Blocks', function () { teardown(function () { workspaceTeardown.call(this, this.workspace); - Blockly.icons.registry.unregister( - Blockly.icons.IconType.COMMENT.toString(), - ); + if ( + Blockly.registry.hasItem( + Blockly.registry.Type.ICON, + Blockly.icons.IconType.COMMENT.toString(), + ) + ) { + Blockly.icons.registry.unregister( + Blockly.icons.IconType.COMMENT.toString(), + ); + } Blockly.icons.registry.register( Blockly.icons.IconType.COMMENT, Blockly.icons.CommentIcon, diff --git a/packages/blockly/tests/mocha/keyboard_movement_test.js b/packages/blockly/tests/mocha/keyboard_movement_test.js index 1e7b0bff21d..e6d3ade5de2 100644 --- a/packages/blockly/tests/mocha/keyboard_movement_test.js +++ b/packages/blockly/tests/mocha/keyboard_movement_test.js @@ -52,6 +52,9 @@ suite('Keyboard-driven movement', function () { teardown(function () { Blockly.KeyboardMover.mover.setMoveDistance(20); + for (const block of Object.keys(p5blocks)) { + delete Blockly.Blocks[block]; + } sharedTestTeardown.call(this); }); diff --git a/packages/blockly/tests/mocha/keyboard_navigation_test.js b/packages/blockly/tests/mocha/keyboard_navigation_test.js index 077b9e95cc1..2dfbcb36314 100644 --- a/packages/blockly/tests/mocha/keyboard_navigation_test.js +++ b/packages/blockly/tests/mocha/keyboard_navigation_test.js @@ -148,6 +148,9 @@ suite('Keyboard navigation on Blocks', function () { }); teardown(function () { + for (const block of Object.keys(p5blocks)) { + delete Blockly.Blocks[block]; + } sharedTestTeardown.call(this); }); @@ -420,6 +423,9 @@ suite('Keyboard navigation on Fields', function () { }); teardown(function () { + for (const block of Object.keys(p5blocks)) { + delete Blockly.Blocks[block]; + } sharedTestTeardown.call(this); }); @@ -500,6 +506,9 @@ suite('Workspace comment navigation', function () { }); teardown(function () { + for (const block of Object.keys(p5blocks)) { + delete Blockly.Blocks[block]; + } sharedTestTeardown.call(this); }); diff --git a/packages/blockly/tests/mocha/render_management_test.js b/packages/blockly/tests/mocha/render_management_test.js index 1839bf3dd58..28a2ef4f8c2 100644 --- a/packages/blockly/tests/mocha/render_management_test.js +++ b/packages/blockly/tests/mocha/render_management_test.js @@ -6,6 +6,7 @@ import {assert} from 'chai'; import { + DEFAULT_INJECT_OPTIONS, sharedTestSetup, sharedTestTeardown, workspaceTeardown, @@ -130,7 +131,7 @@ suite('Render Management', function () { suite('Post-render bumpNeighbours', function () { setup(function () { - this.workspace = Blockly.inject('blocklyDiv', {}); + this.workspace = Blockly.inject('blocklyDiv', DEFAULT_INJECT_OPTIONS); this.block = this.workspace.newBlock('controls_if'); this.block.initSvg(); diff --git a/packages/blockly/tests/mocha/test_helpers/setup_teardown.js b/packages/blockly/tests/mocha/test_helpers/setup_teardown.js index 8f7b78a5c50..61f35db6513 100644 --- a/packages/blockly/tests/mocha/test_helpers/setup_teardown.js +++ b/packages/blockly/tests/mocha/test_helpers/setup_teardown.js @@ -23,6 +23,7 @@ const TEST_MEDIA_PATH = '../../media/'; */ export const DEFAULT_INJECT_OPTIONS = Object.freeze({ media: TEST_MEDIA_PATH, + scrollbars: true, }); /** @@ -186,6 +187,16 @@ export function sharedTestTeardown(workspace = this.workspace) { console.error('"' + testRef.fullTitle() + '" did not call sharedTestSetup'); } + // Remove the globally registered listener from FocusManager to avoid state + // being shared across test boundaries. + for (const registeredListener of this.globalDocumentEventListeners) { + document.removeEventListener( + registeredListener.type, + registeredListener.listener, + ); + } + this.globalDocumentEventListeners = []; + try { if (workspace) { workspaceTeardown.call(this, workspace); @@ -230,14 +241,6 @@ export function sharedTestTeardown(workspace = this.workspace) { Blockly.WidgetDiv.testOnly_setDiv(null); - // Remove the globally registered listener from FocusManager to avoid state - // being shared across test boundaries. - for (const registeredListener of this.globalDocumentEventListeners) { - const eventType = registeredListener.type; - const eventListener = registeredListener.listener; - document.removeEventListener(eventType, eventListener); - } - this.globalDocumentEventListeners = []; FocusManager.getFocusManager = this.oldGetFocusManager; } }