Skip to content

Commit 52de824

Browse files
committedAug 13, 2023
[Refactor] use es-iterator-helpers
- also, maximally avoid iterator spreads
1 parent 9a8edde commit 52de824

22 files changed

+94
-90
lines changed
 

‎__tests__/src/rules/aria-unsupported-elements-test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ const invalidAriaValidityTests = domElements
6969
}));
7070

7171
ruleTester.run('aria-unsupported-elements', rule, {
72-
valid: parsers.all([].concat(roleValidityTests.concat(ariaValidityTests))).map(parserOptionsMapper),
73-
invalid: parsers.all([].concat(invalidRoleValidityTests.concat(invalidAriaValidityTests)))
72+
valid: parsers.all([].concat(roleValidityTests, ariaValidityTests)).map(parserOptionsMapper),
73+
invalid: parsers.all([].concat(invalidRoleValidityTests, invalidAriaValidityTests))
7474
.map(parserOptionsMapper),
7575
});

‎__tests__/src/rules/role-has-required-aria-props-test.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010

1111
import { roles } from 'aria-query';
1212
import { RuleTester } from 'eslint';
13+
import iterFrom from 'es-iterator-helpers/Iterator.from';
14+
import map from 'es-iterator-helpers/Iterator.prototype.map';
15+
import toArray from 'es-iterator-helpers/Iterator.prototype.toArray';
16+
1317
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
1418
import parsers from '../../__util__/helpers/parsers';
1519
import rule from '../../../src/rules/role-has-required-aria-props';
@@ -38,7 +42,7 @@ const componentsSettings = {
3842
};
3943

