accessibility.js -> ts; + set aria-roledescription; add spec

This commit is contained in:
Ashley Engelund (weedySeaDragon @ github)
2022-11-15 13:47:16 -08:00
parent 3b79ee35e0
commit 8d96518092
3 changed files with 118 additions and 29 deletions

View File

@@ -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);
}

View 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');
});
});
});

View 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());
}