You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
209 lines
5.6 KiB
209 lines
5.6 KiB
// 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
|