@arcaauth/eslint-plugin-jsx-a11y 6.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. package/.babelrc +17 -0
  2. package/.eslintrc +44 -0
  3. package/CHANGELOG.md +774 -0
  4. package/LICENSE.md +8 -0
  5. package/README.md +423 -0
  6. package/__mocks__/IdentifierMock.js +15 -0
  7. package/__mocks__/JSXAttributeMock.js +39 -0
  8. package/__mocks__/JSXElementMock.js +37 -0
  9. package/__mocks__/JSXExpressionContainerMock.js +15 -0
  10. package/__mocks__/JSXSpreadAttributeMock.js +18 -0
  11. package/__mocks__/JSXTextMock.js +17 -0
  12. package/__mocks__/LiteralMock.js +17 -0
  13. package/__mocks__/genInteractives.js +218 -0
  14. package/__tests__/__util__/axeMapping.js +6 -0
  15. package/__tests__/__util__/helpers/getESLintCoreRule.js +9 -0
  16. package/__tests__/__util__/helpers/parsers.js +186 -0
  17. package/__tests__/__util__/parserOptionsMapper.js +53 -0
  18. package/__tests__/__util__/ruleOptionsMapperFactory.js +33 -0
  19. package/__tests__/index-test.js +40 -0
  20. package/__tests__/src/rules/accessible-emoji-test.js +66 -0
  21. package/__tests__/src/rules/alt-text-test.js +291 -0
  22. package/__tests__/src/rules/anchor-ambiguous-text-test.js +117 -0
  23. package/__tests__/src/rules/anchor-has-content-test.js +54 -0
  24. package/__tests__/src/rules/anchor-is-valid-test.js +532 -0
  25. package/__tests__/src/rules/aria-activedescendant-has-tabindex-test.js +95 -0
  26. package/__tests__/src/rules/aria-props-test.js +69 -0
  27. package/__tests__/src/rules/aria-proptypes-test.js +311 -0
  28. package/__tests__/src/rules/aria-role-test.js +118 -0
  29. package/__tests__/src/rules/aria-unsupported-elements-test.js +75 -0
  30. package/__tests__/src/rules/autocomplete-valid-test.js +77 -0
  31. package/__tests__/src/rules/click-events-have-key-events-test.js +77 -0
  32. package/__tests__/src/rules/control-has-associated-label-test.js +327 -0
  33. package/__tests__/src/rules/heading-has-content-test.js +85 -0
  34. package/__tests__/src/rules/html-has-lang-test.js +42 -0
  35. package/__tests__/src/rules/iframe-has-title-test.js +55 -0
  36. package/__tests__/src/rules/img-redundant-alt-test.js +137 -0
  37. package/__tests__/src/rules/interactive-supports-focus-test.js +267 -0
  38. package/__tests__/src/rules/label-has-associated-control-test.js +243 -0
  39. package/__tests__/src/rules/label-has-for-test.js +235 -0
  40. package/__tests__/src/rules/lang-test.js +59 -0
  41. package/__tests__/src/rules/media-has-caption-test.js +220 -0
  42. package/__tests__/src/rules/mouse-events-have-key-events-test.js +154 -0
  43. package/__tests__/src/rules/no-access-key-test.js +48 -0
  44. package/__tests__/src/rules/no-aria-hidden-on-focusable-test.js +44 -0
  45. package/__tests__/src/rules/no-autofocus-test.js +68 -0
  46. package/__tests__/src/rules/no-distracting-elements-test.js +51 -0
  47. package/__tests__/src/rules/no-interactive-element-to-noninteractive-role-test.js +405 -0
  48. package/__tests__/src/rules/no-noninteractive-element-interactions-test.js +502 -0
  49. package/__tests__/src/rules/no-noninteractive-element-to-interactive-role-test.js +500 -0
  50. package/__tests__/src/rules/no-noninteractive-tabindex-test.js +123 -0
  51. package/__tests__/src/rules/no-onchange-test.js +57 -0
  52. package/__tests__/src/rules/no-redundant-roles-test.js +98 -0
  53. package/__tests__/src/rules/no-static-element-interactions-test.js +501 -0
  54. package/__tests__/src/rules/prefer-tag-over-role-test.js +63 -0
  55. package/__tests__/src/rules/role-has-required-aria-props-test.js +134 -0
  56. package/__tests__/src/rules/role-supports-aria-props-test.js +570 -0
  57. package/__tests__/src/rules/scope-test.js +50 -0
  58. package/__tests__/src/rules/tabindex-no-positive-test.js +55 -0
  59. package/__tests__/src/util/attributesComparator-test.js +91 -0
  60. package/__tests__/src/util/getAccessibleChildText-test.js +174 -0
  61. package/__tests__/src/util/getComputedRole-test.js +71 -0
  62. package/__tests__/src/util/getElementType-test.js +154 -0
  63. package/__tests__/src/util/getExplicitRole-test.js +35 -0
  64. package/__tests__/src/util/getImplicitRole-test.js +25 -0
  65. package/__tests__/src/util/getSuggestion-test.js +33 -0
  66. package/__tests__/src/util/getTabIndex-test.js +85 -0
  67. package/__tests__/src/util/hasAccessibleChild-test.js +157 -0
  68. package/__tests__/src/util/implicitRoles/input-test.js +87 -0
  69. package/__tests__/src/util/implicitRoles/menu-test.js +20 -0
  70. package/__tests__/src/util/implicitRoles/menuitem-test.js +38 -0
  71. package/__tests__/src/util/isAbstractRole-test.js +51 -0
  72. package/__tests__/src/util/isContentEditable-test.js +52 -0
  73. package/__tests__/src/util/isDOMElement-test.js +30 -0
  74. package/__tests__/src/util/isDisabledElement-test.js +88 -0
  75. package/__tests__/src/util/isFocusable-test.js +111 -0
  76. package/__tests__/src/util/isInteractiveElement-test.js +104 -0
  77. package/__tests__/src/util/isInteractiveRole-test.js +59 -0
  78. package/__tests__/src/util/isNonInteractiveElement-test.js +97 -0
  79. package/__tests__/src/util/isNonInteractiveRole-test.js +59 -0
  80. package/__tests__/src/util/isNonLiteralProperty-test.js +52 -0
  81. package/__tests__/src/util/isSemanticRoleElement-test.js +72 -0
  82. package/__tests__/src/util/mayContainChildComponent-test.js +219 -0
  83. package/__tests__/src/util/mayHaveAccessibleLabel-test.js +256 -0
  84. package/__tests__/src/util/parserOptionsMapper-test.js +93 -0
  85. package/__tests__/src/util/schemas-test.js +35 -0
  86. package/docs/rules/accessible-emoji.md +30 -0
  87. package/docs/rules/alt-text.md +168 -0
  88. package/docs/rules/anchor-ambiguous-text.md +91 -0
  89. package/docs/rules/anchor-has-content.md +64 -0
  90. package/docs/rules/anchor-is-valid.md +270 -0
  91. package/docs/rules/aria-activedescendant-has-tabindex.md +52 -0
  92. package/docs/rules/aria-props.md +29 -0
  93. package/docs/rules/aria-proptypes.md +30 -0
  94. package/docs/rules/aria-role.md +51 -0
  95. package/docs/rules/aria-unsupported-elements.md +30 -0
  96. package/docs/rules/autocomplete-valid.md +49 -0
  97. package/docs/rules/click-events-have-key-events.md +28 -0
  98. package/docs/rules/control-has-associated-label.md +113 -0
  99. package/docs/rules/heading-has-content.md +67 -0
  100. package/docs/rules/html-has-lang.md +31 -0
  101. package/docs/rules/iframe-has-title.md +37 -0
  102. package/docs/rules/img-redundant-alt.md +48 -0
  103. package/docs/rules/interactive-supports-focus.md +156 -0
  104. package/docs/rules/label-has-associated-control.md +152 -0
  105. package/docs/rules/label-has-for.md +130 -0
  106. package/docs/rules/lang.md +31 -0
  107. package/docs/rules/media-has-caption.md +48 -0
  108. package/docs/rules/mouse-events-have-key-events.md +58 -0
  109. package/docs/rules/no-access-key.md +30 -0
  110. package/docs/rules/no-aria-hidden-on-focusable.md +37 -0
  111. package/docs/rules/no-autofocus.md +43 -0
  112. package/docs/rules/no-distracting-elements.md +41 -0
  113. package/docs/rules/no-interactive-element-to-noninteractive-role.md +73 -0
  114. package/docs/rules/no-noninteractive-element-interactions.md +145 -0
  115. package/docs/rules/no-noninteractive-element-to-interactive-role.md +76 -0
  116. package/docs/rules/no-noninteractive-tabindex.md +115 -0
  117. package/docs/rules/no-onchange.md +36 -0
  118. package/docs/rules/no-redundant-roles.md +46 -0
  119. package/docs/rules/no-static-element-interactions.md +114 -0
  120. package/docs/rules/prefer-tag-over-role.md +32 -0
  121. package/docs/rules/role-has-required-aria-props.md +31 -0
  122. package/docs/rules/role-supports-aria-props.md +39 -0
  123. package/docs/rules/scope.md +30 -0
  124. package/docs/rules/tabindex-no-positive.md +32 -0
  125. package/lib/configs/flat-config-base.js +11 -0
  126. package/lib/configs/legacy-config-base.js +9 -0
  127. package/lib/index.js +209 -0
  128. package/lib/rules/accessible-emoji.js +63 -0
  129. package/lib/rules/alt-text.js +218 -0
  130. package/lib/rules/anchor-ambiguous-text.js +64 -0
  131. package/lib/rules/anchor-has-content.js +60 -0
  132. package/lib/rules/anchor-is-valid.js +122 -0
  133. package/lib/rules/aria-activedescendant-has-tabindex.js +66 -0
  134. package/lib/rules/aria-props.js +59 -0
  135. package/lib/rules/aria-proptypes.js +114 -0
  136. package/lib/rules/aria-role.js +89 -0
  137. package/lib/rules/aria-unsupported-elements.js +64 -0
  138. package/lib/rules/autocomplete-valid.js +67 -0
  139. package/lib/rules/click-events-have-key-events.js +68 -0
  140. package/lib/rules/control-has-associated-label.js +103 -0
  141. package/lib/rules/heading-has-content.js +61 -0
  142. package/lib/rules/html-has-lang.js +50 -0
  143. package/lib/rules/iframe-has-title.js +50 -0
  144. package/lib/rules/img-redundant-alt.js +88 -0
  145. package/lib/rules/interactive-supports-focus.js +87 -0
  146. package/lib/rules/label-has-associated-control.js +127 -0
  147. package/lib/rules/label-has-for.js +150 -0
  148. package/lib/rules/lang.js +68 -0
  149. package/lib/rules/media-has-caption.js +96 -0
  150. package/lib/rules/mouse-events-have-key-events.js +94 -0
  151. package/lib/rules/no-access-key.js +43 -0
  152. package/lib/rules/no-aria-hidden-on-focusable.js +47 -0
  153. package/lib/rules/no-autofocus.js +62 -0
  154. package/lib/rules/no-distracting-elements.js +54 -0
  155. package/lib/rules/no-interactive-element-to-noninteractive-role.js +81 -0
  156. package/lib/rules/no-noninteractive-element-interactions.js +95 -0
  157. package/lib/rules/no-noninteractive-element-to-interactive-role.js +80 -0
  158. package/lib/rules/no-noninteractive-tabindex.js +109 -0
  159. package/lib/rules/no-onchange.js +52 -0
  160. package/lib/rules/no-redundant-roles.js +86 -0
  161. package/lib/rules/no-static-element-interactions.js +102 -0
  162. package/lib/rules/prefer-tag-over-role.js +75 -0
  163. package/lib/rules/role-has-required-aria-props.js +88 -0
  164. package/lib/rules/role-supports-aria-props.js +78 -0
  165. package/lib/rules/scope.js +58 -0
  166. package/lib/rules/tabindex-no-positive.js +53 -0
  167. package/lib/util/attributesComparator.js +34 -0
  168. package/lib/util/getAccessibleChildText.js +55 -0
  169. package/lib/util/getComputedRole.js +19 -0
  170. package/lib/util/getElementType.js +30 -0
  171. package/lib/util/getExplicitRole.js +27 -0
  172. package/lib/util/getImplicitRole.js +24 -0
  173. package/lib/util/getSuggestion.js +32 -0
  174. package/lib/util/getTabIndex.js +34 -0
  175. package/lib/util/hasAccessibleChild.js +30 -0
  176. package/lib/util/implicitRoles/a.js +17 -0
  177. package/lib/util/implicitRoles/area.js +17 -0
  178. package/lib/util/implicitRoles/article.js +13 -0
  179. package/lib/util/implicitRoles/aside.js +13 -0
  180. package/lib/util/implicitRoles/body.js +13 -0
  181. package/lib/util/implicitRoles/button.js +13 -0
  182. package/lib/util/implicitRoles/datalist.js +13 -0
  183. package/lib/util/implicitRoles/details.js +13 -0
  184. package/lib/util/implicitRoles/dialog.js +13 -0
  185. package/lib/util/implicitRoles/form.js +13 -0
  186. package/lib/util/implicitRoles/h1.js +13 -0
  187. package/lib/util/implicitRoles/h2.js +13 -0
  188. package/lib/util/implicitRoles/h3.js +13 -0
  189. package/lib/util/implicitRoles/h4.js +13 -0
  190. package/lib/util/implicitRoles/h5.js +13 -0
  191. package/lib/util/implicitRoles/h6.js +13 -0
  192. package/lib/util/implicitRoles/hr.js +13 -0
  193. package/lib/util/implicitRoles/img.js +31 -0
  194. package/lib/util/implicitRoles/index.js +82 -0
  195. package/lib/util/implicitRoles/input.js +38 -0
  196. package/lib/util/implicitRoles/li.js +13 -0
  197. package/lib/util/implicitRoles/link.js +17 -0
  198. package/lib/util/implicitRoles/menu.js +19 -0
  199. package/lib/util/implicitRoles/menuitem.js +28 -0
  200. package/lib/util/implicitRoles/meter.js +13 -0
  201. package/lib/util/implicitRoles/nav.js +13 -0
  202. package/lib/util/implicitRoles/ol.js +13 -0
  203. package/lib/util/implicitRoles/option.js +13 -0
  204. package/lib/util/implicitRoles/output.js +13 -0
  205. package/lib/util/implicitRoles/progress.js +13 -0
  206. package/lib/util/implicitRoles/section.js +13 -0
  207. package/lib/util/implicitRoles/select.js +13 -0
  208. package/lib/util/implicitRoles/tbody.js +13 -0
  209. package/lib/util/implicitRoles/textarea.js +13 -0
  210. package/lib/util/implicitRoles/tfoot.js +13 -0
  211. package/lib/util/implicitRoles/thead.js +13 -0
  212. package/lib/util/implicitRoles/ul.js +13 -0
  213. package/lib/util/isAbstractRole.js +23 -0
  214. package/lib/util/isContentEditable.js +13 -0
  215. package/lib/util/isDOMElement.js +15 -0
  216. package/lib/util/isDisabledElement.js +23 -0
  217. package/lib/util/isFocusable.js +23 -0
  218. package/lib/util/isHiddenFromScreenReader.js +26 -0
  219. package/lib/util/isInteractiveElement.js +116 -0
  220. package/lib/util/isInteractiveRole.js +54 -0
  221. package/lib/util/isNonInteractiveElement.js +131 -0
  222. package/lib/util/isNonInteractiveRole.js +55 -0
  223. package/lib/util/isNonLiteralProperty.js +29 -0
  224. package/lib/util/isPresentationRole.js +13 -0
  225. package/lib/util/isSemanticRoleElement.js +54 -0
  226. package/lib/util/mayContainChildComponent.js +50 -0
  227. package/lib/util/mayHaveAccessibleLabel.js +95 -0
  228. package/lib/util/schemas.js +52 -0
  229. package/package.json +120 -0
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = void 0;
7
+ var _jsxAstUtils = require("jsx-ast-utils");
8
+ var _safeRegexTest = _interopRequireDefault(require("safe-regex-test"));
9
+ var _schemas = require("../util/schemas");
10
+ var _getElementType = _interopRequireDefault(require("../util/getElementType"));
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
12
+ /**
13
+ * @fileoverview Performs validity check on anchor hrefs. Warns when anchors are used as buttons.
14
+ * @author Almero Steyn
15
+ *
16
+ */
17
+
18
+ // ----------------------------------------------------------------------------
19
+ // Rule Definition
20
+ // ----------------------------------------------------------------------------
21
+
22
+ var allAspects = ['noHref', 'invalidHref', 'preferButton'];
23
+ var preferButtonErrorMessage = 'Anchor used as a button. Anchors are primarily expected to navigate. Use the button element instead. Learn more: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/HEAD/docs/rules/anchor-is-valid.md';
24
+ var noHrefErrorMessage = 'The href attribute is required for an anchor to be keyboard accessible. Provide a valid, navigable address as the href value. If you cannot provide an href, but still need the element to resemble a link, use a button and change it with appropriate styles. Learn more: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/HEAD/docs/rules/anchor-is-valid.md';
25
+ var invalidHrefErrorMessage = 'The href attribute requires a valid value to be accessible. Provide a valid, navigable address as the href value. If you cannot provide a valid href, but still need the element to resemble a link, use a button and change it with appropriate styles. Learn more: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/HEAD/docs/rules/anchor-is-valid.md';
26
+ var schema = (0, _schemas.generateObjSchema)({
27
+ components: _schemas.arraySchema,
28
+ specialLink: _schemas.arraySchema,
29
+ aspects: (0, _schemas.enumArraySchema)(allAspects, 1)
30
+ });
31
+ var _default = exports["default"] = {
32
+ meta: {
33
+ docs: {
34
+ url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/anchor-is-valid.md',
35
+ description: 'Enforce all anchors are valid, navigable elements.'
36
+ },
37
+ schema: [schema]
38
+ },
39
+ create: function create(context) {
40
+ var elementType = (0, _getElementType["default"])(context);
41
+ var testJShref = (0, _safeRegexTest["default"])(/^\W*?javascript:/);
42
+ return {
43
+ JSXOpeningElement: function JSXOpeningElement(node) {
44
+ var attributes = node.attributes;
45
+ var options = context.options[0] || {};
46
+ var componentOptions = options.components || [];
47
+ var typeCheck = ['a'].concat(componentOptions);
48
+ var nodeType = elementType(node);
49
+
50
+ // Only check anchor elements and custom types.
51
+ if (typeCheck.indexOf(nodeType) === -1) {
52
+ return;
53
+ }
54
+
55
+ // Set up the rule aspects to check.
56
+ var aspects = options.aspects || allAspects;
57
+
58
+ // Create active aspect flag object. Failing checks will only report
59
+ // if the related flag is set to true.
60
+ var activeAspects = {};
61
+ allAspects.forEach(function (aspect) {
62
+ activeAspects[aspect] = aspects.indexOf(aspect) !== -1;
63
+ });
64
+ var propOptions = options.specialLink || [];
65
+ var propsToValidate = ['href'].concat(propOptions);
66
+ var values = propsToValidate.map(function (prop) {
67
+ return (0, _jsxAstUtils.getPropValue)((0, _jsxAstUtils.getProp)(node.attributes, prop));
68
+ });
69
+ // Checks if any actual or custom href prop is provided.
70
+ var hasAnyHref = values.some(function (value) {
71
+ return value != null;
72
+ });
73
+ // Need to check for spread operator as props can be spread onto the element
74
+ // leading to an incorrect validation error.
75
+ var hasSpreadOperator = attributes.some(function (prop) {
76
+ return prop.type === 'JSXSpreadAttribute';
77
+ });
78
+ var onClick = (0, _jsxAstUtils.getProp)(attributes, 'onClick');
79
+
80
+ // When there is no href at all, specific scenarios apply:
81
+ if (!hasAnyHref) {
82
+ // If no spread operator is found and no onClick event is present
83
+ // it is a link without href.
84
+ if (!hasSpreadOperator && activeAspects.noHref && (!onClick || onClick && !activeAspects.preferButton)) {
85
+ context.report({
86
+ node,
87
+ message: noHrefErrorMessage
88
+ });
89
+ }
90
+ // If no spread operator is found but an onClick is preset it should be a button.
91
+ if (!hasSpreadOperator && onClick && activeAspects.preferButton) {
92
+ context.report({
93
+ node,
94
+ message: preferButtonErrorMessage
95
+ });
96
+ }
97
+ return;
98
+ }
99
+
100
+ // Hrefs have been found, now check for validity.
101
+ var invalidHrefValues = values.filter(function (value) {
102
+ return value != null && typeof value === 'string' && (!value.length || value === '#' || testJShref(value));
103
+ });
104
+ if (invalidHrefValues.length !== 0) {
105
+ // If an onClick is found it should be a button, otherwise it is an invalid link.
106
+ if (onClick && activeAspects.preferButton) {
107
+ context.report({
108
+ node,
109
+ message: preferButtonErrorMessage
110
+ });
111
+ } else if (activeAspects.invalidHref) {
112
+ context.report({
113
+ node,
114
+ message: invalidHrefErrorMessage
115
+ });
116
+ }
117
+ }
118
+ }
119
+ };
120
+ }
121
+ };
122
+ module.exports = exports.default;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = void 0;
7
+ var _ariaQuery = require("aria-query");
8
+ var _jsxAstUtils = require("jsx-ast-utils");
9
+ var _schemas = require("../util/schemas");
10
+ var _getElementType = _interopRequireDefault(require("../util/getElementType"));
11
+ var _getTabIndex = _interopRequireDefault(require("../util/getTabIndex"));
12
+ var _isInteractiveElement = _interopRequireDefault(require("../util/isInteractiveElement"));
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
14
+ /**
15
+ * @fileoverview Enforce elements with aria-activedescendant are tabbable.
16
+ * @author Jesse Beach <@jessebeach>
17
+ */
18
+
19
+ // ----------------------------------------------------------------------------
20
+ // Rule Definition
21
+ // ----------------------------------------------------------------------------
22
+
23
+ var errorMessage = 'An element that manages focus with `aria-activedescendant` must have a tabindex';
24
+ var schema = (0, _schemas.generateObjSchema)();
25
+ var _default = exports["default"] = {
26
+ meta: {
27
+ docs: {
28
+ url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-activedescendant-has-tabindex.md',
29
+ description: 'Enforce elements with aria-activedescendant are tabbable.'
30
+ },
31
+ schema: [schema]
32
+ },
33
+ create: function create(context) {
34
+ var elementType = (0, _getElementType["default"])(context);
35
+ return {
36
+ JSXOpeningElement: function JSXOpeningElement(node) {
37
+ var attributes = node.attributes;
38
+ if ((0, _jsxAstUtils.getProp)(attributes, 'aria-activedescendant') === undefined) {
39
+ return;
40
+ }
41
+ var type = elementType(node);
42
+ // Do not test higher level JSX components, as we do not know what
43
+ // low-level DOM element this maps to.
44
+ if (!_ariaQuery.dom.has(type)) {
45
+ return;
46
+ }
47
+ var tabIndex = (0, _getTabIndex["default"])((0, _jsxAstUtils.getProp)(attributes, 'tabIndex'));
48
+
49
+ // If this is an interactive element and the tabindex attribute is not specified,
50
+ // or the tabIndex property was not mutated, then the tabIndex
51
+ // property will be undefined.
52
+ if ((0, _isInteractiveElement["default"])(type, attributes) && tabIndex === undefined) {
53
+ return;
54
+ }
55
+ if (tabIndex >= -1) {
56
+ return;
57
+ }
58
+ context.report({
59
+ node,
60
+ message: errorMessage
61
+ });
62
+ }
63
+ };
64
+ }
65
+ };
66
+ module.exports = exports.default;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = void 0;
7
+ var _ariaQuery = require("aria-query");
8
+ var _jsxAstUtils = require("jsx-ast-utils");
9
+ var _schemas = require("../util/schemas");
10
+ var _getSuggestion = _interopRequireDefault(require("../util/getSuggestion"));
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
12
+ /**
13
+ * @fileoverview Enforce all aria-* properties are valid.
14
+ * @author Ethan Cohen
15
+ */
16
+
17
+ // ----------------------------------------------------------------------------
18
+ // Rule Definition
19
+ // ----------------------------------------------------------------------------
20
+
21
+ var ariaAttributes = _ariaQuery.aria.keys();
22
+ var errorMessage = function errorMessage(name) {
23
+ var suggestions = (0, _getSuggestion["default"])(name, ariaAttributes);
24
+ var message = "".concat(name, ": This attribute is an invalid ARIA attribute.");
25
+ if (suggestions.length > 0) {
26
+ return "".concat(message, " Did you mean to use ").concat(suggestions, "?");
27
+ }
28
+ return message;
29
+ };
30
+ var schema = (0, _schemas.generateObjSchema)();
31
+ var _default = exports["default"] = {
32
+ meta: {
33
+ docs: {
34
+ url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-props.md',
35
+ description: 'Enforce all `aria-*` props are valid.'
36
+ },
37
+ schema: [schema]
38
+ },
39
+ create: function create(context) {
40
+ return {
41
+ JSXAttribute: function JSXAttribute(attribute) {
42
+ var name = (0, _jsxAstUtils.propName)(attribute);
43
+
44
+ // `aria` needs to be prefix of property.
45
+ if (name.indexOf('aria-') !== 0) {
46
+ return;
47
+ }
48
+ var isValid = _ariaQuery.aria.has(name);
49
+ if (isValid === false) {
50
+ context.report({
51
+ node: attribute,
52
+ message: errorMessage(name)
53
+ });
54
+ }
55
+ }
56
+ };
57
+ }
58
+ };
59
+ module.exports = exports.default;
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = void 0;
7
+ var _ariaQuery = require("aria-query");
8
+ var _jsxAstUtils = require("jsx-ast-utils");
9
+ var _schemas = require("../util/schemas");
10
+ /**
11
+ * @fileoverview Enforce ARIA state and property values are valid.
12
+ * @author Ethan Cohen
13
+ */
14
+
15
+ // ----------------------------------------------------------------------------
16
+ // Rule Definition
17
+ // ----------------------------------------------------------------------------
18
+
19
+ var errorMessage = function errorMessage(name, type, permittedValues) {
20
+ switch (type) {
21
+ case 'tristate':
22
+ return "The value for ".concat(name, " must be a boolean or the string \"mixed\".");
23
+ case 'token':
24
+ return "The value for ".concat(name, " must be a single token from the following: ").concat(permittedValues, ".");
25
+ case 'tokenlist':
26
+ return "The value for ".concat(name, " must be a list of one or more tokens from the following: ").concat(permittedValues, ".");
27
+ case 'idlist':
28
+ return "The value for ".concat(name, " must be a list of strings that represent DOM element IDs (idlist)");
29
+ case 'id':
30
+ return "The value for ".concat(name, " must be a string that represents a DOM element ID");
31
+ case 'boolean':
32
+ case 'string':
33
+ case 'integer':
34
+ case 'number':
35
+ default:
36
+ return "The value for ".concat(name, " must be a ").concat(type, ".");
37
+ }
38
+ };
39
+ var _validityCheck = function validityCheck(value, expectedType, permittedValues) {
40
+ switch (expectedType) {
41
+ case 'boolean':
42
+ return typeof value === 'boolean';
43
+ case 'string':
44
+ case 'id':
45
+ return typeof value === 'string';
46
+ case 'tristate':
47
+ return typeof value === 'boolean' || value === 'mixed';
48
+ case 'integer':
49
+ case 'number':
50
+ // Booleans resolve to 0/1 values so hard check that it's not first.
51
+ // eslint-disable-next-line no-restricted-globals
52
+ return typeof value !== 'boolean' && isNaN(Number(value)) === false;
53
+ case 'token':
54
+ return permittedValues.indexOf(typeof value === 'string' ? value.toLowerCase() : value) > -1;
55
+ case 'idlist':
56
+ return typeof value === 'string' && value.split(' ').every(function (token) {
57
+ return _validityCheck(token, 'id', []);
58
+ });
59
+ case 'tokenlist':
60
+ return typeof value === 'string' && value.split(' ').every(function (token) {
61
+ return permittedValues.indexOf(token.toLowerCase()) > -1;
62
+ });
63
+ default:
64
+ return false;
65
+ }
66
+ };
67
+ var schema = (0, _schemas.generateObjSchema)();
68
+ var _default = exports["default"] = {
69
+ validityCheck: _validityCheck,
70
+ meta: {
71
+ docs: {
72
+ url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-proptypes.md',
73
+ description: 'Enforce ARIA state and property values are valid.'
74
+ },
75
+ schema: [schema]
76
+ },
77
+ create: function create(context) {
78
+ return {
79
+ JSXAttribute: function JSXAttribute(attribute) {
80
+ var name = (0, _jsxAstUtils.propName)(attribute);
81
+ var normalizedName = name.toLowerCase();
82
+
83
+ // Not a valid aria-* state or property.
84
+ if (normalizedName.indexOf('aria-') !== 0 || _ariaQuery.aria.get(normalizedName) === undefined) {
85
+ return;
86
+ }
87
+
88
+ // Ignore the attribute if its value is null or undefined.
89
+ if ((0, _jsxAstUtils.getPropValue)(attribute) == null) return;
90
+ var value = (0, _jsxAstUtils.getLiteralPropValue)(attribute);
91
+
92
+ // Ignore the attribute if its value is not a literal.
93
+ if (value === null) {
94
+ return;
95
+ }
96
+
97
+ // These are the attributes of the property/state to check against.
98
+ var attributes = _ariaQuery.aria.get(normalizedName);
99
+ var permittedType = attributes.type;
100
+ var allowUndefined = attributes.allowUndefined || false;
101
+ var permittedValues = attributes.values || [];
102
+ var isValid = _validityCheck(value, permittedType, permittedValues) || allowUndefined && value === undefined;
103
+ if (isValid) {
104
+ return;
105
+ }
106
+ context.report({
107
+ node: attribute,
108
+ message: errorMessage(name, permittedType, permittedValues)
109
+ });
110
+ }
111
+ };
112
+ }
113
+ };
114
+ module.exports = exports.default;
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = void 0;
7
+ var _ariaQuery = require("aria-query");
8
+ var _jsxAstUtils = require("jsx-ast-utils");
9
+ var _getElementType = _interopRequireDefault(require("../util/getElementType"));
10
+ var _schemas = require("../util/schemas");
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
12
+ /**
13
+ * @fileoverview Enforce aria role attribute is valid.
14
+ * @author Ethan Cohen
15
+ */
16
+
17
+ // ----------------------------------------------------------------------------
18
+ // Rule Definition
19
+ // ----------------------------------------------------------------------------
20
+
21
+ var errorMessage = 'Elements with ARIA roles must use a valid, non-abstract ARIA role.';
22
+ var schema = (0, _schemas.generateObjSchema)({
23
+ allowedInvalidRoles: {
24
+ items: {
25
+ type: 'string'
26
+ },
27
+ type: 'array',
28
+ uniqueItems: true
29
+ },
30
+ ignoreNonDOM: {
31
+ type: 'boolean',
32
+ "default": false
33
+ }
34
+ });
35
+ var validRoles = new Set(_ariaQuery.roles.keys().filter(function (role) {
36
+ return _ariaQuery.roles.get(role)["abstract"] === false;
37
+ }));
38
+ var _default = exports["default"] = {
39
+ meta: {
40
+ docs: {
41
+ url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-role.md',
42
+ description: 'Enforce that elements with ARIA roles must use a valid, non-abstract ARIA role.'
43
+ },
44
+ schema: [schema]
45
+ },
46
+ create: function create(context) {
47
+ var options = context.options[0] || {};
48
+ var ignoreNonDOM = !!options.ignoreNonDOM;
49
+ var allowedInvalidRoles = new Set(options.allowedInvalidRoles || []);
50
+ var elementType = (0, _getElementType["default"])(context);
51
+ return {
52
+ JSXAttribute: function JSXAttribute(attribute) {
53
+ // If ignoreNonDOM and the parent isn't DOM, don't run rule.
54
+ if (ignoreNonDOM) {
55
+ var type = elementType(attribute.parent);
56
+ if (!_ariaQuery.dom.get(type)) {
57
+ return;
58
+ }
59
+ }
60
+
61
+ // Get prop name
62
+ var name = (0, _jsxAstUtils.propName)(attribute).toUpperCase();
63
+ if (name !== 'ROLE') {
64
+ return;
65
+ }
66
+ var value = (0, _jsxAstUtils.getLiteralPropValue)(attribute);
67
+
68
+ // If value is undefined, then the role attribute will be dropped in the DOM.
69
+ // If value is null, then getLiteralAttributeValue is telling us that the
70
+ // value isn't in the form of a literal.
71
+ if (value === undefined || value === null) {
72
+ return;
73
+ }
74
+ var values = String(value).split(' ');
75
+ var isValid = values.every(function (val) {
76
+ return allowedInvalidRoles.has(val) || validRoles.has(val);
77
+ });
78
+ if (isValid === true) {
79
+ return;
80
+ }
81
+ context.report({
82
+ node: attribute,
83
+ message: errorMessage
84
+ });
85
+ }
86
+ };
87
+ }
88
+ };
89
+ module.exports = exports.default;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = void 0;
7
+ var _ariaQuery = require("aria-query");
8
+ var _jsxAstUtils = require("jsx-ast-utils");
9
+ var _schemas = require("../util/schemas");
10
+ var _getElementType = _interopRequireDefault(require("../util/getElementType"));
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
12
+ /**
13
+ * @fileoverview Enforce that elements that do not support ARIA roles,
14
+ * states and properties do not have those attributes.
15
+ * @author Ethan Cohen
16
+ */
17
+
18
+ // ----------------------------------------------------------------------------
19
+ // Rule Definition
20
+ // ----------------------------------------------------------------------------
21
+
22
+ var errorMessage = function errorMessage(invalidProp) {
23
+ return "This element does not support ARIA roles, states and properties. Try removing the prop '".concat(invalidProp, "'.");
24
+ };
25
+ var invalidAttributes = new Set(_ariaQuery.aria.keys().concat('role'));
26
+ var schema = (0, _schemas.generateObjSchema)();
27
+ var _default = exports["default"] = {
28
+ meta: {
29
+ docs: {
30
+ url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-unsupported-elements.md',
31
+ description: 'Enforce that elements that do not support ARIA roles, states, and properties do not have those attributes.'
32
+ },
33
+ schema: [schema]
34
+ },
35
+ create: function create(context) {
36
+ var elementType = (0, _getElementType["default"])(context);
37
+ return {
38
+ JSXOpeningElement: function JSXOpeningElement(node) {
39
+ var nodeType = elementType(node);
40
+ var nodeAttrs = _ariaQuery.dom.get(nodeType) || {};
41
+ var _nodeAttrs$reserved = nodeAttrs.reserved,
42
+ isReservedNodeType = _nodeAttrs$reserved === void 0 ? false : _nodeAttrs$reserved;
43
+
44
+ // If it's not reserved, then it can have aria-* roles, states, and properties
45
+ if (isReservedNodeType === false) {
46
+ return;
47
+ }
48
+ node.attributes.forEach(function (prop) {
49
+ if (prop.type === 'JSXSpreadAttribute') {
50
+ return;
51
+ }
52
+ var name = (0, _jsxAstUtils.propName)(prop).toLowerCase();
53
+ if (invalidAttributes.has(name)) {
54
+ context.report({
55
+ node,
56
+ message: errorMessage(name)
57
+ });
58
+ }
59
+ });
60
+ }
61
+ };
62
+ }
63
+ };
64
+ module.exports = exports.default;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = void 0;
7
+ var _axeCore = require("axe-core");
8
+ var _jsxAstUtils = require("jsx-ast-utils");
9
+ var _schemas = require("../util/schemas");
10
+ var _getElementType = _interopRequireDefault(require("../util/getElementType"));
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
12
+ /**
13
+ * @fileoverview Ensure autocomplete attribute is correct.
14
+ * @author Wilco Fiers
15
+ */
16
+
17
+ // ----------------------------------------------------------------------------
18
+ // Rule Definition
19
+ // ----------------------------------------------------------------------------
20
+
21
+ var schema = (0, _schemas.generateObjSchema)({
22
+ inputComponents: _schemas.arraySchema
23
+ });
24
+ var _default = exports["default"] = {
25
+ meta: {
26
+ docs: {
27
+ url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/autocomplete-valid.md',
28
+ description: 'Enforce that autocomplete attributes are used correctly.'
29
+ },
30
+ schema: [schema]
31
+ },
32
+ create: function create(context) {
33
+ var elementType = (0, _getElementType["default"])(context);
34
+ return {
35
+ JSXOpeningElement: function JSXOpeningElement(node) {
36
+ var options = context.options[0] || {};
37
+ var _options$inputCompone = options.inputComponents,
38
+ inputComponents = _options$inputCompone === void 0 ? [] : _options$inputCompone;
39
+ var inputTypes = ['input'].concat(inputComponents);
40
+ var elType = elementType(node);
41
+ var autocomplete = (0, _jsxAstUtils.getLiteralPropValue)((0, _jsxAstUtils.getProp)(node.attributes, 'autocomplete'));
42
+ if (typeof autocomplete !== 'string' || !inputTypes.includes(elType)) {
43
+ return;
44
+ }
45
+ var type = (0, _jsxAstUtils.getLiteralPropValue)((0, _jsxAstUtils.getProp)(node.attributes, 'type'));
46
+ var _runVirtualRule = (0, _axeCore.runVirtualRule)('autocomplete-valid', {
47
+ nodeName: 'input',
48
+ attributes: {
49
+ autocomplete,
50
+ // Which autocomplete is valid depends on the input type
51
+ type: type === null ? undefined : type
52
+ }
53
+ }),
54
+ violations = _runVirtualRule.violations;
55
+ if (violations.length === 0) {
56
+ return;
57
+ }
58
+ // Since we only test one rule, with one node, return the message from first (and only) instance of each
59
+ context.report({
60
+ node,
61
+ message: violations[0].nodes[0].all[0].message
62
+ });
63
+ }
64
+ };
65
+ }
66
+ };
67
+ module.exports = exports.default;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = void 0;
7
+ var _ariaQuery = require("aria-query");
8
+ var _jsxAstUtils = require("jsx-ast-utils");
9
+ var _schemas = require("../util/schemas");
10
+ var _getElementType = _interopRequireDefault(require("../util/getElementType"));
11
+ var _isHiddenFromScreenReader = _interopRequireDefault(require("../util/isHiddenFromScreenReader"));
12
+ var _isInteractiveElement = _interopRequireDefault(require("../util/isInteractiveElement"));
13
+ var _isPresentationRole = _interopRequireDefault(require("../util/isPresentationRole"));
14
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
15
+ /**
16
+ * @fileoverview Enforce a clickable non-interactive element has at least 1 keyboard event listener.
17
+ * @author Ethan Cohen
18
+ */
19
+
20
+ // ----------------------------------------------------------------------------
21
+ // Rule Definition
22
+ // ----------------------------------------------------------------------------
23
+
24
+ var errorMessage = 'Visible, non-interactive elements with click handlers must have at least one keyboard listener.';
25
+ var schema = (0, _schemas.generateObjSchema)();
26
+ var _default = exports["default"] = {
27
+ meta: {
28
+ docs: {
29
+ url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/click-events-have-key-events.md',
30
+ description: 'Enforce a clickable non-interactive element has at least one keyboard event listener.'
31
+ },
32
+ schema: [schema]
33
+ },
34
+ create: function create(context) {
35
+ var elementType = (0, _getElementType["default"])(context);
36
+ return {
37
+ JSXOpeningElement: function JSXOpeningElement(node) {
38
+ var props = node.attributes;
39
+ if ((0, _jsxAstUtils.getProp)(props, 'onclick') === undefined) {
40
+ return;
41
+ }
42
+ var type = elementType(node);
43
+ var requiredProps = ['onkeydown', 'onkeyup', 'onkeypress'];
44
+ if (!_ariaQuery.dom.has(type)) {
45
+ // Do not test higher level JSX components, as we do not know what
46
+ // low-level DOM element this maps to.
47
+ return;
48
+ }
49
+ if ((0, _isHiddenFromScreenReader["default"])(type, props) || (0, _isPresentationRole["default"])(type, props)) {
50
+ return;
51
+ }
52
+ if ((0, _isInteractiveElement["default"])(type, props)) {
53
+ return;
54
+ }
55
+ if ((0, _jsxAstUtils.hasAnyProp)(props, requiredProps)) {
56
+ return;
57
+ }
58
+
59
+ // Visible, non-interactive elements with click handlers require one keyboard event listener.
60
+ context.report({
61
+ node,
62
+ message: errorMessage
63
+ });
64
+ }
65
+ };
66
+ }
67
+ };
68
+ module.exports = exports.default;