@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,23 @@
|
|
|
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 abstractRoles = new Set(_ariaQuery.roles.keys().filter(function (role) {
|
|
10
|
+
return _ariaQuery.roles.get(role)["abstract"];
|
|
11
|
+
}));
|
|
12
|
+
var DOMElements = new Set(_ariaQuery.dom.keys());
|
|
13
|
+
var isAbstractRole = function isAbstractRole(tagName, attributes) {
|
|
14
|
+
// Do not test higher level JSX components, as we do not know what
|
|
15
|
+
// low-level DOM element this maps to.
|
|
16
|
+
if (!DOMElements.has(tagName)) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
var role = (0, _jsxAstUtils.getLiteralPropValue)((0, _jsxAstUtils.getProp)(attributes, 'role'));
|
|
20
|
+
return abstractRoles.has(role);
|
|
21
|
+
};
|
|
22
|
+
var _default = exports["default"] = isAbstractRole;
|
|
23
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = isContentEditable;
|
|
7
|
+
var _jsxAstUtils = require("jsx-ast-utils");
|
|
8
|
+
function isContentEditable(tagName, attributes) {
|
|
9
|
+
var _prop$value;
|
|
10
|
+
var prop = (0, _jsxAstUtils.getProp)(attributes, 'contentEditable');
|
|
11
|
+
return (prop === null || prop === void 0 ? void 0 : (_prop$value = prop.value) === null || _prop$value === void 0 ? void 0 : _prop$value.raw) === '"true"';
|
|
12
|
+
}
|
|
13
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,15 @@
|
|
|
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
|
+
/**
|
|
9
|
+
* Returns boolean indicating whether the given element is a DOM element.
|
|
10
|
+
*/
|
|
11
|
+
var isDOMElement = function isDOMElement(tagName) {
|
|
12
|
+
return _ariaQuery.dom.has(tagName);
|
|
13
|
+
};
|
|
14
|
+
var _default = exports["default"] = isDOMElement;
|
|
15
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,23 @@
|
|
|
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 isDisabledElement = function isDisabledElement(attributes) {
|
|
9
|
+
var disabledAttr = (0, _jsxAstUtils.getProp)(attributes, 'disabled');
|
|
10
|
+
var disabledAttrValue = (0, _jsxAstUtils.getPropValue)(disabledAttr);
|
|
11
|
+
var isHTML5Disabled = disabledAttr && disabledAttrValue !== undefined;
|
|
12
|
+
if (isHTML5Disabled) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
var ariaDisabledAttr = (0, _jsxAstUtils.getProp)(attributes, 'aria-disabled');
|
|
16
|
+
var ariaDisabledAttrValue = (0, _jsxAstUtils.getLiteralPropValue)(ariaDisabledAttr);
|
|
17
|
+
if (ariaDisabledAttr && ariaDisabledAttrValue !== undefined && ariaDisabledAttrValue === true) {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
return false;
|
|
21
|
+
};
|
|
22
|
+
var _default = exports["default"] = isDisabledElement;
|
|
23
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,23 @@
|
|
|
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 _getTabIndex = _interopRequireDefault(require("./getTabIndex"));
|
|
9
|
+
var _isInteractiveElement = _interopRequireDefault(require("./isInteractiveElement"));
|
|
10
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
11
|
+
/**
|
|
12
|
+
* Returns boolean indicating whether an element appears in tab focus.
|
|
13
|
+
* Identifies an element as focusable if it is an interactive element, or an element with a tabIndex greater than or equal to 0.
|
|
14
|
+
*/
|
|
15
|
+
function isFocusable(type, attributes) {
|
|
16
|
+
var tabIndex = (0, _getTabIndex["default"])((0, _jsxAstUtils.getProp)(attributes, 'tabIndex'));
|
|
17
|
+
if ((0, _isInteractiveElement["default"])(type, attributes)) {
|
|
18
|
+
return tabIndex === undefined || tabIndex >= 0;
|
|
19
|
+
}
|
|
20
|
+
return tabIndex >= 0;
|
|
21
|
+
}
|
|
22
|
+
var _default = exports["default"] = isFocusable;
|
|
23
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,26 @@
|
|
|
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 boolean indicating that the aria-hidden prop
|
|
10
|
+
* is present or the value is true. Will also return true if
|
|
11
|
+
* there is an input with type='hidden'.
|
|
12
|
+
*
|
|
13
|
+
* <div aria-hidden /> is equivalent to the DOM as <div aria-hidden=true />.
|
|
14
|
+
*/
|
|
15
|
+
var isHiddenFromScreenReader = function isHiddenFromScreenReader(type, attributes) {
|
|
16
|
+
if (type.toUpperCase() === 'INPUT') {
|
|
17
|
+
var hidden = (0, _jsxAstUtils.getLiteralPropValue)((0, _jsxAstUtils.getProp)(attributes, 'type'));
|
|
18
|
+
if (hidden && hidden.toUpperCase() === 'HIDDEN') {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
var ariaHidden = (0, _jsxAstUtils.getPropValue)((0, _jsxAstUtils.getProp)(attributes, 'aria-hidden'));
|
|
23
|
+
return ariaHidden === true;
|
|
24
|
+
};
|
|
25
|
+
var _default = exports["default"] = isHiddenFromScreenReader;
|
|
26
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,116 @@
|
|
|
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 _axobjectQuery = require("axobject-query");
|
|
9
|
+
var _arrayIncludes = _interopRequireDefault(require("array-includes"));
|
|
10
|
+
var _arrayPrototype = _interopRequireDefault(require("array.prototype.flatmap"));
|
|
11
|
+
var _attributesComparator = _interopRequireDefault(require("./attributesComparator"));
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
13
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
14
|
+
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."); }
|
|
15
|
+
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; } }
|
|
16
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
17
|
+
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
|
|
18
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
19
|
+
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; } }
|
|
20
|
+
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
|
|
21
|
+
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
|
|
22
|
+
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; }
|
|
23
|
+
var roleKeys = _ariaQuery.roles.keys();
|
|
24
|
+
var elementRoleEntries = _toConsumableArray(_ariaQuery.elementRoles);
|
|
25
|
+
var nonInteractiveRoles = new Set(roleKeys.filter(function (name) {
|
|
26
|
+
var role = _ariaQuery.roles.get(name);
|
|
27
|
+
return !role["abstract"]
|
|
28
|
+
// 'toolbar' does not descend from widget, but it does support
|
|
29
|
+
// aria-activedescendant, thus in practice we treat it as a widget.
|
|
30
|
+
&& name !== 'toolbar' && !role.superClass.some(function (classes) {
|
|
31
|
+
return (0, _arrayIncludes["default"])(classes, 'widget');
|
|
32
|
+
});
|
|
33
|
+
}).concat(
|
|
34
|
+
// The `progressbar` is descended from `widget`, but in practice, its
|
|
35
|
+
// value is always `readonly`, so we treat it as a non-interactive role.
|
|
36
|
+
'progressbar'));
|
|
37
|
+
var interactiveRoles = new Set(roleKeys.filter(function (name) {
|
|
38
|
+
var role = _ariaQuery.roles.get(name);
|
|
39
|
+
return !role["abstract"]
|
|
40
|
+
// The `progressbar` is descended from `widget`, but in practice, its
|
|
41
|
+
// value is always `readonly`, so we treat it as a non-interactive role.
|
|
42
|
+
&& name !== 'progressbar' && role.superClass.some(function (classes) {
|
|
43
|
+
return (0, _arrayIncludes["default"])(classes, 'widget');
|
|
44
|
+
});
|
|
45
|
+
}).concat(
|
|
46
|
+
// 'toolbar' does not descend from widget, but it does support
|
|
47
|
+
// aria-activedescendant, thus in practice we treat it as a widget.
|
|
48
|
+
'toolbar'));
|
|
49
|
+
var interactiveElementRoleSchemas = (0, _arrayPrototype["default"])(elementRoleEntries, function (_ref) {
|
|
50
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
51
|
+
elementSchema = _ref2[0],
|
|
52
|
+
rolesArr = _ref2[1];
|
|
53
|
+
return rolesArr.some(function (role) {
|
|
54
|
+
return interactiveRoles.has(role);
|
|
55
|
+
}) ? [elementSchema] : [];
|
|
56
|
+
});
|
|
57
|
+
var nonInteractiveElementRoleSchemas = (0, _arrayPrototype["default"])(elementRoleEntries, function (_ref3) {
|
|
58
|
+
var _ref4 = _slicedToArray(_ref3, 2),
|
|
59
|
+
elementSchema = _ref4[0],
|
|
60
|
+
rolesArr = _ref4[1];
|
|
61
|
+
return rolesArr.every(function (role) {
|
|
62
|
+
return nonInteractiveRoles.has(role);
|
|
63
|
+
}) ? [elementSchema] : [];
|
|
64
|
+
});
|
|
65
|
+
var interactiveAXObjects = new Set(_axobjectQuery.AXObjects.keys().filter(function (name) {
|
|
66
|
+
return _axobjectQuery.AXObjects.get(name).type === 'widget';
|
|
67
|
+
}));
|
|
68
|
+
var interactiveElementAXObjectSchemas = (0, _arrayPrototype["default"])(_toConsumableArray(_axobjectQuery.elementAXObjects), function (_ref5) {
|
|
69
|
+
var _ref6 = _slicedToArray(_ref5, 2),
|
|
70
|
+
elementSchema = _ref6[0],
|
|
71
|
+
AXObjectsArr = _ref6[1];
|
|
72
|
+
return AXObjectsArr.every(function (role) {
|
|
73
|
+
return interactiveAXObjects.has(role);
|
|
74
|
+
}) ? [elementSchema] : [];
|
|
75
|
+
});
|
|
76
|
+
function checkIsInteractiveElement(tagName, attributes) {
|
|
77
|
+
function elementSchemaMatcher(elementSchema) {
|
|
78
|
+
return tagName === elementSchema.name && (0, _attributesComparator["default"])(elementSchema.attributes, attributes);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Check in elementRoles for inherent interactive role associations for
|
|
82
|
+
// this element.
|
|
83
|
+
var isInherentInteractiveElement = interactiveElementRoleSchemas.some(elementSchemaMatcher);
|
|
84
|
+
if (isInherentInteractiveElement) {
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
// Check in elementRoles for inherent non-interactive role associations for
|
|
88
|
+
// this element.
|
|
89
|
+
var isInherentNonInteractiveElement = nonInteractiveElementRoleSchemas.some(elementSchemaMatcher);
|
|
90
|
+
if (isInherentNonInteractiveElement) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
// Check in elementAXObjects for AX Tree associations for this element.
|
|
94
|
+
var isInteractiveAXElement = interactiveElementAXObjectSchemas.some(elementSchemaMatcher);
|
|
95
|
+
if (isInteractiveAXElement) {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Returns boolean indicating whether the given element is
|
|
103
|
+
* interactive on the DOM or not. Usually used when an element
|
|
104
|
+
* has a dynamic handler on it and we need to discern whether or not
|
|
105
|
+
* it's intention is to be interacted with on the DOM.
|
|
106
|
+
*/
|
|
107
|
+
var isInteractiveElement = function isInteractiveElement(tagName, attributes) {
|
|
108
|
+
// Do not test higher level JSX components, as we do not know what
|
|
109
|
+
// low-level DOM element this maps to.
|
|
110
|
+
if (!_ariaQuery.dom.has(tagName)) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
return checkIsInteractiveElement(tagName, attributes);
|
|
114
|
+
};
|
|
115
|
+
var _default = exports["default"] = isInteractiveElement;
|
|
116
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,54 @@
|
|
|
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 _arrayIncludes = _interopRequireDefault(require("array-includes"));
|
|
10
|
+
var _arrayPrototype = _interopRequireDefault(require("array.prototype.flatmap"));
|
|
11
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
12
|
+
var roles = _ariaQuery.roles.keys();
|
|
13
|
+
var interactiveRoles = roles.filter(function (name) {
|
|
14
|
+
return !_ariaQuery.roles.get(name)["abstract"] && _ariaQuery.roles.get(name).superClass.some(function (klasses) {
|
|
15
|
+
return (0, _arrayIncludes["default"])(klasses, 'widget');
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// 'toolbar' does not descend from widget, but it does support
|
|
20
|
+
// aria-activedescendant, thus in practice we treat it as a widget.
|
|
21
|
+
interactiveRoles.push('toolbar');
|
|
22
|
+
/**
|
|
23
|
+
* Returns boolean indicating whether the given element has a role
|
|
24
|
+
* that is associated with an interactive component. Used when an element
|
|
25
|
+
* has a dynamic handler on it and we need to discern whether or not
|
|
26
|
+
* its intention is to be interacted with in the DOM.
|
|
27
|
+
*
|
|
28
|
+
* isInteractiveRole is a Logical Disjunction:
|
|
29
|
+
* https://en.wikipedia.org/wiki/Logical_disjunction
|
|
30
|
+
* The JSX element does not have a tagName or it has a tagName and a role
|
|
31
|
+
* attribute with a value in the set of non-interactive roles.
|
|
32
|
+
*/
|
|
33
|
+
var isInteractiveRole = function isInteractiveRole(tagName, attributes) {
|
|
34
|
+
var value = (0, _jsxAstUtils.getLiteralPropValue)((0, _jsxAstUtils.getProp)(attributes, 'role'));
|
|
35
|
+
|
|
36
|
+
// If value is undefined, then the role attribute will be dropped in the DOM.
|
|
37
|
+
// If value is null, then getLiteralAttributeValue is telling us that the
|
|
38
|
+
// value isn't in the form of a literal
|
|
39
|
+
if (value === undefined || value === null) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
var isInteractive = false;
|
|
43
|
+
var normalizedValues = String(value).toLowerCase().split(' ');
|
|
44
|
+
var validRoles = (0, _arrayPrototype["default"])(normalizedValues, function (name) {
|
|
45
|
+
return (0, _arrayIncludes["default"])(roles, name) ? [name] : [];
|
|
46
|
+
});
|
|
47
|
+
if (validRoles.length > 0) {
|
|
48
|
+
// The first role value is a series takes precedence.
|
|
49
|
+
isInteractive = (0, _arrayIncludes["default"])(interactiveRoles, validRoles[0]);
|
|
50
|
+
}
|
|
51
|
+
return isInteractive;
|
|
52
|
+
};
|
|
53
|
+
var _default = exports["default"] = isInteractiveRole;
|
|
54
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,131 @@
|
|
|
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 _axobjectQuery = require("axobject-query");
|
|
9
|
+
var _arrayIncludes = _interopRequireDefault(require("array-includes"));
|
|
10
|
+
var _arrayPrototype = _interopRequireDefault(require("array.prototype.flatmap"));
|
|
11
|
+
var _attributesComparator = _interopRequireDefault(require("./attributesComparator"));
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
13
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
14
|
+
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."); }
|
|
15
|
+
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; } }
|
|
16
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
17
|
+
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
|
|
18
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
19
|
+
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; } }
|
|
20
|
+
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
|
|
21
|
+
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
|
|
22
|
+
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; }
|
|
23
|
+
var roleKeys = _ariaQuery.roles.keys();
|
|
24
|
+
var elementRoleEntries = _toConsumableArray(_ariaQuery.elementRoles);
|
|
25
|
+
var nonInteractiveRoles = new Set(roleKeys.filter(function (name) {
|
|
26
|
+
var role = _ariaQuery.roles.get(name);
|
|
27
|
+
return !role["abstract"]
|
|
28
|
+
// 'toolbar' does not descend from widget, but it does support
|
|
29
|
+
// aria-activedescendant, thus in practice we treat it as a widget.
|
|
30
|
+
&& name !== 'toolbar'
|
|
31
|
+
// This role is meant to have no semantic value.
|
|
32
|
+
// @see https://www.w3.org/TR/wai-aria-1.2/#generic
|
|
33
|
+
&& name !== 'generic' && !role.superClass.some(function (classes) {
|
|
34
|
+
return (0, _arrayIncludes["default"])(classes, 'widget');
|
|
35
|
+
});
|
|
36
|
+
}).concat(
|
|
37
|
+
// The `progressbar` is descended from `widget`, but in practice, its
|
|
38
|
+
// value is always `readonly`, so we treat it as a non-interactive role.
|
|
39
|
+
'progressbar'));
|
|
40
|
+
var interactiveRoles = new Set(roleKeys.filter(function (name) {
|
|
41
|
+
var role = _ariaQuery.roles.get(name);
|
|
42
|
+
return !role["abstract"]
|
|
43
|
+
// The `progressbar` is descended from `widget`, but in practice, its
|
|
44
|
+
// value is always `readonly`, so we treat it as a non-interactive role.
|
|
45
|
+
&& name !== 'progressbar'
|
|
46
|
+
// This role is meant to have no semantic value.
|
|
47
|
+
// @see https://www.w3.org/TR/wai-aria-1.2/#generic
|
|
48
|
+
&& name !== 'generic' && role.superClass.some(function (classes) {
|
|
49
|
+
return (0, _arrayIncludes["default"])(classes, 'widget');
|
|
50
|
+
});
|
|
51
|
+
}).concat(
|
|
52
|
+
// 'toolbar' does not descend from widget, but it does support
|
|
53
|
+
// aria-activedescendant, thus in practice we treat it as a widget.
|
|
54
|
+
'toolbar'));
|
|
55
|
+
var interactiveElementRoleSchemas = (0, _arrayPrototype["default"])(elementRoleEntries, function (_ref) {
|
|
56
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
57
|
+
elementSchema = _ref2[0],
|
|
58
|
+
rolesArr = _ref2[1];
|
|
59
|
+
return rolesArr.some(function (role) {
|
|
60
|
+
return interactiveRoles.has(role);
|
|
61
|
+
}) ? [elementSchema] : [];
|
|
62
|
+
});
|
|
63
|
+
var nonInteractiveElementRoleSchemas = (0, _arrayPrototype["default"])(elementRoleEntries, function (_ref3) {
|
|
64
|
+
var _ref4 = _slicedToArray(_ref3, 2),
|
|
65
|
+
elementSchema = _ref4[0],
|
|
66
|
+
rolesArr = _ref4[1];
|
|
67
|
+
return rolesArr.every(function (role) {
|
|
68
|
+
return nonInteractiveRoles.has(role);
|
|
69
|
+
}) ? [elementSchema] : [];
|
|
70
|
+
});
|
|
71
|
+
var nonInteractiveAXObjects = new Set(_axobjectQuery.AXObjects.keys().filter(function (name) {
|
|
72
|
+
return (0, _arrayIncludes["default"])(['window', 'structure'], _axobjectQuery.AXObjects.get(name).type);
|
|
73
|
+
}));
|
|
74
|
+
var nonInteractiveElementAXObjectSchemas = (0, _arrayPrototype["default"])(_toConsumableArray(_axobjectQuery.elementAXObjects), function (_ref5) {
|
|
75
|
+
var _ref6 = _slicedToArray(_ref5, 2),
|
|
76
|
+
elementSchema = _ref6[0],
|
|
77
|
+
AXObjectsArr = _ref6[1];
|
|
78
|
+
return AXObjectsArr.every(function (role) {
|
|
79
|
+
return nonInteractiveAXObjects.has(role);
|
|
80
|
+
}) ? [elementSchema] : [];
|
|
81
|
+
});
|
|
82
|
+
function checkIsNonInteractiveElement(tagName, attributes) {
|
|
83
|
+
function elementSchemaMatcher(elementSchema) {
|
|
84
|
+
return tagName === elementSchema.name && tagName !== 'td' // TODO: investigate why this is needed
|
|
85
|
+
&& (0, _attributesComparator["default"])(elementSchema.attributes, attributes);
|
|
86
|
+
}
|
|
87
|
+
// Check in elementRoles for inherent non-interactive role associations for
|
|
88
|
+
// this element.
|
|
89
|
+
var isInherentNonInteractiveElement = nonInteractiveElementRoleSchemas.some(elementSchemaMatcher);
|
|
90
|
+
if (isInherentNonInteractiveElement) {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
// Check in elementRoles for inherent interactive role associations for
|
|
94
|
+
// this element.
|
|
95
|
+
var isInherentInteractiveElement = interactiveElementRoleSchemas.some(elementSchemaMatcher);
|
|
96
|
+
if (isInherentInteractiveElement) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
// Check in elementAXObjects for AX Tree associations for this element.
|
|
100
|
+
var isNonInteractiveAXElement = nonInteractiveElementAXObjectSchemas.some(elementSchemaMatcher);
|
|
101
|
+
if (isNonInteractiveAXElement) {
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Returns boolean indicating whether the given element is a non-interactive
|
|
109
|
+
* element. If the element has either a non-interactive role assigned or it
|
|
110
|
+
* is an element with an inherently non-interactive role, then this utility
|
|
111
|
+
* returns true. Elements that lack either an explicitly assigned role or
|
|
112
|
+
* an inherent role are not considered. For those, this utility returns false
|
|
113
|
+
* because a positive determination of interactiveness cannot be determined.
|
|
114
|
+
*/
|
|
115
|
+
var isNonInteractiveElement = function isNonInteractiveElement(tagName, attributes) {
|
|
116
|
+
// Do not test higher level JSX components, as we do not know what
|
|
117
|
+
// low-level DOM element this maps to.
|
|
118
|
+
if (!_ariaQuery.dom.has(tagName)) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
// <header> elements do not technically have semantics, unless the
|
|
122
|
+
// element is a direct descendant of <body>, and this plugin cannot
|
|
123
|
+
// reliably test that.
|
|
124
|
+
// @see https://www.w3.org/TR/wai-aria-practices/examples/landmarks/banner.html
|
|
125
|
+
if (tagName === 'header') {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
return checkIsNonInteractiveElement(tagName, attributes);
|
|
129
|
+
};
|
|
130
|
+
var _default = exports["default"] = isNonInteractiveElement;
|
|
131
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,55 @@
|
|
|
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 _arrayIncludes = _interopRequireDefault(require("array-includes"));
|
|
10
|
+
var _arrayPrototype = _interopRequireDefault(require("array.prototype.flatmap"));
|
|
11
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
12
|
+
var nonInteractiveRoles = _ariaQuery.roles.keys().filter(function (name) {
|
|
13
|
+
return !_ariaQuery.roles.get(name)["abstract"] && !_ariaQuery.roles.get(name).superClass.some(function (klasses) {
|
|
14
|
+
return (0, _arrayIncludes["default"])(klasses, 'widget');
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Returns boolean indicating whether the given element has a role
|
|
20
|
+
* that is associated with a non-interactive component. Non-interactive roles
|
|
21
|
+
* include `listitem`, `article`, or `dialog`. These are roles that indicate
|
|
22
|
+
* for the most part containers.
|
|
23
|
+
*
|
|
24
|
+
* Elements with these roles should not respond or handle user interactions.
|
|
25
|
+
* For example, an `onClick` handler should not be assigned to an element with
|
|
26
|
+
* the role `listitem`. An element inside the `listitem`, like a button or a
|
|
27
|
+
* link, should handle the click.
|
|
28
|
+
*
|
|
29
|
+
* This utility returns true for elements that are assigned a non-interactive
|
|
30
|
+
* role. It will return false for elements that do not have a role. So whereas
|
|
31
|
+
* a `div` might be considered non-interactive, for the purpose of this utility,
|
|
32
|
+
* it is considered neither interactive nor non-interactive -- a determination
|
|
33
|
+
* cannot be made in this case and false is returned.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
var isNonInteractiveRole = function isNonInteractiveRole(tagName, attributes) {
|
|
37
|
+
// Do not test higher level JSX components, as we do not know what
|
|
38
|
+
// low-level DOM element this maps to.
|
|
39
|
+
if (!_ariaQuery.dom.has(tagName)) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
var role = (0, _jsxAstUtils.getLiteralPropValue)((0, _jsxAstUtils.getProp)(attributes, 'role'));
|
|
43
|
+
var isNonInteractive = false;
|
|
44
|
+
var normalizedValues = String(role).toLowerCase().split(' ');
|
|
45
|
+
var validRoles = (0, _arrayPrototype["default"])(normalizedValues, function (name) {
|
|
46
|
+
return _ariaQuery.roles.has(name) ? [name] : [];
|
|
47
|
+
});
|
|
48
|
+
if (validRoles.length > 0) {
|
|
49
|
+
// The first role value is a series takes precedence.
|
|
50
|
+
isNonInteractive = (0, _arrayIncludes["default"])(nonInteractiveRoles, validRoles[0]);
|
|
51
|
+
}
|
|
52
|
+
return isNonInteractive;
|
|
53
|
+
};
|
|
54
|
+
var _default = exports["default"] = isNonInteractiveRole;
|
|
55
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,29 @@
|
|
|
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 boolean indicating whether the given element has been specified with
|
|
10
|
+
* an AST node with a non-literal type.
|
|
11
|
+
*
|
|
12
|
+
* Returns true if the elements has a role and its value is not of a type Literal.
|
|
13
|
+
* Otherwise returns false.
|
|
14
|
+
*/
|
|
15
|
+
var isNonLiteralProperty = function isNonLiteralProperty(attributes, propName) {
|
|
16
|
+
var prop = (0, _jsxAstUtils.getProp)(attributes, propName);
|
|
17
|
+
if (!prop) return false;
|
|
18
|
+
var propValue = prop.value;
|
|
19
|
+
if (!propValue) return false;
|
|
20
|
+
if (propValue.type === 'Literal') return false;
|
|
21
|
+
if (propValue.type === 'JSXExpressionContainer') {
|
|
22
|
+
var expression = propValue.expression;
|
|
23
|
+
if (expression.type === 'Identifier' && expression.name === 'undefined') return false;
|
|
24
|
+
if (expression.type === 'JSXText') return false;
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
};
|
|
28
|
+
var _default = exports["default"] = isNonLiteralProperty;
|
|
29
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,13 @@
|
|
|
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 presentationRoles = new Set(['presentation', 'none']);
|
|
9
|
+
var isPresentationRole = function isPresentationRole(tagName, attributes) {
|
|
10
|
+
return presentationRoles.has((0, _jsxAstUtils.getLiteralPropValue)((0, _jsxAstUtils.getProp)(attributes, 'role')));
|
|
11
|
+
};
|
|
12
|
+
var _default = exports["default"] = isPresentationRole;
|
|
13
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = void 0;
|
|
7
|
+
var _axobjectQuery = require("axobject-query");
|
|
8
|
+
var _jsxAstUtils = require("jsx-ast-utils");
|
|
9
|
+
var isSemanticRoleElement = function isSemanticRoleElement(elementType, attributes) {
|
|
10
|
+
var roleAttr = (0, _jsxAstUtils.getProp)(attributes, 'role');
|
|
11
|
+
var res = false;
|
|
12
|
+
var roleAttrValue = (0, _jsxAstUtils.getLiteralPropValue)(roleAttr);
|
|
13
|
+
_axobjectQuery.elementAXObjects.forEach(function (axObjects, concept) {
|
|
14
|
+
if (res) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (concept.name === elementType && (concept.attributes || []).every(function (cAttr) {
|
|
18
|
+
return attributes.some(function (attr) {
|
|
19
|
+
if (!attr.type || attr.type !== 'JSXAttribute') {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
var namesMatch = cAttr.name === (0, _jsxAstUtils.propName)(attr);
|
|
23
|
+
var valuesMatch;
|
|
24
|
+
if (cAttr.value !== undefined) {
|
|
25
|
+
valuesMatch = cAttr.value === (0, _jsxAstUtils.getLiteralPropValue)(attr);
|
|
26
|
+
}
|
|
27
|
+
if (!namesMatch) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
return namesMatch && valuesMatch !== undefined ? valuesMatch : true;
|
|
31
|
+
});
|
|
32
|
+
})) {
|
|
33
|
+
axObjects.forEach(function (name) {
|
|
34
|
+
if (res) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
var roles = _axobjectQuery.AXObjectRoles.get(name);
|
|
38
|
+
if (roles) {
|
|
39
|
+
roles.forEach(function (role) {
|
|
40
|
+
if (res === true) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (role.name === roleAttrValue) {
|
|
44
|
+
res = true;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
return res;
|
|
52
|
+
};
|
|
53
|
+
var _default = exports["default"] = isSemanticRoleElement;
|
|
54
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = mayContainChildComponent;
|
|
7
|
+
var _jsxAstUtils = require("jsx-ast-utils");
|
|
8
|
+
var _minimatch = _interopRequireDefault(require("minimatch"));
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
10
|
+
/**
|
|
11
|
+
* Returns true if it can positively determine that the element lacks an
|
|
12
|
+
* accessible label. If no determination is possible, it returns false. Treat
|
|
13
|
+
* false as an unknown value. The element might still have an accessible label,
|
|
14
|
+
* but this module cannot determine it positively.
|
|
15
|
+
*
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
function mayContainChildComponent(root, componentName) {
|
|
20
|
+
var maxDepth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
|
|
21
|
+
var elementType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _jsxAstUtils.elementType;
|
|
22
|
+
function traverseChildren(node, depth) {
|
|
23
|
+
// Bail when maxDepth is exceeded.
|
|
24
|
+
if (depth > maxDepth) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
if (node.children) {
|
|
28
|
+
/* $FlowFixMe */
|
|
29
|
+
for (var i = 0; i < node.children.length; i += 1) {
|
|
30
|
+
/* $FlowFixMe */
|
|
31
|
+
var childNode = node.children[i];
|
|
32
|
+
// Assume an expression container renders a label. It is the best we can
|
|
33
|
+
// do in this case.
|
|
34
|
+
if (childNode.type === 'JSXExpressionContainer') {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
// Check for components with the provided name.
|
|
38
|
+
if (childNode.type === 'JSXElement' && childNode.openingElement && (0, _minimatch["default"])(elementType(childNode.openingElement), componentName)) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
if (traverseChildren(childNode, depth + 1)) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return traverseChildren(root, 1);
|
|
49
|
+
}
|
|
50
|
+
module.exports = exports.default;
|