Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

eslint-plugin-jsx-a11y

Package Overview
Dependencies
Maintainers
1
Versions
84
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.1.1 to 0.1.2

src/hasAttribute.js

11

lib/hasAttribute.js
'use strict';
const hasAttribute = (attributes, attribute) => {
let idx = 0;
Object.defineProperty(exports, "__esModule", {
value: true
});
var hasAttribute = function hasAttribute(attributes, attribute) {
var idx = 0;
const hasAttr = attributes.some((attr, index) => {
var hasAttr = attributes.some(function (attr, index) {
// If the attributes contain a spread attribute, then skip.

@@ -24,2 +27,2 @@ if (attr.type === 'JSXSpreadAttribute') {

export default hasAttribute;
exports.default = hasAttribute;

@@ -21,2 +21,2 @@ 'use strict';

}
};
};
'use strict';
const isHiddenFromScreenReader = attributes => (
attributes.some(attribute => {
Object.defineProperty(exports, "__esModule", {
value: true
});
var isHiddenFromScreenReader = function isHiddenFromScreenReader(attributes) {
return attributes.some(function (attribute) {
if (attribute.type === 'JSXSpreadAttribute') {

@@ -9,9 +12,9 @@ return false;

const name = attribute.name.name.toUpperCase();
const value = attribute.value && attribute.value.value;
var name = attribute.name.name.toUpperCase();
var value = attribute.value && attribute.value.value;
return name === 'ARIA-HIDDEN' && (value === true || value === null);
})
);
});
};
export default isHiddenFromScreenReader;
exports.default = isHiddenFromScreenReader;
'use strict';
import hasAttribute from './hasAttribute';
Object.defineProperty(exports, "__esModule", {
value: true
});
const interactiveMap = {
a: attributes => {
const hasHref = hasAttribute(attributes, 'href');
const hasTabIndex = hasAttribute(attributes, 'tabIndex');
return (Boolean(hasHref) || !hasHref && Boolean(hasTabIndex));
var _hasAttribute = require('./hasAttribute');
var _hasAttribute2 = _interopRequireDefault(_hasAttribute);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var interactiveMap = {
a: function a(attributes) {
var hasHref = (0, _hasAttribute2.default)(attributes, 'href');
var hasTabIndex = (0, _hasAttribute2.default)(attributes, 'tabIndex');
return Boolean(hasHref) || !hasHref && Boolean(hasTabIndex);
},
button: () => true,
input: attributes => {
const hasTypeAttr = hasAttribute(attributes, 'type');
button: function button() {
return true;
},
input: function input(attributes) {
var hasTypeAttr = (0, _hasAttribute2.default)(attributes, 'type');
return hasTypeAttr ? hasTypeAttr.value.value.toUpperCase() !== 'HIDDEN' : true;
},
option: () => true,
select: () => true,
textarea: () => true
option: function option() {
return true;
},
select: function select() {
return true;
},
textarea: function textarea() {
return true;
}
};
const isInteractiveElement = (tagName, attributes) => {
var isInteractiveElement = function isInteractiveElement(tagName, attributes) {
if (interactiveMap.hasOwnProperty(tagName) === false) {

@@ -29,2 +45,2 @@ return false;

export default isInteractiveElement;
exports.default = isInteractiveElement;

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

import hasAttribute from '../hasAttribute';
var _hasAttribute = require('../hasAttribute');
const errorMessage = 'img elements must have an alt tag.';
var _hasAttribute2 = _interopRequireDefault(_hasAttribute);
module.exports = context => ({
JSXOpeningElement: node => {
const type = node.name.name;
if (type.toUpperCase() !== 'IMG') {
return;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const hasAltProp = hasAttribute(node.attributes, 'alt');
var errorMessage = 'img elements must have an alt tag.';
if (hasAltProp === false) {
context.report({
node,
message: errorMessage
});
module.exports = function (context) {
return {
JSXOpeningElement: function JSXOpeningElement(node) {
var type = node.name.name;
if (type.toUpperCase() !== 'IMG') {
return;
}
var hasAltProp = (0, _hasAttribute2.default)(node.attributes, 'alt');
if (hasAltProp === false) {
context.report({
node: node,
message: errorMessage
});
}
}
}
});
};
};
module.exports.schema = [
{ type: 'object' }
];
module.exports.schema = [{ type: 'object' }];

@@ -12,39 +12,43 @@ /**

import hasAttribute from '../hasAttribute';
var _hasAttribute = require('../hasAttribute');
const mouseOverErrorMessage = 'onMouseOver must be accompanied by onFocus for accessibility.';
const mouseOutErrorMessage = 'onMouseOut must be accompanied by onBlur for accessibility.';
var _hasAttribute2 = _interopRequireDefault(_hasAttribute);
module.exports = context => ({
JSXOpeningElement: node => {
const attributes = node.attributes;
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// Check onmouseover / onfocus pairing.
const hasOnMouseOver = hasAttribute(attributes, 'onMouseOver');
if (Boolean(hasOnMouseOver) === true) {
const hasOnFocus = hasAttribute(attributes, 'onFocus');
if (hasOnFocus === false) {
context.report({
node,
message: mouseOverErrorMessage
});
var mouseOverErrorMessage = 'onMouseOver must be accompanied by onFocus for accessibility.';
var mouseOutErrorMessage = 'onMouseOut must be accompanied by onBlur for accessibility.';
module.exports = function (context) {
return {
JSXOpeningElement: function JSXOpeningElement(node) {
var attributes = node.attributes;
// Check onmouseover / onfocus pairing.
var hasOnMouseOver = (0, _hasAttribute2.default)(attributes, 'onMouseOver');
if (Boolean(hasOnMouseOver) === true) {
var hasOnFocus = (0, _hasAttribute2.default)(attributes, 'onFocus');
if (hasOnFocus === false) {
context.report({
node: node,
message: mouseOverErrorMessage
});
}
}
}
// Checkout onmouseout / onblur pairing
const hasOnMouseOut = hasAttribute(attributes, 'onMouseOut');
if (Boolean(hasOnMouseOut) === true) {
const hasOnBlur = hasAttribute(attributes, 'onBlur');
if (hasOnBlur === false) {
context.report({
node,
message: mouseOutErrorMessage
});
// Checkout onmouseout / onblur pairing
var hasOnMouseOut = (0, _hasAttribute2.default)(attributes, 'onMouseOut');
if (Boolean(hasOnMouseOut) === true) {
var hasOnBlur = (0, _hasAttribute2.default)(attributes, 'onBlur');
if (hasOnBlur === false) {
context.report({
node: node,
message: mouseOutErrorMessage
});
}
}
}
}
});
};
};
module.exports.schema = [
{ type: 'object' }
];
module.exports.schema = [{ type: 'object' }];

@@ -11,23 +11,25 @@ /**

import hasAttribute from '../hasAttribute';
var _hasAttribute = require('../hasAttribute');
const errorMessage = 'No access key attribute allowed. Incosistencies ' +
'between keyboard shortcuts and keyboard comments used by screenreader ' +
'and keyboard only users create a11y complications.';
var _hasAttribute2 = _interopRequireDefault(_hasAttribute);
module.exports = context => ({
JSXOpeningElement: node => {
const hasAccessKey = hasAttribute(node.attributes, 'accesskey');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
if (Boolean(hasAccessKey) === true) {
context.report({
node,
message: errorMessage
});
var errorMessage = 'No access key attribute allowed. Incosistencies ' + 'between keyboard shortcuts and keyboard comments used by screenreader ' + 'and keyboard only users create a11y complications.';
module.exports = function (context) {
return {
JSXOpeningElement: function JSXOpeningElement(node) {
var hasAccessKey = (0, _hasAttribute2.default)(node.attributes, 'accesskey');
if (Boolean(hasAccessKey) === true) {
context.report({
node: node,
message: errorMessage
});
}
}
}
});
};
};
module.exports.schema = [
{ type: 'object' }
];
module.exports.schema = [{ type: 'object' }];

@@ -8,6 +8,16 @@ /**

import isHiddenFromScreenReader from '../isHiddenFromScreenReader';
import isInteractiveElement from '../isInteractiveElement';
import hasAttribute from '../hasAttribute';
var _isHiddenFromScreenReader = require('../isHiddenFromScreenReader');
var _isHiddenFromScreenReader2 = _interopRequireDefault(_isHiddenFromScreenReader);
var _isInteractiveElement = require('../isInteractiveElement');
var _isInteractiveElement2 = _interopRequireDefault(_isInteractiveElement);
var _hasAttribute = require('../hasAttribute');
var _hasAttribute2 = _interopRequireDefault(_hasAttribute);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// ----------------------------------------------------------------------------

@@ -17,28 +27,27 @@ // Rule Definition

const errorMessage = 'Visible, non-interactive elements with click handlers must ' +
'have role attribute.';
var errorMessage = 'Visible, non-interactive elements with click handlers must ' + 'have role attribute.';
module.exports = context => ({
JSXOpeningElement: node => {
const attributes = node.attributes;
if (hasAttribute(attributes, 'onclick') === false) {
return;
}
module.exports = function (context) {
return {
JSXOpeningElement: function JSXOpeningElement(node) {
var attributes = node.attributes;
if ((0, _hasAttribute2.default)(attributes, 'onclick') === false) {
return;
}
const isVisible = isHiddenFromScreenReader(attributes) === false;
const isNonInteractive = isInteractiveElement(node.name.name, attributes) === false;
const noRoleAttribute = hasAttribute(attributes, 'role') === false;
var isVisible = (0, _isHiddenFromScreenReader2.default)(attributes) === false;
var isNonInteractive = (0, _isInteractiveElement2.default)(node.name.name, attributes) === false;
var noRoleAttribute = (0, _hasAttribute2.default)(attributes, 'role') === false;
// Visible, non-interactive elements require role attribute.
if (isVisible && isNonInteractive && noRoleAttribute) {
context.report({
node,
message: errorMessage
});
// Visible, non-interactive elements require role attribute.
if (isVisible && isNonInteractive && noRoleAttribute) {
context.report({
node: node,
message: errorMessage
});
}
}
}
});
};
};
module.exports.schema = [
{ type: 'object' }
];
module.exports.schema = [{ type: 'object' }];

@@ -11,27 +11,30 @@ /**

import hasAttribute from '../hasAttribute';
var _hasAttribute = require('../hasAttribute');
const errorMessage = 'Form controls using a label to identify them must be ' +
'programmatically associated with the control using htmlFor';
var _hasAttribute2 = _interopRequireDefault(_hasAttribute);
module.exports = context => ({
JSXOpeningElement: node => {
const type = node.name.name;
if (type.toUpperCase() !== 'LABEL') {
return;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const hasHtmlForAttr = hasAttribute(node.attributes, 'htmlFor');
var errorMessage = 'Form controls using a label to identify them must be ' + 'programmatically associated with the control using htmlFor';
if (hasHtmlForAttr === false) {
context.report({
node,
message: errorMessage
});
module.exports = function (context) {
return {
JSXOpeningElement: function JSXOpeningElement(node) {
var type = node.name.name;
if (type.toUpperCase() !== 'LABEL') {
return;
}
var hasHtmlForAttr = (0, _hasAttribute2.default)(node.attributes, 'htmlFor');
if (hasHtmlForAttr === false) {
context.report({
node: node,
message: errorMessage
});
}
}
}
});
};
};
module.exports.schema = [
{ type: 'object' }
];
module.exports.schema = [{ type: 'object' }];

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

import hasAttribute from '../hasAttribute';
var _hasAttribute = require('../hasAttribute');
const errorMessage = 'onBlur must be used instead of onchange, ' +
'unless absolutely necessary and it causes no negative consequences ' +
'for keyboard only or screen reader users.';
var _hasAttribute2 = _interopRequireDefault(_hasAttribute);
module.exports = context => ({
JSXOpeningElement: node => {
const hasOnChange = hasAttribute(node.attributes, 'onChange');
const hasOnBlur = hasAttribute(node.attributes, 'onBlur');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
if (Boolean(hasOnChange) === true && hasOnBlur === false) {
context.report({
node,
message: errorMessage
});
var errorMessage = 'onBlur must be used instead of onchange, ' + 'unless absolutely necessary and it causes no negative consequences ' + 'for keyboard only or screen reader users.';
module.exports = function (context) {
return {
JSXOpeningElement: function JSXOpeningElement(node) {
var hasOnChange = (0, _hasAttribute2.default)(node.attributes, 'onChange');
var hasOnBlur = (0, _hasAttribute2.default)(node.attributes, 'onBlur');
if (Boolean(hasOnChange) === true && hasOnBlur === false) {
context.report({
node: node,
message: errorMessage
});
}
}
}
});
};
};
module.exports.schema = [
{ type: 'object' }
];
module.exports.schema = [{ type: 'object' }];
{
"name": "eslint-plugin-jsx-a11y",
"version": "0.1.1",
"version": "0.1.2",
"description": "A static analysis linter of jsx and their accessibility with screen readers.",

@@ -18,8 +18,8 @@ "keywords": [

},
"main": "index.js",
"main": "lib/index.js",
"scripts": {
"build": "webpack --config .webpack.config.js --optimize-minimize",
"build": "babel src --out-dir lib",
"prepublish": "npm run lint && npm run test && npm run build",
"coveralls": "cat ./reports/coverage/lcov.info | coveralls",
"lint": "eslint --config .eslintrc.js ./",
"lint": "eslint --config .eslintrc.js src tests",
"pretest": "npm run lint",

@@ -32,3 +32,2 @@ "test": "istanbul cover --dir reports/coverage node_modules/mocha/bin/_mocha tests/**/*.js -- --compilers js:babel-core/register --reporter nyan"

"babel-eslint": "^5.0.0",
"babel-loader": "^6.2.4",
"babel-preset-es2015": "^6.6.0",

@@ -38,4 +37,3 @@ "coveralls": "^2.11.8",

"istanbul": "^1.0.0-alpha.2",
"mocha": "^2.4.5",
"webpack": "^1.12.14"
"mocha": "^2.4.5"
},

@@ -42,0 +40,0 @@ "engines": {

/* eslint-env mocha */
'use strict';
import plugin from '../lib';
import plugin from '../src';

@@ -10,3 +10,3 @@ import assert from 'assert';

const rules = fs.readdirSync(path.resolve(__dirname, '../lib/rules/'))
const rules = fs.readdirSync(path.resolve(__dirname, '../src/rules/'))
.map(f => path.basename(f, '.js'));

@@ -19,3 +19,3 @@

plugin.rules[ruleName],
require(path.join('../lib/rules', ruleName))
require(path.join('../src/rules', ruleName))
);

@@ -22,0 +22,0 @@ });

Sorry, the diff of this file is not supported yet

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