From 3622f5042a4e1c0aa9d0a997cf0a99a31e6b8277 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 18 Aug 2026 13:21:20 -0700 Subject: [PATCH 1/2] fix: Fix bug that could cause dragged blocks to connect to and delete others --- .../core/dragging/block_drag_strategy.ts | 8 +++- .../tests/browser/test/dragger_test.mjs | 47 +++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/packages/blockly/core/dragging/block_drag_strategy.ts b/packages/blockly/core/dragging/block_drag_strategy.ts index a7c4c5747f0..3ed6fbead18 100644 --- a/packages/blockly/core/dragging/block_drag_strategy.ts +++ b/packages/blockly/core/dragging/block_drag_strategy.ts @@ -902,7 +902,11 @@ export class BlockDragStrategy implements IDragStrategy { blockAnimation.disconnectUiStop(); this.connectionPreviewer?.hidePreview(); - if (!this.block.isDeadOrDying() && this.dragging) { + if ( + !this.block.isDeadOrDying() && + this.dragging && + disposition !== DragDisposition.DELETE + ) { // These are expensive and don't need to be done if we're deleting, or // if we've already stopped dragging because we moved back to the start. this.workspace @@ -921,7 +925,7 @@ export class BlockDragStrategy implements IDragStrategy { this.redisableAllDraggedBlocks(this.block); } - if (this.connectionCandidate) { + if (this.connectionCandidate && disposition !== DragDisposition.DELETE) { // Applying connections also rerenders the relevant blocks. this.applyConnections(this.connectionCandidate); this.disposeStep(); diff --git a/packages/blockly/tests/browser/test/dragger_test.mjs b/packages/blockly/tests/browser/test/dragger_test.mjs index 87b70207409..f84b25d8984 100644 --- a/packages/blockly/tests/browser/test/dragger_test.mjs +++ b/packages/blockly/tests/browser/test/dragger_test.mjs @@ -372,4 +372,51 @@ suite('Dragging into a delete area', function () { }); }); }); + + test('does not delete blocks already on the workspace within the connection radius of a dragged block dropped on a delete area', async function () { + const {blockHasDeleteStyle, blockIsDeadOrDying, existingBlockDeleted} = + await this.browser.execute(() => { + const workspace = Blockly.getMainWorkspace(); + + const existingBlock = workspace.newBlock('controls_repeat'); + existingBlock.initSvg(); + existingBlock.render(); + + const draggingBlock = workspace.newBlock('controls_if'); + draggingBlock.initSvg(); + draggingBlock.render(); + + const deleteRect = workspace.trashcan.getClientRect(); + const deleteRectCenter = rectCenterClient(deleteRect); + + // Move the existing block near the trash so that the dragged block will + // attempt to connect on top of it. + existingBlock.moveTo(new Blockly.utils.Coordinate(0, 0)); + existingBlock.moveTo( + new Blockly.utils.Coordinate( + deleteRectCenter.x - workspace.toolbox.getClientRect().right - 30, + deleteRectCenter.y + existingBlock.height / 2, + ), + ); + + const state = getAssertionState( + draggingBlock, + deleteRectCenter, + deleteRect, + ); + + return { + ...state, + existingBlockDeleted: existingBlock.isDeadOrDying(), + }; + }); + + chai.assert.isFalse( + existingBlockDeleted, + 'Expected existing block to not be deleted', + ); + + chai.assert.isTrue(blockHasDeleteStyle); + chai.assert.isTrue(blockIsDeadOrDying); + }); }); From 7c686e098f949bad039dbc4ee42e0a2ec23a7f29 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 18 Aug 2026 13:39:48 -0700 Subject: [PATCH 2/2] chore: Remove unneeded move --- packages/blockly/tests/browser/test/dragger_test.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/blockly/tests/browser/test/dragger_test.mjs b/packages/blockly/tests/browser/test/dragger_test.mjs index f84b25d8984..75e247f0685 100644 --- a/packages/blockly/tests/browser/test/dragger_test.mjs +++ b/packages/blockly/tests/browser/test/dragger_test.mjs @@ -391,7 +391,6 @@ suite('Dragging into a delete area', function () { // Move the existing block near the trash so that the dragged block will // attempt to connect on top of it. - existingBlock.moveTo(new Blockly.utils.Coordinate(0, 0)); existingBlock.moveTo( new Blockly.utils.Coordinate( deleteRectCenter.x - workspace.toolbox.getClientRect().right - 30,