Skip to content
Open
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
64 changes: 63 additions & 1 deletion core/block_svg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,58 @@ export class BlockSvg
* @internal
*/
recomputeAriaLabel() {
if (this.initialized) {
const childElemIds: string[] = [];
for (const input of this.inputList) {
if (input.isVisible() && input.connection) {
if (input.connection.type === ConnectionType.NEXT_STATEMENT) {
let currentBlock: BlockSvg | null =
input.connection.targetBlock() as BlockSvg | null;
while (currentBlock) {
if (currentBlock.canBeFocused()) {
childElemIds.push(currentBlock.getBlockSvgFocusElem().id);
}
currentBlock = currentBlock.getNextBlock();
}
} else if (input.connection.type === ConnectionType.INPUT_VALUE) {
const inpBlock = input.connection.targetBlock() as BlockSvg | null;
if (inpBlock && inpBlock.canBeFocused()) {
childElemIds.push(inpBlock.getBlockSvgFocusElem().id);
}
}
}
for (const field of input.fieldRow) {
if (field.getSvgRoot() && field.canBeFocused()) {
// Only track the field if it's been initialized.
childElemIds.push(field.getFocusableElement().id);
}
}
for (const icon of this.icons) {
if (icon.canBeFocused()) {
childElemIds.push(icon.getFocusableElement().id);
}
}
for (const connection of this.getConnections_(true)) {
// TODO: Somehow it's possible for a connection to be highlighted but
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you file an issue for this and link it here so we don't lose track of this?

// have no focusable element. This might be some sort of race
// condition or perhaps dispose-esque situation happening.
if (
connection.canBeFocused() &&
connection.isHighlighted() &&
connection.findHighlightSvg() !== null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need to check this? What happens if you say aria-owns with an id that doesn't exist in the dom?

If you need to keep it, can you add the same bug ID in the todo that makes it public so that we can make it private again when it's no longer needed (I'm assuming if this bug didn't exist you wouldn't need to check this)

) {
childElemIds.push(connection.getFocusableElement().id);
}
}
}
aria.setState(this.getBlockSvgFocusElem(), aria.State.OWNS, childElemIds);
}

if (this.isSimpleReporter()) {
const field = Array.from(this.getFields())[0];
if (field.isFullBlockField() && field.isCurrentlyEditable()) return;
if (field && field.isFullBlockField() && field.isCurrentlyEditable()) {
return;
}
}

aria.setState(
Expand All @@ -245,6 +294,12 @@ export class BlockSvg
);
}

private getBlockSvgFocusElem(): Element {
// Note that this deviates from getFocusableElement() to ensure that
// single field blocks are properly set up in the hierarchy.
return this.pathObject.svgPath;
}

private computeAriaLabel(): string {
const {blockSummary, inputCount} = buildBlockSummary(this);
const inputSummary = inputCount
Expand Down Expand Up @@ -353,6 +408,7 @@ export class BlockSvg
this.workspace.getCanvas().appendChild(svg);
}
this.initialized = true;
this.recomputeAriaLabel();
}

/**
Expand Down Expand Up @@ -457,6 +513,12 @@ export class BlockSvg
this.applyColour();

this.workspace.recomputeAriaTree();
this.recomputeAriaLabelRecursive();
}

private recomputeAriaLabelRecursive() {
this.recomputeAriaLabel();
this.parentBlock_?.recomputeAriaLabelRecursive();
}

/**
Expand Down
7 changes: 6 additions & 1 deletion core/rendered_connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,8 @@ export class RenderedConnection
aria.setState(highlightSvg, aria.State.LABEL, 'Open connection');
}
}

this.sourceBlock_.recomputeAriaLabel();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like a lot of extra work to recompute the entire aria label which includes searching through all of the inputs, child blocks, etc. just to remove one specific ID for the connection highlight, which we already know the ID of.

Could you keep track of the childElemIds as a set and just remove or add this connection ID to the set, and then update the aria-owns attribute with the set of IDs instead of recalculating the entire set of IDs on each highlight?

}

/** Remove the highlighting around this connection. */
Expand All @@ -373,6 +375,8 @@ export class RenderedConnection
if (highlightSvg) {
highlightSvg.style.display = 'none';
}

this.sourceBlock_.recomputeAriaLabel();
}

/** Returns true if this connection is highlighted, false otherwise. */
Expand Down Expand Up @@ -688,7 +692,8 @@ export class RenderedConnection
return true;
}

private findHighlightSvg(): SVGPathElement | null {
// TODO: Figure out how to make this private again.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a tsdoc with @internal so it doesn't get made part of our public API, and add same bug id from previous comment

findHighlightSvg(): SVGPathElement | null {
// This cast is valid as TypeScript's definition is wrong. See:
// https://github.com/microsoft/TypeScript/issues/60996.
return document.getElementById(this.id) as
Expand Down
Loading