Skip to content

Commit 60c487e

Browse files
authored
[new] - Add option to ignore non-DOM elements for rule aria-role. (#171)
1 parent e790336 commit 60c487e

File tree

2 files changed

+28
-11
lines changed

2 files changed

+28
-11
lines changed

__tests__/src/rules/aria-role-test.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ const invalidTests = createTests(invalidRoles).map((test) => {
3939
return invalidTest;
4040
});
4141

42+
const ignoreNonDOMSchema = [{
43+
ignoreNonDOM: true,
44+
}];
45+
4246
ruleTester.run('aria-role', rule, {
4347
valid: [
4448
// Variables should pass, as we are only testing literals.
@@ -52,6 +56,7 @@ ruleTester.run('aria-role', rule, {
5256
{ code: '<div role="doc-abstract" />' },
5357
{ code: '<div role="doc-appendix doc-bibliography" />' },
5458
{ code: '<Bar baz />' },
59+
{ code: '<Foo role="bar" />', options: ignoreNonDOMSchema },
5560
].concat(validTests).map(parserOptionsMapper),
5661

5762
invalid: [
@@ -64,5 +69,6 @@ ruleTester.run('aria-role', rule, {
6469
{ code: '<div role="doc-endnotes range"></div>', errors: [errorMessage] },
6570
{ code: '<div role />', errors: [errorMessage] },
6671
{ code: '<div role={null}></div>', errors: [errorMessage] },
72+
{ code: '<Foo role="datepicker" />', errors: [errorMessage] },
6773
].concat(invalidTests).map(parserOptionsMapper),
6874
});

src/rules/aria-role.js

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,19 @@
77
// Rule Definition
88
// ----------------------------------------------------------------------------
99

10-
import { getLiteralPropValue, propName } from 'jsx-ast-utils';
10+
import { getLiteralPropValue, propName, elementType } from 'jsx-ast-utils';
1111
import { generateObjSchema } from '../util/schemas';
1212
import roles from '../util/attributes/role.json';
13+
import DOMElements from '../util/attributes/DOM.json';
1314

1415
const errorMessage = 'Elements with ARIA roles must use a valid, non-abstract ARIA role.';
1516

16-
const schema = generateObjSchema();
17+
const schema = generateObjSchema({
18+
ignoreNonDOM: {
19+
type: 'boolean',
20+
default: false,
21+
},
22+
});
1723

1824
module.exports = {
1925
meta: {
@@ -23,29 +29,34 @@ module.exports = {
2329

2430
create: context => ({
2531
JSXAttribute: (attribute) => {
32+
// Determine if ignoreNonDOM is set to true
33+
// If true, then do not run rule.
34+
const options = context.options[0] || {};
35+
const ignoreNonDOM = !!options.ignoreNonDOM;
36+
37+
if (ignoreNonDOM) {
38+
const type = elementType(attribute.parent);
39+
if (!DOMElements[type]) { return; }
40+
}
41+
42+
// Get prop name
2643
const name = propName(attribute);
2744
const normalizedName = name ? name.toUpperCase() : '';
2845

29-
if (normalizedName !== 'ROLE') {
30-
return;
31-
}
46+
if (normalizedName !== 'ROLE') { return; }
3247

3348
const value = getLiteralPropValue(attribute);
3449

3550
// If value is undefined, then the role attribute will be dropped in the DOM.
3651
// If value is null, then getLiteralAttributeValue is telling us that the
3752
// value isn't in the form of a literal.
38-
if (value === undefined || value === null) {
39-
return;
40-
}
53+
if (value === undefined || value === null) { return; }
4154

4255
const normalizedValues = String(value).toUpperCase().split(' ');
4356
const validRoles = Object.keys(roles).filter(role => roles[role].abstract === false);
4457
const isValid = normalizedValues.every(val => validRoles.indexOf(val) > -1);
4558

46-
if (isValid === true) {
47-
return;
48-
}
59+
if (isValid === true) { return; }
4960

5061
context.report({
5162
node: attribute,

0 commit comments

Comments
 (0)