Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/blockly/core/delete_area.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {DragTarget} from './drag_target.js';
import {isDeletable} from './interfaces/i_deletable.js';
import type {IDeleteArea} from './interfaces/i_delete_area.js';
import type {IDraggable} from './interfaces/i_draggable.js';
import {KeyboardMover} from './keyboard_nav/keyboard_mover.js';

/**
* Abstract class for a component that can delete a block or bubble that is
Expand Down Expand Up @@ -56,7 +57,10 @@ export class DeleteArea extends DragTarget implements IDeleteArea {
* area.
*/
wouldDelete(element: IDraggable): boolean {
if (element instanceof BlockSvg) {
// don't delete things if we're doing a keyboard move
if (KeyboardMover.mover.isMoving()) {
this.updateWouldDelete_(false);
} else if (element instanceof BlockSvg) {
const block = element;
const couldDeleteBlock = !block.getParent() && block.isDeletable();
this.updateWouldDelete_(couldDeleteBlock);
Expand Down
29 changes: 7 additions & 22 deletions packages/blockly/core/toolbox/toolbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
*/
// Former goog.module ID: Blockly.Toolbox

import {BlockSvg} from '../block_svg.js';
import * as browserEvents from '../browser_events.js';
import * as common from '../common.js';
import {ComponentManager} from '../component_manager.js';
Expand All @@ -26,7 +25,6 @@ import {
isCollapsibleToolboxItem,
type ICollapsibleToolboxItem,
} from '../interfaces/i_collapsible_toolbox_item.js';
import {isDeletable} from '../interfaces/i_deletable.js';
import type {IDraggable} from '../interfaces/i_draggable.js';
import type {IFlyout} from '../interfaces/i_flyout.js';
import type {IFocusableNode} from '../interfaces/i_focusable_node.js';
Expand All @@ -37,6 +35,7 @@ import {isSelectableToolboxItem} from '../interfaces/i_selectable_toolbox_item.j
import type {IStyleable} from '../interfaces/i_styleable.js';
import type {IToolbox} from '../interfaces/i_toolbox.js';
import type {IToolboxItem} from '../interfaces/i_toolbox_item.js';
import {KeyboardMover} from '../keyboard_nav/keyboard_mover.js';
import {ToolboxNavigator} from '../keyboard_nav/navigators/toolbox_navigator.js';
import * as registry from '../registry.js';
import type {KeyboardShortcut} from '../shortcut_registry.js';
Expand Down Expand Up @@ -508,32 +507,14 @@ export class Toolbox
}
}

/**
* Returns whether the provided block or bubble would be deleted if dropped on
* this area.
* This method should check if the element is deletable and is always called
* before onDragEnter/onDragOver/onDragExit.
*
* @param element The block or bubble currently being dragged.
* @returns Whether the element provided would be deleted if dropped on this
* area.
*/
override wouldDelete(element: IDraggable): boolean {
if (element instanceof BlockSvg) {
const block = element;
this.updateWouldDelete_(!block.getParent() && block.isDeletable());
} else {
this.updateWouldDelete_(isDeletable(element) && element.isDeletable());
}
return this.wouldDelete_;
}

/**
* Handles when a cursor with a block or bubble enters this drag target.
*
* @param _dragElement The block or bubble currently being dragged.
*/
override onDragEnter(_dragElement: IDraggable) {
// don't trigger for keyboard moves
if (KeyboardMover.mover.isMoving()) return;
this.updateCursorDeleteStyle_(true);
}

Expand All @@ -543,6 +524,8 @@ export class Toolbox
* @param _dragElement The block or bubble currently being dragged.
*/
override onDragExit(_dragElement: IDraggable) {
// don't trigger for keyboard moves
if (KeyboardMover.mover.isMoving()) return;
this.updateCursorDeleteStyle_(false);
}

Expand All @@ -553,6 +536,8 @@ export class Toolbox
* @param _dragElement The block or bubble currently being dragged.
*/
override onDrop(_dragElement: IDraggable) {
// don't trigger for keyboard moves
if (KeyboardMover.mover.isMoving()) return;
this.updateCursorDeleteStyle_(false);
}

Expand Down
7 changes: 7 additions & 0 deletions packages/blockly/core/trashcan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import type {IAutoHideable} from './interfaces/i_autohideable.js';
import type {IDraggable} from './interfaces/i_draggable.js';
import type {IFlyout} from './interfaces/i_flyout.js';
import type {IPositionable} from './interfaces/i_positionable.js';
import {KeyboardMover} from './keyboard_nav/keyboard_mover.js';
import type {UiMetrics} from './metrics_manager.js';
import * as uiPosition from './positionable_helpers.js';
import * as registry from './registry.js';
Expand Down Expand Up @@ -426,6 +427,8 @@ export class Trashcan
* @param _dragElement The block or bubble currently being dragged.
*/
override onDragOver(_dragElement: IDraggable) {
// don't trigger for keyboard moves
if (KeyboardMover.mover.isMoving()) return;
this.setLidOpen(this.wouldDelete_);
}

Expand All @@ -435,6 +438,8 @@ export class Trashcan
* @param _dragElement The block or bubble currently being dragged.
*/
override onDragExit(_dragElement: IDraggable) {
// don't trigger for keyboard moves
if (KeyboardMover.mover.isMoving()) return;
this.setLidOpen(false);
}

Expand All @@ -445,6 +450,8 @@ export class Trashcan
* @param _dragElement The block or bubble currently being dragged.
*/
override onDrop(_dragElement: IDraggable) {
// don't trigger for keyboard moves
if (KeyboardMover.mover.isMoving()) return;
setTimeout(this.setLidOpen.bind(this, false), 100);
}

Expand Down
29 changes: 28 additions & 1 deletion packages/blockly/tests/mocha/toolbox_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
*/

import {assert} from '../../node_modules/chai/index.js';
import {defineStackBlock} from './test_helpers/block_definitions.js';
import {
defineBasicBlockWithField,
defineStackBlock,
} from './test_helpers/block_definitions.js';
import {
sharedTestSetup,
sharedTestTeardown,
Expand Down Expand Up @@ -812,4 +815,28 @@ suite('Toolbox', function () {
);
});
});
suite('delete area', function () {
test('Keyboard drag - wouldDelete returns false', function () {
// Create a deletable block
defineBasicBlockWithField();
const block = this.toolbox.getWorkspace().newBlock('test_field_block');
block.initSvg();
block.render();

// Stub KeyboardMover.mover.isMoving() to return true
const isMovingStub = sinon
.stub(Blockly.KeyboardMover.mover, 'isMoving')
.returns(true);

try {
const result = this.toolbox.wouldDelete(block);
assert.isFalse(
result,
'wouldDelete should return false during keyboard move',
);
} finally {
isMovingStub.restore();
}
});
});
});
23 changes: 23 additions & 0 deletions packages/blockly/tests/mocha/trashcan_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -373,4 +373,27 @@ suite('Trashcan', function () {
this.workspace.options.maxTrashcanContents = Infinity;
});
});
suite('delete area', function () {
test('Keyboard drag - wouldDelete returns false', function () {
// Create a deletable block
const block = this.workspace.newBlock('test_field_block');
block.initSvg();
block.render();

// Stub KeyboardMover.mover.isMoving() to return true
const isMovingStub = sinon
.stub(Blockly.KeyboardMover.mover, 'isMoving')
.returns(true);

try {
const result = this.trashcan.wouldDelete(block);
assert.isFalse(
result,
'wouldDelete should return false during keyboard move',
);
} finally {
isMovingStub.restore();
}
});
});
});