@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.
- package/.babelrc +17 -0
- package/.eslintrc +44 -0
- package/CHANGELOG.md +774 -0
- package/LICENSE.md +8 -0
- package/README.md +423 -0
- package/__mocks__/IdentifierMock.js +15 -0
- package/__mocks__/JSXAttributeMock.js +39 -0
- package/__mocks__/JSXElementMock.js +37 -0
- package/__mocks__/JSXExpressionContainerMock.js +15 -0
- package/__mocks__/JSXSpreadAttributeMock.js +18 -0
- package/__mocks__/JSXTextMock.js +17 -0
- package/__mocks__/LiteralMock.js +17 -0
- package/__mocks__/genInteractives.js +218 -0
- package/__tests__/__util__/axeMapping.js +6 -0
- package/__tests__/__util__/helpers/getESLintCoreRule.js +9 -0
- package/__tests__/__util__/helpers/parsers.js +186 -0
- package/__tests__/__util__/parserOptionsMapper.js +53 -0
- package/__tests__/__util__/ruleOptionsMapperFactory.js +33 -0
- package/__tests__/index-test.js +40 -0
- package/__tests__/src/rules/accessible-emoji-test.js +66 -0
- package/__tests__/src/rules/alt-text-test.js +291 -0
- package/__tests__/src/rules/anchor-ambiguous-text-test.js +117 -0
- package/__tests__/src/rules/anchor-has-content-test.js +54 -0
- package/__tests__/src/rules/anchor-is-valid-test.js +532 -0
- package/__tests__/src/rules/aria-activedescendant-has-tabindex-test.js +95 -0
- package/__tests__/src/rules/aria-props-test.js +69 -0
- package/__tests__/src/rules/aria-proptypes-test.js +311 -0
- package/__tests__/src/rules/aria-role-test.js +118 -0
- package/__tests__/src/rules/aria-unsupported-elements-test.js +75 -0
- package/__tests__/src/rules/autocomplete-valid-test.js +77 -0
- package/__tests__/src/rules/click-events-have-key-events-test.js +77 -0
- package/__tests__/src/rules/control-has-associated-label-test.js +327 -0
- package/__tests__/src/rules/heading-has-content-test.js +85 -0
- package/__tests__/src/rules/html-has-lang-test.js +42 -0
- package/__tests__/src/rules/iframe-has-title-test.js +55 -0
- package/__tests__/src/rules/img-redundant-alt-test.js +137 -0
- package/__tests__/src/rules/interactive-supports-focus-test.js +267 -0
- package/__tests__/src/rules/label-has-associated-control-test.js +243 -0
- package/__tests__/src/rules/label-has-for-test.js +235 -0
- package/__tests__/src/rules/lang-test.js +59 -0
- package/__tests__/src/rules/media-has-caption-test.js +220 -0
- package/__tests__/src/rules/mouse-events-have-key-events-test.js +154 -0
- package/__tests__/src/rules/no-access-key-test.js +48 -0
- package/__tests__/src/rules/no-aria-hidden-on-focusable-test.js +44 -0
- package/__tests__/src/rules/no-autofocus-test.js +68 -0
- package/__tests__/src/rules/no-distracting-elements-test.js +51 -0
- package/__tests__/src/rules/no-interactive-element-to-noninteractive-role-test.js +405 -0
- package/__tests__/src/rules/no-noninteractive-element-interactions-test.js +502 -0
- package/__tests__/src/rules/no-noninteractive-element-to-interactive-role-test.js +500 -0
- package/__tests__/src/rules/no-noninteractive-tabindex-test.js +123 -0
- package/__tests__/src/rules/no-onchange-test.js +57 -0
- package/__tests__/src/rules/no-redundant-roles-test.js +98 -0
- package/__tests__/src/rules/no-static-element-interactions-test.js +501 -0
- package/__tests__/src/rules/prefer-tag-over-role-test.js +63 -0
- package/__tests__/src/rules/role-has-required-aria-props-test.js +134 -0
- package/__tests__/src/rules/role-supports-aria-props-test.js +570 -0
- package/__tests__/src/rules/scope-test.js +50 -0
- package/__tests__/src/rules/tabindex-no-positive-test.js +55 -0
- package/__tests__/src/util/attributesComparator-test.js +91 -0
- package/__tests__/src/util/getAccessibleChildText-test.js +174 -0
- package/__tests__/src/util/getComputedRole-test.js +71 -0
- package/__tests__/src/util/getElementType-test.js +154 -0
- package/__tests__/src/util/getExplicitRole-test.js +35 -0
- package/__tests__/src/util/getImplicitRole-test.js +25 -0
- package/__tests__/src/util/getSuggestion-test.js +33 -0
- package/__tests__/src/util/getTabIndex-test.js +85 -0
- package/__tests__/src/util/hasAccessibleChild-test.js +157 -0
- package/__tests__/src/util/implicitRoles/input-test.js +87 -0
- package/__tests__/src/util/implicitRoles/menu-test.js +20 -0
- package/__tests__/src/util/implicitRoles/menuitem-test.js +38 -0
- package/__tests__/src/util/isAbstractRole-test.js +51 -0
- package/__tests__/src/util/isContentEditable-test.js +52 -0
- package/__tests__/src/util/isDOMElement-test.js +30 -0
- package/__tests__/src/util/isDisabledElement-test.js +88 -0
- package/__tests__/src/util/isFocusable-test.js +111 -0
- package/__tests__/src/util/isInteractiveElement-test.js +104 -0
- package/__tests__/src/util/isInteractiveRole-test.js +59 -0
- package/__tests__/src/util/isNonInteractiveElement-test.js +97 -0
- package/__tests__/src/util/isNonInteractiveRole-test.js +59 -0
- package/__tests__/src/util/isNonLiteralProperty-test.js +52 -0
- package/__tests__/src/util/isSemanticRoleElement-test.js +72 -0
- package/__tests__/src/util/mayContainChildComponent-test.js +219 -0
- package/__tests__/src/util/mayHaveAccessibleLabel-test.js +256 -0
- package/__tests__/src/util/parserOptionsMapper-test.js +93 -0
- package/__tests__/src/util/schemas-test.js +35 -0
- package/docs/rules/accessible-emoji.md +30 -0
- package/docs/rules/alt-text.md +168 -0
- package/docs/rules/anchor-ambiguous-text.md +91 -0
- package/docs/rules/anchor-has-content.md +64 -0
- package/docs/rules/anchor-is-valid.md +270 -0
- package/docs/rules/aria-activedescendant-has-tabindex.md +52 -0
- package/docs/rules/aria-props.md +29 -0
- package/docs/rules/aria-proptypes.md +30 -0
- package/docs/rules/aria-role.md +51 -0
- package/docs/rules/aria-unsupported-elements.md +30 -0
- package/docs/rules/autocomplete-valid.md +49 -0
- package/docs/rules/click-events-have-key-events.md +28 -0
- package/docs/rules/control-has-associated-label.md +113 -0
- package/docs/rules/heading-has-content.md +67 -0
- package/docs/rules/html-has-lang.md +31 -0
- package/docs/rules/iframe-has-title.md +37 -0
- package/docs/rules/img-redundant-alt.md +48 -0
- package/docs/rules/interactive-supports-focus.md +156 -0
- package/docs/rules/label-has-associated-control.md +152 -0
- package/docs/rules/label-has-for.md +130 -0
- package/docs/rules/lang.md +31 -0
- package/docs/rules/media-has-caption.md +48 -0
- package/docs/rules/mouse-events-have-key-events.md +58 -0
- package/docs/rules/no-access-key.md +30 -0
- package/docs/rules/no-aria-hidden-on-focusable.md +37 -0
- package/docs/rules/no-autofocus.md +43 -0
- package/docs/rules/no-distracting-elements.md +41 -0
- package/docs/rules/no-interactive-element-to-noninteractive-role.md +73 -0
- package/docs/rules/no-noninteractive-element-interactions.md +145 -0
- package/docs/rules/no-noninteractive-element-to-interactive-role.md +76 -0
- package/docs/rules/no-noninteractive-tabindex.md +115 -0
- package/docs/rules/no-onchange.md +36 -0
- package/docs/rules/no-redundant-roles.md +46 -0
- package/docs/rules/no-static-element-interactions.md +114 -0
- package/docs/rules/prefer-tag-over-role.md +32 -0
- package/docs/rules/role-has-required-aria-props.md +31 -0
- package/docs/rules/role-supports-aria-props.md +39 -0
- package/docs/rules/scope.md +30 -0
- package/docs/rules/tabindex-no-positive.md +32 -0
- package/lib/configs/flat-config-base.js +11 -0
- package/lib/configs/legacy-config-base.js +9 -0
- package/lib/index.js +209 -0
- package/lib/rules/accessible-emoji.js +63 -0
- package/lib/rules/alt-text.js +218 -0
- package/lib/rules/anchor-ambiguous-text.js +64 -0
- package/lib/rules/anchor-has-content.js +60 -0
- package/lib/rules/anchor-is-valid.js +122 -0
- package/lib/rules/aria-activedescendant-has-tabindex.js +66 -0
- package/lib/rules/aria-props.js +59 -0
- package/lib/rules/aria-proptypes.js +114 -0
- package/lib/rules/aria-role.js +89 -0
- package/lib/rules/aria-unsupported-elements.js +64 -0
- package/lib/rules/autocomplete-valid.js +67 -0
- package/lib/rules/click-events-have-key-events.js +68 -0
- package/lib/rules/control-has-associated-label.js +103 -0
- package/lib/rules/heading-has-content.js +61 -0
- package/lib/rules/html-has-lang.js +50 -0
- package/lib/rules/iframe-has-title.js +50 -0
- package/lib/rules/img-redundant-alt.js +88 -0
- package/lib/rules/interactive-supports-focus.js +87 -0
- package/lib/rules/label-has-associated-control.js +127 -0
- package/lib/rules/label-has-for.js +150 -0
- package/lib/rules/lang.js +68 -0
- package/lib/rules/media-has-caption.js +96 -0
- package/lib/rules/mouse-events-have-key-events.js +94 -0
- package/lib/rules/no-access-key.js +43 -0
- package/lib/rules/no-aria-hidden-on-focusable.js +47 -0
- package/lib/rules/no-autofocus.js +62 -0
- package/lib/rules/no-distracting-elements.js +54 -0
- package/lib/rules/no-interactive-element-to-noninteractive-role.js +81 -0
- package/lib/rules/no-noninteractive-element-interactions.js +95 -0
- package/lib/rules/no-noninteractive-element-to-interactive-role.js +80 -0
- package/lib/rules/no-noninteractive-tabindex.js +109 -0
- package/lib/rules/no-onchange.js +52 -0
- package/lib/rules/no-redundant-roles.js +86 -0
- package/lib/rules/no-static-element-interactions.js +102 -0
- package/lib/rules/prefer-tag-over-role.js +75 -0
- package/lib/rules/role-has-required-aria-props.js +88 -0
- package/lib/rules/role-supports-aria-props.js +78 -0
- package/lib/rules/scope.js +58 -0
- package/lib/rules/tabindex-no-positive.js +53 -0
- package/lib/util/attributesComparator.js +34 -0
- package/lib/util/getAccessibleChildText.js +55 -0
- package/lib/util/getComputedRole.js +19 -0
- package/lib/util/getElementType.js +30 -0
- package/lib/util/getExplicitRole.js +27 -0
- package/lib/util/getImplicitRole.js +24 -0
- package/lib/util/getSuggestion.js +32 -0
- package/lib/util/getTabIndex.js +34 -0
- package/lib/util/hasAccessibleChild.js +30 -0
- package/lib/util/implicitRoles/a.js +17 -0
- package/lib/util/implicitRoles/area.js +17 -0
- package/lib/util/implicitRoles/article.js +13 -0
- package/lib/util/implicitRoles/aside.js +13 -0
- package/lib/util/implicitRoles/body.js +13 -0
- package/lib/util/implicitRoles/button.js +13 -0
- package/lib/util/implicitRoles/datalist.js +13 -0
- package/lib/util/implicitRoles/details.js +13 -0
- package/lib/util/implicitRoles/dialog.js +13 -0
- package/lib/util/implicitRoles/form.js +13 -0
- package/lib/util/implicitRoles/h1.js +13 -0
- package/lib/util/implicitRoles/h2.js +13 -0
- package/lib/util/implicitRoles/h3.js +13 -0
- package/lib/util/implicitRoles/h4.js +13 -0
- package/lib/util/implicitRoles/h5.js +13 -0
- package/lib/util/implicitRoles/h6.js +13 -0
- package/lib/util/implicitRoles/hr.js +13 -0
- package/lib/util/implicitRoles/img.js +31 -0
- package/lib/util/implicitRoles/index.js +82 -0
- package/lib/util/implicitRoles/input.js +38 -0
- package/lib/util/implicitRoles/li.js +13 -0
- package/lib/util/implicitRoles/link.js +17 -0
- package/lib/util/implicitRoles/menu.js +19 -0
- package/lib/util/implicitRoles/menuitem.js +28 -0
- package/lib/util/implicitRoles/meter.js +13 -0
- package/lib/util/implicitRoles/nav.js +13 -0
- package/lib/util/implicitRoles/ol.js +13 -0
- package/lib/util/implicitRoles/option.js +13 -0
- package/lib/util/implicitRoles/output.js +13 -0
- package/lib/util/implicitRoles/progress.js +13 -0
- package/lib/util/implicitRoles/section.js +13 -0
- package/lib/util/implicitRoles/select.js +13 -0
- package/lib/util/implicitRoles/tbody.js +13 -0
- package/lib/util/implicitRoles/textarea.js +13 -0
- package/lib/util/implicitRoles/tfoot.js +13 -0
- package/lib/util/implicitRoles/thead.js +13 -0
- package/lib/util/implicitRoles/ul.js +13 -0
- package/lib/util/isAbstractRole.js +23 -0
- package/lib/util/isContentEditable.js +13 -0
- package/lib/util/isDOMElement.js +15 -0
- package/lib/util/isDisabledElement.js +23 -0
- package/lib/util/isFocusable.js +23 -0
- package/lib/util/isHiddenFromScreenReader.js +26 -0
- package/lib/util/isInteractiveElement.js +116 -0
- package/lib/util/isInteractiveRole.js +54 -0
- package/lib/util/isNonInteractiveElement.js +131 -0
- package/lib/util/isNonInteractiveRole.js +55 -0
- package/lib/util/isNonLiteralProperty.js +29 -0
- package/lib/util/isPresentationRole.js +13 -0
- package/lib/util/isSemanticRoleElement.js +54 -0
- package/lib/util/mayContainChildComponent.js +50 -0
- package/lib/util/mayHaveAccessibleLabel.js +95 -0
- package/lib/util/schemas.js +52 -0
- package/package.json +120 -0
|
@@ -0,0 +1,75 @@
|
|
|
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
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
13
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
14
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
15
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
16
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
17
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
18
|
+
var errorMessage = 'Use {{tag}} instead of the "{{role}}" role to ensure accessibility across all devices.';
|
|
19
|
+
var schema = (0, _schemas.generateObjSchema)();
|
|
20
|
+
var formatTag = function formatTag(tag) {
|
|
21
|
+
if (!tag.attributes) {
|
|
22
|
+
return "<".concat(tag.name, ">");
|
|
23
|
+
}
|
|
24
|
+
var _tag$attributes = _slicedToArray(tag.attributes, 1),
|
|
25
|
+
attribute = _tag$attributes[0];
|
|
26
|
+
var value = attribute.value ? "\"".concat(attribute.value, "\"") : '...';
|
|
27
|
+
return "<".concat(tag.name, " ").concat(attribute.name, "=").concat(value, ">");
|
|
28
|
+
};
|
|
29
|
+
var getLastPropValue = function getLastPropValue(rawProp) {
|
|
30
|
+
var propValue = (0, _jsxAstUtils.getPropValue)(rawProp);
|
|
31
|
+
if (!propValue) {
|
|
32
|
+
return propValue;
|
|
33
|
+
}
|
|
34
|
+
var lastSpaceIndex = propValue.lastIndexOf(' ');
|
|
35
|
+
return lastSpaceIndex === -1 ? propValue : propValue.substring(lastSpaceIndex + 1);
|
|
36
|
+
};
|
|
37
|
+
var _default = exports["default"] = {
|
|
38
|
+
meta: {
|
|
39
|
+
docs: {
|
|
40
|
+
description: 'Enforces using semantic DOM elements over the ARIA `role` property.',
|
|
41
|
+
url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/prefer-tag-over-role.md'
|
|
42
|
+
},
|
|
43
|
+
schema: [schema]
|
|
44
|
+
},
|
|
45
|
+
create: function create(context) {
|
|
46
|
+
var elementType = (0, _getElementType["default"])(context);
|
|
47
|
+
return {
|
|
48
|
+
JSXOpeningElement: function JSXOpeningElement(node) {
|
|
49
|
+
var role = getLastPropValue((0, _jsxAstUtils.getProp)(node.attributes, 'role'));
|
|
50
|
+
if (!role) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
var matchedTagsSet = _ariaQuery.roleElements.get(role);
|
|
54
|
+
if (!matchedTagsSet) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
var matchedTags = Array.from(matchedTagsSet);
|
|
58
|
+
if (matchedTags.some(function (matchedTag) {
|
|
59
|
+
return matchedTag.name === elementType(node);
|
|
60
|
+
})) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
context.report({
|
|
64
|
+
data: {
|
|
65
|
+
tag: matchedTags.length === 1 ? formatTag(matchedTags[0]) : [matchedTags.slice(0, matchedTags.length - 1).map(formatTag).join(', '), formatTag(matchedTags[matchedTags.length - 1])].join(', or '),
|
|
66
|
+
role
|
|
67
|
+
},
|
|
68
|
+
node,
|
|
69
|
+
message: errorMessage
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,88 @@
|
|
|
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 _isSemanticRoleElement = _interopRequireDefault(require("../util/isSemanticRoleElement"));
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
13
|
+
/**
|
|
14
|
+
* @fileoverview Enforce that elements with ARIA roles must
|
|
15
|
+
* have all required attributes for that role.
|
|
16
|
+
* @author Ethan Cohen
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
// ----------------------------------------------------------------------------
|
|
20
|
+
// Rule Definition
|
|
21
|
+
// ----------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
var errorMessage = function errorMessage(role, requiredProps) {
|
|
24
|
+
return "Elements with the ARIA role \"".concat(role, "\" must have the following attributes defined: ").concat(String(requiredProps).toLowerCase());
|
|
25
|
+
};
|
|
26
|
+
var schema = (0, _schemas.generateObjSchema)();
|
|
27
|
+
var roleKeys = _ariaQuery.roles.keys();
|
|
28
|
+
var _default = exports["default"] = {
|
|
29
|
+
meta: {
|
|
30
|
+
docs: {
|
|
31
|
+
url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/role-has-required-aria-props.md',
|
|
32
|
+
description: 'Enforce that elements with ARIA roles must have all required attributes for that role.'
|
|
33
|
+
},
|
|
34
|
+
schema: [schema]
|
|
35
|
+
},
|
|
36
|
+
create: function create(context) {
|
|
37
|
+
var elementType = (0, _getElementType["default"])(context);
|
|
38
|
+
return {
|
|
39
|
+
JSXAttribute: function JSXAttribute(attribute) {
|
|
40
|
+
var name = (0, _jsxAstUtils.propName)(attribute).toLowerCase();
|
|
41
|
+
if (name !== 'role') {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
var type = elementType(attribute.parent);
|
|
45
|
+
if (!_ariaQuery.dom.get(type)) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
var roleAttrValue = (0, _jsxAstUtils.getLiteralPropValue)(attribute);
|
|
49
|
+
var attributes = attribute.parent.attributes;
|
|
50
|
+
|
|
51
|
+
// If value is undefined, then the role attribute will be dropped in the DOM.
|
|
52
|
+
// If value is null, then getLiteralAttributeValue is telling us
|
|
53
|
+
// that the value isn't in the form of a literal.
|
|
54
|
+
if (roleAttrValue === undefined || roleAttrValue === null) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
var normalizedValues = String(roleAttrValue).toLowerCase().split(' ');
|
|
58
|
+
var validRoles = normalizedValues.filter(function (val) {
|
|
59
|
+
return roleKeys.indexOf(val) > -1;
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Check semantic DOM elements
|
|
63
|
+
// For example, <input type="checkbox" role="switch" />
|
|
64
|
+
if ((0, _isSemanticRoleElement["default"])(type, attributes)) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// Check arbitrary DOM elements
|
|
68
|
+
validRoles.forEach(function (role) {
|
|
69
|
+
var _roles$get = _ariaQuery.roles.get(role),
|
|
70
|
+
requiredPropKeyValues = _roles$get.requiredProps;
|
|
71
|
+
var requiredProps = Object.keys(requiredPropKeyValues);
|
|
72
|
+
if (requiredProps.length > 0) {
|
|
73
|
+
var hasRequiredProps = requiredProps.every(function (prop) {
|
|
74
|
+
return (0, _jsxAstUtils.getProp)(attributes, prop);
|
|
75
|
+
});
|
|
76
|
+
if (hasRequiredProps === false) {
|
|
77
|
+
context.report({
|
|
78
|
+
node: attribute,
|
|
79
|
+
message: errorMessage(role.toLowerCase(), requiredProps)
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,78 @@
|
|
|
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 _getImplicitRole = _interopRequireDefault(require("../util/getImplicitRole"));
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
13
|
+
/**
|
|
14
|
+
* @fileoverview Enforce that elements with explicit or implicit roles defined contain only
|
|
15
|
+
* `aria-*` properties supported by that `role`.
|
|
16
|
+
* @author Ethan Cohen
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
// ----------------------------------------------------------------------------
|
|
20
|
+
// Rule Definition
|
|
21
|
+
// ----------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
var errorMessage = function errorMessage(attr, role, tag, isImplicit) {
|
|
24
|
+
if (isImplicit) {
|
|
25
|
+
return "The attribute ".concat(attr, " is not supported by the role ").concat(role, ". This role is implicit on the element ").concat(tag, ".");
|
|
26
|
+
}
|
|
27
|
+
return "The attribute ".concat(attr, " is not supported by the role ").concat(role, ".");
|
|
28
|
+
};
|
|
29
|
+
var schema = (0, _schemas.generateObjSchema)();
|
|
30
|
+
var _default = exports["default"] = {
|
|
31
|
+
meta: {
|
|
32
|
+
docs: {
|
|
33
|
+
url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/role-supports-aria-props.md',
|
|
34
|
+
description: 'Enforce that elements with explicit or implicit roles defined contain only `aria-*` properties supported by that `role`.'
|
|
35
|
+
},
|
|
36
|
+
schema: [schema]
|
|
37
|
+
},
|
|
38
|
+
create(context) {
|
|
39
|
+
var elementType = (0, _getElementType["default"])(context);
|
|
40
|
+
return {
|
|
41
|
+
JSXOpeningElement(node) {
|
|
42
|
+
// If role is not explicitly defined, then try and get its implicit role.
|
|
43
|
+
var type = elementType(node);
|
|
44
|
+
var role = (0, _jsxAstUtils.getProp)(node.attributes, 'role');
|
|
45
|
+
var roleValue = role ? (0, _jsxAstUtils.getLiteralPropValue)(role) : (0, _getImplicitRole["default"])(type, node.attributes);
|
|
46
|
+
var isImplicit = roleValue && role === undefined;
|
|
47
|
+
|
|
48
|
+
// If there is no explicit or implicit role, then assume that the element
|
|
49
|
+
// can handle the global set of aria-* properties.
|
|
50
|
+
// This actually isn't true - should fix in future release.
|
|
51
|
+
if (typeof roleValue !== 'string' || _ariaQuery.roles.get(roleValue) === undefined) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Make sure it has no aria-* properties defined outside its property set.
|
|
56
|
+
var _roles$get = _ariaQuery.roles.get(roleValue),
|
|
57
|
+
propKeyValues = _roles$get.props;
|
|
58
|
+
var invalidAriaPropsForRole = new Set(_ariaQuery.aria.keys().filter(function (attribute) {
|
|
59
|
+
return !(attribute in propKeyValues);
|
|
60
|
+
}));
|
|
61
|
+
node.attributes.filter(function (prop) {
|
|
62
|
+
return (0, _jsxAstUtils.getPropValue)(prop) != null // Ignore the attribute if its value is null or undefined.
|
|
63
|
+
&& prop.type !== 'JSXSpreadAttribute' // Ignore the attribute if it's a spread.
|
|
64
|
+
;
|
|
65
|
+
}).forEach(function (prop) {
|
|
66
|
+
var name = (0, _jsxAstUtils.propName)(prop);
|
|
67
|
+
if (invalidAriaPropsForRole.has(name)) {
|
|
68
|
+
context.report({
|
|
69
|
+
node,
|
|
70
|
+
message: errorMessage(name, roleValue, type, isImplicit)
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,58 @@
|
|
|
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 scope prop is only used on <th> elements.
|
|
14
|
+
* @author Ethan Cohen
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// ----------------------------------------------------------------------------
|
|
18
|
+
// Rule Definition
|
|
19
|
+
// ----------------------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
var errorMessage = 'The scope prop can only be used on <th> elements.';
|
|
22
|
+
var schema = (0, _schemas.generateObjSchema)();
|
|
23
|
+
var _default = exports["default"] = {
|
|
24
|
+
meta: {
|
|
25
|
+
docs: {
|
|
26
|
+
url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/scope.md',
|
|
27
|
+
description: 'Enforce `scope` prop is only used on `<th>` elements.'
|
|
28
|
+
},
|
|
29
|
+
schema: [schema]
|
|
30
|
+
},
|
|
31
|
+
create: function create(context) {
|
|
32
|
+
var elementType = (0, _getElementType["default"])(context);
|
|
33
|
+
return {
|
|
34
|
+
JSXAttribute: function JSXAttribute(node) {
|
|
35
|
+
var name = (0, _jsxAstUtils.propName)(node);
|
|
36
|
+
if (name && name.toUpperCase() !== 'SCOPE') {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
var parent = node.parent;
|
|
40
|
+
var tagName = elementType(parent);
|
|
41
|
+
|
|
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(tagName)) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (tagName && tagName.toUpperCase() === 'TH') {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
context.report({
|
|
51
|
+
node,
|
|
52
|
+
message: errorMessage
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,53 @@
|
|
|
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 _schemas = require("../util/schemas");
|
|
9
|
+
/**
|
|
10
|
+
* @fileoverview Enforce tabIndex value is not greater than zero.
|
|
11
|
+
* @author Ethan Cohen
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// ----------------------------------------------------------------------------
|
|
15
|
+
// Rule Definition
|
|
16
|
+
// ----------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
var errorMessage = 'Avoid positive integer values for tabIndex.';
|
|
19
|
+
var schema = (0, _schemas.generateObjSchema)();
|
|
20
|
+
var _default = exports["default"] = {
|
|
21
|
+
meta: {
|
|
22
|
+
docs: {
|
|
23
|
+
url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/tabindex-no-positive.md',
|
|
24
|
+
description: 'Enforce `tabIndex` value is not greater than zero.'
|
|
25
|
+
},
|
|
26
|
+
schema: [schema]
|
|
27
|
+
},
|
|
28
|
+
create: function create(context) {
|
|
29
|
+
return {
|
|
30
|
+
JSXAttribute: function JSXAttribute(attribute) {
|
|
31
|
+
var name = (0, _jsxAstUtils.propName)(attribute).toUpperCase();
|
|
32
|
+
|
|
33
|
+
// Check if tabIndex is the attribute
|
|
34
|
+
if (name !== 'TABINDEX') {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Only check literals because we can't infer values from certain expressions.
|
|
39
|
+
var value = Number((0, _jsxAstUtils.getLiteralPropValue)(attribute));
|
|
40
|
+
|
|
41
|
+
// eslint-disable-next-line no-restricted-globals
|
|
42
|
+
if (isNaN(value) || value <= 0) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
context.report({
|
|
46
|
+
node: attribute,
|
|
47
|
+
message: errorMessage
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
/**
|
|
9
|
+
* Returns true if all items in baseAttributes are found in attributes. Always
|
|
10
|
+
* returns true if baseAttributes is empty.
|
|
11
|
+
*/
|
|
12
|
+
function attributesComparator() {
|
|
13
|
+
var baseAttributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
14
|
+
var attributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
15
|
+
return baseAttributes.every(function (baseAttr) {
|
|
16
|
+
return attributes.some(function (attribute) {
|
|
17
|
+
// Guard against non-JSXAttribute nodes like JSXSpreadAttribute
|
|
18
|
+
if (attribute.type !== 'JSXAttribute') {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
// Attribute matches.
|
|
22
|
+
if (baseAttr.name !== (0, _jsxAstUtils.propName)(attribute)) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
// Value exists and does not match.
|
|
26
|
+
if (baseAttr.value && baseAttr.value !== (0, _jsxAstUtils.getLiteralPropValue)(attribute)) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
var _default = exports["default"] = attributesComparator;
|
|
34
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = getAccessibleChildText;
|
|
7
|
+
var _jsxAstUtils = require("jsx-ast-utils");
|
|
8
|
+
var _isHiddenFromScreenReader = _interopRequireDefault(require("./isHiddenFromScreenReader"));
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
10
|
+
/**
|
|
11
|
+
* Returns a new "standardized" string: all whitespace is collapsed to one space,
|
|
12
|
+
* and the string is lowercase
|
|
13
|
+
* @param {string} input
|
|
14
|
+
* @returns lowercase, single-spaced, punctuation-stripped, trimmed string
|
|
15
|
+
*/
|
|
16
|
+
function standardizeSpaceAndCase(input) {
|
|
17
|
+
return input.trim().replace(/[,.?¿!‽¡;:]/g, '') // strip punctuation
|
|
18
|
+
.replace(/\s\s+/g, ' ') // collapse spaces
|
|
19
|
+
.toLowerCase();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Returns the (recursively-defined) accessible child text of a node, which (in-order) is:
|
|
24
|
+
* 1. The element's aria-label
|
|
25
|
+
* 2. If the element is a direct literal, the literal value
|
|
26
|
+
* 3. Otherwise, merge all of its children
|
|
27
|
+
* @param {JSXElement} node - node to traverse
|
|
28
|
+
* @returns child text as a string
|
|
29
|
+
*/
|
|
30
|
+
function getAccessibleChildText(node, elementType) {
|
|
31
|
+
var ariaLabel = (0, _jsxAstUtils.getLiteralPropValue)((0, _jsxAstUtils.getProp)(node.openingElement.attributes, 'aria-label'));
|
|
32
|
+
// early escape-hatch when aria-label is applied
|
|
33
|
+
if (ariaLabel) return standardizeSpaceAndCase(ariaLabel);
|
|
34
|
+
|
|
35
|
+
// early-return if alt prop exists and is an image
|
|
36
|
+
var altTag = (0, _jsxAstUtils.getLiteralPropValue)((0, _jsxAstUtils.getProp)(node.openingElement.attributes, 'alt'));
|
|
37
|
+
if (elementType(node.openingElement) === 'img' && altTag) return standardizeSpaceAndCase(altTag);
|
|
38
|
+
|
|
39
|
+
// skip if aria-hidden is true
|
|
40
|
+
if ((0, _isHiddenFromScreenReader["default"])(elementType(node.openingElement), node.openingElement.attributes)) {
|
|
41
|
+
return '';
|
|
42
|
+
}
|
|
43
|
+
var rawChildText = node.children.map(function (currentNode) {
|
|
44
|
+
// $FlowFixMe JSXText is missing in ast-types-flow
|
|
45
|
+
if (currentNode.type === 'Literal' || currentNode.type === 'JSXText') {
|
|
46
|
+
return String(currentNode.value);
|
|
47
|
+
}
|
|
48
|
+
if (currentNode.type === 'JSXElement') {
|
|
49
|
+
return getAccessibleChildText(currentNode, elementType);
|
|
50
|
+
}
|
|
51
|
+
return '';
|
|
52
|
+
}).join(' ');
|
|
53
|
+
return standardizeSpaceAndCase(rawChildText);
|
|
54
|
+
}
|
|
55
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = getComputedRole;
|
|
7
|
+
var _getExplicitRole = _interopRequireDefault(require("./getExplicitRole"));
|
|
8
|
+
var _getImplicitRole = _interopRequireDefault(require("./getImplicitRole"));
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
10
|
+
/**
|
|
11
|
+
* Returns an element's computed role, which is
|
|
12
|
+
*
|
|
13
|
+
* 1. The valid value of its explicit role attribute; or
|
|
14
|
+
* 2. The implicit value of its tag.
|
|
15
|
+
*/
|
|
16
|
+
function getComputedRole(tag, attributes) {
|
|
17
|
+
return (0, _getExplicitRole["default"])(tag, attributes) || (0, _getImplicitRole["default"])(tag, attributes);
|
|
18
|
+
}
|
|
19
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = void 0;
|
|
7
|
+
var _hasown = _interopRequireDefault(require("hasown"));
|
|
8
|
+
var _arrayIncludes = _interopRequireDefault(require("array-includes"));
|
|
9
|
+
var _jsxAstUtils = require("jsx-ast-utils");
|
|
10
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
11
|
+
var getElementType = function getElementType(context) {
|
|
12
|
+
var _settings$jsxA11y, _settings$jsxA11y2, _settings$jsxA11y3;
|
|
13
|
+
var settings = context.settings;
|
|
14
|
+
var polymorphicPropName = (_settings$jsxA11y = settings['jsx-a11y']) === null || _settings$jsxA11y === void 0 ? void 0 : _settings$jsxA11y.polymorphicPropName;
|
|
15
|
+
var polymorphicAllowList = (_settings$jsxA11y2 = settings['jsx-a11y']) === null || _settings$jsxA11y2 === void 0 ? void 0 : _settings$jsxA11y2.polymorphicAllowList;
|
|
16
|
+
var componentMap = (_settings$jsxA11y3 = settings['jsx-a11y']) === null || _settings$jsxA11y3 === void 0 ? void 0 : _settings$jsxA11y3.components;
|
|
17
|
+
return function (node) {
|
|
18
|
+
var polymorphicProp = polymorphicPropName ? (0, _jsxAstUtils.getLiteralPropValue)((0, _jsxAstUtils.getProp)(node.attributes, polymorphicPropName)) : undefined;
|
|
19
|
+
var rawType = (0, _jsxAstUtils.elementType)(node);
|
|
20
|
+
if (polymorphicProp && (!polymorphicAllowList || (0, _arrayIncludes["default"])(polymorphicAllowList, rawType))) {
|
|
21
|
+
rawType = polymorphicProp;
|
|
22
|
+
}
|
|
23
|
+
if (!componentMap) {
|
|
24
|
+
return rawType;
|
|
25
|
+
}
|
|
26
|
+
return (0, _hasown["default"])(componentMap, rawType) ? componentMap[rawType] : rawType;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
var _default = exports["default"] = getElementType;
|
|
30
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = getExplicitRole;
|
|
7
|
+
var _ariaQuery = require("aria-query");
|
|
8
|
+
var _jsxAstUtils = require("jsx-ast-utils");
|
|
9
|
+
/**
|
|
10
|
+
* Returns an element's computed role, which is
|
|
11
|
+
*
|
|
12
|
+
* 1. The valid value of its explicit role attribute; or
|
|
13
|
+
* 2. The implicit value of its tag.
|
|
14
|
+
*/
|
|
15
|
+
function getExplicitRole(tag, attributes) {
|
|
16
|
+
var explicitRole = function toLowerCase(role) {
|
|
17
|
+
if (typeof role === 'string') {
|
|
18
|
+
return role.toLowerCase();
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}((0, _jsxAstUtils.getLiteralPropValue)((0, _jsxAstUtils.getProp)(attributes, 'role')));
|
|
22
|
+
if (_ariaQuery.roles.has(explicitRole)) {
|
|
23
|
+
return explicitRole;
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = getImplicitRole;
|
|
7
|
+
var _ariaQuery = require("aria-query");
|
|
8
|
+
var _implicitRoles = _interopRequireDefault(require("./implicitRoles"));
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
10
|
+
/**
|
|
11
|
+
* Returns an element's implicit role given its attributes and type.
|
|
12
|
+
* Some elements only have an implicit role when certain props are defined.
|
|
13
|
+
*/
|
|
14
|
+
function getImplicitRole(type, attributes) {
|
|
15
|
+
var implicitRole;
|
|
16
|
+
if (_implicitRoles["default"][type]) {
|
|
17
|
+
implicitRole = _implicitRoles["default"][type](attributes);
|
|
18
|
+
}
|
|
19
|
+
if (_ariaQuery.roles.has(implicitRole)) {
|
|
20
|
+
return implicitRole;
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = getSuggestion;
|
|
7
|
+
var _damerauLevenshtein = _interopRequireDefault(require("damerau-levenshtein"));
|
|
8
|
+
var _object = _interopRequireDefault(require("object.fromentries"));
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
10
|
+
// Minimum edit distance to be considered a good suggestion.
|
|
11
|
+
var THRESHOLD = 2;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Returns an array of suggestions given a word and a dictionary and limit of suggestions
|
|
15
|
+
* to return.
|
|
16
|
+
*/
|
|
17
|
+
function getSuggestion(word) {
|
|
18
|
+
var dictionary = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
19
|
+
var limit = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 2;
|
|
20
|
+
var distances = (0, _object["default"])(dictionary.map(function (dictionaryWord) {
|
|
21
|
+
var distance = (0, _damerauLevenshtein["default"])(word.toUpperCase(), dictionaryWord.toUpperCase());
|
|
22
|
+
var steps = distance.steps;
|
|
23
|
+
return [dictionaryWord, steps];
|
|
24
|
+
}));
|
|
25
|
+
return Object.keys(distances).filter(function (suggestion) {
|
|
26
|
+
return distances[suggestion] <= THRESHOLD;
|
|
27
|
+
}).sort(function (a, b) {
|
|
28
|
+
return distances[a] - distances[b];
|
|
29
|
+
}) // Sort by distance
|
|
30
|
+
.slice(0, limit);
|
|
31
|
+
}
|
|
32
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = getTabIndex;
|
|
7
|
+
var _jsxAstUtils = require("jsx-ast-utils");
|
|
8
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
9
|
+
/**
|
|
10
|
+
* Returns the tabIndex value.
|
|
11
|
+
*/
|
|
12
|
+
function getTabIndex(tabIndex) {
|
|
13
|
+
var literalValue = (0, _jsxAstUtils.getLiteralPropValue)(tabIndex);
|
|
14
|
+
|
|
15
|
+
// String and number values.
|
|
16
|
+
if (['string', 'number'].indexOf(_typeof(literalValue)) > -1) {
|
|
17
|
+
// Empty string will convert to zero, so check for it explicity.
|
|
18
|
+
if (typeof literalValue === 'string' && literalValue.length === 0) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
var value = Number(literalValue);
|
|
22
|
+
if (Number.isNaN(value)) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
return Number.isInteger(value) ? value : undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Booleans are not valid values, return undefined.
|
|
29
|
+
if (literalValue === true || literalValue === false) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
return (0, _jsxAstUtils.getPropValue)(tabIndex);
|
|
33
|
+
}
|
|
34
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = hasAccessibleChild;
|
|
7
|
+
var _jsxAstUtils = require("jsx-ast-utils");
|
|
8
|
+
var _isHiddenFromScreenReader = _interopRequireDefault(require("./isHiddenFromScreenReader"));
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
10
|
+
function hasAccessibleChild(node, elementType) {
|
|
11
|
+
return node.children.some(function (child) {
|
|
12
|
+
switch (child.type) {
|
|
13
|
+
case 'Literal':
|
|
14
|
+
return !!child.value;
|
|
15
|
+
// $FlowFixMe JSXText is missing in ast-types-flow
|
|
16
|
+
case 'JSXText':
|
|
17
|
+
return !!child.value;
|
|
18
|
+
case 'JSXElement':
|
|
19
|
+
return !(0, _isHiddenFromScreenReader["default"])(elementType(child.openingElement), child.openingElement.attributes);
|
|
20
|
+
case 'JSXExpressionContainer':
|
|
21
|
+
if (child.expression.type === 'Identifier') {
|
|
22
|
+
return child.expression.name !== 'undefined';
|
|
23
|
+
}
|
|
24
|
+
return true;
|
|
25
|
+
default:
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}) || (0, _jsxAstUtils.hasAnyProp)(node.openingElement.attributes, ['dangerouslySetInnerHTML', 'children']);
|
|
29
|
+
}
|
|
30
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = getImplicitRoleForAnchor;
|
|
7
|
+
var _jsxAstUtils = require("jsx-ast-utils");
|
|
8
|
+
/**
|
|
9
|
+
* Returns the implicit role for an anchor tag.
|
|
10
|
+
*/
|
|
11
|
+
function getImplicitRoleForAnchor(attributes) {
|
|
12
|
+
if ((0, _jsxAstUtils.getProp)(attributes, 'href')) {
|
|
13
|
+
return 'link';
|
|
14
|
+
}
|
|
15
|
+
return '';
|
|
16
|
+
}
|
|
17
|
+
module.exports = exports.default;
|