Skip to content

Commit 28526f4

Browse files
committed
Extract rule: template-no-aria-hidden-body
1 parent 688cf6b commit 28526f4

4 files changed

Lines changed: 102 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ rules in templates can be disabled with eslint directives with mustache or html
183183
| [template-link-href-attributes](docs/rules/template-link-href-attributes.md) | require href attribute on link elements | | | |
184184
| [template-no-abstract-roles](docs/rules/template-no-abstract-roles.md) | disallow abstract ARIA roles | | | |
185185
| [template-no-accesskey-attribute](docs/rules/template-no-accesskey-attribute.md) | disallow accesskey attribute | | 🔧 | |
186+
| [template-no-aria-hidden-body](docs/rules/template-no-aria-hidden-body.md) | disallow aria-hidden on body element | | 🔧 | |
186187
| [template-no-aria-unsupported-elements](docs/rules/template-no-aria-unsupported-elements.md) | disallow ARIA roles, states, and properties on elements that do not support them | | | |
187188

188189
### Best Practices
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# ember/template-no-aria-hidden-body
2+
3+
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
4+
5+
<!-- end auto-generated rule header -->
6+
7+
The aria-hidden attribute should never be present on the `<body>` element, as it hides the entire document from assistive technology.
8+
9+
## Examples
10+
11+
This rule **forbids** the following:
12+
13+
```hbs
14+
<body aria-hidden>
15+
```
16+
17+
```hbs
18+
<body aria-hidden="true">
19+
```
20+
21+
This rule **allows** the following:
22+
23+
```hbs
24+
<body>
25+
```
26+
27+
## References
28+
29+
- [Using the aria-hidden attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-hidden_attribute)
30+
- [How Lighthouse identifies hidden body elements](https://web.dev/aria-hidden-body/)
31+
- [WCAG 4.1.2 - Name, Role, Value (Level A)](https://www.w3.org/TR/WCAG21/#name-role-value)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/** @type {import('eslint').Rule.RuleModule} */
2+
module.exports = {
3+
meta: {
4+
type: 'problem',
5+
docs: {
6+
description: 'disallow aria-hidden on body element',
7+
category: 'Accessibility',
8+
strictGjs: true,
9+
strictGts: true,
10+
url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-no-aria-hidden-body.md',
11+
},
12+
fixable: 'code',
13+
schema: [],
14+
messages: {
15+
noAriaHiddenBody:
16+
'The aria-hidden attribute should never be present on the <body> element, as it hides the entire document from assistive technology',
17+
},
18+
},
19+
20+
create(context) {
21+
return {
22+
GlimmerElementNode(node) {
23+
if (node.tag === 'body') {
24+
const ariaHiddenAttr = node.attributes?.find((attr) => attr.name === 'aria-hidden');
25+
26+
if (ariaHiddenAttr) {
27+
context.report({
28+
node: ariaHiddenAttr,
29+
messageId: 'noAriaHiddenBody',
30+
fix(fixer) {
31+
const sourceCode = context.sourceCode;
32+
const text = sourceCode.getText();
33+
const attrStart = ariaHiddenAttr.range[0];
34+
const attrEnd = ariaHiddenAttr.range[1];
35+
36+
let removeStart = attrStart;
37+
while (removeStart > 0 && /\s/.test(text[removeStart - 1])) {
38+
removeStart--;
39+
}
40+
41+
return fixer.removeRange([removeStart, attrEnd]);
42+
},
43+
});
44+
}
45+
}
46+
},
47+
};
48+
},
49+
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const rule = require('../../../lib/rules/template-no-aria-hidden-body');
2+
const RuleTester = require('eslint').RuleTester;
3+
4+
const ruleTester = new RuleTester({
5+
parser: require.resolve('ember-eslint-parser'),
6+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
7+
});
8+
9+
ruleTester.run('template-no-aria-hidden-body', rule, {
10+
valid: [
11+
'<template><body></body></template>',
12+
'<template><div aria-hidden="true"></div></template>',
13+
],
14+
invalid: [
15+
{
16+
code: '<template><body aria-hidden="true"></body></template>',
17+
output: '<template><body></body></template>',
18+
errors: [{ messageId: 'noAriaHiddenBody' }],
19+
},
20+
],
21+
});

0 commit comments

Comments
 (0)