mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-18 06:49:47 +02:00
accessibility.js -> ts; + set aria-roledescription; add spec
This commit is contained in:

parent
3b79ee35e0
commit
8d96518092
@@ -1,29 +0,0 @@
|
||||
/**
|
||||
* This method will add a basic title and description element to a chart. The yy parser will need to
|
||||
* respond to getAccTitle and getAccDescription, where the title is the title element on the chart,
|
||||
* which is generally not displayed and the accDescription is the description element on the chart,
|
||||
* which is never displayed.
|
||||
*
|
||||
* The following charts display their title as a visual and accessibility element: gantt
|
||||
*
|
||||
* @param yy_parser
|
||||
* @param svg
|
||||
* @param id
|
||||
*/
|
||||
export default function addSVGAccessibilityFields(yy_parser, svg, id) {
|
||||
if (typeof svg.insert === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
let title_string = yy_parser.getAccTitle();
|
||||
let description = yy_parser.getAccDescription();
|
||||
svg.attr('role', 'img').attr('aria-labelledby', 'chart-title-' + id + ' chart-desc-' + id);
|
||||
svg
|
||||
.insert('desc', ':first-child')
|
||||
.attr('id', 'chart-desc-' + id)
|
||||
.text(description);
|
||||
svg
|
||||
.insert('title', ':first-child')
|
||||
.attr('id', 'chart-title-' + id)
|
||||
.text(title_string);
|
||||
}
|
73
packages/mermaid/src/accessibility.spec.ts
Normal file
73
packages/mermaid/src/accessibility.spec.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
// Spec/tests for accessibility
|
||||
|
||||
import { setA11yDiagramInfo, addSVGa11yTitleDescription } from './accessibility';
|
||||
|
||||
import { MockedD3 } from './tests/MockedD3';
|
||||
|
||||
const fauxSvgNode = new MockedD3();
|
||||
|
||||
const MockedDiagramDb = {
|
||||
getAccTitle: vi.fn().mockReturnValue('the title'),
|
||||
getAccDescription: vi.fn().mockReturnValue('the description'),
|
||||
};
|
||||
|
||||
describe('setA11yDiagramInfo', () => {
|
||||
it('sets the aria-roledescription to the diagram type', () => {
|
||||
// @ts-ignore Required to easily handle the d3 select types
|
||||
const svg_attr_spy = vi.spyOn(fauxSvgNode, 'attr').mockReturnValue(fauxSvgNode);
|
||||
setA11yDiagramInfo(fauxSvgNode, 'flowchart');
|
||||
expect(svg_attr_spy).toHaveBeenCalledWith('aria-roledescription', 'flowchart');
|
||||
});
|
||||
});
|
||||
|
||||
describe('addSVGa11yTitleDescription', () => {
|
||||
const testDiagramDb = MockedDiagramDb;
|
||||
const givenId = 'theBaseId';
|
||||
|
||||
describe('with the given svg d3 object:', () => {
|
||||
it('does nothing if there is no insert defined', () => {
|
||||
const noInsertSvg = {
|
||||
attr: vi.fn(),
|
||||
};
|
||||
const noInsert_attr_spy = vi.spyOn(noInsertSvg, 'attr').mockReturnValue(noInsertSvg);
|
||||
addSVGa11yTitleDescription(testDiagramDb, noInsertSvg, givenId);
|
||||
expect(noInsert_attr_spy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('sets aria-labelledby to the title id and the description id inserted as children', () => {
|
||||
// @ts-ignore Required to easily handle the d3 select types
|
||||
const svg_attr_spy = vi.spyOn(fauxSvgNode, 'attr').mockReturnValue(fauxSvgNode);
|
||||
addSVGa11yTitleDescription(testDiagramDb, fauxSvgNode, givenId);
|
||||
expect(svg_attr_spy).toHaveBeenCalledWith(
|
||||
'aria-labelledby',
|
||||
`chart-title-${givenId} chart-desc-${givenId}`
|
||||
);
|
||||
});
|
||||
|
||||
it('inserts a title tag as the first child with the text set to the accTitle returned by the diagram db', () => {
|
||||
const faux_title = new MockedD3();
|
||||
const svg_insert_spy = vi.spyOn(fauxSvgNode, 'insert').mockReturnValue(faux_title);
|
||||
// @ts-ignore Required to easily handle the d3 select types
|
||||
const title_attr_spy = vi.spyOn(faux_title, 'attr').mockReturnValue(faux_title);
|
||||
const title_text_spy = vi.spyOn(faux_title, 'text');
|
||||
|
||||
addSVGa11yTitleDescription(testDiagramDb, fauxSvgNode, givenId);
|
||||
expect(svg_insert_spy).toHaveBeenCalledWith('title', ':first-child');
|
||||
expect(title_attr_spy).toHaveBeenCalledWith('id', `chart-title-` + givenId);
|
||||
expect(title_text_spy).toHaveBeenNthCalledWith(2, 'the title');
|
||||
});
|
||||
|
||||
it('inserts a desc tag as the 2nd child with the text set to accDescription returned by the diagram db', () => {
|
||||
const faux_desc = new MockedD3();
|
||||
const svg_insert_spy = vi.spyOn(fauxSvgNode, 'insert').mockReturnValue(faux_desc);
|
||||
// @ts-ignore Required to easily handle the d3 select types
|
||||
const desc_attr_spy = vi.spyOn(faux_desc, 'attr').mockReturnValue(faux_desc);
|
||||
const desc_text_spy = vi.spyOn(faux_desc, 'text');
|
||||
|
||||
addSVGa11yTitleDescription(testDiagramDb, fauxSvgNode, givenId);
|
||||
expect(svg_insert_spy).toHaveBeenCalledWith('desc', ':first-child');
|
||||
expect(desc_attr_spy).toHaveBeenCalledWith('id', `chart-desc-` + givenId);
|
||||
expect(desc_text_spy).toHaveBeenNthCalledWith(1, 'the description');
|
||||
});
|
||||
});
|
||||
});
|
45
packages/mermaid/src/accessibility.ts
Normal file
45
packages/mermaid/src/accessibility.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Accessibility (a11y) functions, types, helpers
|
||||
*
|
||||
*/
|
||||
|
||||
// This is just a convenience alias to make it clear the type is a d3 object. (It's easier to make it 'any' instead of the comple typing set in d3)
|
||||
type D3object = any;
|
||||
|
||||
/**
|
||||
* Set the accessibility (a11y) information for the svg d3 object using the given diagram type
|
||||
* Note that the svg element role _should_ be mapped to a 'graphics-document' by default. Thus we don't set it here, but can set it in the future if needed.
|
||||
* @param svg - d3 object that contains the SVG HTML element
|
||||
* @param diagramType - diagram name for to the aria-roledescription
|
||||
*/
|
||||
export function setA11yDiagramInfo(svg: D3object, diagramType: string) {
|
||||
svg.attr('aria-roledescription', diagramType);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will add a basic title and description element to a chart. The yy parser will need to
|
||||
* respond to getAccTitle and getAccDescription,
|
||||
* where the accessible title is the title element on the chart.
|
||||
*
|
||||
* Note that the accessible title is generally _not_ displayed
|
||||
* and the accessible description is never displayed.
|
||||
*
|
||||
*
|
||||
* The following charts display their title as a visual and accessibility element: gantt. TODO fix this
|
||||
*
|
||||
* @param diagramDb - the 'db' object/module for a diagram. Must respond to getAccTitle() and getAccDescription()
|
||||
* @param svg - the d3 object that represents the svg element
|
||||
* @param baseId - the id to use as the base for the title and description
|
||||
*/
|
||||
export function addSVGa11yTitleDescription(diagramDb: any, svg: D3object, baseId: string) {
|
||||
if (typeof svg.insert === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
const titleId = 'chart-title-' + baseId;
|
||||
const descId = 'chart-desc-' + baseId;
|
||||
|
||||
svg.attr('aria-labelledby', titleId + ' ' + descId);
|
||||
svg.insert('desc', ':first-child').attr('id', descId).text(diagramDb.getAccDescription());
|
||||
svg.insert('title', ':first-child').attr('id', titleId).text(diagramDb.getAccTitle());
|
||||
}
|
Reference in New Issue
Block a user