aria.js 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. const FOCUSABLE_ELEMENT_SELECTORS = `a[href],button:not([disabled]),button:not([hidden]),:not([tabindex="-1"]),input:not([disabled]),input:not([type="hidden"]),select:not([disabled]),textarea:not([disabled])`;
  4. const isHTMLElement = (e) => {
  5. if (typeof Element === "undefined")
  6. return false;
  7. return e instanceof Element;
  8. };
  9. const isVisible = (element) => {
  10. if (process.env.NODE_ENV === "test")
  11. return true;
  12. const computed = getComputedStyle(element);
  13. return computed.position === "fixed" ? false : element.offsetParent !== null;
  14. };
  15. const obtainAllFocusableElements = (element) => {
  16. return Array.from(
  17. element.querySelectorAll(FOCUSABLE_ELEMENT_SELECTORS)
  18. ).filter((item) => isFocusable(item) && isVisible(item));
  19. };
  20. const isFocusable = (element) => {
  21. if (element.tabIndex > 0 || element.tabIndex === 0 && element.getAttribute("tabIndex") !== null) {
  22. return true;
  23. }
  24. if (element.tabIndex < 0 || element.hasAttribute("disabled") || element.getAttribute("aria-disabled") === "true") {
  25. return false;
  26. }
  27. switch (element.nodeName) {
  28. case "A": {
  29. return !!element.href && element.rel !== "ignore";
  30. }
  31. case "INPUT": {
  32. return !(element.type === "hidden" || element.type === "file");
  33. }
  34. case "BUTTON":
  35. case "SELECT":
  36. case "TEXTAREA": {
  37. return true;
  38. }
  39. default: {
  40. return false;
  41. }
  42. }
  43. };
  44. const triggerEvent = function(elm, name, ...opts) {
  45. let eventName;
  46. if (name.includes("mouse") || name.includes("click")) {
  47. eventName = "MouseEvents";
  48. } else if (name.includes("key")) {
  49. eventName = "KeyboardEvent";
  50. } else {
  51. eventName = "HTMLEvents";
  52. }
  53. const evt = document.createEvent(eventName);
  54. evt.initEvent(name, ...opts);
  55. elm.dispatchEvent(evt);
  56. return elm;
  57. };
  58. const isLeaf = (el) => !el.getAttribute("aria-owns");
  59. const getSibling = (el, distance, elClass) => {
  60. const { parentNode } = el;
  61. if (!parentNode)
  62. return null;
  63. const siblings = parentNode.querySelectorAll(elClass);
  64. const index = Array.prototype.indexOf.call(siblings, el);
  65. return siblings[index + distance] || null;
  66. };
  67. const focusElement = (el, options) => {
  68. if (!el || !el.focus)
  69. return;
  70. let cleanup = false;
  71. if (isHTMLElement(el) && !isFocusable(el) && !el.getAttribute("tabindex")) {
  72. el.setAttribute("tabindex", "-1");
  73. cleanup = true;
  74. }
  75. el.focus(options);
  76. if (isHTMLElement(el) && cleanup) {
  77. el.removeAttribute("tabindex");
  78. }
  79. };
  80. const focusNode = (el) => {
  81. if (!el)
  82. return;
  83. focusElement(el);
  84. !isLeaf(el) && el.click();
  85. };
  86. exports.focusElement = focusElement;
  87. exports.focusNode = focusNode;
  88. exports.getSibling = getSibling;
  89. exports.isFocusable = isFocusable;
  90. exports.isLeaf = isLeaf;
  91. exports.isVisible = isVisible;
  92. exports.obtainAllFocusableElements = obtainAllFocusableElements;
  93. exports.triggerEvent = triggerEvent;
  94. //# sourceMappingURL=aria.js.map