Skip to content

Commit 963847c

Browse files
author
Ethan Cohen
committed
Enforce labels have htmlFor attribute.
1 parent 33bdb0d commit 963847c

File tree

3 files changed

+83
-1
lines changed

3 files changed

+83
-1
lines changed

index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ module.exports = {
66
'onClick-uses-role': require('./lib/rules/onClick-uses-role'),
77
'mouseEvents-require-keyEvents': require('./lib/rules/mouseEvents-require-keyEvents'),
88
'use-onblur-not-onchange': require('./lib/rules/use-onblur-not-onchange'),
9-
'no-access-key': require('./lib/rules/no-access-key')
9+
'no-access-key': require('./lib/rules/no-access-key'),
10+
'use-label-for': require('./lib/rules/use-label-for')
1011
},
1112
configs: {
1213
recommended: {

lib/rules/use-label-for.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* @fileoverview Enforce label tags have htmlFor attribute.
3+
* @author Ethan Cohen
4+
*/
5+
'use strict';
6+
7+
// ------------------------------------------------------------------------------
8+
// Rule Definition
9+
// ------------------------------------------------------------------------------
10+
11+
var hasAttribute = require('../hasAttribute');
12+
13+
module.exports = function(context) {
14+
15+
return {
16+
JSXOpeningElement: function(node) {
17+
var type = node.name.name;
18+
if (type.toUpperCase() !== 'LABEL') {
19+
return;
20+
}
21+
22+
var hasHtmlForAttr = hasAttribute(node.attributes, 'htmlFor');
23+
24+
if (hasHtmlForAttr === false) {
25+
context.report({
26+
node: node,
27+
message: 'Form controls using a label to identify them must have only one label ' +
28+
'that is programmatically associated with the control using: label for=[ID of control].'
29+
});
30+
}
31+
}
32+
};
33+
};
34+
35+
module.exports.schema = [{
36+
type: 'object'
37+
}];

tests/lib/rules/use-label-for.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* @fileoverview Enforce label tags have htmlFor attribute.
3+
* @author Ethan Cohen
4+
*/
5+
6+
'use strict';
7+
8+
// -----------------------------------------------------------------------------
9+
// Requirements
10+
// -----------------------------------------------------------------------------
11+
12+
var rule = require('../../../lib/rules/use-label-for');
13+
var RuleTester = require('eslint').RuleTester;
14+
15+
var parserOptions = {
16+
ecmaVersion: 6,
17+
ecmaFeatures: {
18+
jsx: true
19+
}
20+
};
21+
22+
// -----------------------------------------------------------------------------
23+
// Tests
24+
// -----------------------------------------------------------------------------
25+
26+
var ruleTester = new RuleTester();
27+
28+
var expectedError = {
29+
message: 'Form controls using a label to identify them must have only one label ' +
30+
'that is programmatically associated with the control using: label for=[ID of control].',
31+
type: 'JSXOpeningElement'
32+
};
33+
34+
ruleTester.run('use-label-for', rule, {
35+
valid: [
36+
{code: '<label htmlFor="foo" />;', parserOptions: parserOptions},
37+
{code: '<div />;', parserOptions: parserOptions},
38+
{code: '<label htmlFor="foo">Test!</label>;', parserOptions: parserOptions}
39+
],
40+
invalid: [
41+
{code: '<label id="foo" />;', errors: [expectedError], parserOptions: parserOptions},
42+
{code: '<label>First Name</label>', errors: [expectedError], parserOptions: parserOptions}
43+
]
44+
});

0 commit comments

Comments
 (0)