diff --git a/.changeset/chilly-glasses-retire.md b/.changeset/chilly-glasses-retire.md new file mode 100644 index 0000000000..d98cd25f31 --- /dev/null +++ b/.changeset/chilly-glasses-retire.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: exclude custom elements from HTML tree validation diff --git a/packages/svelte/src/html-tree-validation.js b/packages/svelte/src/html-tree-validation.js index 9a191ba3f1..da5567f56a 100644 --- a/packages/svelte/src/html-tree-validation.js +++ b/packages/svelte/src/html-tree-validation.js @@ -142,12 +142,17 @@ const disallowed_children = { * @returns {boolean} */ export function is_tag_valid_with_ancestor(tag, ancestors) { + if (tag.includes('-')) return true; // custom elements can be anything + const target = ancestors[ancestors.length - 1]; const disallowed = disallowed_children[target]; if (!disallowed) return true; if ('reset_by' in disallowed && disallowed.reset_by) { for (let i = ancestors.length - 2; i >= 0; i--) { + const ancestor = ancestors[i]; + if (ancestor.includes('-')) return true; // custom elements can be anything + // A reset means that forbidden descendants are allowed again if (disallowed.reset_by.includes(ancestors[i])) { return true; @@ -166,6 +171,8 @@ export function is_tag_valid_with_ancestor(tag, ancestors) { * @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]; diff --git a/packages/svelte/tests/validator/samples/invalid-node-placement-6/errors.json b/packages/svelte/tests/validator/samples/invalid-node-placement-6/errors.json index b80d739621..63fc9c517e 100644 --- a/packages/svelte/tests/validator/samples/invalid-node-placement-6/errors.json +++ b/packages/svelte/tests/validator/samples/invalid-node-placement-6/errors.json @@ -3,11 +3,11 @@ "code": "node_invalid_placement", "message": "`
` is invalid inside `
`", "start": { - "line": 11, + "line": 16, "column": 3 }, "end": { - "line": 11, + "line": 16, "column": 19 } } diff --git a/packages/svelte/tests/validator/samples/invalid-node-placement-6/input.svelte b/packages/svelte/tests/validator/samples/invalid-node-placement-6/input.svelte index 0077ffd36e..96e0acd9f9 100644 --- a/packages/svelte/tests/validator/samples/invalid-node-placement-6/input.svelte +++ b/packages/svelte/tests/validator/samples/invalid-node-placement-6/input.svelte @@ -6,6 +6,11 @@
valid
valid
+ + +
valid
+
valid
+
invalid
diff --git a/packages/svelte/tests/validator/samples/invalid-node-placement-7/errors.json b/packages/svelte/tests/validator/samples/invalid-node-placement-7/errors.json new file mode 100644 index 0000000000..edfc158c9d --- /dev/null +++ b/packages/svelte/tests/validator/samples/invalid-node-placement-7/errors.json @@ -0,0 +1,14 @@ +[ + { + "code": "node_invalid_placement", + "message": "`` is invalid inside `
`", + "start": { + "line": 8, + "column": 1 + }, + "end": { + "line": 8, + "column": 16 + } + } +] diff --git a/packages/svelte/tests/validator/samples/invalid-node-placement-7/input.svelte b/packages/svelte/tests/validator/samples/invalid-node-placement-7/input.svelte new file mode 100644 index 0000000000..decef2110d --- /dev/null +++ b/packages/svelte/tests/validator/samples/invalid-node-placement-7/input.svelte @@ -0,0 +1,9 @@ + + + + + +
+ + +