185 lines
5.6 KiB
JavaScript
185 lines
5.6 KiB
JavaScript
// https://w3c.github.io/html-aria/#document-conformance-requirements-for-use-of-aria-attributes-in-html
|
|
|
|
/**
|
|
* Safe Element.localName for all supported environments
|
|
* @param element
|
|
*/
|
|
export function getLocalName(element) {
|
|
var _element$localName;
|
|
return (// eslint-disable-next-line no-restricted-properties -- actual guard for environments without localName
|
|
(_element$localName = element.localName) !== null && _element$localName !== void 0 ? _element$localName :
|
|
// eslint-disable-next-line no-restricted-properties -- required for the fallback
|
|
element.tagName.toLowerCase()
|
|
);
|
|
}
|
|
var localNameToRoleMappings = {
|
|
article: "article",
|
|
aside: "complementary",
|
|
button: "button",
|
|
datalist: "listbox",
|
|
dd: "definition",
|
|
details: "group",
|
|
dialog: "dialog",
|
|
dt: "term",
|
|
fieldset: "group",
|
|
figure: "figure",
|
|
// WARNING: Only with an accessible name
|
|
form: "form",
|
|
footer: "contentinfo",
|
|
h1: "heading",
|
|
h2: "heading",
|
|
h3: "heading",
|
|
h4: "heading",
|
|
h5: "heading",
|
|
h6: "heading",
|
|
header: "banner",
|
|
hr: "separator",
|
|
html: "document",
|
|
legend: "legend",
|
|
li: "listitem",
|
|
math: "math",
|
|
main: "main",
|
|
menu: "list",
|
|
nav: "navigation",
|
|
ol: "list",
|
|
optgroup: "group",
|
|
// WARNING: Only in certain context
|
|
option: "option",
|
|
output: "status",
|
|
progress: "progressbar",
|
|
// WARNING: Only with an accessible name
|
|
section: "region",
|
|
summary: "button",
|
|
table: "table",
|
|
tbody: "rowgroup",
|
|
textarea: "textbox",
|
|
tfoot: "rowgroup",
|
|
// WARNING: Only in certain context
|
|
td: "cell",
|
|
th: "columnheader",
|
|
thead: "rowgroup",
|
|
tr: "row",
|
|
ul: "list"
|
|
};
|
|
var prohibitedAttributes = {
|
|
caption: new Set(["aria-label", "aria-labelledby"]),
|
|
code: new Set(["aria-label", "aria-labelledby"]),
|
|
deletion: new Set(["aria-label", "aria-labelledby"]),
|
|
emphasis: new Set(["aria-label", "aria-labelledby"]),
|
|
generic: new Set(["aria-label", "aria-labelledby", "aria-roledescription"]),
|
|
insertion: new Set(["aria-label", "aria-labelledby"]),
|
|
paragraph: new Set(["aria-label", "aria-labelledby"]),
|
|
presentation: new Set(["aria-label", "aria-labelledby"]),
|
|
strong: new Set(["aria-label", "aria-labelledby"]),
|
|
subscript: new Set(["aria-label", "aria-labelledby"]),
|
|
superscript: new Set(["aria-label", "aria-labelledby"])
|
|
};
|
|
|
|
/**
|
|
*
|
|
* @param element
|
|
* @param role The role used for this element. This is specified to control whether you want to use the implicit or explicit role.
|
|
*/
|
|
function hasGlobalAriaAttributes(element, role) {
|
|
// https://rawgit.com/w3c/aria/stable/#global_states
|
|
// commented attributes are deprecated
|
|
return ["aria-atomic", "aria-busy", "aria-controls", "aria-current", "aria-describedby", "aria-details",
|
|
// "disabled",
|
|
"aria-dropeffect",
|
|
// "errormessage",
|
|
"aria-flowto", "aria-grabbed",
|
|
// "haspopup",
|
|
"aria-hidden",
|
|
// "invalid",
|
|
"aria-keyshortcuts", "aria-label", "aria-labelledby", "aria-live", "aria-owns", "aria-relevant", "aria-roledescription"].some(function (attributeName) {
|
|
var _prohibitedAttributes;
|
|
return element.hasAttribute(attributeName) && !((_prohibitedAttributes = prohibitedAttributes[role]) !== null && _prohibitedAttributes !== void 0 && _prohibitedAttributes.has(attributeName));
|
|
});
|
|
}
|
|
function ignorePresentationalRole(element, implicitRole) {
|
|
// https://rawgit.com/w3c/aria/stable/#conflict_resolution_presentation_none
|
|
return hasGlobalAriaAttributes(element, implicitRole);
|
|
}
|
|
export default function getRole(element) {
|
|
var explicitRole = getExplicitRole(element);
|
|
if (explicitRole === null || explicitRole === "presentation") {
|
|
var implicitRole = getImplicitRole(element);
|
|
if (explicitRole !== "presentation" || ignorePresentationalRole(element, implicitRole || "")) {
|
|
return implicitRole;
|
|
}
|
|
}
|
|
return explicitRole;
|
|
}
|
|
function getImplicitRole(element) {
|
|
var mappedByTag = localNameToRoleMappings[getLocalName(element)];
|
|
if (mappedByTag !== undefined) {
|
|
return mappedByTag;
|
|
}
|
|
switch (getLocalName(element)) {
|
|
case "a":
|
|
case "area":
|
|
case "link":
|
|
if (element.hasAttribute("href")) {
|
|
return "link";
|
|
}
|
|
break;
|
|
case "img":
|
|
if (element.getAttribute("alt") === "" && !ignorePresentationalRole(element, "img")) {
|
|
return "presentation";
|
|
}
|
|
return "img";
|
|
case "input":
|
|
{
|
|
var _ref = element,
|
|
type = _ref.type;
|
|
switch (type) {
|
|
case "button":
|
|
case "image":
|
|
case "reset":
|
|
case "submit":
|
|
return "button";
|
|
case "checkbox":
|
|
case "radio":
|
|
return type;
|
|
case "range":
|
|
return "slider";
|
|
case "email":
|
|
case "tel":
|
|
case "text":
|
|
case "url":
|
|
if (element.hasAttribute("list")) {
|
|
return "combobox";
|
|
}
|
|
return "textbox";
|
|
case "search":
|
|
if (element.hasAttribute("list")) {
|
|
return "combobox";
|
|
}
|
|
return "searchbox";
|
|
case "number":
|
|
return "spinbutton";
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
case "select":
|
|
if (element.hasAttribute("multiple") || element.size > 1) {
|
|
return "listbox";
|
|
}
|
|
return "combobox";
|
|
}
|
|
return null;
|
|
}
|
|
function getExplicitRole(element) {
|
|
var role = element.getAttribute("role");
|
|
if (role !== null) {
|
|
var explicitRole = role.trim().split(" ")[0];
|
|
// String.prototype.split(sep, limit) will always return an array with at least one member
|
|
// as long as limit is either undefined or > 0
|
|
if (explicitRole.length > 0) {
|
|
return explicitRole;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
//# sourceMappingURL=getRole.mjs.map
|