fix: read parent hierarchy with shift+i (#9527)

* fix: read parent hierarchy with shift+i

* fix: use a default argument instead of optional
This commit is contained in:
Maribeth Moffatt
2025-12-11 16:07:51 -05:00
committed by GitHub
parent 12da1fb577
commit 9a8293096b
2 changed files with 62 additions and 19 deletions

View File

@@ -243,7 +243,11 @@ export class BlockSvg
);
}
computeAriaLabel(verbose: boolean = false): string {
computeAriaLabel(
verbose: boolean = false,
minimal: boolean = false,
currentBlock: this | undefined = undefined,
): string {
const labelComponents = [];
if (!this.workspace.isFlyout && this.getRootBlock() === this) {
@@ -274,23 +278,26 @@ export class BlockSvg
const {commaSeparatedSummary, inputCount} = buildBlockSummary(
this,
verbose,
currentBlock,
);
labelComponents.push(commaSeparatedSummary);
if (!this.isEnabled()) {
labelComponents.push('disabled');
}
if (this.isCollapsed()) {
labelComponents.push('collapsed');
}
if (this.isShadow()) {
labelComponents.push('replaceable');
}
if (!minimal) {
if (!this.isEnabled()) {
labelComponents.push('disabled');
}
if (this.isCollapsed()) {
labelComponents.push('collapsed');
}
if (this.isShadow()) {
labelComponents.push('replaceable');
}
if (inputCount > 1) {
labelComponents.push('has inputs');
} else if (inputCount === 1) {
labelComponents.push('has input');
if (inputCount > 1) {
labelComponents.push('has inputs');
} else if (inputCount === 1) {
labelComponents.push('has input');
}
}
return labelComponents.join(', ');
@@ -2063,7 +2070,11 @@ interface BlockSummary {
inputCount: number;
}
function buildBlockSummary(block: BlockSvg, verbose: boolean): BlockSummary {
function buildBlockSummary(
block: BlockSvg,
verbose: boolean,
currentBlock?: BlockSvg,
): BlockSummary {
let inputCount = 0;
// Produce structured segments
@@ -2120,6 +2131,10 @@ function buildBlockSummary(block: BlockSvg, verbose: boolean): BlockSummary {
true,
);
if (targetBlock === currentBlock) {
nestedSegments.unshift({kind: 'label', text: 'Current block: '});
}
if (!isNestedInput) {
// treat the whole nested summary as a single input segment
const nestedText = nestedSegments.map((s) => s.text).join(' ');

View File

@@ -450,10 +450,38 @@ export function registerReadBlockParentSummary() {
callback(workspace, e) {
const selectedBlock = workspace.getCursor().getSourceBlock();
if (!selectedBlock) return false;
const parentBlock = selectedBlock.getParent();
if (parentBlock) {
const blockSummary = parentBlock.computeAriaLabel(true);
aria.announceDynamicAriaState(`Parent block: ${blockSummary}`);
const toAnnounce = [];
// First go up the chain of output connections and start finding parents from there
// because the outputs of a block are read anyway, so we don't need to repeat them
let startBlock = selectedBlock;
while (startBlock.outputConnection?.isConnected()) {
startBlock = startBlock.getParent()!;
}
if (startBlock !== selectedBlock) {
toAnnounce.push(
startBlock.computeAriaLabel(false, true, selectedBlock),
);
}
let parent = startBlock.getParent();
while (parent) {
toAnnounce.push(parent.computeAriaLabel(false, true));
parent = parent.getParent();
}
if (toAnnounce.length) {
toAnnounce.reverse();
if (!selectedBlock.outputConnection?.isConnected()) {
// The current block was already read out earlier if it has an output connection
toAnnounce.push(
`Current block: ${selectedBlock.computeAriaLabel(false, true)}`,
);
}
aria.announceDynamicAriaState(`Parent blocks: ${toAnnounce.join(',')}`);
} else {
aria.announceDynamicAriaState('Current block has no parent');
}