Skip to content

Commit f466d4d

Browse files
fix: Bring blocks to the front when focused via keyboard (#10032)
* fix: Bring blocks to the front when focused via keyboard * Address test failures
1 parent 9ede433 commit f466d4d

2 files changed

Lines changed: 35 additions & 11 deletions

File tree

packages/blockly/core/block_svg.ts

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,6 +1354,29 @@ export class BlockSvg
13541354
*/
13551355
bringToFront(blockOnly = false) {
13561356
const previouslyFocused = getFocusManager().getFocusedNode();
1357+
this.moveSvgRootToFront(blockOnly);
1358+
if (previouslyFocused) {
1359+
// Bringing a block to the front of the stack doesn't fundamentally change
1360+
// the logical structure of the page, but it does change element ordering
1361+
// which can take automatically take away focus from a node. Ensure focus
1362+
// is restored to avoid a discontinuity.
1363+
getFocusManager().focusNode(previouslyFocused);
1364+
}
1365+
}
1366+
1367+
/**
1368+
* Reorders this block's SVG root and those of its parents (unless
1369+
* `blockOnly`` is set to `true`) to the end of their respective parents so
1370+
* they render on top of their siblings.
1371+
*
1372+
* Unlike `bringToFront`, this does not preserve focus across the reorder, so
1373+
* it is safe to call from within a focus callback
1374+
*
1375+
* @param blockOnly True to only move this block to the front without
1376+
* adjusting its parents.
1377+
* @internal
1378+
*/
1379+
moveSvgRootToFront(blockOnly = false) {
13571380
/* eslint-disable-next-line @typescript-eslint/no-this-alias */
13581381
let block: this | null = this;
13591382
if (block.isDeadOrDying()) {
@@ -1362,21 +1385,15 @@ export class BlockSvg
13621385
do {
13631386
const root = block.getSvgRoot();
13641387
const parent = root.parentNode;
1365-
const childNodes = parent!.childNodes;
1388+
if (!parent) return;
1389+
const childNodes = parent.childNodes;
13661390
// Avoid moving the block if it's already at the bottom.
13671391
if (childNodes[childNodes.length - 1] !== root) {
1368-
parent!.appendChild(root);
1392+
parent.appendChild(root);
13691393
}
13701394
if (blockOnly) break;
13711395
block = block.getParent();
13721396
} while (block);
1373-
if (previouslyFocused) {
1374-
// Bringing a block to the front of the stack doesn't fundamentally change
1375-
// the logical structure of the page, but it does change element ordering
1376-
// which can take automatically take away focus from a node. Ensure focus
1377-
// is restored to avoid a discontinuity.
1378-
getFocusManager().focusNode(previouslyFocused);
1379-
}
13801397
}
13811398

13821399
/**
@@ -1909,6 +1926,9 @@ export class BlockSvg
19091926
onNodeFocus(): void {
19101927
this.recomputeAriaContext();
19111928
this.select();
1929+
if (!this.workspace.isFlyout) {
1930+
this.moveSvgRootToFront();
1931+
}
19121932
const focusedNode = getFocusManager().getFocusedNode();
19131933
if (focusedNode && focusedNode !== this) {
19141934
renderManagement.finishQueuedRenders().then(() => {

packages/blockly/core/rendered_connection.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -700,8 +700,12 @@ export class RenderedConnection
700700
/** See IFocusableNode.onNodeFocus. */
701701
onNodeFocus(): void {
702702
this.highlight();
703-
this.getSourceBlock().workspace.scrollBoundsIntoView(
704-
this.getSourceBlock().getBoundingRectangleWithoutChildren(),
703+
const sourceBlock = this.getSourceBlock();
704+
if (!sourceBlock.workspace.isFlyout) {
705+
sourceBlock.moveSvgRootToFront();
706+
}
707+
sourceBlock.workspace.scrollBoundsIntoView(
708+
sourceBlock.getBoundingRectangleWithoutChildren(),
705709
);
706710
}
707711

0 commit comments

Comments
 (0)