eslint-plugin-jsx-a11y
Advanced tools
Comparing version 0.5.4 to 0.6.0
@@ -38,3 +38,3 @@ # img-uses-alt | ||
"rules": { | ||
"jsx-a11y/img-uses-alt": [ 2, "Image" ], // OR | ||
"jsx-a11y/img-uses-alt": [ 2, "Image" ], <!-- OR --> | ||
"jsx-a11y/img-uses-alt": [ 2, [ "Image", "Avatar" ] ] | ||
@@ -53,2 +53,3 @@ } | ||
<img src="foo" alt={`${person} smiling`} /> | ||
<img src="foo" alt="" role="presentation" /> <!-- Alt text can be an empty string if `role="presentation"` --> | ||
``` | ||
@@ -55,0 +56,0 @@ |
@@ -25,6 +25,2 @@ /** | ||
var errorMessage = function errorMessage(type) { | ||
return type + ' elements must have an alt tag.'; | ||
}; | ||
module.exports = function (context) { | ||
@@ -42,12 +38,32 @@ return { | ||
var hasAltProp = (0, _hasAttribute2.default)(node.attributes, 'alt'); | ||
var altProp = hasAltProp ? (0, _getAttributeValue2.default)(hasAltProp) : undefined; | ||
var isInvalid = hasAltProp === false || Boolean(altProp) === false; | ||
// alt must have a value. | ||
if (isInvalid) { | ||
// Missing alt prop error. | ||
if (!hasAltProp) { | ||
context.report({ | ||
node: node, | ||
message: errorMessage(nodeType) | ||
message: nodeType + ' elements must have an alt prop.' | ||
}); | ||
return; | ||
} | ||
// Check if alt prop is undefined. | ||
var altProp = (0, _getAttributeValue2.default)(hasAltProp); | ||
// Check if alt prop is "" | ||
var emptyAlt = hasAltProp && hasAltProp.value && hasAltProp.value.type === 'Literal' && hasAltProp.value.value === ""; | ||
var hasRoleProp = (0, _hasAttribute2.default)(node.attributes, 'role'); | ||
var roleProp = (0, _getAttributeValue2.default)(hasRoleProp); | ||
// Allow altProp to be "" if `role="presentation"` is present. | ||
var isValid = altProp || emptyAlt && hasRoleProp && roleProp.toUpperCase() === 'PRESENTATION'; | ||
// Undefined alt prop error. | ||
if (!isValid) { | ||
context.report({ | ||
node: node, | ||
message: nodeType + ' alt prop must have a value. You can set alt="" if role="presentation" is applied.' | ||
}); | ||
return; | ||
} | ||
} | ||
@@ -54,0 +70,0 @@ }; |
{ | ||
"name": "eslint-plugin-jsx-a11y", | ||
"version": "0.5.4", | ||
"version": "0.6.0", | ||
"description": "A static analysis linter of jsx and their accessibility with screen readers.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -15,4 +15,2 @@ /** | ||
const errorMessage = type => `${type} elements must have an alt tag.`; | ||
module.exports = context => ({ | ||
@@ -29,12 +27,34 @@ JSXOpeningElement: node => { | ||
const hasAltProp = hasAttribute(node.attributes, 'alt'); | ||
const altProp = hasAltProp ? getAttributeValue(hasAltProp) : undefined; | ||
const isInvalid = hasAltProp === false || Boolean(altProp) === false; | ||
// alt must have a value. | ||
if (isInvalid) { | ||
// Missing alt prop error. | ||
if (!hasAltProp) { | ||
context.report({ | ||
node, | ||
message: errorMessage(nodeType) | ||
message: `${nodeType} elements must have an alt prop.` | ||
}); | ||
return; | ||
} | ||
// Check if alt prop is undefined. | ||
const altProp = getAttributeValue(hasAltProp); | ||
// Check if alt prop is "" | ||
const emptyAlt = hasAltProp && hasAltProp.value | ||
&& hasAltProp.value.type === 'Literal' | ||
&& hasAltProp.value.value === ""; | ||
const hasRoleProp = hasAttribute(node.attributes, 'role'); | ||
const roleProp = getAttributeValue(hasRoleProp); | ||
// Allow altProp to be "" if `role="presentation"` is present. | ||
const isValid = altProp || (emptyAlt && hasRoleProp && roleProp.toUpperCase() === 'PRESENTATION'); | ||
// Undefined alt prop error. | ||
if (!isValid) { | ||
context.report({ | ||
node, | ||
message: `${nodeType} alt prop must have a value. You can set alt="" if role="presentation" is applied.` | ||
}); | ||
return; | ||
} | ||
} | ||
@@ -41,0 +61,0 @@ }); |
@@ -28,14 +28,18 @@ /** | ||
const expectedError = { | ||
message: 'img elements must have an alt tag.', | ||
const customMissingPropError = type => ({ | ||
message: `${type} elements must have an alt prop.`, | ||
type: 'JSXOpeningElement' | ||
}; | ||
}); | ||
const customAltValueError = type => ({ | ||
message: `${type} alt prop must have a value. You can set alt="" if role="presentation" is applied.`, | ||
type: 'JSXOpeningElement' | ||
}); | ||
const expectedMissingPropError = customMissingPropError('img'); | ||
const expectedAltValueError = customAltValueError('img'); | ||
const string = [ 'Avatar' ]; | ||
const array = [ [ 'Thumbnail', 'Image' ] ]; | ||
const customError = type => ({ | ||
message: `${type} elements must have an alt tag.`, | ||
type: 'JSXOpeningElement' | ||
}); | ||
@@ -65,2 +69,6 @@ ruleTester.run('img-uses-alt', rule, { | ||
{ code: '<img alt={foo.bar() || ""} />', parserOptions }, | ||
{ code: '<img alt="" role="presentation" />', parserOptions }, // Allow alt to be undefined if role="presentation" | ||
{ code: '<img alt="" role={`presentation`} />', parserOptions }, | ||
{ code: '<img alt="" role={"presentation"} />', parserOptions }, | ||
{ code: '<img alt="this is lit..." role="presentation" />', parserOptions }, | ||
{ code: '<img alt=" " />', parserOptions }, // For decorative images. | ||
@@ -116,36 +124,64 @@ | ||
// DEFAULT ELEMENT 'img' TESTS | ||
{ code: '<img />;', errors: [ expectedError ], parserOptions }, | ||
{ code: '<img alt />;', errors: [ expectedError ], parserOptions }, | ||
{ code: '<img alt={undefined} />;', errors: [ expectedError ], parserOptions }, | ||
{ code: '<img alt={`${undefined}`} />;', errors: [ expectedError ], parserOptions }, | ||
{ code: '<img alt="" />;', errors: [ expectedError ], parserOptions }, | ||
{ code: '<img src="xyz" />', errors: [ expectedError ], parserOptions }, | ||
{ code: '<img {...this.props} />', errors: [ expectedError ], parserOptions }, | ||
{ code: '<img alt={false || false} />', errors: [ expectedError ], parserOptions }, | ||
{ code: '<img />;', errors: [ expectedMissingPropError ], parserOptions }, | ||
{ code: '<img alt />;', errors: [ expectedAltValueError ], parserOptions }, | ||
{ code: '<img alt={undefined} />;', errors: [ expectedAltValueError ], parserOptions }, | ||
{ code: '<img alt={`${undefined}`} />;', errors: [ expectedAltValueError ], parserOptions }, | ||
{ code: '<img alt="" />;', errors: [ expectedAltValueError ], parserOptions }, | ||
{ code: '<img role="presentation" />;', errors: [ expectedMissingPropError ], parserOptions }, | ||
{ code: '<img alt={undefined} role="presentation" />;', errors: [ expectedAltValueError ], parserOptions }, | ||
{ code: '<img alt role="presentation" />;', errors: [ expectedAltValueError ], parserOptions }, | ||
{ code: '<img src="xyz" />', errors: [ expectedMissingPropError ], parserOptions }, | ||
{ code: '<img {...this.props} />', errors: [ expectedMissingPropError ], parserOptions }, | ||
{ code: '<img alt={false || false} />', errors: [ expectedAltValueError ], parserOptions }, | ||
// CUSTOM ELEMENT TESTS FOR STRING OPTION | ||
{ code: '<Avatar />;', errors: [ customError('Avatar') ], options: string, parserOptions }, | ||
{ code: '<Avatar alt />;', errors: [ customError('Avatar') ], options: string, parserOptions }, | ||
{ code: '<Avatar alt={undefined} />;', errors: [ customError('Avatar') ], options: string, parserOptions }, | ||
{ code: '<Avatar alt={`${undefined}`} />;', errors: [ customError('Avatar') ], options: string, parserOptions }, | ||
{ code: '<Avatar alt="" />;', errors: [ customError('Avatar') ], options: string, parserOptions }, | ||
{ code: '<Avatar src="xyz" />', errors: [ customError('Avatar') ], options: string, parserOptions }, | ||
{ code: '<Avatar {...this.props} />', errors: [ customError('Avatar') ], options: string, parserOptions }, | ||
{ | ||
code: '<Avatar />;', | ||
errors: [ customMissingPropError('Avatar') ], | ||
options: string, | ||
parserOptions | ||
}, | ||
{ code: '<Avatar alt />;', errors: [ customAltValueError('Avatar') ], options: string, parserOptions }, | ||
{ code: '<Avatar alt={undefined} />;', errors: [ customAltValueError('Avatar') ], options: string, parserOptions }, | ||
{ | ||
code: '<Avatar alt={`${undefined}`} />;', | ||
errors: [ customAltValueError('Avatar') ], | ||
options: string, | ||
parserOptions | ||
}, | ||
{ code: '<Avatar alt="" />;', errors: [ customAltValueError('Avatar') ], options: string, parserOptions }, | ||
{ code: '<Avatar src="xyz" />', errors: [ customMissingPropError('Avatar') ], options: string, parserOptions }, | ||
{ code: '<Avatar {...this.props} />', errors: [ customMissingPropError('Avatar') ], options: string, parserOptions }, | ||
// CUSTOM ELEMENT TESTS FOR ARRAY OPTION TESTS | ||
{ code: '<Thumbnail />;', errors: [ customError('Thumbnail') ], options: array, parserOptions }, | ||
{ code: '<Thumbnail alt />;', errors: [ customError('Thumbnail') ], options: array, parserOptions }, | ||
{ code: '<Thumbnail alt={undefined} />;', errors: [ customError('Thumbnail') ], options: array, parserOptions }, | ||
{ code: '<Thumbnail alt={`${undefined}`} />;', errors: [ customError('Thumbnail') ], options: array, parserOptions }, | ||
{ code: '<Thumbnail alt="" />;', errors: [ customError('Thumbnail') ], options: array, parserOptions }, | ||
{ code: '<Thumbnail src="xyz" />', errors: [ customError('Thumbnail') ], options: array, parserOptions }, | ||
{ code: '<Thumbnail {...this.props} />', errors: [ customError('Thumbnail') ], options: array, parserOptions }, | ||
{ code: '<Image />;', errors: [ customError('Image') ], options: array, parserOptions }, | ||
{ code: '<Image alt />;', errors: [ customError('Image') ], options: array, parserOptions }, | ||
{ code: '<Image alt={undefined} />;', errors: [ customError('Image') ], options: array, parserOptions }, | ||
{ code: '<Image alt={`${undefined}`} />;', errors: [ customError('Image') ], options: array, parserOptions }, | ||
{ code: '<Image alt="" />;', errors: [ customError('Image') ], options: array, parserOptions }, | ||
{ code: '<Image src="xyz" />', errors: [ customError('Image') ], options: array, parserOptions }, | ||
{ code: '<Image {...this.props} />', errors: [ customError('Image') ], options: array, parserOptions } | ||
{ code: '<Thumbnail />;', errors: [ customMissingPropError('Thumbnail') ], options: array, parserOptions }, | ||
{ code: '<Thumbnail alt />;', errors: [ customAltValueError('Thumbnail') ], options: array, parserOptions }, | ||
{ | ||
code: '<Thumbnail alt={undefined} />;', | ||
errors: [ customAltValueError('Thumbnail') ], | ||
options: array, | ||
parserOptions | ||
}, | ||
{ | ||
code: '<Thumbnail alt={`${undefined}`} />;', | ||
errors: [ customAltValueError('Thumbnail') ], | ||
options: array, | ||
parserOptions | ||
}, | ||
{ code: '<Thumbnail alt="" />;', errors: [ customAltValueError('Thumbnail') ], options: array, parserOptions }, | ||
{ code: '<Thumbnail src="xyz" />', errors: [ customMissingPropError('Thumbnail') ], options: array, parserOptions }, | ||
{ | ||
code: '<Thumbnail {...this.props} />', | ||
errors: [ customMissingPropError('Thumbnail') ], | ||
options: array, | ||
parserOptions | ||
}, | ||
{ code: '<Image />;', errors: [ customMissingPropError('Image') ], options: array, parserOptions }, | ||
{ code: '<Image alt />;', errors: [ customAltValueError('Image') ], options: array, parserOptions }, | ||
{ code: '<Image alt={undefined} />;', errors: [ customAltValueError('Image') ], options: array, parserOptions }, | ||
{ code: '<Image alt={`${undefined}`} />;', errors: [ customAltValueError('Image') ], options: array, parserOptions }, | ||
{ code: '<Image alt="" />;', errors: [ customAltValueError('Image') ], options: array, parserOptions }, | ||
{ code: '<Image src="xyz" />', errors: [ customMissingPropError('Image') ], options: array, parserOptions }, | ||
{ code: '<Image {...this.props} />', errors: [ customMissingPropError('Image') ], options: array, parserOptions } | ||
] | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
105886
2112