@@ -20,4 +20,57 @@ export function monkeyPatchBlockSvg() {
2020 }
2121 }
2222 }
23+
24+ // This is duplicated exactly from Blockly.BlockSvg.prototype.dispose,
25+ // except the radius of the connection search is increased to make
26+ // it more likely to focus a nearby block instead of the workspace
27+ // when a block is deleted. See https://github.com/RaspberryPiFoundation/blockly/issues/9585
28+ Blockly . BlockSvg . prototype . dispose = function ( this : Blockly . BlockSvg , healStack : boolean , animate : boolean ) {
29+ this . disposing = true ;
30+
31+ Blockly . Tooltip . dispose ( ) ;
32+ Blockly . ContextMenu . hide ( ) ;
33+
34+ // If this block (or a descendant) was focused, focus its parent or
35+ // workspace instead.
36+ const focusManager = Blockly . getFocusManager ( ) ;
37+ if (
38+ this . getSvgRoot ( ) . contains (
39+ focusManager . getFocusedNode ( ) ?. getFocusableElement ( ) ?? null ,
40+ )
41+ ) {
42+ let parent : Blockly . BlockSvg | undefined | null = this . getParent ( ) ;
43+ if ( ! parent ) {
44+ const connection = this . outputConnection ?? this . previousConnection ;
45+ if ( connection ) {
46+ // By default, Blockly searches for nearby connections within a radius of 0
47+ // to only get blocks that are touching. As a result, it usually returns nothing
48+ // and focuses the root of the workspace. Instead, we use the workspace dimensions
49+ // to try and find a block that's on screen
50+ const workspace = this . workspace ;
51+ const viewMetrics = workspace ?. getMetrics ( ) ;
52+ const radius = viewMetrics ? Math . max ( viewMetrics . viewWidth , viewMetrics . viewHeight ) / 2 : 0 ;
53+
54+ const targetConnection = connection . closest (
55+ radius ,
56+ new Blockly . utils . Coordinate ( 0 , 0 ) ,
57+ ) . connection ;
58+ parent = targetConnection ?. getSourceBlock ( ) ;
59+ }
60+ }
61+ if ( parent ) {
62+ focusManager . focusNode ( parent ) ;
63+ } else {
64+ setTimeout ( ( ) => focusManager . focusTree ( this . workspace ) , 0 ) ;
65+ }
66+ }
67+
68+ if ( animate ) {
69+ this . unplug ( healStack ) ;
70+ Blockly . blockAnimations . disposeUiEffect ( this ) ;
71+ }
72+
73+ Blockly . Block . prototype . dispose . call ( this , ! ! healStack ) ;
74+ Blockly . utils . dom . removeNode ( this . getSvgRoot ( ) ) ;
75+ }
2376}
0 commit comments