Skip to content

Commit 37dfe10

Browse files
committed
warn on self-closing non-void HTML tags
1 parent a531625 commit 37dfe10

File tree

129 files changed

+1455
-1105
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

129 files changed

+1455
-1105
lines changed

packages/svelte/src/compiler/phases/2-analyze/validation.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ import {
1515
import { warn } from '../../warnings.js';
1616
import fuzzymatch from '../1-parse/utils/fuzzymatch.js';
1717
import { binding_properties } from '../bindings.js';
18-
import { ContentEditableBindings, EventModifiers, SVGElements } from '../constants.js';
18+
import {
19+
ContentEditableBindings,
20+
EventModifiers,
21+
SVGElements,
22+
VoidElements
23+
} from '../constants.js';
1924
import { is_custom_element_node } from '../nodes.js';
2025
import {
2126
regex_illegal_attribute_character,
@@ -565,6 +570,17 @@ const validation = {
565570
}
566571
}
567572

573+
const is_self_closing = context.state.analysis.source[node.end - 2] === '/';
574+
if (is_self_closing && !VoidElements.includes(node.name) && !SVGElements.includes(node.name)) {
575+
warn(
576+
context.state.analysis.warnings,
577+
node,
578+
context.path,
579+
'invalid-self-closing-tag',
580+
node.name
581+
);
582+
}
583+
568584
context.next({
569585
...context.state,
570586
parent_element: node.name

packages/svelte/src/compiler/warnings.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,12 @@ const options = {
243243
"The 'customElement' option is used when generating a custom element. Did you forget the 'customElement: true' compile option?"
244244
};
245245

246+
const misc = {
247+
/** @param {string} name */
248+
'invalid-self-closing-tag': (name) =>
249+
`Self-closing HTML tags for non-void elements are ambiguous — use <${name} ...></${name}> rather than <${name} ... />`
250+
};
251+
246252
/** @satisfies {Warnings} */
247253
const warnings = {
248254
...css,
@@ -254,7 +260,8 @@ const warnings = {
254260
...components,
255261
...legacy,
256262
...block,
257-
...options
263+
...options,
264+
...misc
258265
};
259266

260267
/** @typedef {typeof warnings} AllWarnings */

packages/svelte/tests/compiler-errors/samples/component-slot-nested-error-2/main.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<Nested>
66
<div slot="slot1">
77
<div>
8-
<div slot="slot2" />
8+
<div slot="slot2"></div>
99
</div>
1010
</div>
1111
</Nested>

packages/svelte/tests/compiler-errors/samples/component-slot-nested-error-3/main.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<Nested>
66
<div>
77
<div>
8-
<div slot="slot2" />
8+
<div slot="slot2"></div>
99
</div>
1010
</div>
1111
</Nested>

packages/svelte/tests/compiler-errors/samples/component-slot-nested-error/main.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44

55
<Nested>
66
<div slot="slot1">
7-
<div slot="slot2" />
7+
<div slot="slot2"></div>
88
</div>
99
</Nested>

packages/svelte/tests/css/samples/general-siblings-combinator-await-not-exhaustive/input.svelte

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,24 @@
1818
.c ~ .g { color: green; }
1919
</style>
2020

21-
<div class="a" />
21+
<div class="a"></div>
2222

2323
{#await promise then value}
24-
<div class="b" />
24+
<div class="b"></div>
2525
{:catch error}
26-
<div class="c" />
26+
<div class="c"></div>
2727
{/await}
2828

2929
{#await promise}
30-
<div class="d" />
30+
<div class="d"></div>
3131
{:catch error}
32-
<div class="e" />
32+
<div class="e"></div>
3333
{/await}
3434

3535
{#await promise}
36-
<div class="f" />
36+
<div class="f"></div>
3737
{:then error}
38-
<div class="g" />
38+
<div class="g"></div>
3939
{/await}
4040

41-
<div class="h" />
41+
<div class="h"></div>

packages/svelte/tests/css/samples/general-siblings-combinator-await/input.svelte

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@
1717
.b ~ .d { color: green; }
1818
</style>
1919

20-
<div class="a" />
20+
<div class="a"></div>
2121

2222
{#await promise}
23-
<div class="b" />
23+
<div class="b"></div>
2424
{:then value}
25-
<div class="c" />
25+
<div class="c"></div>
2626
{:catch error}
27-
<div class="d" />
27+
<div class="d"></div>
2828
{/await}
2929

30-
<div class="e" />
30+
<div class="e"></div>

packages/svelte/tests/css/samples/general-siblings-combinator-each-2/input.svelte

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@
2727
}
2828
</style>
2929

30-
<div class="a" />
30+
<div class="a"></div>
3131

3232
{#each array as item}
33-
<div class="b" />
34-
<div class="c" />
33+
<div class="b"></div>
34+
<div class="c"></div>
3535
{/each}
3636

37-
<div class="d" />
37+
<div class="d"></div>

packages/svelte/tests/css/samples/general-siblings-combinator-each-else-nested/input.svelte

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,43 +35,43 @@
3535
.e ~ .f { color: green; }
3636
</style>
3737

38-
<div class="a" />
38+
<div class="a"></div>
3939

4040
{#each array as a}
41-
<div class="b" />
41+
<div class="b"></div>
4242
{#each array as b}
43-
<div class="c" />
43+
<div class="c"></div>
4444
{:else}
45-
<div class="d" />
45+
<div class="d"></div>
4646
{/each}
4747
{/each}
4848

4949
{#each array as c}
5050
{#each array as d}
51-
<div class="e" />
51+
<div class="e"></div>
5252
{/each}
5353
{:else}
54-
<div class="f" />
54+
<div class="f"></div>
5555
{/each}
5656

5757
{#each array as x}
58-
<div class="g" />
58+
<div class="g"></div>
5959
{#each array as y}
6060
{#each array as z}
61-
<div class="h" />
61+
<div class="h"></div>
6262
{/each}
6363
{:else}
64-
<div class="i" />
64+
<div class="i"></div>
6565
{/each}
66-
<div class="j" />
66+
<div class="j"></div>
6767
{/each}
6868

69-
<div class="k" />
69+
<div class="k"></div>
7070

7171
{#each array as item}
7272
{#each array as item}
73-
<div class="l" />
73+
<div class="l"></div>
7474
{:else}
75-
<div class="m" />
75+
<div class="m"></div>
7676
{/each}
77-
{/each}
77+
{/each}

packages/svelte/tests/css/samples/general-siblings-combinator-each-else/input.svelte

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
.b ~ .c { color: green; }
1414
</style>
1515

16-
<div class="a" />
16+
<div class="a"></div>
1717

1818
{#each array as item}
19-
<div class="b" />
19+
<div class="b"></div>
2020
{:else}
21-
<div class="c" />
21+
<div class="c"></div>
2222
{/each}
2323

24-
<div class="d" />
24+
<div class="d"></div>

packages/svelte/tests/css/samples/general-siblings-combinator-each-nested/input.svelte

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -65,49 +65,49 @@
6565
.g ~ .i { color: green; }
6666
</style>
6767

68-
<div class="a" />
68+
<div class="a"></div>
6969

7070
{#each array as item}
71-
<div class="b" />
72-
<div class="c" />
71+
<div class="b"></div>
72+
<div class="c"></div>
7373
{/each}
7474

7575
{#each array as item}
7676
{#each array as item}
7777
{#each array as item}
78-
<div class="d" />
78+
<div class="d"></div>
7979
{/each}
80-
<div class="e" />
80+
<div class="e"></div>
8181
{/each}
82-
<div class="f" />
82+
<div class="f"></div>
8383
{/each}
8484

8585
{#each array as item}
86-
<div class="g" />
86+
<div class="g"></div>
8787
{#each array as item}
88-
<div class="h" />
88+
<div class="h"></div>
8989
{#each array as item}
90-
<div class="i" />
90+
<div class="i"></div>
9191
{/each}
9292
{/each}
9393
{/each}
9494

9595
{#each array as item}
96-
<div class="j" />
96+
<div class="j"></div>
9797
{#each array as item}
98-
<div class="k" />
98+
<div class="k"></div>
9999
{#each array as item}
100-
<div class="l" />
100+
<div class="l"></div>
101101
{/each}
102102
{/each}
103103
{/each}
104104

105105
{#each array as item}
106106
{#each array as item}
107107
{#each array as item}
108-
<div class="m" />
108+
<div class="m"></div>
109109
{/each}
110-
<div class="n" />
110+
<div class="n"></div>
111111
{/each}
112-
<div class="o" />
113-
{/each}
112+
<div class="o"></div>
113+
{/each}

packages/svelte/tests/css/samples/general-siblings-combinator-each/input.svelte

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
}
99
</style>
1010

11-
<div />
11+
<div></div>
1212

1313
{#each array as item}
14-
<span class="each" />
15-
<div class="each" />
16-
<span class="each" />
17-
<div class="each" />
14+
<span class="each"></span>
15+
<div class="each"></div>
16+
<span class="each"></span>
17+
<div class="each"></div>
1818
{/each}
1919

20-
<span />
20+
<span />

packages/svelte/tests/css/samples/general-siblings-combinator-if-not-exhaustive-with-each/input.svelte

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818
.b ~ .c { color: green; }
1919
</style>
2020

21-
<div class="a" />
21+
<div class="a"></div>
2222

2323
{#if foo}
24-
<div class="b" />
24+
<div class="b"></div>
2525
{:else}
2626
{#each array as item}
27-
<div class="c" />
27+
<div class="c"></div>
2828
{/each}
2929
{/if}
3030

31-
<div class="d" />
31+
<div class="d"></div>

packages/svelte/tests/css/samples/general-siblings-combinator-if-not-exhaustive/input.svelte

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@
1414
.b ~ .c { color: green; }
1515
</style>
1616

17-
<div class="a" />
17+
<div class="a"></div>
1818

1919
{#if foo}
20-
<div class="b" />
20+
<div class="b"></div>
2121
{:else if bar}
22-
<div class="c" />
22+
<div class="c"></div>
2323
{/if}
2424

25-
<div class="d" />
25+
<div class="d"></div>

packages/svelte/tests/css/samples/general-siblings-combinator-if/input.svelte

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818
.c ~ .d { color: green; }
1919
</style>
2020

21-
<div class="a" />
21+
<div class="a"></div>
2222

2323
{#if foo}
24-
<div class="b" />
24+
<div class="b"></div>
2525
{:else if bar}
26-
<div class="c" />
26+
<div class="c"></div>
2727
{:else}
28-
<div class="d" />
28+
<div class="d"></div>
2929
{/if}
3030

31-
<div class="e" />
31+
<div class="e"></div>

packages/svelte/tests/css/samples/general-siblings-combinator-slot/input.svelte

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@
1515
.b ~ .g { color: green; }
1616
</style>
1717

18-
<div class="a" />
18+
<div class="a"></div>
1919
<App>
20-
<div class="b" slot="a" />
20+
<div class="b" slot="a"></div>
2121

2222
<div class="c" slot="b">
23-
<div class="d" />
24-
<div class="e" />
23+
<div class="d"></div>
24+
<div class="e"></div>
2525
</div>
2626

27-
<div class="f" slot="c" />
27+
<div class="f" slot="c"></div>
2828
</App>
2929

30-
<div class="g" />
30+
<div class="g"></div>

0 commit comments

Comments
 (0)