Skip to content

Commit

Permalink
fix: relax parent validation (#14442)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
dummdidumm authored Nov 26, 2024
1 parent 4f0dde5 commit 9e9fb24
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 23 deletions.
5 changes: 5 additions & 0 deletions .changeset/cool-gifts-sniff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: relax html parent validation
24 changes: 11 additions & 13 deletions packages/svelte/src/html-tree-validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,25 +167,23 @@ export function is_tag_valid_with_ancestor(tag, ancestors) {
* Returns false if the tag is not allowed inside the parent tag such that it will result
* in the browser repairing the HTML, which will likely result in an error during hydration.
* @param {string} tag
* @param {string | null} parent_tag
* @param {string} parent_tag
* @returns {boolean}
*/
export function is_tag_valid_with_parent(tag, parent_tag) {
if (tag.includes('-') || parent_tag?.includes('-')) return true; // custom elements can be anything

if (parent_tag !== null) {
const disallowed = disallowed_children[parent_tag];
const disallowed = disallowed_children[parent_tag];

if (disallowed) {
if ('direct' in disallowed && disallowed.direct.includes(tag)) {
return false;
}
if ('descendant' in disallowed && disallowed.descendant.includes(tag)) {
return false;
}
if ('only' in disallowed && disallowed.only) {
return disallowed.only.includes(tag);
}
if (disallowed) {
if ('direct' in disallowed && disallowed.direct.includes(tag)) {
return false;
}
if ('descendant' in disallowed && disallowed.descendant.includes(tag)) {
return false;
}
if ('only' in disallowed && disallowed.only) {
return disallowed.only.includes(tag);
}
}

Expand Down
8 changes: 2 additions & 6 deletions packages/svelte/src/internal/server/dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,12 @@ function stringify(element) {

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

if ((seen ??= new Set()).has(message)) return;
Expand Down Expand Up @@ -85,8 +83,6 @@ export function push_element(payload, tag, line, column) {
}
ancestor = ancestor.parent;
}
} else if (!is_tag_valid_with_parent(tag, null)) {
print_error(payload, null, child);
}

parent = child;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@ export default test({
dev: true
},

html: `<p></p><h1>foo</h1><p></p><form></form> hello`,
html: `<p></p><h1>foo</h1><p></p><form></form>`,

recover: true,

mode: ['hydrate'],

errors: [
'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.',
'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.',
'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.'
'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.'
],

warnings: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,3 @@
<form>
<Form />
</form>
<td>hello</td>

0 comments on commit 9e9fb24

Please sign in to comment.