Skip to content

Commit f08551a

Browse files
fix: insert then cancel with workspace selected (#626)
* test: insert then cancel tests The workspace selection case is broken * fix: insert then cancel with workspace selected Fixes #623
1 parent 8714c2c commit f08551a

File tree

5 files changed

+87
-27
lines changed

5 files changed

+87
-27
lines changed

src/actions/enter.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import type {Block} from 'blockly/core';
2424

2525
import * as Constants from '../constants';
2626
import type {Navigation} from '../navigation';
27-
import {Mover} from './mover';
27+
import {Mover, MoveType} from './mover';
2828
import {
2929
showConstrainedMovementHint,
3030
showHelpHint,
@@ -210,13 +210,19 @@ export class EnterAction {
210210
const insertStartPoint = stationaryNode
211211
? this.navigation.findInsertStartPoint(stationaryNode, newBlock)
212212
: null;
213+
213214
if (workspace.getTopBlocks().includes(newBlock)) {
214215
this.positionNewTopLevelBlock(workspace, newBlock);
215216
}
216217

217218
workspace.setResizesEnabled(true);
218219

219-
this.mover.startMove(workspace, newBlock, insertStartPoint);
220+
this.mover.startMove(
221+
workspace,
222+
newBlock,
223+
MoveType.Insert,
224+
insertStartPoint,
225+
);
220226

221227
const isStartBlock =
222228
!newBlock.outputConnection &&

src/actions/move.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
ISelectable,
2020
} from 'blockly';
2121
import {Direction} from '../drag_direction';
22-
import {Mover} from './mover';
22+
import {Mover, MoveType} from './mover';
2323
import {getMenuItem} from '../shortcut_formatting';
2424

2525
const KeyCodes = utils.KeyCodes;
@@ -57,7 +57,7 @@ export class MoveActions {
5757
}
5858
return (
5959
!!startDraggable &&
60-
this.mover.startMove(workspace, startDraggable, null)
60+
this.mover.startMove(workspace, startDraggable, MoveType.Move, null)
6161
);
6262
},
6363
keyCodes: [KeyCodes.M],
@@ -186,7 +186,7 @@ export class MoveActions {
186186
}
187187
return (
188188
!!startDraggable &&
189-
this.mover.startMove(workspace, startDraggable, null)
189+
this.mover.startMove(workspace, startDraggable, MoveType.Move, null)
190190
);
191191
},
192192
scopeType: ContextMenuRegistry.ScopeType.BLOCK,
@@ -209,7 +209,7 @@ export class MoveActions {
209209
callback: (scope) => {
210210
const comment = scope.comment;
211211
if (!comment) return false;
212-
this.mover.startMove(comment.workspace, comment, null);
212+
this.mover.startMove(comment.workspace, comment, MoveType.Move, null);
213213
},
214214
scopeType: ContextMenuRegistry.ScopeType.COMMENT,
215215
id: 'move_comment',

src/actions/mover.ts

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,20 @@ const CONSTRAINED_ADDITIONAL_PADDING = 70;
4747
*/
4848
const COMMIT_MOVE_SHORTCUT = 'commitMove';
4949

50+
/**
51+
* Whether this is an insert or a move.
52+
*/
53+
export enum MoveType {
54+
/**
55+
* An insert will remove the block if the move is aborted.
56+
*/
57+
Insert,
58+
/**
59+
* A regular move of a pre-existing block.
60+
*/
61+
Move,
62+
}
63+
5064
/**
5165
* Low-level code for moving elements with keyboard shortcuts.
5266
*/
@@ -108,17 +122,19 @@ export class Mover {
108122
*
109123
* @param workspace The workspace we might be moving on.
110124
* @param draggable The element to start dragging.
111-
* @param insertStartPoint Where to insert the element, or null if the element
112-
* already existed.
125+
* @param moveType Whether this is an insert or a move.
126+
* @param startPoint Where to start the move, or null to use the current
127+
* location if any.
113128
* @returns True iff a move has successfully begun.
114129
*/
115130
startMove(
116131
workspace: WorkspaceSvg,
117132
draggable: IDraggable & IFocusableNode & IBoundedElement & ISelectable,
118-
insertStartPoint: RenderedConnection | null,
133+
moveType: MoveType,
134+
startPoint: RenderedConnection | null,
119135
) {
120136
if (draggable instanceof BlockSvg) {
121-
this.patchDragStrategy(draggable, insertStartPoint);
137+
this.patchDragStrategy(draggable, moveType, startPoint);
122138
} else if (draggable instanceof comments.RenderedWorkspaceComment) {
123139
this.moveIndicator = new MoveIndicatorBubble(draggable);
124140
}
@@ -225,10 +241,7 @@ export class Mover {
225241
// eslint-disable-next-line @typescript-eslint/no-explicit-any
226242
const dragStrategy = (info.draggable as any)
227243
.dragStrategy as KeyboardDragStrategy;
228-
this.patchDragger(
229-
info.dragger as dragging.Dragger,
230-
dragStrategy.isNewBlock,
231-
);
244+
this.patchDragger(info.dragger as dragging.Dragger, dragStrategy.moveType);
232245

233246
// Save the position so we can put the cursor in a reasonable spot.
234247
// @ts-expect-error Access to private property connectionCandidate.
@@ -243,7 +256,7 @@ export class Mover {
243256
info.startLocation,
244257
);
245258

246-
if (dragStrategy.isNewBlock && target) {
259+
if (dragStrategy.moveType === MoveType.Insert && target) {
247260
workspace.getCursor()?.setCurNode(target);
248261
}
249262

@@ -348,16 +361,20 @@ export class Mover {
348361
* Monkeypatch: replace the block's drag strategy and cache the old value.
349362
*
350363
* @param block The block to patch.
351-
* @param insertStartPoint Where to insert the block, or null if the block
352-
* already existed.
364+
* @param moveType Whether this is an insert or a move.
365+
* @param startPoint Where to start the move, or null to use the current
366+
* location if any.
353367
*/
354368
private patchDragStrategy(
355369
block: BlockSvg,
356-
insertStartPoint: RenderedConnection | null,
370+
moveType: MoveType,
371+
startPoint: RenderedConnection | null,
357372
) {
358373
// @ts-expect-error block.dragStrategy is private.
359374
this.oldDragStrategy = block.dragStrategy;
360-
block.setDragStrategy(new KeyboardDragStrategy(block, insertStartPoint));
375+
block.setDragStrategy(
376+
new KeyboardDragStrategy(block, moveType, startPoint),
377+
);
361378
}
362379

363380
/**
@@ -401,10 +418,10 @@ export class Mover {
401418
* an existing element.
402419
*
403420
* @param dragger The dragger to patch.
404-
* @param isNewBlock Whether a moving block was created for this action.
421+
* @param moveType Whether this is an insert or a move.
405422
*/
406-
private patchDragger(dragger: dragging.Dragger, isNewBlock: boolean) {
407-
if (isNewBlock) {
423+
private patchDragger(dragger: dragging.Dragger, moveType: MoveType) {
424+
if (moveType === MoveType.Insert) {
408425
// Monkey patch dragger to trigger delete.
409426
// eslint-disable-next-line @typescript-eslint/no-explicit-any
410427
(dragger as any).wouldDeleteDraggable = () => true;

src/keyboard_drag_strategy.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
import {Direction, getDirectionFromXY} from './drag_direction';
1515
import {showUnconstrainedMoveHint} from './hints';
1616
import {MoveIcon} from './move_icon';
17+
import {MoveType} from './actions/mover';
1718

1819
// Copied in from core because it is not exported.
1920
interface ConnectionCandidate {
@@ -35,14 +36,12 @@ export class KeyboardDragStrategy extends dragging.BlockDragStrategy {
3536
/** Where a constrained movement should start when traversing the tree. */
3637
private searchNode: RenderedConnection | null = null;
3738

38-
isNewBlock: boolean;
39-
4039
constructor(
4140
private block: BlockSvg,
42-
private insertStartPoint: RenderedConnection | null,
41+
public moveType: MoveType,
42+
private startPoint: RenderedConnection | null,
4343
) {
4444
super(block);
45-
this.isNewBlock = !!this.insertStartPoint;
4645
}
4746

4847
override startDrag(e?: PointerEvent) {
@@ -300,7 +299,7 @@ export class KeyboardDragStrategy extends dragging.BlockDragStrategy {
300299
*/
301300
private createInitialCandidate(): ConnectionCandidate | null {
302301
// @ts-expect-error startParentConn is private.
303-
const neighbour = this.insertStartPoint ?? this.startParentConn;
302+
const neighbour = this.startPoint ?? this.startParentConn;
304303
if (neighbour) {
305304
this.searchNode = neighbour;
306305
switch (neighbour.type) {

test/webdriverio/test/insert_test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import {
1515
testFileLocations,
1616
testSetup,
1717
keyRight,
18+
getCurrentFocusedBlockId,
19+
blockIsPresent,
1820
keyUp,
1921
tabNavigateToToolbox,
2022
} from './test_setup.js';
@@ -29,6 +31,42 @@ suite('Insert test', function () {
2931
await this.browser.pause(PAUSE_TIME);
3032
});
3133

34+
test('Insert and cancel with block selection', async function () {
35+
// Navigate to draw_circle_1.
36+
await tabNavigateToWorkspace(this.browser);
37+
await focusOnBlock(this.browser, 'draw_circle_1');
38+
// Insert 'if' block
39+
await this.browser.keys('t');
40+
await keyRight(this.browser);
41+
await this.browser.keys(Key.Enter);
42+
chai.assert.equal('controls_if', await getFocusedBlockType(this.browser));
43+
const ifId = await getCurrentFocusedBlockId(this.browser);
44+
chai.assert.ok(ifId);
45+
46+
// Cancel
47+
await this.browser.keys(Key.Escape);
48+
49+
chai.assert.isFalse(await blockIsPresent(this.browser, ifId));
50+
});
51+
52+
test('Insert and cancel with workspace selection', async function () {
53+
// Navigate to workspace.
54+
await tabNavigateToWorkspace(this.browser);
55+
await this.browser.keys('w');
56+
// Insert 'if' block
57+
await this.browser.keys('t');
58+
await keyRight(this.browser);
59+
await this.browser.keys(Key.Enter);
60+
chai.assert.equal('controls_if', await getFocusedBlockType(this.browser));
61+
const ifId = await getCurrentFocusedBlockId(this.browser);
62+
chai.assert.ok(ifId);
63+
64+
// Cancel
65+
await this.browser.keys(Key.Escape);
66+
67+
chai.assert.isFalse(await blockIsPresent(this.browser, ifId));
68+
});
69+
3270
test('Insert C-shaped block with statement block selected', async function () {
3371
// Navigate to draw_circle_1.
3472
await tabNavigateToWorkspace(this.browser);

0 commit comments

Comments
 (0)