From 142a8f014f7b85ebcf449d6e28cb4faf8d5b2d92 Mon Sep 17 00:00:00 2001 From: Chovin <Chovin@users.noreply.github.com> Date: Sun, 14 Oct 2018 17:55:04 +1000 Subject: [PATCH 1/3] ensure map areas have non-empty alts (closes #223) --- src/reactA11yImgHasAltRule.ts | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/reactA11yImgHasAltRule.ts b/src/reactA11yImgHasAltRule.ts index 7cd5598bc..d913b664a 100644 --- a/src/reactA11yImgHasAltRule.ts +++ b/src/reactA11yImgHasAltRule.ts @@ -13,6 +13,10 @@ import { isJsxSpreadAttribute } from './utils/TypeGuard'; const ROLE_STRING: string = 'role'; const ALT_STRING: string = 'alt'; +export function getFailureMapAreaNoAlt(): string { + return `area elements of image maps must have a non-empty alt attribute`; +} + export function getFailureStringNoAlt(tagName: string): string { return `<${tagName}> elements must have an non-empty alt attribute or \ use empty alt attribute as well as role='presentation' for decorative/presentational images. \ @@ -79,7 +83,10 @@ class ImgHasAltWalker extends Lint.RuleWalker { // The targetTagNames is the list of tag names we want to check. const targetTagNames: string[] = ['img'].concat(additionalTagNames); - if (!tagName || targetTagNames.indexOf(tagName) === -1) { + const isArea: boolean = node.tagName.getText() === 'area'; + const isMapArea: boolean = isArea && node.parentNode.tagName.getText() === 'map'; + + if (!tagName || (targetTagNames.indexOf(tagName) === -1 && !isMapArea)) { return; } @@ -92,7 +99,15 @@ class ImgHasAltWalker extends Lint.RuleWalker { const attributes: { [propName: string]: ts.JsxAttribute } = getJsxAttributesFromJsxElement(node); const altAttribute: ts.JsxAttribute = attributes[ALT_STRING]; - if (!altAttribute) { + const isEmptyAlt: boolean = altAttribute && (isEmpty(altAttribute) || getStringLiteral(altAttribute) === ''); + + if (isMapArea && (!altAttribute || isEmptyAlt)) { + this.addFailureAt( + node.getStart(), + node.getWidth(), + getFailureMapAreaNoAlt() + ); + } else if (!altAttribute) { this.addFailureAt( node.getStart(), node.getWidth(), @@ -102,7 +117,6 @@ class ImgHasAltWalker extends Lint.RuleWalker { const roleAttribute: ts.JsxAttribute = attributes[ROLE_STRING]; const roleAttributeValue = roleAttribute ? getStringLiteral(roleAttribute) : ''; const isPresentationRole: boolean = !!String(roleAttributeValue).toLowerCase().match(/\bpresentation\b/); - const isEmptyAlt: boolean = isEmpty(altAttribute) || getStringLiteral(altAttribute) === ''; const allowNonEmptyAltWithRolePresentation: boolean = options.length > 1 ? options[1].allowNonEmptyAltWithRolePresentation : false; From dac9e72ce0bf4378c4a3fc28e1b38709132460b1 Mon Sep 17 00:00:00 2001 From: Chovin <Chovin@users.noreply.github.com> Date: Mon, 15 Oct 2018 10:13:30 +1000 Subject: [PATCH 2/3] change parentNode to parent --- src/reactA11yImgHasAltRule.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reactA11yImgHasAltRule.ts b/src/reactA11yImgHasAltRule.ts index d913b664a..ec9555516 100644 --- a/src/reactA11yImgHasAltRule.ts +++ b/src/reactA11yImgHasAltRule.ts @@ -84,7 +84,7 @@ class ImgHasAltWalker extends Lint.RuleWalker { const targetTagNames: string[] = ['img'].concat(additionalTagNames); const isArea: boolean = node.tagName.getText() === 'area'; - const isMapArea: boolean = isArea && node.parentNode.tagName.getText() === 'map'; + const isMapArea: boolean = isArea && node.parent.tagName.getText() === 'map'; if (!tagName || (targetTagNames.indexOf(tagName) === -1 && !isMapArea)) { return; From dafd32c7f2e40c258f20cc1015c2f902ccca013d Mon Sep 17 00:00:00 2001 From: Chovin <Chovin@users.noreply.github.com> Date: Tue, 16 Oct 2018 06:46:38 +1000 Subject: [PATCH 3/3] fix get JSX type instead of tagName --- src/reactA11yImgHasAltRule.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reactA11yImgHasAltRule.ts b/src/reactA11yImgHasAltRule.ts index 2d31df51f..fe90c91a1 100644 --- a/src/reactA11yImgHasAltRule.ts +++ b/src/reactA11yImgHasAltRule.ts @@ -90,7 +90,7 @@ class ImgHasAltWalker extends Lint.RuleWalker { const targetTagNames: string[] = ['img'].concat(additionalTagNames); const isArea: boolean = node.tagName.getText() === 'area'; - const isMapArea: boolean = isArea && node.parent.tagName.getText() === 'map'; + const isMapArea: boolean = isArea && node.parent.type === 'map'; if (!tagName || (targetTagNames.indexOf(tagName) === -1 && !isMapArea)) { return;