4044
// Create basic test cases using all valid role types.
41-
const basicValidityTests = [...roles.keys()].map((role) => {
45+
const basicValidityTests = toArray(map(iterFrom(roles.keys()), (role) => {
4246
const {
4347
requiredProps: requiredPropKeyValues,
4448
} = roles.get(role);
@@ -48,7 +52,7 @@ const basicValidityTests = [...roles.keys()].map((role) => {
4852
return {
4953
code: `<div role="${role.toLowerCase()}" ${propChain} />`,
5054
};
51-
});
55+
}));
5256

5357
ruleTester.run('role-has-required-aria-props', rule, {
5458
valid: parsers.all([].concat(

‎__tests__/src/rules/role-supports-aria-props-test.js

+20-18
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ import {
1414
import { RuleTester } from 'eslint';
1515
import { version as eslintVersion } from 'eslint/package.json';
1616
import semver from 'semver';
17+
import iterFrom from 'es-iterator-helpers/Iterator.from';
18+
import filter from 'es-iterator-helpers/Iterator.prototype.filter';
19+
import map from 'es-iterator-helpers/Iterator.prototype.map';
20+
import toArray from 'es-iterator-helpers/Iterator.prototype.toArray';
21+
1722
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
1823
import parsers from '../../__util__/helpers/parsers';
1924
import rule from '../../../src/rules/role-supports-aria-props';
@@ -26,8 +31,7 @@ const ruleTester = new RuleTester();
2631

2732
const generateErrorMessage = (attr, role, tag, isImplicit) => {
2833
if (isImplicit) {
29-
return `The attribute ${attr} is not supported by the role ${role}. \
30-
This role is implicit on the element ${tag}.`;
34+
return `The attribute ${attr} is not supported by the role ${role}. This role is implicit on the element ${tag}.`;
3135
}
3236

3337
return `The attribute ${attr} is not supported by the role ${role}.`;
@@ -46,30 +50,28 @@ const componentsSettings = {
4650
},
4751
};
4852

49-
const nonAbstractRoles = [...roles.keys()].filter((role) => roles.get(role).abstract === false);
53+
const nonAbstractRoles = toArray(filter(iterFrom(roles.keys()), (role) => roles.get(role).abstract === false));
5054

5155
const createTests = (rolesNames) => rolesNames.reduce((tests, role) => {
5256
const {
5357
props: propKeyValues,
5458
} = roles.get(role);
5559
const validPropsForRole = Object.keys(propKeyValues);
56-
const invalidPropsForRole = [...aria.keys()]
57-
.map((attribute) => attribute.toLowerCase())
58-
.filter((attribute) => validPropsForRole.indexOf(attribute) === -1);
60+
const invalidPropsForRole = filter(
61+
map(iterFrom(aria.keys()), (attribute) => attribute.toLowerCase()),
62+
(attribute) => validPropsForRole.indexOf(attribute) === -1,
63+
);
5964
const normalRole = role.toLowerCase();
6065

61-
const allTests = [];
62-
63-
allTests[0] = tests[0].concat(validPropsForRole.map((prop) => ({
64-
code: `<div role="${normalRole}" ${prop.toLowerCase()} />`,
65-
})));
66-
67-
allTests[1] = tests[1].concat(invalidPropsForRole.map((prop) => ({
68-
code: `<div role="${normalRole}" ${prop.toLowerCase()} />`,
69-
errors: [errorMessage(prop.toLowerCase(), normalRole, 'div', false)],
70-
})));
71-
72-
return allTests;
66+
return [
67+
tests[0].concat(validPropsForRole.map((prop) => ({
68+
code: `<div role="${normalRole}" ${prop.toLowerCase()} />`,
69+
}))),
70+
tests[1].concat(toArray(map(invalidPropsForRole, (prop) => ({
71+
code: `<div role="${normalRole}" ${prop.toLowerCase()} />`,
72+
errors: [errorMessage(prop.toLowerCase(), normalRole, 'div', false)],
73+
})))),
74+
];
7375
}, [[], []]);
7476

7577
const [validTests, invalidTests] = createTests(nonAbstractRoles);

‎__tests__/src/util/isDOMElement-test.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@ import { elementType } from 'jsx-ast-utils';
44
import isDOMElement from '../../../src/util/isDOMElement';
55
import JSXElementMock from '../../../__mocks__/JSXElementMock';
66

7-
const domElements = [...dom.keys()];
8-
97
describe('isDOMElement', () => {
108
describe('DOM elements', () => {
11-
domElements.forEach((el) => {
9+
dom.forEach((_, el) => {
1210
it(`should identify ${el} as a DOM element`, () => {
1311
const element = JSXElementMock(el);
1412
expect(isDOMElement(elementType(element.openingElement)))

‎__tests__/src/util/isFocusable-test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock';
1010

1111
function mergeTabIndex(index, attributes) {
12-
return [...attributes, JSXAttributeMock('tabIndex', index)];
12+
return [].concat(attributes, JSXAttributeMock('tabIndex', index));
1313
}
1414

1515
describe('isFocusable', () => {

‎package.json

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
"axobject-query": "^3.2.1",
8484
"damerau-levenshtein": "^1.0.8",
8585
"emoji-regex": "^9.2.2",
86+
"es-iterator-helpers": "^1.0.15",
8687
"hasown": "^2.0.0",
8788
"jsx-ast-utils": "^3.3.5",
8889
"language-tags": "^1.0.9",

‎src/rules/aria-activedescendant-has-tabindex.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ const errorMessage = 'An element that manages focus with `aria-activedescendant`
1818

1919
const schema = generateObjSchema();
2020

21-
const domElements = [...dom.keys()];
22-
2321
export default {
2422
meta: {
2523
docs: {
@@ -42,7 +40,7 @@ export default {
4240
const type = elementType(node);
4341
// Do not test higher level JSX components, as we do not know what
4442
// low-level DOM element this maps to.
45-
if (domElements.indexOf(type) === -1) {
43+
if (!dom.has(type)) {
4644
return;
4745
}
4846
const tabIndex = getTabIndex(getProp(attributes, 'tabIndex'));

‎src/rules/aria-props.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export default {
4545
return;
4646
}
4747

48-
const isValid = ariaAttributes.indexOf(name) > -1;
48+
const isValid = aria.has(name);
4949

5050
if (isValid === false) {
5151
context.report({

‎src/rules/aria-role.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99

1010
import { dom, roles } from 'aria-query';
1111
import { getLiteralPropValue, propName } from 'jsx-ast-utils';
12+
import iterFrom from 'es-iterator-helpers/Iterator.from';
13+
import filter from 'es-iterator-helpers/Iterator.prototype.filter';
14+
1215
import getElementType from '../util/getElementType';
1316
import { generateObjSchema } from '../util/schemas';
1417

@@ -28,7 +31,7 @@ const schema = generateObjSchema({
2831
},
2932
});
3033

31-
const validRoles = new Set([...roles.keys()].filter((role) => roles.get(role).abstract === false));
34+
const validRoles = new Set(filter(iterFrom(roles.keys()), (role) => roles.get(role).abstract === false));
3235

3336
export default {
3437
meta: {

‎src/rules/aria-unsupported-elements.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export default {
4747
return;
4848
}
4949

50-
const invalidAttributes = [...aria.keys(), 'role'];
50+
const invalidAttributes = new Set([...aria.keys(), 'role']);
5151

5252
node.attributes.forEach((prop) => {
5353
if (prop.type === 'JSXSpreadAttribute') {
@@ -56,7 +56,7 @@ export default {
5656

5757
const name = propName(prop).toLowerCase();
5858

59-
if (invalidAttributes.indexOf(name) > -1) {
59+
if (invalidAttributes.has(name)) {
6060
context.report({
6161
node,
6262
message: errorMessage(name),

‎src/rules/click-events-have-key-events.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
import { dom } from 'aria-query';
1111
import { getProp, hasAnyProp } from 'jsx-ast-utils';
12-
import includes from 'array-includes';
1312
import { generateObjSchema } from '../util/schemas';
1413
import getElementType from '../util/getElementType';
1514
import isHiddenFromScreenReader from '../util/isHiddenFromScreenReader';
@@ -19,7 +18,6 @@ import isPresentationRole from '../util/isPresentationRole';
1918
const errorMessage = 'Visible, non-interactive elements with click handlers must have at least one keyboard listener.';
2019

2120
const schema = generateObjSchema();
22-
const domElements = [...dom.keys()];
2321

2422
export default {
2523
meta: {
@@ -42,7 +40,7 @@ export default {
4240
const type = elementType(node);
4341
const requiredProps = ['onkeydown', 'onkeyup', 'onkeypress'];
4442

45-
if (!includes(domElements, type)) {
43+
if (!dom.has(type)) {
4644
// Do not test higher level JSX components, as we do not know what
4745
// low-level DOM element this maps to.
4846
return;

‎src/rules/interactive-supports-focus.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ import getTabIndex from '../util/getTabIndex';
3636
// ----------------------------------------------------------------------------
3737

3838
const schema = generateObjSchema({
39+
// TODO: convert to use iterFilter and iterFrom
3940
tabbable: enumArraySchema([...roles.keys()].filter((name) => (
4041
!roles.get(name).abstract
4142
&& roles.get(name).superClass.some((klasses) => includes(klasses, 'widget'))
4243
))),
4344
});
44-
const domElements = [...dom.keys()];
4545

4646
const interactiveProps = [].concat(
4747
eventHandlersByType.mouse,
@@ -69,7 +69,7 @@ export default ({
6969
const hasInteractiveProps = hasAnyProp(attributes, interactiveProps);
7070
const hasTabindex = getTabIndex(getProp(attributes, 'tabIndex')) !== undefined;
7171

72-
if (!includes(domElements, type)) {
72+
if (!dom.has(type)) {
7373
// Do not test higher level JSX components, as we do not know what
7474
// low-level DOM element this maps to.
7575
return;

‎src/rules/no-interactive-element-to-noninteractive-role.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ import isPresentationRole from '../util/isPresentationRole';
2727

2828
const errorMessage = 'Interactive elements should not be assigned non-interactive roles.';
2929

30-
const domElements = [...dom.keys()];
31-
3230
export default ({
3331
meta: {
3432
docs: {
@@ -62,7 +60,7 @@ export default ({
6260
const type = elementType(node);
6361
const role = getLiteralPropValue(getProp(node.attributes, 'role'));
6462

65-
if (!includes(domElements, type)) {
63+
if (!dom.has(type)) {
6664
// Do not test higher level JSX components, as we do not know what
6765
// low-level DOM element this maps to.
6866
return;

‎src/rules/no-noninteractive-element-interactions.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import isPresentationRole from '../util/isPresentationRole';
3232

3333
const errorMessage = 'Non-interactive elements should not be assigned mouse or keyboard event listeners.';
3434

35-
const domElements = [...dom.keys()];
3635
const defaultInteractiveProps = [].concat(
3736
eventHandlersByType.focus,
3837
eventHandlersByType.image,
@@ -72,7 +71,7 @@ export default ({
7271
&& getPropValue(getProp(attributes, prop)) != null
7372
));
7473

75-
if (!includes(domElements, type)) {
74+
if (!dom.has(type)) {
7675
// Do not test higher level JSX components, as we do not know what
7776
// low-level DOM element this maps to.
7877
return;

‎src/rules/no-noninteractive-element-to-interactive-role.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ import isInteractiveRole from '../util/isInteractiveRole';
2525

2626
const errorMessage = 'Non-interactive elements should not be assigned interactive roles.';
2727

28-
const domElements = [...dom.keys()];
29-
3028
export default ({
3129
meta: {
3230
docs: {
@@ -60,7 +58,7 @@ export default ({
6058
const type = elementType(node);
6159
const role = getExplicitRole(type, node.attributes);
6260

63-
if (!includes(domElements, type)) {
61+
if (!dom.has(type)) {
6462
// Do not test higher level JSX components, as we do not know what
6563
// low-level DOM element this maps to.
6664
return;

‎src/rules/no-static-element-interactions.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import {
1616
hasProp,
1717
} from 'jsx-ast-utils';
1818
import type { JSXOpeningElement } from 'ast-types-flow';
19-
import includes from 'array-includes';
2019
import type { ESLintConfig, ESLintContext, ESLintVisitorSelectorConfig } from '../../flow/eslint';
2120
import { arraySchema, generateObjSchema } from '../util/schemas';
2221
import getElementType from '../util/getElementType';
@@ -31,7 +30,6 @@ import isPresentationRole from '../util/isPresentationRole';
3130

3231
const errorMessage = 'Avoid non-native interactive elements. If using native HTML is not possible, add an appropriate role and support for tabbing, mouse, keyboard, and touch inputs to an interactive content element.';
3332

34-
const domElements = [...dom.keys()];
3533
const defaultInteractiveProps = [].concat(
3634
eventHandlersByType.focus,
3735
eventHandlersByType.keyboard,
@@ -69,7 +67,7 @@ export default ({
6967
&& getPropValue(getProp(attributes, prop)) != null
7068
));
7169

72-
if (!includes(domElements, type)) {
70+
if (!dom.has(type)) {
7371
// Do not test higher level JSX components, as we do not know what
7472
// low-level DOM element this maps to.
7573
return;

‎src/rules/role-supports-aria-props.js

+6-5
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,16 @@ import {
1818
getPropValue,
1919
propName,
2020
} from 'jsx-ast-utils';
21+
import iterFrom from 'es-iterator-helpers/Iterator.from';
22+
import filter from 'es-iterator-helpers/Iterator.prototype.filter';
23+
2124
import { generateObjSchema } from '../util/schemas';
2225
import getElementType from '../util/getElementType';
2326
import getImplicitRole from '../util/getImplicitRole';
2427

2528
const errorMessage = (attr, role, tag, isImplicit) => {
2629
if (isImplicit) {
27-
return `The attribute ${attr} is not supported by the role ${role}. \
28-
This role is implicit on the element ${tag}.`;
30+
return `The attribute ${attr} is not supported by the role ${role}. This role is implicit on the element ${tag}.`;
2931
}
3032

3133
return `The attribute ${attr} is not supported by the role ${role}.`;
@@ -66,15 +68,14 @@ export default {
6668
const {
6769
props: propKeyValues,
6870
} = roles.get(roleValue);
69-
const invalidAriaPropsForRole = [...aria.keys()]
70-
.filter((attribute) => !(attribute in propKeyValues));
71+
const invalidAriaPropsForRole = new Set(filter(iterFrom(aria.keys()), (attribute) => !(attribute in propKeyValues)));
7172

7273
node.attributes.filter((prop) => (
7374
getPropValue(prop) != null // Ignore the attribute if its value is null or undefined.
7475
&& prop.type !== 'JSXSpreadAttribute' // Ignore the attribute if it's a spread.
7576
)).forEach((prop) => {
7677
const name = propName(prop);
77-
if (invalidAriaPropsForRole.indexOf(name) > -1) {
78+
if (invalidAriaPropsForRole.has(name)) {
7879
context.report({
7980
node,
8081
message: errorMessage(name, roleValue, type, isImplicit),

‎src/util/isAbstractRole.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@ import {
33
roles,
44
} from 'aria-query';
55
import { getProp, getLiteralPropValue } from 'jsx-ast-utils';
6+
import iterFrom from 'es-iterator-helpers/Iterator.from';
7+
import filter from 'es-iterator-helpers/Iterator.prototype.filter';
68

7-
const abstractRoles = new Set([...roles.keys()]
8-
.filter((role) => roles.get(role).abstract));
9+
const abstractRoles = new Set(filter(iterFrom(roles.keys()), (role) => roles.get(role).abstract));
910

10-
const DOMElements = [...dom.keys()];
11+
const DOMElements = new Set(dom.keys());
1112

1213
const isAbstractRole = (tagName, attributes) => {
1314
// Do not test higher level JSX components, as we do not know what
1415
// low-level DOM element this maps to.
15-
if (DOMElements.indexOf(tagName) === -1) {
16+
if (!DOMElements.has(tagName)) {
1617
return false;
1718
}
1819

‎src/util/isDOMElement.js

+1-4
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@
22
* @flow
33
*/
44
import { dom } from 'aria-query';
5-
import includes from 'array-includes';
6-
7-
const domElements = [...dom.keys()];
85

96
/**
107
* Returns boolean indicating whether the given element is a DOM element.
118
*/
129
const isDOMElement = (
1310
tagName: string,
14-
): boolean => includes(domElements, tagName);
11+
): boolean => dom.has(tagName);
1512

1613
export default isDOMElement;

‎src/util/isInteractiveElement.js

+18-12
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@ import {
1313
} from 'axobject-query';
1414
import includes from 'array-includes';
1515
import flatMap from 'array.prototype.flatmap';
16+
import iterFrom from 'es-iterator-helpers/Iterator.from';
17+
// import iterFlatMap from 'es-iterator-helpers/Iterator.prototype.flatMap';
18+
import filter from 'es-iterator-helpers/Iterator.prototype.filter';
19+
import some from 'es-iterator-helpers/Iterator.prototype.some';
20+
1621
import attributesComparator from './attributesComparator';
1722

18-
const domKeys = [...dom.keys()];
1923
const roleKeys = [...roles.keys()];
2024
const elementRoleEntries = [...elementRoles];
2125

@@ -51,22 +55,24 @@ const interactiveRoles = new Set(roleKeys
5155
'toolbar',
5256
));
5357

54-
const nonInteractiveElementRoleSchemas = flatMap(
58+
// TODO: convert to use iterFlatMap and iterFrom
59+
const interactiveElementRoleSchemas = flatMap(
5560
elementRoleEntries,
56-
([elementSchema, roleSet]) => ([...roleSet].every((role): boolean => nonInteractiveRoles.has(role)) ? [elementSchema] : []),
61+
([elementSchema, rolesArr]) => (rolesArr.some((role): boolean => interactiveRoles.has(role)) ? [elementSchema] : []),
5762
);
5863

59-
const interactiveElementRoleSchemas = flatMap(
64+
// TODO: convert to use iterFlatMap and iterFrom
65+
const nonInteractiveElementRoleSchemas = flatMap(
6066
elementRoleEntries,
61-
([elementSchema, roleSet]) => ([...roleSet].some((role): boolean => interactiveRoles.has(role)) ? [elementSchema] : []),
67+
([elementSchema, rolesArr]) => (rolesArr.every((role): boolean => nonInteractiveRoles.has(role)) ? [elementSchema] : []),
6268
);
6369

64-
const interactiveAXObjects = new Set([...AXObjects.keys()]
65-
.filter((name) => AXObjects.get(name).type === 'widget'));
70+
const interactiveAXObjects = new Set(filter(iterFrom(AXObjects.keys()), (name) => AXObjects.get(name).type === 'widget'));
6671

72+
// TODO: convert to use iterFlatMap and iterFrom
6773
const interactiveElementAXObjectSchemas = flatMap(
6874
[...elementAXObjects],
69-
([elementSchema, AXObjectSet]) => ([...AXObjectSet].every((role): boolean => interactiveAXObjects.has(role)) ? [elementSchema] : []),
75+
([elementSchema, AXObjectsArr]) => (AXObjectsArr.every((role): boolean => interactiveAXObjects.has(role)) ? [elementSchema] : []),
7076
);
7177

7278
function checkIsInteractiveElement(tagName, attributes): boolean {
@@ -78,18 +84,18 @@ function checkIsInteractiveElement(tagName, attributes): boolean {
7884
}
7985
// Check in elementRoles for inherent interactive role associations for
8086
// this element.
81-
const isInherentInteractiveElement = interactiveElementRoleSchemas.some(elementSchemaMatcher);
87+
const isInherentInteractiveElement = some(iterFrom(interactiveElementRoleSchemas), elementSchemaMatcher);
8288
if (isInherentInteractiveElement) {
8389
return true;
8490
}
8591
// Check in elementRoles for inherent non-interactive role associations for
8692
// this element.
87-
const isInherentNonInteractiveElement = nonInteractiveElementRoleSchemas.some(elementSchemaMatcher);
93+
const isInherentNonInteractiveElement = some(iterFrom(nonInteractiveElementRoleSchemas), elementSchemaMatcher);
8894
if (isInherentNonInteractiveElement) {
8995
return false;
9096
}
9197
// Check in elementAXObjects for AX Tree associations for this element.
92-
const isInteractiveAXElement = interactiveElementAXObjectSchemas.some(elementSchemaMatcher);
98+
const isInteractiveAXElement = some(iterFrom(interactiveElementAXObjectSchemas), elementSchemaMatcher);
9399
if (isInteractiveAXElement) {
94100
return true;
95101
}
@@ -109,7 +115,7 @@ const isInteractiveElement = (
109115
): boolean => {
110116
// Do not test higher level JSX components, as we do not know what
111117
// low-level DOM element this maps to.
112-
if (!includes(domKeys, tagName)) {
118+
if (!dom.has(tagName)) {
113119
return false;
114120
}
115121

‎src/util/isNonInteractiveElement.js

+16-13
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ import {
1414
import type { Node } from 'ast-types-flow';
1515
import includes from 'array-includes';
1616
import flatMap from 'array.prototype.flatmap';
17+
import iterFrom from 'es-iterator-helpers/Iterator.from';
18+
// import iterFlatMap from 'es-iterator-helpers/Iterator.prototype.flatMap';
19+
import filter from 'es-iterator-helpers/Iterator.prototype.filter';
20+
import some from 'es-iterator-helpers/Iterator.prototype.some';
1721

1822
import attributesComparator from './attributesComparator';
1923

@@ -62,22 +66,24 @@ const interactiveRoles = new Set(roleKeys
6266
'toolbar',
6367
));
6468

65-
const nonInteractiveElementRoleSchemas = flatMap(
69+
// TODO: convert to use iterFlatMap and iterFrom
70+
const interactiveElementRoleSchemas = flatMap(
6671
elementRoleEntries,
67-
([elementSchema, roleSet]) => ([...roleSet].every((role): boolean => nonInteractiveRoles.has(role)) ? [elementSchema] : []),
72+
([elementSchema, rolesArr]) => (rolesArr.some((role): boolean => interactiveRoles.has(role)) ? [elementSchema] : []),
6873
);
6974

70-
const interactiveElementRoleSchemas = flatMap(
75+
// TODO: convert to use iterFlatMap and iterFrom
76+
const nonInteractiveElementRoleSchemas = flatMap(
7177
elementRoleEntries,
72-
([elementSchema, roleSet]) => ([...roleSet].some((role): boolean => interactiveRoles.has(role)) ? [elementSchema] : []),
78+
([elementSchema, rolesArr]) => (rolesArr.every((role): boolean => nonInteractiveRoles.has(role)) ? [elementSchema] : []),
7379
);
7480

75-
const nonInteractiveAXObjects = new Set([...AXObjects.keys()]
76-
.filter((name) => includes(['window', 'structure'], AXObjects.get(name).type)));
81+
const nonInteractiveAXObjects = new Set(filter(iterFrom(AXObjects.keys()), (name) => includes(['window', 'structure'], AXObjects.get(name).type)));
7782

83+
// TODO: convert to use iterFlatMap and iterFrom
7884
const nonInteractiveElementAXObjectSchemas = flatMap(
7985
[...elementAXObjects],
80-
([elementSchema, AXObjectSet]) => ([...AXObjectSet].every((role): boolean => nonInteractiveAXObjects.has(role)) ? [elementSchema] : []),
86+
([elementSchema, AXObjectsArr]) => (AXObjectsArr.every((role): boolean => nonInteractiveAXObjects.has(role)) ? [elementSchema] : []),
8187
);
8288

8389
function checkIsNonInteractiveElement(tagName, attributes): boolean {
@@ -89,21 +95,18 @@ function checkIsNonInteractiveElement(tagName, attributes): boolean {
8995
}
9096
// Check in elementRoles for inherent non-interactive role associations for
9197
// this element.
92-
const isInherentNonInteractiveElement = nonInteractiveElementRoleSchemas
93-
.some(elementSchemaMatcher);
98+
const isInherentNonInteractiveElement = some(iterFrom(nonInteractiveElementRoleSchemas), elementSchemaMatcher);
9499
if (isInherentNonInteractiveElement) {
95100
return true;
96101
}
97102
// Check in elementRoles for inherent interactive role associations for
98103
// this element.
99-
const isInherentInteractiveElement = interactiveElementRoleSchemas
100-
.some(elementSchemaMatcher);
104+
const isInherentInteractiveElement = some(iterFrom(interactiveElementRoleSchemas), elementSchemaMatcher);
101105
if (isInherentInteractiveElement) {
102106
return false;
103107
}
104108
// Check in elementAXObjects for AX Tree associations for this element.
105-
const isNonInteractiveAXElement = nonInteractiveElementAXObjectSchemas
106-
.some(elementSchemaMatcher);
109+
const isNonInteractiveAXElement = some(iterFrom(nonInteractiveElementAXObjectSchemas), elementSchemaMatcher);
107110
if (isNonInteractiveAXElement) {
108111
return true;
109112
}

‎src/util/isNonInteractiveRole.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ import { getProp, getLiteralPropValue } from 'jsx-ast-utils';
1111
import includes from 'array-includes';
1212
import flatMap from 'array.prototype.flatmap';
1313

14-
const roles = [...rolesMap.keys()];
15-
const nonInteractiveRoles = roles.filter((name) => (
14+
const nonInteractiveRoles = [...rolesMap.keys()].filter((name) => (
1615
!rolesMap.get(name).abstract
1716
&& !rolesMap.get(name).superClass.some((klasses) => includes(klasses, 'widget'))
1817
));
@@ -51,7 +50,7 @@ const isNonInteractiveRole = (
5150
const normalizedValues = String(role).toLowerCase().split(' ');
5251
const validRoles = flatMap(
5352
normalizedValues,
54-
(name: string) => (includes(roles, name) ? [name] : []),
53+
(name: string) => (rolesMap.has(name) ? [name] : []),
5554
);
5655
if (validRoles.length > 0) {
5756
// The first role value is a series takes precedence.

0 commit comments

Comments
 (0)
Please sign in to comment.