@@ -14,8 +14,10 @@ import {ConnectionType} from '../connection_type.js';
1414import type { BlockMove } from '../events/events_block_move.js' ;
1515import { EventType } from '../events/type.js' ;
1616import * as eventUtils from '../events/utils.js' ;
17+ import type { IBubble } from '../interfaces/i_bubble.js' ;
1718import { IConnectionPreviewer } from '../interfaces/i_connection_previewer.js' ;
1819import { IDragStrategy } from '../interfaces/i_draggable.js' ;
20+ import { IHasBubble , hasBubble } from '../interfaces/i_has_bubble.js' ;
1921import * as layers from '../layers.js' ;
2022import * as registry from '../registry.js' ;
2123import { finishQueuedRenders } from '../render_management.js' ;
@@ -120,6 +122,34 @@ export class BlockDragStrategy implements IDragStrategy {
120122 }
121123 this . block . setDragging ( true ) ;
122124 this . workspace . getLayerManager ( ) ?. moveToDragLayer ( this . block ) ;
125+ this . getVisibleBubbles ( this . block ) . forEach ( ( bubble ) => {
126+ this . workspace . getLayerManager ( ) ?. moveToDragLayer ( bubble , false ) ;
127+ } ) ;
128+ }
129+
130+ /**
131+ * Returns an array of visible bubbles attached to the given block or its
132+ * descendants.
133+ *
134+ * @param block The block to identify open bubbles on.
135+ * @returns An array of all currently visible bubbles on the given block or
136+ * its descendants.
137+ */
138+ private getVisibleBubbles ( block : BlockSvg ) : IBubble [ ] {
139+ return block
140+ . getDescendants ( false )
141+ . flatMap ( ( block ) => block . getIcons ( ) )
142+ . filter ( ( icon ) => hasBubble ( icon ) && icon . bubbleIsVisible ( ) )
143+ . map ( ( icon ) => ( icon as unknown as IHasBubble ) . getBubble ( ) )
144+ . filter ( ( bubble ) => ! ! bubble ) // Convince TS they're non-null.
145+ . sort ( ( a , b ) => {
146+ // Sort the bubbles by their position in the DOM in order to maintain
147+ // their relative z-ordering when moving between layers.
148+ const position = a . getSvgRoot ( ) . compareDocumentPosition ( b . getSvgRoot ( ) ) ;
149+ if ( position & Node . DOCUMENT_POSITION_PRECEDING ) return 1 ;
150+ if ( position & Node . DOCUMENT_POSITION_FOLLOWING ) return - 1 ;
151+ return 0 ;
152+ } ) ;
123153 }
124154
125155 /**
@@ -393,6 +423,13 @@ export class BlockDragStrategy implements IDragStrategy {
393423 this . workspace
394424 . getLayerManager ( )
395425 ?. moveOffDragLayer ( this . block , layers . BLOCK ) ;
426+
427+ this . getVisibleBubbles ( this . block ) . forEach ( ( bubble ) =>
428+ this . workspace
429+ . getLayerManager ( )
430+ ?. moveOffDragLayer ( bubble , layers . BUBBLE , false ) ,
431+ ) ;
432+
396433 this . block . setDragging ( false ) ;
397434 }
398435
@@ -462,6 +499,12 @@ export class BlockDragStrategy implements IDragStrategy {
462499 this . workspace
463500 . getLayerManager ( )
464501 ?. moveOffDragLayer ( this . block , layers . BLOCK ) ;
502+ this . getVisibleBubbles ( this . block ) . forEach ( ( bubble ) =>
503+ this . workspace
504+ . getLayerManager ( )
505+ ?. moveOffDragLayer ( bubble , layers . BUBBLE , false ) ,
506+ ) ;
507+
465508 // Blocks dragged directly from a flyout may need to be bumped into
466509 // bounds.
467510 bumpObjects . bumpIntoBounds (
0 commit comments