55 */
66
77import {
8- BlockSvg ,
98 ContextMenuRegistry ,
109 Msg ,
1110 ShortcutRegistry ,
1211 utils ,
1312 WorkspaceSvg ,
1413 keyboardNavigationController ,
1514 getFocusManager ,
15+ comments ,
16+ IDraggable ,
17+ IFocusableNode ,
18+ IBoundedElement ,
19+ ISelectable ,
1620} from 'blockly' ;
1721import { Direction } from '../drag_direction' ;
1822import { Mover } from './mover' ;
@@ -24,7 +28,7 @@ const createSerializedKey = ShortcutRegistry.registry.createSerializedKey.bind(
2428) ;
2529
2630/**
27- * Actions for moving blocks with keyboard shortcuts.
31+ * Actions for moving workspace elements with keyboard shortcuts.
2832 */
2933export class MoveActions {
3034 constructor ( private mover : Mover ) { }
@@ -38,19 +42,22 @@ export class MoveActions {
3842 {
3943 name : 'start_move' ,
4044 preconditionFn : ( workspace ) => {
41- const startBlock = this . getCurrentBlock ( workspace ) ;
42- return ! ! startBlock && this . mover . canMove ( workspace , startBlock ) ;
45+ const startDraggable = this . getCurrentDraggable ( workspace ) ;
46+ return (
47+ ! ! startDraggable && this . mover . canMove ( workspace , startDraggable )
48+ ) ;
4349 } ,
4450 callback : ( workspace ) => {
4551 keyboardNavigationController . setIsActive ( true ) ;
46- const startBlock = this . getCurrentBlock ( workspace ) ;
47- // Focus the start block in case one of its fields or a shadow block
52+ const startDraggable = this . getCurrentDraggable ( workspace ) ;
53+ // Focus the root draggable in case one of its children
4854 // was focused when the move was triggered.
49- if ( startBlock ) {
50- getFocusManager ( ) . focusNode ( startBlock ) ;
55+ if ( startDraggable ) {
56+ getFocusManager ( ) . focusNode ( startDraggable ) ;
5157 }
5258 return (
53- ! ! startBlock && this . mover . startMove ( workspace , startBlock , null )
59+ ! ! startDraggable &&
60+ this . mover . startMove ( workspace , startDraggable , null )
5461 ) ;
5562 } ,
5663 keyCodes : [ KeyCodes . M ] ,
@@ -162,28 +169,52 @@ export class MoveActions {
162169 if ( ! workspace || menuOpenEvent instanceof PointerEvent )
163170 return 'hidden' ;
164171
165- const startBlock = this . getCurrentBlock ( workspace ) ;
166- return ! ! startBlock && this . mover . canMove ( workspace , startBlock )
172+ const startDraggable = this . getCurrentDraggable ( workspace ) ;
173+ return ! ! startDraggable &&
174+ this . mover . canMove ( workspace , startDraggable )
167175 ? 'enabled'
168176 : 'disabled' ;
169177 } ,
170178 callback : ( scope ) => {
171179 const workspace = scope . block ?. workspace as WorkspaceSvg | null ;
172180 if ( ! workspace ) return false ;
173- const startBlock = this . getCurrentBlock ( workspace ) ;
181+ const startDraggable = this . getCurrentDraggable ( workspace ) ;
174182 // Focus the start block in case one of its fields or a shadow block
175183 // was focused when the move was triggered.
176- if ( startBlock ) {
177- getFocusManager ( ) . focusNode ( startBlock ) ;
184+ if ( startDraggable ) {
185+ getFocusManager ( ) . focusNode ( startDraggable ) ;
178186 }
179187 return (
180- ! ! startBlock && this . mover . startMove ( workspace , startBlock , null )
188+ ! ! startDraggable &&
189+ this . mover . startMove ( workspace , startDraggable , null )
181190 ) ;
182191 } ,
183192 scopeType : ContextMenuRegistry . ScopeType . BLOCK ,
184193 id : 'move' ,
185194 weight : 8.5 ,
186195 } ,
196+ {
197+ displayText : getMenuItem (
198+ Msg [ 'MOVE_COMMENT' ] ?? 'Move Comment' ,
199+ 'start_move' ,
200+ ) ,
201+ preconditionFn : ( scope , menuOpenEvent ) => {
202+ const comment = scope . comment ;
203+ if ( ! comment ) return 'hidden' ;
204+
205+ return this . mover . canMove ( comment . workspace , comment )
206+ ? 'enabled'
207+ : 'disabled' ;
208+ } ,
209+ callback : ( scope ) => {
210+ const comment = scope . comment ;
211+ if ( ! comment ) return false ;
212+ this . mover . startMove ( comment . workspace , comment , null ) ;
213+ } ,
214+ scopeType : ContextMenuRegistry . ScopeType . COMMENT ,
215+ id : 'move_comment' ,
216+ weight : 8.5 ,
217+ } ,
187218 ] ;
188219
189220 for ( const menuItem of menuItems ) {
@@ -214,16 +245,21 @@ export class MoveActions {
214245 }
215246
216247 /**
217- * Get the source block for the cursor location, or undefined if no
218- * source block can be found.
248+ * Get the source draggable for the cursor location, or undefined if no
249+ * source draggable can be found.
219250 * If the cursor is on a shadow block, walks up the tree until it finds
220251 * a non-shadow block to drag.
221252 *
222253 * @param workspace The workspace to inspect for a cursor.
223- * @returns The source block , or undefined if no appropriate block
254+ * @returns The source draggable , or undefined if no appropriate draggable
224255 * could be found.
225256 */
226- getCurrentBlock ( workspace : WorkspaceSvg ) : BlockSvg | undefined {
257+ getCurrentDraggable (
258+ workspace : WorkspaceSvg ,
259+ ) : ( IDraggable & IFocusableNode & IBoundedElement & ISelectable ) | undefined {
260+ const node = getFocusManager ( ) . getFocusedNode ( ) ;
261+ if ( node instanceof comments . RenderedWorkspaceComment ) return node ;
262+
227263 let block = workspace ?. getCursor ( ) ?. getSourceBlock ( ) ;
228264 if ( ! block ) return undefined ;
229265 while ( block . isShadow ( ) ) {
0 commit comments