From fa9845ddbf51283257ae6e67df48e13508eb6dd2 Mon Sep 17 00:00:00 2001 From: LB <mail@lb.ee> Date: Wed, 23 Oct 2024 14:25:44 +1000 Subject: [PATCH] [patch] `no-redundandant-roles`: allow `<img src="*.svg" role="img" />` Setting role="img" is a valid use case to work around a Safari bug for better accessibility when the source image is an SVG file. This improvement does not account for variables in the `src` attribute but adds a valid exception for when we can parse the string. Fixes #936 --- __tests__/src/rules/no-redundant-roles-test.js | 4 ++++ docs/rules/no-redundant-roles.md | 1 + src/util/implicitRoles/img.js | 10 ++++++++++ 3 files changed, 15 insertions(+) diff --git a/__tests__/src/rules/no-redundant-roles-test.js b/__tests__/src/rules/no-redundant-roles-test.js index 60cc2185e..068e54049 100644 --- a/__tests__/src/rules/no-redundant-roles-test.js +++ b/__tests__/src/rules/no-redundant-roles-test.js @@ -83,12 +83,16 @@ ruleTester.run(`${ruleName}:recommended (valid list role override)`, rule, { { code: '<ul role="list" />' }, { code: '<ol role="list" />' }, { code: '<dl role="list" />' }, + { code: '<img src="example.svg" role="img" />' }, + { code: '<svg role="img" />' }, )) .map(ruleOptionsMapperFactory(listException)) .map(parserOptionsMapper), invalid: parsers.all([].concat( { code: '<ul role="list" />', errors: [expectedError('ul', 'list')] }, { code: '<ol role="list" />', errors: [expectedError('ol', 'list')] }, + { code: '<img role="img" />', errors: [expectedError('img', 'img')] }, + { code: '<img src={someVariable} role="img" />', errors: [expectedError('img', 'img')] }, )) .map(parserOptionsMapper), }); diff --git a/docs/rules/no-redundant-roles.md b/docs/rules/no-redundant-roles.md index 0506b6066..6b20240cf 100644 --- a/docs/rules/no-redundant-roles.md +++ b/docs/rules/no-redundant-roles.md @@ -43,3 +43,4 @@ General best practice (reference resources) ### Resources - [ARIA Spec, ARIA Adds Nothing to Default Semantics of Most HTML Elements](https://www.w3.org/TR/using-aria/#aria-does-nothing) +- [Identifying SVG as an image](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#identifying_svg_as_an_image) diff --git a/src/util/implicitRoles/img.js b/src/util/implicitRoles/img.js index a03217ffd..e62bbc128 100644 --- a/src/util/implicitRoles/img.js +++ b/src/util/implicitRoles/img.js @@ -10,5 +10,15 @@ export default function getImplicitRoleForImg(attributes) { return ''; } + /** + * If the src attribute can be determined to be an svg, allow the role to be set to 'img' + * so that VoiceOver on Safari can be better supported. + * + * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#identifying_svg_as_an_image + * @see https://bugs.webkit.org/show_bug.cgi?id=216364 + */ + const src = getProp(attributes, 'src'); + if (src && getLiteralPropValue(src)?.includes('.svg')) { return ''; } + return 'img'; }