Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 29 additions & 9 deletions packages/blockly/core/block_svg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1354,6 +1354,29 @@ export class BlockSvg
*/
bringToFront(blockOnly = false) {
const previouslyFocused = getFocusManager().getFocusedNode();
this.moveSvgRootToFront(blockOnly);
if (previouslyFocused) {
// Bringing a block to the front of the stack doesn't fundamentally change
// the logical structure of the page, but it does change element ordering
// which can take automatically take away focus from a node. Ensure focus
// is restored to avoid a discontinuity.
getFocusManager().focusNode(previouslyFocused);
}
}

/**
* Reorders this block's SVG root and those of its parents (unless
* `blockOnly`` is set to `true`) to the end of their respective parents so
* they render on top of their siblings.
*
* Unlike `bringToFront`, this does not preserve focus across the reorder, so
* it is safe to call from within a focus callback
*
* @param blockOnly True to only move this block to the front without
* adjusting its parents.
* @internal
*/
moveSvgRootToFront(blockOnly = false) {
/* eslint-disable-next-line @typescript-eslint/no-this-alias */
let block: this | null = this;
if (block.isDeadOrDying()) {
Expand All @@ -1362,21 +1385,15 @@ export class BlockSvg
do {
const root = block.getSvgRoot();
const parent = root.parentNode;
const childNodes = parent!.childNodes;
if (!parent) return;
const childNodes = parent.childNodes;
// Avoid moving the block if it's already at the bottom.
if (childNodes[childNodes.length - 1] !== root) {
parent!.appendChild(root);
parent.appendChild(root);
}
if (blockOnly) break;
block = block.getParent();
} while (block);
if (previouslyFocused) {
// Bringing a block to the front of the stack doesn't fundamentally change
// the logical structure of the page, but it does change element ordering
// which can take automatically take away focus from a node. Ensure focus
// is restored to avoid a discontinuity.
getFocusManager().focusNode(previouslyFocused);
}
}

/**
Expand Down Expand Up @@ -1909,6 +1926,9 @@ export class BlockSvg
onNodeFocus(): void {
this.recomputeAriaContext();
this.select();
if (!this.workspace.isFlyout) {
this.moveSvgRootToFront();
}
const focusedNode = getFocusManager().getFocusedNode();
if (focusedNode && focusedNode !== this) {
renderManagement.finishQueuedRenders().then(() => {
Expand Down
8 changes: 6 additions & 2 deletions packages/blockly/core/rendered_connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -700,8 +700,12 @@ export class RenderedConnection
/** See IFocusableNode.onNodeFocus. */
onNodeFocus(): void {
this.highlight();
this.getSourceBlock().workspace.scrollBoundsIntoView(
this.getSourceBlock().getBoundingRectangleWithoutChildren(),
const sourceBlock = this.getSourceBlock();
if (!sourceBlock.workspace.isFlyout) {
sourceBlock.moveSvgRootToFront();
}
sourceBlock.workspace.scrollBoundsIntoView(
sourceBlock.getBoundingRectangleWithoutChildren(),
);
}

Expand Down
Loading