UNPKG

@uuv/a11y

Version:

A javascript lib for running a11y validation based on multiple reference(RGAA, etc)

106 lines (105 loc) 4.44 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.table = exports.tableCssSelector = exports.commonCssSelector = exports.siblingElement = exports.informativeContent = void 0; class SelectorRule { SELECTOR; ATTRIBUTES; constructor(SELECTOR, ATTRIBUTES) { this.SELECTOR = SELECTOR; this.ATTRIBUTES = ATTRIBUTES; this.SELECTOR = SELECTOR; this.ATTRIBUTES = ATTRIBUTES; } buildSelectorWithAttributes() { const result = this.ATTRIBUTES.map(value => `${this.SELECTOR}[${value}]`); if (result.length === 0) { return [this.SELECTOR]; } return result; } } exports.informativeContent = { image: new SelectorRule("img", ["title", "aria-labelledby", "aria-label", "alt"]), area: new SelectorRule("area[href]", ["title", "aria-labelledby", "aria-label", "alt"]), input: new SelectorRule("input[type=image]", ["title", "aria-labelledby", "aria-label", "alt"]), object: new SelectorRule("object[type^=image]", ["title", "aria-labelledby", "aria-label"]), embed: new SelectorRule("embed[type^=image]", ["title", "aria-labelledby", "aria-label"]), svg: new SelectorRule("svg:not(a svg,button svg)", ["title", "aria-labelledby", "aria-label"]), canvas: new SelectorRule("canvas:not(:empty)", ["title", "aria-labelledby", "aria-label"]), }; exports.siblingElement = { button: new SelectorRule("button", []), a: new SelectorRule("a[href]", []), }; /** CSS SELECTOR HELPER *******/ class CssSelectorRule { attributes; selector; role; constructor(attributes, selector = "", role = selector) { this.attributes = attributes; this.selector = selector; this.role = role; this.selector = selector; this.role = role; this.attributes = attributes; } buildSelector(overrideSelector = [], overrideRole = overrideSelector[0]) { if (overrideSelector && overrideSelector.length === 0 && !overrideRole) { console.error("selector or role must be provided"); } const selectors = []; if (overrideSelector.length > 0) { selectors.push(...overrideSelector); } if (overrideRole) { selectors.push(`[role=${overrideRole}]`); } if (this.attributes.length === 0) { return selectors; } const result = []; selectors.forEach(selector => { this.attributes.forEach(attribute => { result.push(`${selector}${attribute}`); }); }); return result; } } exports.commonCssSelector = { ariaDescribedBy: ["[aria-describedby]:not([aria-describedby=''])"], title: ["[title]:not([title=''])"], ariaLabelledBy: ["[aria-labelledby]:not([aria-labelledby=''])"], ariaLabel: ["[aria-label]:not([aria-label=''])"] }; exports.tableCssSelector = { complexTh: [":has(tr:not(:first-child) th:first-child)"], complexRowHeader: [":has([role=row]:not(:first-child) [role=rowheader])"], complexColumnHeader: [":has([role=row]:not(:first-child) [role=columnheader])"], }; exports.table = { selector: { withFormatting: "table[role=presentation]", complex: [ ...exports.tableCssSelector.complexTh, ...exports.tableCssSelector.complexRowHeader, ...exports.tableCssSelector.complexColumnHeader ].map(value => `table:not([role=presentation])${value}`), withData: "table:not([role=presentation])" }, noCaption: new CssSelectorRule([":not(:has(> caption))", ":has(> caption:empty)"]), caption: new CssSelectorRule(["> caption:not(:empty)"]), summary: new CssSelectorRule(["[summary]:not([summary=''])"]), ariaDescribedBy: new CssSelectorRule(exports.commonCssSelector.ariaDescribedBy), title: new CssSelectorRule(exports.commonCssSelector.title), ariaLabel: new CssSelectorRule(exports.commonCssSelector.ariaLabel), ariaLabelledBy: new CssSelectorRule(exports.commonCssSelector.ariaLabelledBy), thColumnHeader: new CssSelectorRule([" tr:first-child th"]), thRowHeader: new CssSelectorRule([" tr:not(:first-child) th:first-child"]), hasComplexHeader: new CssSelectorRule([ ...exports.tableCssSelector.complexTh, ...exports.tableCssSelector.complexRowHeader, ...exports.tableCssSelector.complexColumnHeader ]) };