Socket
Socket
Sign inDemoInstall

eslint-plugin-jsx-a11y

Package Overview
Dependencies
Maintainers
1
Versions
82
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-jsx-a11y - npm Package Compare versions

Comparing version 0.2.0 to 0.2.1

lib/util/getAttributeValue.js

2

lib/rules/img-uses-alt.js

@@ -23,3 +23,3 @@ /**

var type = node.name.name;
if (type.toUpperCase() !== 'IMG') {
if (type !== 'img') {
return;

@@ -26,0 +26,0 @@ }

@@ -29,12 +29,12 @@ /**

var type = node.name.name;
if (type.toUpperCase() !== 'IMG') {
if (type !== 'img') {
return;
}
var hasAltProp = (0, _hasAttribute2.default)(node.attributes, 'alt');
var altProp = (0, _hasAttribute2.default)(node.attributes, 'alt');
var isVisible = (0, _isHiddenFromScreenReader2.default)(node.attributes) === false;
if (Boolean(hasAltProp) && isVisible) {
if (Boolean(altProp) && typeof altProp === 'string' && isVisible) {
var hasRedundancy = REDUNDANT_WORDS.some(function (word) {
return Boolean(hasAltProp.value.value.match(new RegExp(word, 'gi')));
return Boolean(altProp.match(new RegExp(word, 'gi')));
});

@@ -41,0 +41,0 @@

@@ -23,3 +23,3 @@ /**

var type = node.name.name;
if (type.toUpperCase() !== 'LABEL') {
if (type !== 'label') {
return;

@@ -26,0 +26,0 @@ }

@@ -6,6 +6,13 @@ 'use strict';

});
var _getAttributeValue = require('./getAttributeValue');
var _getAttributeValue2 = _interopRequireDefault(_getAttributeValue);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var hasAttribute = function hasAttribute(attributes, attribute) {
var idx = 0;
var value = false;
var hasAttr = attributes.some(function (attr, index) {
var hasAttr = attributes.some(function (attr) {
// If the attributes contain a spread attribute, then skip.

@@ -18,4 +25,6 @@ if (attr.type === 'JSXSpreadAttribute') {

if (attr.name.name.toUpperCase() === attribute.toUpperCase()) {
idx = index; // Keep track of the index.
return true;
value = (0, _getAttributeValue2.default)(attr);
// If the value is undefined, it doesn't really have the attribute.
return value !== undefined;
}

@@ -26,5 +35,5 @@

return hasAttr ? attributes[idx] : false;
return hasAttr ? value : false;
};
exports.default = hasAttribute;

@@ -6,15 +6,14 @@ 'use strict';

});
var isHiddenFromScreenReader = function isHiddenFromScreenReader(attributes) {
return attributes.some(function (attribute) {
if (attribute.type === 'JSXSpreadAttribute') {
return false;
}
var name = attribute.name.name.toUpperCase();
var value = attribute.value && attribute.value.value;
var _hasAttribute = require('./hasAttribute');
return name === 'ARIA-HIDDEN' && (value === true || value === null);
});
var _hasAttribute2 = _interopRequireDefault(_hasAttribute);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var isHiddenFromScreenReader = function isHiddenFromScreenReader(attributes) {
var hasAriaHidden = (0, _hasAttribute2.default)(attributes, 'aria-hidden');
return hasAriaHidden && (hasAriaHidden === true || hasAriaHidden === null);
};
exports.default = isHiddenFromScreenReader;

@@ -24,3 +24,3 @@ 'use strict';

var hasTypeAttr = (0, _hasAttribute2.default)(attributes, 'type');
return hasTypeAttr ? hasTypeAttr.value.value.toUpperCase() !== 'HIDDEN' : true;
return hasTypeAttr ? hasTypeAttr.toUpperCase() !== 'HIDDEN' : true;
},

@@ -27,0 +27,0 @@ option: function option() {

{
"name": "eslint-plugin-jsx-a11y",
"version": "0.2.0",
"version": "0.2.1",
"description": "A static analysis linter of jsx and their accessibility with screen readers.",

@@ -5,0 +5,0 @@ "keywords": [

@@ -18,3 +18,3 @@ /**

const type = node.name.name;
if (type.toUpperCase() !== 'IMG') {
if (type !== 'img') {
return;

@@ -21,0 +21,0 @@ }

@@ -26,11 +26,11 @@ /**

const type = node.name.name;
if (type.toUpperCase() !== 'IMG') {
if (type !== 'img') {
return;
}
const hasAltProp = hasAttribute(node.attributes, 'alt');
const altProp = hasAttribute(node.attributes, 'alt');
const isVisible = isHiddenFromScreenReader(node.attributes) === false;
if (Boolean(hasAltProp) && isVisible) {
const hasRedundancy = REDUNDANT_WORDS.some(word => Boolean(hasAltProp.value.value.match(new RegExp(word, 'gi'))));
if (Boolean(altProp) && typeof altProp === 'string' && isVisible) {
const hasRedundancy = REDUNDANT_WORDS.some(word => Boolean(altProp.match(new RegExp(word, 'gi'))));

@@ -37,0 +37,0 @@ if (hasRedundancy === true) {

@@ -19,3 +19,3 @@ /**

const type = node.name.name;
if (type.toUpperCase() !== 'LABEL') {
if (type !== 'label') {
return;

@@ -22,0 +22,0 @@ }

'use strict';
import getAttributeValue from './getAttributeValue';
const hasAttribute = (attributes, attribute) => {
let idx = 0;
let value = false;
const hasAttr = attributes.some((attr, index) => {
const hasAttr = attributes.some(attr => {
// If the attributes contain a spread attribute, then skip.

@@ -14,4 +16,6 @@ if (attr.type === 'JSXSpreadAttribute') {

if (attr.name.name.toUpperCase() === attribute.toUpperCase()) {
idx = index; // Keep track of the index.
return true;
value = getAttributeValue(attr);
// If the value is undefined, it doesn't really have the attribute.
return value !== undefined;
}

@@ -22,5 +26,5 @@

return hasAttr ? attributes[idx] : false;
return hasAttr ? value : false;
};
export default hasAttribute;
'use strict';
const isHiddenFromScreenReader = attributes => (
attributes.some(attribute => {
if (attribute.type === 'JSXSpreadAttribute') {
return false;
}
import hasAttribute from './hasAttribute';
const name = attribute.name.name.toUpperCase();
const value = attribute.value && attribute.value.value;
const isHiddenFromScreenReader = attributes => {
const hasAriaHidden = hasAttribute(attributes, 'aria-hidden');
return hasAriaHidden && (hasAriaHidden === true || hasAriaHidden === null);
};
return name === 'ARIA-HIDDEN' && (value === true || value === null);
})
);
export default isHiddenFromScreenReader;

@@ -14,3 +14,3 @@ 'use strict';

const hasTypeAttr = hasAttribute(attributes, 'type');
return hasTypeAttr ? hasTypeAttr.value.value.toUpperCase() !== 'HIDDEN' : true;
return hasTypeAttr ? hasTypeAttr.toUpperCase() !== 'HIDDEN' : true;
},

@@ -17,0 +17,0 @@ option: () => true,

@@ -36,9 +36,17 @@ /**

{ code: '<img alt="foo" />;', parserOptions },
{ code: '<img alt={"foo"} />;', parserOptions },
{ code: '<img alt={alt} />;', parserOptions },
{ code: '<img ALT="foo" />;', parserOptions },
{ code: '<img ALt="foo" />;', parserOptions },
{ code: '<img alt="foo" salt={undefined} />;', parserOptions },
{ code: '<img {...this.props} alt="foo" />', parserOptions },
{ code: '<a />', parserOptions }
{ code: '<a />', parserOptions },
{ code: '<img alt={function(e) {} } />', parserOptions },
{ code: '<div alt={function(e) {} } />', parserOptions },
{ code: '<img alt={() => void 0} />', parserOptions },
{ code: '<IMG />', parserOptions }
],
invalid: [
{ code: '<img />;', errors: [ expectedError ], parserOptions },
{ code: '<img alt={undefined} />;', errors: [ expectedError ], parserOptions },
{ code: '<img src="xyz" />', errors: [ expectedError ], parserOptions },

@@ -45,0 +53,0 @@ { code: '<img {...this.props} />', errors: [ expectedError ], parserOptions }

@@ -38,9 +38,13 @@ /**

ruleTester.run('mouseEvents-require-keyEvents', rule, {
ruleTester.run('mouse-events-map-to-key-events', rule, {
valid: [
{ code: '<div onMouseOver={() => void 0} onFocus={() => void 0} />;', parserOptions },
{ code: '<div onMouseOver={() => void 0} onFocus={() => void 0} {...props} />;', parserOptions },
{ code: '<div onMouseOver={handleMouseOver} onFocus={handleFocus} />;', parserOptions },
{ code: '<div onMouseOver={handleMouseOver} onFocus={handleFocus} {...props} />;', parserOptions },
{ code: '<div />;', parserOptions },
{ code: '<div onMouseOut={() => void 0} onBlur={() => void 0} />', parserOptions },
{ code: '<div onMouseOut={() => void 0} onBlur={() => void 0} {...props} />', parserOptions }
{ code: '<div onMouseOut={() => void 0} onBlur={() => void 0} {...props} />', parserOptions },
{ code: '<div onMouseOut={handleMouseOut} onBlur={handleOnBlur} />', parserOptions },
{ code: '<div onMouseOut={handleMouseOut} onBlur={handleOnBlur} {...props} />', parserOptions }
],

@@ -50,2 +54,4 @@ invalid: [

{ code: '<div onMouseOut={() => void 0} />', errors: [ mouseOutError ], parserOptions },
{ code: '<div onMouseOver={() => void 0} onFocus={undefined} />;', errors: [ mouseOverError ], parserOptions },
{ code: '<div onMouseOut={() => void 0} onBlur={undefined} />', errors: [ mouseOutError ], parserOptions },
{ code: '<div onMouseOver={() => void 0} {...props} />', errors: [ mouseOverError ], parserOptions },

@@ -52,0 +58,0 @@ { code: '<div onMouseOut={() => void 0} {...props} />', errors: [ mouseOutError ], parserOptions }

@@ -38,3 +38,4 @@ /**

{ code: '<div />;', parserOptions },
{ code: '<div {...props} />', parserOptions }
{ code: '<div {...props} />', parserOptions },
{ code: '<div accessKey={undefined} />', parserOptions }
],

@@ -45,4 +46,6 @@ invalid: [

{ code: '<div accessKey="h" {...props} />', errors: [ expectedError ], parserOptions },
{ code: '<div acCesSKeY="y" />', errors: [ expectedError ], parserOptions }
{ code: '<div acCesSKeY="y" />', errors: [ expectedError ], parserOptions },
{ code: '<div accessKey={"y"} />', errors: [ expectedError ], parserOptions },
{ code: '<div accessKey={accessKey} />', errors: [ expectedError ], parserOptions }
]
});

@@ -34,5 +34,7 @@ /**

ruleTester.run('onClick-uses-role', rule, {
ruleTester.run('onclick-uses-role', rule, {
valid: [
{ code: '<div onClick={() => void 0} role="button" />;', parserOptions },
{ code: '<div onClick={() => void 0} role={role} />;', parserOptions },
{ code: '<div onClick={() => void 0} role={"button"} />;', parserOptions },
{ code: '<div onClick={() => void 0} role="button" {...props} />;', parserOptions },

@@ -43,2 +45,3 @@ { code: '<div className="foo" />;', parserOptions },

{ code: '<div onClick={() => void 0} role="button" aria-hidden={false} />;', parserOptions },
{ code: '<div onClick={() => void 0} role="button" aria-hidden={undefined} />;', parserOptions },
{ code: '<input type="text" onClick={() => void 0} />', parserOptions },

@@ -57,2 +60,3 @@ { code: '<input onClick={() => void 0} />', parserOptions },

{ code: '<div onClick={() => void 0} />;', errors: [ expectedError ], parserOptions },
{ code: '<div onClick={() => void 0} role={undefined} />;', errors: [ expectedError ], parserOptions },
{ code: '<div onClick={() => void 0} {...props} />;', errors: [ expectedError ], parserOptions },

@@ -59,0 +63,0 @@ { code: '<section onClick={() => void 0} />;', errors: [ expectedError ], parserOptions },

@@ -34,3 +34,3 @@ /**

ruleTester.run('img-uses-alt', rule, {
ruleTester.run('redundant-alt', rule, {
valid: [

@@ -42,4 +42,11 @@ { code: '<img alt="foo" />;', parserOptions },

{ code: '<img {...this.props} alt="foo" />', parserOptions },
{ code: '<img {...this.props} alt={"foo"} />', parserOptions },
{ code: '<img {...this.props} alt={alt} />', parserOptions },
{ code: '<a />', parserOptions },
{ code: '<img />', parserOptions },
{ code: '<IMG />', parserOptions },
{ code: '<img alt={undefined} />', parserOptions },
{ code: '<img alt={"undefined"} />', parserOptions },
{ code: '<img alt={() => {}} />', parserOptions },
{ code: '<img alt={function(e){}} />', parserOptions },
{ code: '<img aria-hidden={false} alt="Doing cool things." />', parserOptions }

@@ -52,2 +59,3 @@ ],

{ code: '<img alt="PhOtO of friend." />;', errors: [ expectedError ], parserOptions },
{ code: '<img alt={"photo"} />;', errors: [ expectedError ], parserOptions },
{ code: '<img alt="piCTUre of friend." />;', errors: [ expectedError ], parserOptions },

@@ -54,0 +62,0 @@ { code: '<img alt="imAGE of friend." />;', errors: [ expectedError ], parserOptions },

@@ -37,7 +37,12 @@ /**

{ code: '<label htmlFor="foo" />', parserOptions },
{ code: '<label htmlFor={"foo"} />', parserOptions },
{ code: '<label htmlFor={foo} />', parserOptions },
{ code: '<div />', parserOptions },
{ code: '<label htmlFor="foo">Test!</label>', parserOptions }
{ code: '<label htmlFor="foo">Test!</label>', parserOptions },
{ code: '<Label />', parserOptions }, // lower-case convention refers to real HTML elements.
{ code: '<Label htmlFor="foo" />', parserOptions }
],
invalid: [
{ code: '<label id="foo" />', errors: [ expectedError ], parserOptions },
{ code: '<label htmlFor={undefined} />', errors: [ expectedError ], parserOptions },
{ code: '<label>First Name</label>', errors: [ expectedError ], parserOptions },

@@ -44,0 +49,0 @@ { code: '<label {...props}>Foo</label>', errors: [ expectedError ], parserOptions }

@@ -37,2 +37,3 @@ /**

{ code: '<div onBlur={() => {}} />;', parserOptions },
{ code: '<div onBlur={handleOnBlur} />;', parserOptions },
{ code: '<div />;', parserOptions },

@@ -44,2 +45,3 @@ { code: '<div onBlur={() => {}} onChange={() => {}} />;', parserOptions },

{ code: '<div onChange={() => {}} />;', errors: [ expectedError ], parserOptions },
{ code: '<div onChange={handleOnChange} />;', errors: [ expectedError ], parserOptions },
{ code: '<input onChange={() => {}} />', errors: [ expectedError ], parserOptions },

@@ -46,0 +48,0 @@ { code: '<input onChange={() => {}} {...props} />', errors: [ expectedError ], parserOptions }

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc