diff --git a/src/reactA11yAnchorsRule.ts b/src/reactA11yAnchorsRule.ts
index 5b861dea3..7a5dfddc1 100644
--- a/src/reactA11yAnchorsRule.ts
+++ b/src/reactA11yAnchorsRule.ts
@@ -5,11 +5,19 @@ import {ErrorTolerantWalker} from './utils/ErrorTolerantWalker';
import {ExtendedMetadata} from './utils/ExtendedMetadata';
import {SyntaxKind} from './utils/SyntaxKind';
import {Utils} from './utils/Utils';
+import {getImplicitRole} from './utils/getImplicitRole';
+import {
+ getJsxAttributesFromJsxElement,
+ getStringLiteral
+} from './utils/JsxAttribute';
+
+const ROLE_STRING: string = 'role';
const NO_HASH_FAILURE_STRING: string =
'Do not use # as anchor href.';
const LINK_TEXT_TOO_SHORT_FAILURE_STRING: string =
- 'Link text should be at least 4 characters long.';
+ 'Link text should be at least 4 characters long. If you are not using ' +
+ 'element as anchor, please specify explicit role, e.g. role=\'button\'';
const UNIQUE_ALT_FAILURE_STRING: string =
'Links with images and text content, the alt attribute should be unique to the text content or empty.';
const SAME_HREF_SAME_TEXT_FAILURE_STRING: string =
@@ -117,7 +125,7 @@ class ReactA11yAnchorsRuleWalker extends ErrorTolerantWalker {
this.addFailure(this.createFailure(anchorInfo.start, anchorInfo.width, NO_HASH_FAILURE_STRING));
}
- if (!anchorInfo.text || anchorInfo.text.length < 4) {
+ if (this.imageRole(openingElement) === 'link' && (!anchorInfo.text || anchorInfo.text.length < 4)) {
this.addFailure(this.createFailure(anchorInfo.start, anchorInfo.width, LINK_TEXT_TOO_SHORT_FAILURE_STRING));
}
@@ -202,6 +210,14 @@ class ReactA11yAnchorsRuleWalker extends ErrorTolerantWalker {
return altText;
}
+
+ private imageRole(root: ts.Node): string {
+ const attributesInElement: { [propName: string]: ts.JsxAttribute } = getJsxAttributesFromJsxElement(root);
+ const roleProp: ts.JsxAttribute = attributesInElement[ROLE_STRING];
+
+ // If role attribute is specified, get the role value. Otherwise get the implicit role from tag name.
+ return roleProp ? getStringLiteral(roleProp) : getImplicitRole(root);
+ }
}
class AnchorInfo {
diff --git a/src/tests/ReactA11yAnchorsRuleTests.ts b/src/tests/ReactA11yAnchorsRuleTests.ts
index e1d8681ee..def995138 100644
--- a/src/tests/ReactA11yAnchorsRuleTests.ts
+++ b/src/tests/ReactA11yAnchorsRuleTests.ts
@@ -35,7 +35,8 @@ describe('reactA11yAnchorsRule', () : void => {
TestHelper.assertViolations(ruleName, script, [
{
- "failure": "Link text should be at least 4 characters long.",
+ "failure": 'Link text should be at least 4 characters long. If you are not using ' +
+ 'element as anchor, please specify explicit role, e.g. role=\'button\'',
"name": "file.tsx",
"ruleName": "react-a11y-anchors",
"startPosition": { "character": 28, "line": 3 }
@@ -73,7 +74,8 @@ describe('reactA11yAnchorsRule', () : void => {
"startPosition": { "character": 28, "line": 3 }
},
{
- "failure": "Link text should be at least 4 characters long.",
+ "failure": 'Link text should be at least 4 characters long. If you are not using ' +
+ 'element as anchor, please specify explicit role, e.g. role=\'button\'',
"name": "file.tsx",
"ruleName": "react-a11y-anchors",
"startPosition": { "character": 28, "line": 3 }
@@ -93,6 +95,18 @@ describe('reactA11yAnchorsRule', () : void => {
TestHelper.assertViolations(ruleName, script, []);
});
+ it('should pass when role is not link and length of text less than 4', () => {
+ // Anchor without 'href' attribute has no corresponding role.
+ const script: string = `
+ import React = require('react');
+ const anchor1 = add;
+ const anchor2 = ;
+ const anchor3 = ;
+ `;
+
+ TestHelper.assertNoViolation(ruleName, script);
+ });
+
it('should fail when length of text less than 4', (): void => {
const script: string = `
import React = require('react');
@@ -102,13 +116,15 @@ describe('reactA11yAnchorsRule', () : void => {
TestHelper.assertViolations(ruleName, script, [
{
- "failure": "Link text should be at least 4 characters long.",
+ "failure": 'Link text should be at least 4 characters long. If you are not using ' +
+ 'element as anchor, please specify explicit role, e.g. role=\'button\'',
"name": "file.tsx",
"ruleName": "react-a11y-anchors",
"startPosition": { "character": 33, "line": 3 }
},
{
- "failure": "Link text should be at least 4 characters long.",
+ "failure": 'Link text should be at least 4 characters long. If you are not using ' +
+ 'element as anchor, please specify explicit role, e.g. role=\'button\'',
"name": "file.tsx",
"ruleName": "react-a11y-anchors",
"startPosition": { "character": 33, "line": 4 }