diff --git a/src/reactA11yImgHasAltRule.ts b/src/reactA11yImgHasAltRule.ts index 3a1b200d9..fe90c91a1 100644 --- a/src/reactA11yImgHasAltRule.ts +++ b/src/reactA11yImgHasAltRule.ts @@ -14,6 +14,10 @@ const ROLE_STRING: string = 'role'; const ALT_STRING: string = 'alt'; const TITLE_STRING: string = 'title'; +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. \ @@ -85,7 +89,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.parent.type === 'map'; + + if (!tagName || (targetTagNames.indexOf(tagName) === -1 && !isMapArea)) { return; } @@ -98,7 +105,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(), @@ -109,7 +124,6 @@ class ImgHasAltWalker extends Lint.RuleWalker { const roleAttributeValue = roleAttribute ? getStringLiteral(roleAttribute) : ''; const titleAttribute: ts.JsxAttribute = attributes[TITLE_STRING]; const isPresentationRole: boolean = !!String(roleAttributeValue).toLowerCase().match(/\bpresentation\b/); - const isEmptyAlt: boolean = isEmpty(altAttribute) || getStringLiteral(altAttribute) === ''; const isEmptyTitle: boolean = isEmpty(titleAttribute) || getStringLiteral(titleAttribute) === ''; const allowNonEmptyAltWithRolePresentation: boolean = options.length > 1 ? options[1].allowNonEmptyAltWithRolePresentation