Skip to content

Commit 9e9fb24

Browse files
authored
fix: relax parent validation (#14442)
This reverts #13255 / #13158, and helps with the validation error part of #14120 If you would have a component like this... ```svelte <td>hi there</td> ``` ...and then render it on the server via our `render` function like this: ```js const result = render(Main); ``` ...then right now you get an error saying that `td` is not valid at this position. But that doesn't seem right, because we should give people the benefit of the doubt: It may very well be that someone renders such a component and then correctly puts it into a `tr` tag themselves on the server (another example is rendering a full html document like in #14120). All the other validation where there's a known parent (X not valid inside Y) is untouched by this. Doing this as cleanup prior to tackling #13331
1 parent 4f0dde5 commit 9e9fb24

File tree

5 files changed

+20
-23
lines changed

5 files changed

+20
-23
lines changed

.changeset/cool-gifts-sniff.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: relax html parent validation

packages/svelte/src/html-tree-validation.js

+11-13
Original file line numberDiff line numberDiff line change
@@ -167,25 +167,23 @@ export function is_tag_valid_with_ancestor(tag, ancestors) {
167167
* Returns false if the tag is not allowed inside the parent tag such that it will result
168168
* in the browser repairing the HTML, which will likely result in an error during hydration.
169169
* @param {string} tag
170-
* @param {string | null} parent_tag
170+
* @param {string} parent_tag
171171
* @returns {boolean}
172172
*/
173173
export function is_tag_valid_with_parent(tag, parent_tag) {
174174
if (tag.includes('-') || parent_tag?.includes('-')) return true; // custom elements can be anything
175175

176-
if (parent_tag !== null) {
177-
const disallowed = disallowed_children[parent_tag];
176+
const disallowed = disallowed_children[parent_tag];
178177

179-
if (disallowed) {
180-
if ('direct' in disallowed && disallowed.direct.includes(tag)) {
181-
return false;
182-
}
183-
if ('descendant' in disallowed && disallowed.descendant.includes(tag)) {
184-
return false;
185-
}
186-
if ('only' in disallowed && disallowed.only) {
187-
return disallowed.only.includes(tag);
188-
}
178+
if (disallowed) {
179+
if ('direct' in disallowed && disallowed.direct.includes(tag)) {
180+
return false;
181+
}
182+
if ('descendant' in disallowed && disallowed.descendant.includes(tag)) {
183+
return false;
184+
}
185+
if ('only' in disallowed && disallowed.only) {
186+
return disallowed.only.includes(tag);
189187
}
190188
}
191189

packages/svelte/src/internal/server/dev.js

+2-6
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,12 @@ function stringify(element) {
3434

3535
/**
3636
* @param {Payload} payload
37-
* @param {Element | null} parent
37+
* @param {Element} parent
3838
* @param {Element} child
3939
*/
4040
function print_error(payload, parent, child) {
4141
var message =
42-
(parent === null
43-
? `node_invalid_placement_ssr: ${stringify(child)} needs a valid parent element\n\n`
44-
: `node_invalid_placement_ssr: ${stringify(parent)} cannot contain ${stringify(child)}\n\n`) +
42+
`node_invalid_placement_ssr: ${stringify(parent)} cannot contain ${stringify(child)}\n\n` +
4543
'This can cause content to shift around as the browser repairs the HTML, and will likely result in a `hydration_mismatch` warning.';
4644

4745
if ((seen ??= new Set()).has(message)) return;
@@ -85,8 +83,6 @@ export function push_element(payload, tag, line, column) {
8583
}
8684
ancestor = ancestor.parent;
8785
}
88-
} else if (!is_tag_valid_with_parent(tag, null)) {
89-
print_error(payload, null, child);
9086
}
9187

9288
parent = child;

packages/svelte/tests/runtime-runes/samples/invalid-html-ssr/_config.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,15 @@ export default test({
55
dev: true
66
},
77

8-
html: `<p></p><h1>foo</h1><p></p><form></form> hello`,
8+
html: `<p></p><h1>foo</h1><p></p><form></form>`,
99

1010
recover: true,
1111

1212
mode: ['hydrate'],
1313

1414
errors: [
1515
'node_invalid_placement_ssr: `<p>` (main.svelte:6:0) cannot contain `<h1>` (h1.svelte:1:0)\n\nThis can cause content to shift around as the browser repairs the HTML, and will likely result in a `hydration_mismatch` warning.',
16-
'node_invalid_placement_ssr: `<form>` (main.svelte:9:0) cannot contain `<form>` (form.svelte:1:0)\n\nThis can cause content to shift around as the browser repairs the HTML, and will likely result in a `hydration_mismatch` warning.',
17-
'node_invalid_placement_ssr: `<td>` (main.svelte:12:0) needs a valid parent element\n\nThis can cause content to shift around as the browser repairs the HTML, and will likely result in a `hydration_mismatch` warning.'
16+
'node_invalid_placement_ssr: `<form>` (main.svelte:9:0) cannot contain `<form>` (form.svelte:1:0)\n\nThis can cause content to shift around as the browser repairs the HTML, and will likely result in a `hydration_mismatch` warning.'
1817
],
1918

2019
warnings: [

packages/svelte/tests/runtime-runes/samples/invalid-html-ssr/main.svelte

-1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,3 @@
99
<form>
1010
<Form />
1111
</form>
12-
<td>hello</td>

0 commit comments

Comments
 (0)