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.

190 lines
5.7KB

  1. "use strict";
  2. exports.__esModule = true;
  3. exports.default = getRole;
  4. exports.getLocalName = getLocalName;
  5. // https://w3c.github.io/html-aria/#document-conformance-requirements-for-use-of-aria-attributes-in-html
  6. /**
  7. * Safe Element.localName for all supported environments
  8. * @param element
  9. */
  10. function getLocalName(element) {
  11. var _element$localName;
  12. return (// eslint-disable-next-line no-restricted-properties -- actual guard for environments without localName
  13. (_element$localName = element.localName) !== null && _element$localName !== void 0 ? _element$localName :
  14. // eslint-disable-next-line no-restricted-properties -- required for the fallback
  15. element.tagName.toLowerCase()
  16. );
  17. }
  18. var localNameToRoleMappings = {
  19. article: "article",
  20. aside: "complementary",
  21. button: "button",
  22. datalist: "listbox",
  23. dd: "definition",
  24. details: "group",
  25. dialog: "dialog",
  26. dt: "term",
  27. fieldset: "group",
  28. figure: "figure",
  29. // WARNING: Only with an accessible name
  30. form: "form",
  31. footer: "contentinfo",
  32. h1: "heading",
  33. h2: "heading",
  34. h3: "heading",
  35. h4: "heading",
  36. h5: "heading",
  37. h6: "heading",
  38. header: "banner",
  39. hr: "separator",
  40. html: "document",
  41. legend: "legend",
  42. li: "listitem",
  43. math: "math",
  44. main: "main",
  45. menu: "list",
  46. nav: "navigation",
  47. ol: "list",
  48. optgroup: "group",
  49. // WARNING: Only in certain context
  50. option: "option",
  51. output: "status",
  52. progress: "progressbar",
  53. // WARNING: Only with an accessible name
  54. section: "region",
  55. summary: "button",
  56. table: "table",
  57. tbody: "rowgroup",
  58. textarea: "textbox",
  59. tfoot: "rowgroup",
  60. // WARNING: Only in certain context
  61. td: "cell",
  62. th: "columnheader",
  63. thead: "rowgroup",
  64. tr: "row",
  65. ul: "list"
  66. };
  67. var prohibitedAttributes = {
  68. caption: new Set(["aria-label", "aria-labelledby"]),
  69. code: new Set(["aria-label", "aria-labelledby"]),
  70. deletion: new Set(["aria-label", "aria-labelledby"]),
  71. emphasis: new Set(["aria-label", "aria-labelledby"]),
  72. generic: new Set(["aria-label", "aria-labelledby", "aria-roledescription"]),
  73. insertion: new Set(["aria-label", "aria-labelledby"]),
  74. paragraph: new Set(["aria-label", "aria-labelledby"]),
  75. presentation: new Set(["aria-label", "aria-labelledby"]),
  76. strong: new Set(["aria-label", "aria-labelledby"]),
  77. subscript: new Set(["aria-label", "aria-labelledby"]),
  78. superscript: new Set(["aria-label", "aria-labelledby"])
  79. };
  80. /**
  81. *
  82. * @param element
  83. * @param role The role used for this element. This is specified to control whether you want to use the implicit or explicit role.
  84. */
  85. function hasGlobalAriaAttributes(element, role) {
  86. // https://rawgit.com/w3c/aria/stable/#global_states
  87. // commented attributes are deprecated
  88. return ["aria-atomic", "aria-busy", "aria-controls", "aria-current", "aria-describedby", "aria-details",
  89. // "disabled",
  90. "aria-dropeffect",
  91. // "errormessage",
  92. "aria-flowto", "aria-grabbed",
  93. // "haspopup",
  94. "aria-hidden",
  95. // "invalid",
  96. "aria-keyshortcuts", "aria-label", "aria-labelledby", "aria-live", "aria-owns", "aria-relevant", "aria-roledescription"].some(function (attributeName) {
  97. var _prohibitedAttributes;
  98. return element.hasAttribute(attributeName) && !((_prohibitedAttributes = prohibitedAttributes[role]) !== null && _prohibitedAttributes !== void 0 && _prohibitedAttributes.has(attributeName));
  99. });
  100. }
  101. function ignorePresentationalRole(element, implicitRole) {
  102. // https://rawgit.com/w3c/aria/stable/#conflict_resolution_presentation_none
  103. return hasGlobalAriaAttributes(element, implicitRole);
  104. }
  105. function getRole(element) {
  106. var explicitRole = getExplicitRole(element);
  107. if (explicitRole === null || explicitRole === "presentation") {
  108. var implicitRole = getImplicitRole(element);
  109. if (explicitRole !== "presentation" || ignorePresentationalRole(element, implicitRole || "")) {
  110. return implicitRole;
  111. }
  112. }
  113. return explicitRole;
  114. }
  115. function getImplicitRole(element) {
  116. var mappedByTag = localNameToRoleMappings[getLocalName(element)];
  117. if (mappedByTag !== undefined) {
  118. return mappedByTag;
  119. }
  120. switch (getLocalName(element)) {
  121. case "a":
  122. case "area":
  123. case "link":
  124. if (element.hasAttribute("href")) {
  125. return "link";
  126. }
  127. break;
  128. case "img":
  129. if (element.getAttribute("alt") === "" && !ignorePresentationalRole(element, "img")) {
  130. return "presentation";
  131. }
  132. return "img";
  133. case "input":
  134. {
  135. var _ref = element,
  136. type = _ref.type;
  137. switch (type) {
  138. case "button":
  139. case "image":
  140. case "reset":
  141. case "submit":
  142. return "button";
  143. case "checkbox":
  144. case "radio":
  145. return type;
  146. case "range":
  147. return "slider";
  148. case "email":
  149. case "tel":
  150. case "text":
  151. case "url":
  152. if (element.hasAttribute("list")) {
  153. return "combobox";
  154. }
  155. return "textbox";
  156. case "search":
  157. if (element.hasAttribute("list")) {
  158. return "combobox";
  159. }
  160. return "searchbox";
  161. case "number":
  162. return "spinbutton";
  163. default:
  164. return null;
  165. }
  166. }
  167. case "select":
  168. if (element.hasAttribute("multiple") || element.size > 1) {
  169. return "listbox";
  170. }
  171. return "combobox";
  172. }
  173. return null;
  174. }
  175. function getExplicitRole(element) {
  176. var role = element.getAttribute("role");
  177. if (role !== null) {
  178. var explicitRole = role.trim().split(" ")[0];
  179. // String.prototype.split(sep, limit) will always return an array with at least one member
  180. // as long as limit is either undefined or > 0
  181. if (explicitRole.length > 0) {
  182. return explicitRole;
  183. }
  184. }
  185. return null;
  186. }
  187. //# sourceMappingURL=getRole.js.map