Skip to content

Commit 9ddf20f

Browse files
committed
Sync with template-lint
1 parent af0a016 commit 9ddf20f

3 files changed

Lines changed: 127 additions & 110 deletions

File tree

docs/rules/template-self-closing-void-elements.md

Lines changed: 17 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,59 +6,41 @@
66

77
Disallow or require self-closing void elements.
88

9-
## Rule Details
10-
11-
Void elements (like `<img>`, `<br>`, `<input>`, etc.) cannot have child content. By default, this rule disallows redundant self-closing syntax (`/>`) on void elements since it's unnecessary in HTML.
12-
13-
## Config
14-
15-
This rule accepts a single option:
16-
17-
- `true` (default) — disallow self-closing void elements (e.g., `<br />``<br>`)
18-
- `"require"` — require self-closing void elements (e.g., `<br>``<br />`)
9+
HTML has no self-closing tags. The HTML5 parser will ignore a self-closing marker on
10+
[void elements](https://html.spec.whatwg.org/#void-elements) (elements that should not
11+
have a closing tag), but it is unnecessary and can be confusing when mixed with
12+
SVG/XML-like syntax.
1913

2014
## Examples
2115

22-
Examples of **incorrect** code for this rule (with default config):
16+
This rule **forbids** the following:
2317

2418
```gjs
2519
<template>
26-
<img src="foo.jpg" />
20+
<img src="http://emberjs.com/images/ember-logo.svg" alt="ember" />
21+
<hr />
2722
</template>
2823
```
2924

30-
```gjs
31-
<template>
32-
<br />
33-
</template>
34-
```
25+
This rule **allows** the following:
3526

3627
```gjs
3728
<template>
38-
<input type="text" />
29+
<img src="http://emberjs.com/images/ember-logo.svg" alt="ember">
30+
<hr>
3931
</template>
4032
```
4133

42-
Examples of **correct** code for this rule (with default config):
34+
There may be cases where a self-closing tag is preferred for void elements. In those
35+
cases, pass the string `"require"` to require the self-closing form instead.
4336

44-
```gjs
45-
<template>
46-
<img src="foo.jpg">
47-
</template>
48-
```
37+
## Configuration
4938

50-
```gjs
51-
<template>
52-
<br>
53-
</template>
54-
```
39+
The following values are valid configuration:
5540

56-
```gjs
57-
<template>
58-
<input type="text">
59-
</template>
60-
```
41+
- boolean -- `true` for enabled / `false` for disabled
42+
- string -- `"require"` to mandate the use of self-closing tags
6143

6244
## References
6345

64-
- [eslint-plugin-ember template-self-closing-void-elements](https://github.com/ember-cli/eslint-plugin-ember/blob/master/docs/rules/template-self-closing-void-elements.md)
46+
- [HTML spec/void elements](https://html.spec.whatwg.org/#void-elements)

lib/rules/template-self-closing-void-elements.js

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ module.exports = {
1515
},
1616
],
1717
messages: {
18-
redundantSelfClosing: 'Self-closing a void element is redundant.',
19-
requireSelfClosing: 'Self-closing a void element is required.',
18+
redundantSelfClosing: 'Self-closing a void element is redundant',
19+
requireSelfClosing: 'Self-closing a void element is required',
2020
},
2121
originallyFrom: {
2222
name: 'ember-template-lint',
@@ -46,7 +46,13 @@ module.exports = {
4646
'wbr',
4747
]);
4848

49-
const config = context.options[0];
49+
const sourceCode = context.sourceCode;
50+
const config = context.options[0] ?? true;
51+
52+
if (config === false) {
53+
return {};
54+
}
55+
5056
const requireSelfClosing = config === 'require';
5157

5258
return {
@@ -57,16 +63,30 @@ module.exports = {
5763

5864
if (requireSelfClosing) {
5965
if (!node.selfClosing) {
66+
const source = sourceCode.getText(node).trim();
67+
6068
context.report({
6169
node,
6270
messageId: 'requireSelfClosing',
71+
fix(fixer) {
72+
return fixer.replaceText(node, source.replace(/>$/, '/>'));
73+
},
6374
});
6475
}
6576
} else {
6677
if (node.selfClosing) {
78+
const source = sourceCode.getText(node).trim();
79+
6780
context.report({
6881
node,
6982
messageId: 'redundantSelfClosing',
83+
fix(fixer) {
84+
const replacement = node.blockParams?.length
85+
? source.replace(/\/>$/, '>')
86+
: source.replace(/\s*\/>$/, '>');
87+
88+
return fixer.replaceText(node, replacement);
89+
},
7090
});
7191
}
7292
}

0 commit comments

Comments
 (0)