treat special elements that never have content as void elements

pull/11245/head
Jeremiasz Major 2 years ago
parent 669d2d7a1e
commit e33af522ab
No known key found for this signature in database
GPG Key ID: 482514409C7EBE01

@ -229,8 +229,6 @@ const elements = {
'invalid-textarea-content': () =>
`A <textarea> can have either a value attribute or (equivalently) child content, but not both`,
'invalid-void-content': () => `Void elements cannot have children or closing tags`,
/** @param {string} name */
'invalid-element-content': (name) => `<${name}> cannot have children`,
'invalid-tag-name': () => 'Expected valid tag name',
/**
* @param {string} node

@ -99,18 +99,7 @@ export default function tag(parser) {
const name = read_tag_name(parser);
if (root_only_meta_tags.has(name)) {
if (is_closing_tag) {
if (
(name === 'svelte:window' || name === 'svelte:body' || name === 'svelte:document') &&
/** @type {import('#compiler').ElementLike} */ (parent).fragment.nodes.length
) {
error(
/** @type {import('#compiler').ElementLike} */ (parent).fragment.nodes[0].start,
'invalid-element-content',
name
);
}
} else {
if (!is_closing_tag) {
if (name in parser.meta_tags) {
error(start, 'duplicate-svelte-element', name);
}

@ -65,7 +65,11 @@ const void_element_names = [
'param',
'source',
'track',
'wbr'
'wbr',
'svelte:options',
'svelte:window',
'svelte:document',
'svelte:body'
];
/** @param {string} name */

@ -0,0 +1,9 @@
import { test } from '../../test';
export default test({
error: {
code: 'invalid-void-content',
message: 'Void elements cannot have children or closing tags',
position: [23, 23]
}
});

@ -0,0 +1,9 @@
import { test } from '../../test';
export default test({
error: {
code: 'invalid-void-content',
message: 'Void elements cannot have children or closing tags',
position: [33, 33]
}
});

@ -0,0 +1 @@
<svelte:options immutable={true}></svelte:options>

@ -1,9 +0,0 @@
import { test } from '../../test';
export default test({
error: {
code: 'invalid-element-content',
message: '<svelte:window> cannot have children',
position: [15, 15]
}
});

@ -0,0 +1,4 @@
<svelte:options immutable={false}>
<svelte:window on:event={() => null}>
<svelte:document on:event={() => null}>
<svelte:body on:event={() => null}>

@ -0,0 +1,210 @@
{
"css": null,
"js": [],
"start": 0,
"end": 148,
"type": "Root",
"fragment": {
"type": "Fragment",
"nodes": [
{
"type": "Text",
"start": 34,
"end": 35,
"raw": "\n",
"data": "\n"
},
{
"type": "SvelteWindow",
"start": 35,
"end": 72,
"name": "svelte:window",
"attributes": [
{
"start": 50,
"end": 71,
"type": "OnDirective",
"name": "event",
"modifiers": [],
"expression": {
"type": "ArrowFunctionExpression",
"start": 60,
"end": 70,
"loc": {
"start": {
"line": 2,
"column": 25
},
"end": {
"line": 2,
"column": 35
}
},
"id": null,
"expression": true,
"generator": false,
"async": false,
"params": [],
"body": {
"type": "Literal",
"start": 66,
"end": 70,
"loc": {
"start": {
"line": 2,
"column": 31
},
"end": {
"line": 2,
"column": 35
}
},
"value": null,
"raw": "null"
}
}
}
],
"fragment": {
"type": "Fragment",
"nodes": [],
"transparent": true
}
},
{
"type": "Text",
"start": 72,
"end": 73,
"raw": "\n",
"data": "\n"
},
{
"type": "SvelteDocument",
"start": 73,
"end": 112,
"name": "svelte:document",
"attributes": [
{
"start": 90,
"end": 111,
"type": "OnDirective",
"name": "event",
"modifiers": [],
"expression": {
"type": "ArrowFunctionExpression",
"start": 100,
"end": 110,
"loc": {
"start": {
"line": 3,
"column": 27
},
"end": {
"line": 3,
"column": 37
}
},
"id": null,
"expression": true,
"generator": false,
"async": false,
"params": [],
"body": {
"type": "Literal",
"start": 106,
"end": 110,
"loc": {
"start": {
"line": 3,
"column": 33
},
"end": {
"line": 3,
"column": 37
}
},
"value": null,
"raw": "null"
}
}
}
],
"fragment": {
"type": "Fragment",
"nodes": [],
"transparent": true
}
},
{
"type": "Text",
"start": 112,
"end": 113,
"raw": "\n",
"data": "\n"
},
{
"type": "SvelteBody",
"start": 113,
"end": 148,
"name": "svelte:body",
"attributes": [
{
"start": 126,
"end": 147,
"type": "OnDirective",
"name": "event",
"modifiers": [],
"expression": {
"type": "ArrowFunctionExpression",
"start": 136,
"end": 146,
"loc": {
"start": {
"line": 4,
"column": 23
},
"end": {
"line": 4,
"column": 33
}
},
"id": null,
"expression": true,
"generator": false,
"async": false,
"params": [],
"body": {
"type": "Literal",
"start": 142,
"end": 146,
"loc": {
"start": {
"line": 4,
"column": 29
},
"end": {
"line": 4,
"column": 33
}
},
"value": null,
"raw": "null"
}
}
}
],
"fragment": {
"type": "Fragment",
"nodes": [],
"transparent": true
}
}
],
"transparent": false
},
"options": {
"start": 0,
"end": 34,
"immutable": false
}
}

@ -12,8 +12,8 @@
<title>Cute test</title>
</svelte:head>
<svelte:window on:click></svelte:window>
<svelte:body on:mouseenter></svelte:body>
<svelte:window on:click>
<svelte:body on:mouseenter>
{#each everyone as someone (someone)}
<p>{someone}</p>

@ -3,4 +3,4 @@
{/if}
<Component let:x></Component>
<div let:x></div><!-- strictly speaking this is invalid, but it was never checked in Svelte 3/4 either, and is now deprecated, so don't mind -->
<svelte:window let:x></svelte:window>
<svelte:window let:x>

Loading…
Cancel
Save