diff --git a/src/reactA11yRoleSupportsAriaPropsRule.ts b/src/reactA11yRoleSupportsAriaPropsRule.ts index 69c214969..eb90c52ef 100644 --- a/src/reactA11yRoleSupportsAriaPropsRule.ts +++ b/src/reactA11yRoleSupportsAriaPropsRule.ts @@ -7,7 +7,7 @@ import * as Lint from 'tslint/lib/lint'; import { ExtendedMetadata } from './utils/ExtendedMetadata'; import { getImplicitRole } from './utils/getImplicitRole'; -import { getJsxAttributesFromJsxElement, getStringLiteral } from './utils/JsxAttribute'; +import { getJsxAttributesFromJsxElement, getStringLiteral, isEmpty } from './utils/JsxAttribute'; import { IRole, IRoleSchema } from './utils/attributes/IRole'; import { IAria } from './utils/attributes/IAria'; @@ -69,9 +69,17 @@ class A11yRoleSupportsAriaPropsWalker extends Lint.RuleWalker { private checkJsxElement(node: ts.JsxOpeningElement): void { const attributesInElement: { [propName: string]: ts.JsxAttribute } = getJsxAttributesFromJsxElement(node); const roleProp: ts.JsxAttribute = attributesInElement[ROLE_STRING]; + let roleValue: string; + + if (roleProp != null) { + roleValue = getStringLiteral(roleProp); + if (!isEmpty(roleProp) && roleValue == null) { // Do NOT check if can't retrieve the right role. + return; + } + } else { + roleValue = getImplicitRole(node); // Get implicit role if not specified. + } - // If role attribute is specified, get the role value. Otherwise get the implicit role from tag name. - const roleValue: string = roleProp ? getStringLiteral(roleProp) : getImplicitRole(node); const isImplicitRole: boolean = !roleProp && !!roleValue; const normalizedRoles: string[] = (roleValue || '').toLowerCase().split(' ') .filter((role: string) => !!ROLES[role]); diff --git a/test-data/a11yRoleSupportsAriaProps/PassingTestInputs/UnretrievableRoleSupportsAllAriaPropsInElement.tsx b/test-data/a11yRoleSupportsAriaProps/PassingTestInputs/UnretrievableRoleSupportsAllAriaPropsInElement.tsx new file mode 100644 index 000000000..ab46aa3ee --- /dev/null +++ b/test-data/a11yRoleSupportsAriaProps/PassingTestInputs/UnretrievableRoleSupportsAllAriaPropsInElement.tsx @@ -0,0 +1,38 @@ +import React = require('react'); + +const role = 'some role'; + +// Only one role. +const a =
+const b =
+const c =
+const d =
+const e =
+const f =
+const g =
+const h =
+const i =
+const j =
+const k =
+const l =
+const m =
+const n =
+const o =
+const p =
+const r =
+const s =
+const t =
+const u =
+const v =
+const w =
+const x =
+const y =
+const z =
+const a1 =
+const b1 =
+ +// Multiple roles. +const c1 =
+ +// when there have explicit role and implicit role, the explicit role will be used first. +const d1 = diff --git a/tests/reactA11yRoleSupportsAriaPropsRuleTests.ts b/tests/reactA11yRoleSupportsAriaPropsRuleTests.ts index 2e01c3a74..6f2364e19 100644 --- a/tests/reactA11yRoleSupportsAriaPropsRuleTests.ts +++ b/tests/reactA11yRoleSupportsAriaPropsRuleTests.ts @@ -28,6 +28,11 @@ describe('a11yRoleSupportsAriaPropsRule', () => { const fileName: string = fileDirectory + 'ImplicitRoleSupportsAllAriaPropsInElement.tsx'; TestHelper.assertNoViolation(ruleName, fileName); }); + + it('when role is defined but not retrievable', () => { + const fileName: string = fileDirectory + 'UnretrievableRoleSupportsAllAriaPropsInElement.tsx'; + TestHelper.assertNoViolation(ruleName, fileName); + }); }); describe('should fail', () => {