Skip to content

Commit

Permalink
breaking: warn on self-closing non-void HTML tags (#11114)
Browse files Browse the repository at this point in the history
* warn on self-closing non-void HTML tags

* fix tests

* changeset

* account for foreign namespace
  • Loading branch information
Rich-Harris authored Apr 18, 2024
1 parent 5665498 commit 42ce8d7
Show file tree
Hide file tree
Showing 137 changed files with 1,475 additions and 1,116 deletions.
5 changes: 5 additions & 0 deletions .changeset/nine-cooks-join.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

breaking: warn on self-closing non-void HTML tags
22 changes: 21 additions & 1 deletion packages/svelte/src/compiler/phases/2-analyze/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ import {
import { warn } from '../../warnings.js';
import fuzzymatch from '../1-parse/utils/fuzzymatch.js';
import { binding_properties } from '../bindings.js';
import { ContentEditableBindings, EventModifiers, SVGElements } from '../constants.js';
import {
ContentEditableBindings,
EventModifiers,
SVGElements,
VoidElements
} from '../constants.js';
import { is_custom_element_node } from '../nodes.js';
import {
regex_illegal_attribute_character,
Expand Down Expand Up @@ -572,6 +577,21 @@ const validation = {
}
}

if (
context.state.analysis.source[node.end - 2] === '/' &&
context.state.options.namespace !== 'foreign' &&
!VoidElements.includes(node.name) &&
!SVGElements.includes(node.name)
) {
warn(
context.state.analysis.warnings,
node,
context.path,
'invalid-self-closing-tag',
node.name
);
}

context.next({
...context.state,
parent_element: node.name
Expand Down
9 changes: 8 additions & 1 deletion packages/svelte/src/compiler/warnings.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,12 @@ const options = {
"The 'customElement' option is used when generating a custom element. Did you forget the 'customElement: true' compile option?"
};

const misc = {
/** @param {string} name */
'invalid-self-closing-tag': (name) =>
`Self-closing HTML tags for non-void elements are ambiguous — use <${name} ...></${name}> rather than <${name} ... />`
};

/** @satisfies {Warnings} */
const warnings = {
...css,
Expand All @@ -261,7 +267,8 @@ const warnings = {
...components,
...legacy,
...block,
...options
...options,
...misc
};

/** @typedef {typeof warnings} AllWarnings */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<Nested>
<div slot="slot1">
<div>
<div slot="slot2" />
<div slot="slot2"></div>
</div>
</div>
</Nested>
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<Nested>
<div>
<div>
<div slot="slot2" />
<div slot="slot2"></div>
</div>
</div>
</Nested>
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

<Nested>
<div slot="slot1">
<div slot="slot2" />
<div slot="slot2"></div>
</div>
</Nested>
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,24 @@
.c ~ .g { color: green; }
</style>

<div class="a" />
<div class="a"></div>

{#await promise then value}
<div class="b" />
<div class="b"></div>
{:catch error}
<div class="c" />
<div class="c"></div>
{/await}

{#await promise}
<div class="d" />
<div class="d"></div>
{:catch error}
<div class="e" />
<div class="e"></div>
{/await}

{#await promise}
<div class="f" />
<div class="f"></div>
{:then error}
<div class="g" />
<div class="g"></div>
{/await}

<div class="h" />
<div class="h"></div>
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
.b ~ .d { color: green; }
</style>

<div class="a" />
<div class="a"></div>

{#await promise}
<div class="b" />
<div class="b"></div>
{:then value}
<div class="c" />
<div class="c"></div>
{:catch error}
<div class="d" />
<div class="d"></div>
{/await}

<div class="e" />
<div class="e"></div>
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
}
</style>

<div class="a" />
<div class="a"></div>

{#each array as item}
<div class="b" />
<div class="c" />
<div class="b"></div>
<div class="c"></div>
{/each}

<div class="d" />
<div class="d"></div>
Original file line number Diff line number Diff line change
Expand Up @@ -35,43 +35,43 @@
.e ~ .f { color: green; }
</style>

<div class="a" />
<div class="a"></div>

{#each array as a}
<div class="b" />
<div class="b"></div>
{#each array as b}
<div class="c" />
<div class="c"></div>
{:else}
<div class="d" />
<div class="d"></div>
{/each}
{/each}

{#each array as c}
{#each array as d}
<div class="e" />
<div class="e"></div>
{/each}
{:else}
<div class="f" />
<div class="f"></div>
{/each}

{#each array as x}
<div class="g" />
<div class="g"></div>
{#each array as y}
{#each array as z}
<div class="h" />
<div class="h"></div>
{/each}
{:else}
<div class="i" />
<div class="i"></div>
{/each}
<div class="j" />
<div class="j"></div>
{/each}

<div class="k" />
<div class="k"></div>

{#each array as item}
{#each array as item}
<div class="l" />
<div class="l"></div>
{:else}
<div class="m" />
<div class="m"></div>
{/each}
{/each}
{/each}
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
.b ~ .c { color: green; }
</style>

<div class="a" />
<div class="a"></div>

{#each array as item}
<div class="b" />
<div class="b"></div>
{:else}
<div class="c" />
<div class="c"></div>
{/each}

<div class="d" />
<div class="d"></div>
Original file line number Diff line number Diff line change
Expand Up @@ -65,49 +65,49 @@
.g ~ .i { color: green; }
</style>

<div class="a" />
<div class="a"></div>

{#each array as item}
<div class="b" />
<div class="c" />
<div class="b"></div>
<div class="c"></div>
{/each}

{#each array as item}
{#each array as item}
{#each array as item}
<div class="d" />
<div class="d"></div>
{/each}
<div class="e" />
<div class="e"></div>
{/each}
<div class="f" />
<div class="f"></div>
{/each}

{#each array as item}
<div class="g" />
<div class="g"></div>
{#each array as item}
<div class="h" />
<div class="h"></div>
{#each array as item}
<div class="i" />
<div class="i"></div>
{/each}
{/each}
{/each}

{#each array as item}
<div class="j" />
<div class="j"></div>
{#each array as item}
<div class="k" />
<div class="k"></div>
{#each array as item}
<div class="l" />
<div class="l"></div>
{/each}
{/each}
{/each}

{#each array as item}
{#each array as item}
{#each array as item}
<div class="m" />
<div class="m"></div>
{/each}
<div class="n" />
<div class="n"></div>
{/each}
<div class="o" />
{/each}
<div class="o"></div>
{/each}
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
}
</style>

<div />
<div></div>

{#each array as item}
<span class="each" />
<div class="each" />
<span class="each" />
<div class="each" />
<span class="each"></span>
<div class="each"></div>
<span class="each"></span>
<div class="each"></div>
{/each}

<span />
<span></span>
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@
.b ~ .c { color: green; }
</style>

<div class="a" />
<div class="a"></div>

{#if foo}
<div class="b" />
<div class="b"></div>
{:else}
{#each array as item}
<div class="c" />
<div class="c"></div>
{/each}
{/if}

<div class="d" />
<div class="d"></div>
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
.b ~ .c { color: green; }
</style>

<div class="a" />
<div class="a"></div>

{#if foo}
<div class="b" />
<div class="b"></div>
{:else if bar}
<div class="c" />
<div class="c"></div>
{/if}

<div class="d" />
<div class="d"></div>
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@
.c ~ .d { color: green; }
</style>

<div class="a" />
<div class="a"></div>

{#if foo}
<div class="b" />
<div class="b"></div>
{:else if bar}
<div class="c" />
<div class="c"></div>
{:else}
<div class="d" />
<div class="d"></div>
{/if}

<div class="e" />
<div class="e"></div>
Loading

0 comments on commit 42ce8d7

Please sign in to comment.