Skip to content

Commit c8a7fc6

Browse files
authored
feat: Remove most block tree support. (#9412)
Also, use regions for identifiying toolbox, workspace, and flyout.
1 parent 40aa0d3 commit c8a7fc6

File tree

4 files changed

+23
-96
lines changed

4 files changed

+23
-96
lines changed

core/block_svg.ts

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -300,42 +300,18 @@ export class BlockSvg
300300
private computeAriaRole() {
301301
if (this.isSimpleReporter()) {
302302
aria.setRole(this.pathObject.svgPath, aria.Role.BUTTON);
303-
} else {
304-
// This isn't read out by VoiceOver and it will read in the wrong place
305-
// as a duplicate in ChromeVox due to the other changes in this branch.
306-
// aria.setState(
307-
// this.pathObject.svgPath,
308-
// aria.State.ROLEDESCRIPTION,
309-
// 'block',
310-
// );
303+
} else if (this.workspace.isFlyout) {
311304
aria.setRole(this.pathObject.svgPath, aria.Role.TREEITEM);
312-
}
313-
}
314-
315-
collectSiblingBlocks(surroundParent: BlockSvg | null): BlockSvg[] {
316-
// NOTE TO DEVELOPERS: it's very important that these are NOT sorted. The
317-
// returned list needs to be relatively stable for consistent block indexes
318-
// read out to users via screen readers.
319-
if (surroundParent) {
320-
// Start from the first sibling and iterate in navigation order.
321-
const firstSibling: BlockSvg = surroundParent.getChildren(false)[0];
322-
const siblings: BlockSvg[] = [firstSibling];
323-
let nextSibling: BlockSvg | null = firstSibling;
324-
while ((nextSibling = nextSibling?.getNextBlock())) {
325-
siblings.push(nextSibling);
326-
}
327-
return siblings;
328305
} else {
329-
// For top-level blocks, simply return those from the workspace.
330-
return this.workspace.getTopBlocks(false);
306+
aria.setState(
307+
this.pathObject.svgPath,
308+
aria.State.ROLEDESCRIPTION,
309+
'block',
310+
);
311+
aria.setRole(this.pathObject.svgPath, aria.Role.FIGURE);
331312
}
332313
}
333314

334-
computeLevelInWorkspace(): number {
335-
const surroundParent = this.getSurroundParent();
336-
return surroundParent ? surroundParent.computeLevelInWorkspace() + 1 : 0;
337-
}
338-
339315
/**
340316
* Create and initialize the SVG representation of the block.
341317
* May be called more than once.

core/toolbox/toolbox.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,6 @@ export class Toolbox
154154
this.setVisible(true);
155155
this.flyout.init(workspace);
156156

157-
aria.setRole(this.HtmlDiv, aria.Role.TREE);
158-
aria.setState(this.HtmlDiv, aria.State.LABEL, Msg['TOOLBOX_ARIA_LABEL']);
159-
160157
this.render(this.toolboxDef_);
161158
const themeManager = workspace.getThemeManager();
162159
themeManager.subscribe(
@@ -208,6 +205,12 @@ export class Toolbox
208205
toolboxContainer.setAttribute('layout', this.isHorizontal() ? 'h' : 'v');
209206
dom.addClass(toolboxContainer, 'blocklyToolbox');
210207
toolboxContainer.setAttribute('dir', this.RTL ? 'RTL' : 'LTR');
208+
aria.setRole(toolboxContainer, aria.Role.REGION);
209+
aria.setState(
210+
toolboxContainer,
211+
aria.State.LABEL,
212+
Msg['TOOLBOX_ARIA_LABEL'],
213+
);
211214
return toolboxContainer;
212215
}
213216

@@ -222,6 +225,7 @@ export class Toolbox
222225
if (this.isHorizontal()) {
223226
contentsContainer.style.flexDirection = 'row';
224227
}
228+
aria.setRole(contentsContainer, aria.Role.TREE);
225229
return contentsContainer;
226230
}
227231

core/utils/aria.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export enum Role {
5353
TEXTBOX = 'textbox',
5454
COMBOBOX = 'combobox',
5555
SPINBUTTON = 'spinbutton',
56+
REGION = 'region',
5657
}
5758

5859
/**

core/workspace_svg.ts

Lines changed: 8 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import {WorkspaceComment} from './comments/workspace_comment.js';
3131
import * as common from './common.js';
3232
import {ComponentManager} from './component_manager.js';
3333
import {ConnectionDB} from './connection_db.js';
34-
import {ConnectionType} from './connection_type.js';
3534
import * as ContextMenu from './contextmenu.js';
3635
import {
3736
ContextMenuOption,
@@ -763,19 +762,15 @@ export class WorkspaceSvg
763762
});
764763

765764
let ariaLabel = null;
766-
if (injectionDiv) {
767-
ariaLabel = Msg['WORKSPACE_ARIA_LABEL'];
768-
} else if (this.isFlyout) {
765+
if (this.isFlyout) {
769766
ariaLabel = 'Flyout';
770767
} else if (this.isMutator) {
771-
ariaLabel = 'Mutator';
768+
ariaLabel = 'Mutator Workspace';
772769
} else {
773-
// This case can happen in some test scenarios.
774-
// TODO: Figure out when this can happen in non-test scenarios (if ever).
775-
ariaLabel = 'Workspace';
770+
ariaLabel = Msg['WORKSPACE_ARIA_LABEL'];
776771
}
772+
aria.setRole(this.svgGroup_, aria.Role.REGION);
777773
aria.setState(this.svgGroup_, aria.State.LABEL, ariaLabel);
778-
aria.setRole(this.svgGroup_, aria.Role.TREE);
779774

780775
// Note that a <g> alone does not receive mouse events--it must have a
781776
// valid target inside it. If no background class is specified, as in the
@@ -803,7 +798,10 @@ export class WorkspaceSvg
803798
this.svgBlockCanvas_ = this.layerManager.getBlockLayer();
804799
this.svgBubbleCanvas_ = this.layerManager.getBubbleLayer();
805800

806-
if (!this.isFlyout) {
801+
if (this.isFlyout) {
802+
// Use the block canvas as the primary tree parent for flyout blocks.
803+
aria.setRole(this.svgBlockCanvas_, aria.Role.TREE);
804+
} else {
807805
browserEvents.conditionalBind(
808806
this.svgGroup_,
809807
'pointerdown',
@@ -2959,61 +2957,9 @@ export class WorkspaceSvg
29592957
aria.setState(treeItemElem, aria.State.POSINSET, index + 1);
29602958
aria.setState(treeItemElem, aria.State.SETSIZE, focusableItems.length);
29612959
aria.setState(treeItemElem, aria.State.LEVEL, 1); // They are always top-level.
2962-
if (item instanceof BlockSvg) {
2963-
item
2964-
.getChildren(false)
2965-
.forEach((child) =>
2966-
this.recomputeAriaTreeItemDetailsRecursively(child),
2967-
);
2968-
}
29692960
});
2970-
} else {
2971-
// TODO: Do this efficiently (probably incrementally).
2972-
this.getTopBlocks(false).forEach((block) =>
2973-
this.recomputeAriaTreeItemDetailsRecursively(block),
2974-
);
29752961
}
29762962
}
2977-
2978-
private recomputeAriaTreeItemDetailsRecursively(block: BlockSvg) {
2979-
const elem = block.getFocusableElement();
2980-
const connection = block.currentConnectionCandidate;
2981-
let childPosition: number;
2982-
let parentsChildCount: number;
2983-
let hierarchyDepth: number;
2984-
if (connection) {
2985-
// If the block is being inserted into a new location, the position is hypothetical.
2986-
// TODO: Figure out how to deal with output connections.
2987-
let surroundParent: BlockSvg | null;
2988-
let siblingBlocks: BlockSvg[];
2989-
if (connection.type === ConnectionType.INPUT_VALUE) {
2990-
surroundParent = connection.sourceBlock_;
2991-
siblingBlocks = block.collectSiblingBlocks(surroundParent);
2992-
// The block is being added as a child since it's input.
2993-
// TODO: Figure out how to compute the correct position.
2994-
childPosition = 0;
2995-
} else {
2996-
surroundParent = connection.sourceBlock_.getSurroundParent();
2997-
siblingBlocks = block.collectSiblingBlocks(surroundParent);
2998-
// The block is being added after the connected block.
2999-
childPosition = siblingBlocks.indexOf(connection.sourceBlock_) + 1;
3000-
}
3001-
parentsChildCount = siblingBlocks.length + 1;
3002-
hierarchyDepth = surroundParent?.computeLevelInWorkspace() ?? 0;
3003-
} else {
3004-
const surroundParent = block.getSurroundParent();
3005-
const siblingBlocks = block.collectSiblingBlocks(surroundParent);
3006-
childPosition = siblingBlocks.indexOf(block);
3007-
parentsChildCount = siblingBlocks.length;
3008-
hierarchyDepth = block.computeLevelInWorkspace();
3009-
}
3010-
aria.setState(elem, aria.State.POSINSET, childPosition + 1);
3011-
aria.setState(elem, aria.State.SETSIZE, parentsChildCount);
3012-
aria.setState(elem, aria.State.LEVEL, hierarchyDepth + 1);
3013-
block
3014-
.getChildren(false)
3015-
.forEach((child) => this.recomputeAriaTreeItemDetailsRecursively(child));
3016-
}
30172963
}
30182964

30192965
/**

0 commit comments

Comments
 (0)