Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
34 changes: 33 additions & 1 deletion src/actions/mover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ import {
registry,
utils,
} from 'blockly';
import type {Block, BlockSvg, IDragger} from 'blockly';
import type {Block, BlockSvg, IDragger, IDragStrategy} from 'blockly';
import {Navigation} from '../navigation';
import {KeyboardDragStrategy} from '../keyboard_drag_strategy';

const KeyCodes = utils.KeyCodes;
const createSerializedKey = ShortcutRegistry.registry.createSerializedKey.bind(
Expand Down Expand Up @@ -48,6 +49,12 @@ export class Mover {
*/
oldIsDragging: (() => boolean) | null = null;

/**
* The block's base drag strategy, which will be overridden during
* keyboard drags and reset at the end of the drag.
*/
private oldDragStrategy: IDragStrategy | null = null;
Copy link
Collaborator

@cpcallen cpcallen Jun 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be on MoveInfo because Mover can handle multiple simultaneous moves on different workspaces.


constructor(
protected navigation: Navigation,
protected canEdit: (ws: WorkspaceSvg) => boolean,
Expand Down Expand Up @@ -237,6 +244,7 @@ export class Mover {
cursor.setCurNode(ASTNode.createBlockNode(block));

this.patchIsDragging(workspace);
this.patchDragStrategy(block);
// Begin dragging block.
const DraggerClass = registry.getClassFromOptions(
registry.Type.BLOCK_DRAGGER,
Expand Down Expand Up @@ -271,6 +279,7 @@ export class Mover {
);

this.unpatchIsDragging(workspace);
this.unpatchDragStrategy(info.block as BlockSvg);
this.moves.delete(workspace);
return true;
}
Expand Down Expand Up @@ -301,6 +310,7 @@ export class Mover {
);

this.unpatchIsDragging(workspace);
this.unpatchDragStrategy(info.block as BlockSvg);
this.moves.delete(workspace);
return true;
}
Expand Down Expand Up @@ -388,6 +398,28 @@ Use enter to complete the move, or escape to abort.`);
(workspace as any).isDragging = this.oldIsDragging;
}
}
/**
* Monkeypatch: replace the block's drag strategy and cache the old value.
*
* @param block The block to patch.
*/
private patchDragStrategy(block: BlockSvg) {
// @ts-expect-error block.dragStrategy is private.
this.oldDragStrategy = block.dragStrategy;
block.setDragStrategy(new KeyboardDragStrategy(block));
}

/**
* Undo the monkeypatching of the block's drag strategy.
*
* @param block The block to patch.
*/
private unpatchDragStrategy(block: BlockSvg) {
if (this.oldDragStrategy) {
block.setDragStrategy(this.oldDragStrategy);
this.oldDragStrategy = null;
}
}
}

/**
Expand Down
9 changes: 9 additions & 0 deletions src/keyboard_drag_strategy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

import {dragging} from 'blockly';

export class KeyboardDragStrategy extends dragging.BlockDragStrategy {}
Loading