mirror of
https://github.com/google/blockly.git
synced 2026-01-10 02:17:09 +01:00
## The basics - [x] I [validated my changes](https://developers.google.com/blockly/guides/contribute/core#making_and_verifying_a_change) ## The details ### Resolves Fixes #9386 Fixes part of #9293 ### Proposed Changes Addresses #9386 through a number of changes: - Ensures the flyout contents are reevaluated for ARIA changes whenever they themselves change (since previously `WorkspaceSvg` only recomputed its ARIA properties when one of its blocks self-registered which doesn't account for labels or buttons). - Collapsible categories are now correctly wrapped by a group (since groups of tree items must be in a parent group). - Updates toolbox ARIA computations to be on content changes rather than having items self-specify recomputing the ARIA properties. This mitigates an issue with collapsible categories not updating the toolbox contents and thus being omitted. - Introduced a separate pathway for computing tree info for flyout workspaces (vs. for the main workspace) in order to account for `FlyoutButton`s. - Updated `FlyoutButton` to use a nested structure of `treeitem` then `button` in order to actually count correctly in the tree and still be an interactive button. The readout experience is actually better now on ChromeVox, as well, since it reads out _both_ 'Button' and 'Tree item' which is interesting. It seems screen readers are designed to look for this pattern but it only works if set up in a very particular way. ### Reason for Changes Most of the changes here fixed incidental problems noticed while trying to address #9386 (such as the variables category not correctly accounting for the 'Create variable' button in the count, or not having the correct labels). Much of the count issues in the original issue were caused by a combination of missing some flyout items, and trying to compute the labels too early (i.e. before the categories were fully populated). ### Test Coverage Since this is an experimental change, no new tests were added. ### Documentation No documentation changes are directly needed here. ### Additional Information None.
113 lines
2.8 KiB
TypeScript
113 lines
2.8 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2020 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
/**
|
|
* A separator used for separating toolbox categories.
|
|
*
|
|
* @class
|
|
*/
|
|
// Former goog.module ID: Blockly.ToolboxSeparator
|
|
|
|
import * as Css from '../css.js';
|
|
import type {IToolbox} from '../interfaces/i_toolbox.js';
|
|
import * as registry from '../registry.js';
|
|
import * as aria from '../utils/aria.js';
|
|
import * as dom from '../utils/dom.js';
|
|
import type * as toolbox from '../utils/toolbox.js';
|
|
import {ToolboxItem} from './toolbox_item.js';
|
|
|
|
/**
|
|
* Class for a toolbox separator. This is the thin visual line that appears on
|
|
* the toolbox. This item is not interactable.
|
|
*/
|
|
export class ToolboxSeparator extends ToolboxItem {
|
|
/** Name used for registering a toolbox separator. */
|
|
static registrationName = 'sep';
|
|
|
|
/** All the CSS class names that are used to create a separator. */
|
|
protected cssConfig_: CssConfig = {'container': 'blocklyTreeSeparator'};
|
|
|
|
private htmlDiv: HTMLDivElement | null = null;
|
|
|
|
/**
|
|
* @param separatorDef The information needed to create a separator.
|
|
* @param toolbox The parent toolbox for the separator.
|
|
*/
|
|
constructor(separatorDef: toolbox.SeparatorInfo, toolbox: IToolbox) {
|
|
super(separatorDef, toolbox);
|
|
|
|
const cssConfig =
|
|
separatorDef['cssconfig'] || (separatorDef as any)['cssConfig'];
|
|
Object.assign(this.cssConfig_, cssConfig);
|
|
}
|
|
|
|
override init() {
|
|
this.createDom_();
|
|
}
|
|
|
|
/**
|
|
* Creates the DOM for a separator.
|
|
*
|
|
* @returns The parent element for the separator.
|
|
*/
|
|
protected createDom_(): HTMLDivElement {
|
|
const container = document.createElement('div');
|
|
// Ensure that the separator has a tab index to ensure it receives focus
|
|
// when clicked (since clicking isn't managed by the toolbox).
|
|
container.tabIndex = -1;
|
|
container.id = this.getId();
|
|
const className = this.cssConfig_['container'];
|
|
if (className) {
|
|
dom.addClass(container, className);
|
|
}
|
|
this.htmlDiv = container;
|
|
|
|
aria.setRole(this.htmlDiv, aria.Role.SEPARATOR);
|
|
|
|
return container;
|
|
}
|
|
|
|
override getDiv() {
|
|
return this.htmlDiv as HTMLDivElement;
|
|
}
|
|
|
|
override dispose() {
|
|
dom.removeNode(this.htmlDiv as HTMLDivElement);
|
|
}
|
|
}
|
|
|
|
export namespace ToolboxSeparator {
|
|
export interface CssConfig {
|
|
container: string | undefined;
|
|
}
|
|
}
|
|
|
|
export type CssConfig = ToolboxSeparator.CssConfig;
|
|
|
|
/** CSS for Toolbox. See css.js for use. */
|
|
Css.register(`
|
|
.blocklyTreeSeparator {
|
|
border-bottom: solid #e5e5e5 1px;
|
|
height: 0;
|
|
margin: 5px 0;
|
|
}
|
|
|
|
.blocklyToolbox[layout="h"] .blocklyTreeSeparator {
|
|
border-right: solid #e5e5e5 1px;
|
|
border-bottom: none;
|
|
height: auto;
|
|
margin: 0 5px 0 5px;
|
|
padding: 5px 0;
|
|
width: 0;
|
|
}
|
|
`);
|
|
|
|
registry.register(
|
|
registry.Type.TOOLBOX_ITEM,
|
|
ToolboxSeparator.registrationName,
|
|
ToolboxSeparator,
|
|
);
|