UNPKG

@jsxtools/eslint-plugin-jsx-a11y

Version:

Static AST checker for accessibility rules on JSX elements for flat ESLint Config.

69 lines (66 loc) 2.61 kB
import safeRegexTest from 'safe-regex-test'; import { getProp, getLiteralPropValue } from '../util/module/jsx-ast-utils.js'; import { generateObjSchema, arraySchema } from '../util/schemas.js'; import getElementType from '../util/getElementType.js'; import isHiddenFromScreenReader from '../util/isHiddenFromScreenReader.js'; const REDUNDANT_WORDS = [ "image", "photo", "picture" ]; const errorMessage = "Redundant alt attribute. Screen-readers already announce `img` tags as an image. You don’t need to use the words `image`, `photo,` or `picture` (or any specified custom words) in the alt prop."; const schema = generateObjSchema({ components: arraySchema, words: arraySchema }); const isASCII = safeRegexTest(/[\x20-\x7F]+/); function containsRedundantWord(value, redundantWords) { const lowercaseRedundantWords = redundantWords.map((redundantWord) => redundantWord.toLowerCase()); if (isASCII(value)) { return value.split(/\s+/).some((valueWord) => lowercaseRedundantWords.includes(valueWord.toLowerCase())); } return lowercaseRedundantWords.some((redundantWord) => value.toLowerCase().includes(redundantWord)); } const ruleOfImgRedundantAlt = { meta: { docs: { url: "https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/img-redundant-alt.md", description: 'Enforce `<img>` alt prop does not contain the word "image", "picture", or "photo".' }, schema: [schema] }, create: (context) => { const elementType = getElementType(context); return { JSXOpeningElement: (node) => { const options = context.options[0] || {}; const componentOptions = options.components || []; const typesToValidate = ["img"].concat(componentOptions); const nodeType = elementType(node); if (typesToValidate.indexOf(nodeType) === -1) { return; } const altProp = getProp(node.attributes, "alt"); if (altProp === void 0) { return; } const value = getLiteralPropValue(altProp); const isVisible = isHiddenFromScreenReader(nodeType, node.attributes) === false; const { words = [] } = options; const redundantWords = REDUNDANT_WORDS.concat(words); if (typeof value === "string" && isVisible) { const hasRedundancy = containsRedundantWord(value, redundantWords); if (hasRedundancy === true) { context.report({ node, message: errorMessage }); } } } }; } }; export { ruleOfImgRedundantAlt as default };