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
14 changes: 13 additions & 1 deletion packages/blockly/core/utils/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

// Former goog.module ID: Blockly.utils.dom

import type {Svg} from './svg.js';
import * as aria from './aria.js';
import {Svg} from './svg.js';
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

In order to use Svg as a value below I needed to change the import statement. This does not appear to affect anything, but I wanted to highlight it as I'm unsure of the reasons we were previously importing it as a type.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Generally we just import the type alone if it's being used strictly for TS typings, e.g. never instantiated/having any fields accessed. It's fine to import the full thing when we are actually using it though.


/**
* Required name space for SVG elements.
Expand Down Expand Up @@ -56,6 +57,17 @@ export function createSvgElement<T extends SVGElement>(
opt_parent?: Element | null,
): T {
const e = document.createElementNS(SVG_NS, `${name}`) as T;
/**
* For svg and group (g) elements, we set the role to generic so that they are ignored by assistive technologies.
*/
if (
name === Svg.SVG.toString() ||
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Svg.SVG.tagName is private, but toString() returns the tagName.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah good point, but yes this is fine, thanks!

name === Svg.G.toString() ||
e.tagName === Svg.SVG.toString() ||
e.tagName === Svg.G.toString()
) {
aria.setRole(e, aria.Role.GENERIC);
}
for (const key in attrs) {
e.setAttribute(key, `${attrs[key]}`);
}
Expand Down
45 changes: 45 additions & 0 deletions packages/blockly/tests/mocha/utils_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,51 @@ suite('Utils', function () {
Blockly.utils.dom.removeClass(p, 'zero');
assert.equal(p.className, '', 'Removing "zero"');
});

suite('createSvgElement', function () {
test('svg elements of type g have the generic role by default', function () {
const svgG = Blockly.utils.dom.createSvgElement(
Blockly.utils.Svg.G,
{},
);
const g = Blockly.utils.dom.createSvgElement('g', {});
assert.equal(svgG.getAttribute('role'), 'generic');
assert.equal(g.getAttribute('role'), 'generic');
});
test('svg elements of type svg have the generic role by default', function () {
const svgSvg = Blockly.utils.dom.createSvgElement(
Blockly.utils.Svg.SVG,
{},
);
const svg = Blockly.utils.dom.createSvgElement('svg', {});
assert.equal(svgSvg.getAttribute('role'), 'generic');
assert.equal(svg.getAttribute('role'), 'generic');
});
test('svg elements of type g reflect the role passed in when created', function () {
const svgG = Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.G, {
role: 'button',
});
const g = Blockly.utils.dom.createSvgElement('g', {role: 'button'});
assert.equal(svgG.getAttribute('role'), 'button');
assert.equal(g.getAttribute('role'), 'button');
});
test('svg elements of type svg reflect the role passed in when created', function () {
const svgSvg = Blockly.utils.dom.createSvgElement(
Blockly.utils.Svg.SVG,
{role: 'button'},
);
const svg = Blockly.utils.dom.createSvgElement('svg', {role: 'button'});
assert.equal(svgSvg.getAttribute('role'), 'button');
assert.equal(svg.getAttribute('role'), 'button');
});
test('other svg elements do not default to generic role', function () {
const textElement = Blockly.utils.dom.createSvgElement(
Blockly.utils.Svg.TEXT,
{},
);
assert.equal(textElement.getAttribute('role'), null);
});
});
});

suite('String', function () {
Expand Down