UNPKG

dom-to-svg

Version:
201 lines 6.75 kB
import { hasLabels, isHTMLElement } from './dom.js'; const isStandaloneFooter = (element) => !element.closest('article, aside, main, nav, section, [role="article"], [role="complementary"], [role="main"], [role="navigation"], [role="region"]'); export function getAccessibilityAttributes(element, { labels, getUniqueId }) { var _a, _b, _c; // https://www.w3.org/TR/html-aria/ const attributes = new Map(); switch (element.tagName) { case 'A': attributes.set('role', 'link'); break; case 'ARTICLE': attributes.set('role', 'article'); break; case 'ASIDE': attributes.set('role', 'complementary'); break; case 'BODY': attributes.set('role', 'document'); break; case 'BUTTON': case 'SUMMARY': attributes.set('role', 'button'); break; case 'DD': attributes.set('role', 'definition'); break; case 'DETAILS': attributes.set('role', 'group'); break; case 'DFN': attributes.set('role', 'term'); break; case 'DIALOG': attributes.set('role', 'dialog'); break; case 'DT': attributes.set('role', 'term'); break; case 'FIELDSET': attributes.set('role', 'group'); break; case 'FIGURE': attributes.set('role', 'figure'); break; case 'FOOTER': if (isStandaloneFooter(element)) { attributes.set('role', 'contentinfo'); } break; case 'FORM': attributes.set('role', 'form'); break; case 'H1': case 'H2': case 'H3': case 'H4': case 'H5': case 'H6': attributes.set('role', 'heading'); attributes.set('aria-level', element.tagName.slice(1)); break; case 'HEADER': if (isStandaloneFooter(element)) { attributes.set('role', 'banner'); } break; case 'HR': attributes.set('role', 'separator'); break; case 'IMG': { const alt = element.getAttribute('alt'); if (alt === null || alt !== '') { attributes.set('role', 'img'); if (alt) { attributes.set('aria-label', alt); } } break; } case 'INPUT': switch (element.type) { case 'button': case 'image': case 'reset': case 'submit': attributes.set('role', 'button'); break; case 'number': attributes.set('role', 'spinbutton'); break; case 'range': attributes.set('role', 'slider'); break; case 'checkbox': attributes.set('role', 'checkbox'); break; case 'radio': attributes.set('role', 'radio'); break; case 'email': case 'tel': if (!element.hasAttribute('list')) { attributes.set('role', 'textbox'); } break; } break; case 'LI': if (((_a = element.parentElement) === null || _a === void 0 ? void 0 : _a.tagName) === 'OL' || ((_b = element.parentElement) === null || _b === void 0 ? void 0 : _b.tagName) === 'UL' || ((_c = element.parentElement) === null || _c === void 0 ? void 0 : _c.tagName) === 'MENU') { attributes.set('role', 'listitem'); } break; case 'LINK': if (element.href) { attributes.set('role', 'link'); } break; case 'MAIN': attributes.set('role', 'main'); break; case 'MATH': attributes.set('role', 'math'); break; case 'OL': case 'UL': case 'MENU': attributes.set('role', 'list'); break; case 'NAV': attributes.set('role', 'navigation'); break; case 'OPTION': attributes.set('role', 'option'); break; case 'PROGRESS': attributes.set('role', 'progressbar'); break; case 'SECTION': attributes.set('role', 'region'); break; case 'SELECT': attributes.set('role', !element.hasAttribute('multiple') && element.size <= 1 ? 'combobox' : 'listbox'); break; case 'TABLE': attributes.set('role', 'table'); break; case 'THEAD': case 'TBODY': case 'TFOOT': attributes.set('role', 'rowgroup'); break; case 'TEXTAREA': attributes.set('role', 'textbox'); break; case 'TD': attributes.set('role', 'cell'); break; case 'TH': attributes.set('role', element.closest('thead') ? 'columnheader' : 'rowheader'); break; case 'TR': attributes.set('role', 'tablerow'); break; } if (element.hasAttribute('disabled')) { attributes.set('aria-disabled', 'true'); } if (element.hasAttribute('placeholder')) { attributes.set('aria-placeholder', element.getAttribute('placeholder') || ''); } const tabIndex = element.getAttribute('tabindex'); if (tabIndex) { attributes.set('tabindex', tabIndex); } if (isHTMLElement(element) && hasLabels(element) && element.labels) { // Need to invert the label[for] / [aria-labelledby] relationship attributes.set('aria-labelledby', [...element.labels] .map(label => { let labelId = label.id || labels.get(label); if (!labelId) { labelId = getUniqueId('label'); labels.set(label, labelId); } return labelId; }) .join(' ')); } for (const attribute of element.attributes) { if (attribute.name.startsWith('aria-')) { attributes.set(attribute.name, attribute.value); } } const customRole = element.getAttribute('role'); if (customRole) { attributes.set('role', customRole); } return attributes; } //# sourceMappingURL=accessibility.js.map