Skip to content
This repository has been archived by the owner on Jul 15, 2023. It is now read-only.

Commit

Permalink
fix anchors rule not correctly apply 4 chars rule (#305)
Browse files Browse the repository at this point in the history
- only apply rule 'text must longer than 4 characters' to role='link' or
   anchor with href attribute defined.
 - Only <a role=link'></a> and <a href='...'></a> should have text longer
   than 4 characters.
 - Other links like <a role='button'><span>add</span></a> or
   <a><img /></a> don't have this limitation.
  • Loading branch information
ipip2005 authored Oct 25, 2016
1 parent 58e62a1 commit bb0cf61
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 6 deletions.
20 changes: 18 additions & 2 deletions src/reactA11yAnchorsRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 <a> ' +
'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 =
Expand Down Expand Up @@ -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));
}

Expand Down Expand Up @@ -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 {
Expand Down
24 changes: 20 additions & 4 deletions src/tests/ReactA11yAnchorsRuleTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 <a> ' +
'element as anchor, please specify explicit role, e.g. role=\'button\'',
"name": "file.tsx",
"ruleName": "react-a11y-anchors",
"startPosition": { "character": 28, "line": 3 }
Expand Down Expand Up @@ -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 <a> ' +
'element as anchor, please specify explicit role, e.g. role=\'button\'',
"name": "file.tsx",
"ruleName": "react-a11y-anchors",
"startPosition": { "character": 28, "line": 3 }
Expand All @@ -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 = <a role='button'>add</a>;
const anchor2 = <a role='button'><span className='iconClass'></span></a>;
const anchor3 = <a><img src='someURL' alt='someAlt' /></a>;
`;

TestHelper.assertNoViolation(ruleName, script);
});

it('should fail when length of text less than 4', (): void => {
const script: string = `
import React = require('react');
Expand All @@ -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 <a> ' +
'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 <a> ' +
'element as anchor, please specify explicit role, e.g. role=\'button\'',
"name": "file.tsx",
"ruleName": "react-a11y-anchors",
"startPosition": { "character": 33, "line": 4 }
Expand Down

0 comments on commit bb0cf61

Please sign in to comment.