@@ -15,8 +15,9 @@ import {
1515 registry ,
1616 utils ,
1717} from 'blockly' ;
18- import type { Block , BlockSvg , IDragger } from 'blockly' ;
18+ import type { BlockSvg , IDragger , IDragStrategy } from 'blockly' ;
1919import { Navigation } from '../navigation' ;
20+ import { KeyboardDragStrategy } from '../keyboard_drag_strategy' ;
2021
2122const KeyCodes = utils . KeyCodes ;
2223const createSerializedKey = ShortcutRegistry . registry . createSerializedKey . bind (
@@ -48,6 +49,12 @@ export class Mover {
4849 */
4950 oldIsDragging : ( ( ) => boolean ) | null = null ;
5051
52+ /**
53+ * The block's base drag strategy, which will be overridden during
54+ * keyboard drags and reset at the end of the drag.
55+ */
56+ private oldDragStrategy : IDragStrategy | null = null ;
57+
5158 constructor (
5259 protected navigation : Navigation ,
5360 protected canEdit : ( ws : WorkspaceSvg ) => boolean ,
@@ -237,6 +244,7 @@ export class Mover {
237244 cursor . setCurNode ( ASTNode . createBlockNode ( block ) ) ;
238245
239246 this . patchIsDragging ( workspace ) ;
247+ this . patchDragStrategy ( block ) ;
240248 // Begin dragging block.
241249 const DraggerClass = registry . getClassFromOptions (
242250 registry . Type . BLOCK_DRAGGER ,
@@ -271,6 +279,7 @@ export class Mover {
271279 ) ;
272280
273281 this . unpatchIsDragging ( workspace ) ;
282+ this . unpatchDragStrategy ( info . block ) ;
274283 this . moves . delete ( workspace ) ;
275284 return true ;
276285 }
@@ -290,7 +299,7 @@ export class Mover {
290299 // Monkey patch dragger to trigger call to draggable.revertDrag.
291300 // eslint-disable-next-line @typescript-eslint/no-explicit-any
292301 ( info . dragger as any ) . shouldReturnToStart = ( ) => true ;
293- const blockSvg = info . block as BlockSvg ;
302+ const blockSvg = info . block ;
294303
295304 // Explicitly call `hidePreview` because it is not called in revertDrag.
296305 // @ts -expect-error Access to private property dragStrategy.
@@ -301,6 +310,7 @@ export class Mover {
301310 ) ;
302311
303312 this . unpatchIsDragging ( workspace ) ;
313+ this . unpatchDragStrategy ( info . block ) ;
304314 this . moves . delete ( workspace ) ;
305315 return true ;
306316 }
@@ -388,6 +398,28 @@ Use enter to complete the move, or escape to abort.`);
388398 ( workspace as any ) . isDragging = this . oldIsDragging ;
389399 }
390400 }
401+ /**
402+ * Monkeypatch: replace the block's drag strategy and cache the old value.
403+ *
404+ * @param block The block to patch.
405+ */
406+ private patchDragStrategy ( block : BlockSvg ) {
407+ // @ts -expect-error block.dragStrategy is private.
408+ this . oldDragStrategy = block . dragStrategy ;
409+ block . setDragStrategy ( new KeyboardDragStrategy ( block ) ) ;
410+ }
411+
412+ /**
413+ * Undo the monkeypatching of the block's drag strategy.
414+ *
415+ * @param block The block to patch.
416+ */
417+ private unpatchDragStrategy ( block : BlockSvg ) {
418+ if ( this . oldDragStrategy ) {
419+ block . setDragStrategy ( this . oldDragStrategy ) ;
420+ this . oldDragStrategy = null ;
421+ }
422+ }
391423}
392424
393425/**
@@ -402,7 +434,7 @@ export class MoveInfo {
402434 readonly startLocation : utils . Coordinate ;
403435
404436 constructor (
405- readonly block : Block ,
437+ readonly block : BlockSvg ,
406438 readonly dragger : IDragger ,
407439 ) {
408440 this . parentNext = block . previousConnection ?. targetConnection ?? null ;
0 commit comments