|
4 | 4 | * SPDX-License-Identifier: Apache-2.0 |
5 | 5 | */ |
6 | 6 |
|
7 | | -import type {BlockSvg, IDragger, IDragStrategy} from 'blockly'; |
| 7 | +import type {BlockSvg, IDragger, IDragStrategy, Gesture} from 'blockly'; |
8 | 8 | import { |
9 | 9 | ASTNode, |
10 | 10 | common, |
@@ -43,6 +43,12 @@ export class Mover { |
43 | 43 | */ |
44 | 44 | oldIsDragging: (() => boolean) | null = null; |
45 | 45 |
|
| 46 | + /** |
| 47 | + * The stashed getGesture function, which is replaced at the beginning |
| 48 | + * of a keyboard drag and reset at the end of a keyboard drag. |
| 49 | + */ |
| 50 | + oldGetGesture: ((e: PointerEvent) => Gesture | null) | null = null; |
| 51 | + |
46 | 52 | /** |
47 | 53 | * The block's base drag strategy, which will be overridden during |
48 | 54 | * keyboard drags and reset at the end of the drag. |
@@ -100,7 +106,7 @@ export class Mover { |
100 | 106 | common.setSelected(block); |
101 | 107 | cursor.setCurNode(ASTNode.createBlockNode(block)); |
102 | 108 |
|
103 | | - this.patchIsDragging(workspace); |
| 109 | + this.patchWorkspace(workspace); |
104 | 110 | this.patchDragStrategy(block); |
105 | 111 | // Begin dragging block. |
106 | 112 | const DraggerClass = registry.getClassFromOptions( |
@@ -136,7 +142,7 @@ export class Mover { |
136 | 142 | new utils.Coordinate(0, 0), |
137 | 143 | ); |
138 | 144 |
|
139 | | - this.unpatchIsDragging(workspace); |
| 145 | + this.unpatchWorkspace(workspace); |
140 | 146 | this.unpatchDragStrategy(info.block); |
141 | 147 | this.moves.delete(workspace); |
142 | 148 | return true; |
@@ -167,7 +173,7 @@ export class Mover { |
167 | 173 | new utils.Coordinate(0, 0), |
168 | 174 | ); |
169 | 175 |
|
170 | | - this.unpatchIsDragging(workspace); |
| 176 | + this.unpatchWorkspace(workspace); |
171 | 177 | this.unpatchDragStrategy(info.block); |
172 | 178 | this.moves.delete(workspace); |
173 | 179 | return true; |
@@ -243,27 +249,42 @@ export class Mover { |
243 | 249 | } |
244 | 250 |
|
245 | 251 | /** |
246 | | - * Monkeypatch over workspace.isDragging to return whether a keyboard |
247 | | - * drag is in progress. |
| 252 | + * Monkeypatch over workspace functions to consider keyboard drags as |
| 253 | + * well as mouse/pointer drags. |
248 | 254 | * |
249 | 255 | * @param workspace The workspace to patch. |
250 | 256 | */ |
251 | | - private patchIsDragging(workspace: WorkspaceSvg) { |
| 257 | + private patchWorkspace(workspace: WorkspaceSvg) { |
| 258 | + // Keyboard drags are real drags. |
252 | 259 | this.oldIsDragging = workspace.isDragging; |
253 | 260 | // eslint-disable-next-line @typescript-eslint/no-explicit-any |
254 | 261 | (workspace as any).isDragging = () => this.isMoving(workspace); |
| 262 | + |
| 263 | + // Ignore mouse/pointer events during keyboard drags. |
| 264 | + this.oldGetGesture = workspace.getGesture; |
| 265 | + // eslint-disable-next-line @typescript-eslint/no-explicit-any |
| 266 | + (workspace as any).getGesture = (e: PointerEvent) => { |
| 267 | + // Normally these would be called from Gesture.doStart. |
| 268 | + e.preventDefault(); |
| 269 | + e.stopPropagation(); |
| 270 | + return null; |
| 271 | + }; |
255 | 272 | } |
256 | 273 |
|
257 | 274 | /** |
258 | | - * Remove the monkeypatch on workspace.isDragging. |
| 275 | + * Remove monkeypatches on the workspace. |
259 | 276 | * |
260 | 277 | * @param workspace The workspace to unpatch. |
261 | 278 | */ |
262 | | - private unpatchIsDragging(workspace: WorkspaceSvg) { |
| 279 | + private unpatchWorkspace(workspace: WorkspaceSvg) { |
263 | 280 | if (this.oldIsDragging) { |
264 | 281 | // eslint-disable-next-line @typescript-eslint/no-explicit-any |
265 | 282 | (workspace as any).isDragging = this.oldIsDragging; |
266 | 283 | } |
| 284 | + if (this.oldGetGesture) { |
| 285 | + // eslint-disable-next-line @typescript-eslint/no-explicit-any |
| 286 | + (workspace as any).getGesture = this.oldGetGesture; |
| 287 | + } |
267 | 288 | } |
268 | 289 | /** |
269 | 290 | * Monkeypatch: replace the block's drag strategy and cache the old value. |
|
0 commit comments