From 2e0dcd78722d457f4c9e4b6db4ef4cb3ab26c037 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Thu, 12 Dec 2024 20:09:29 +0000 Subject: [PATCH] fix: ensure if block paths retain correct template namespacing (#14685) * fix: ensure if block paths retain correct template namespacing * add tests * address feedback * address feedback * simplify --------- Co-authored-by: Rich Harris --- .changeset/giant-moons-accept.md | 5 +++++ .../src/compiler/phases/3-transform/utils.js | 19 ++++++++++++++++++- .../svg-namespace-if-block/Child.svelte | 8 ++++++++ .../samples/svg-namespace-if-block/_config.js | 14 ++++++++++++++ .../svg-namespace-if-block/main.svelte | 7 +++++++ 5 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 .changeset/giant-moons-accept.md create mode 100644 packages/svelte/tests/runtime-runes/samples/svg-namespace-if-block/Child.svelte create mode 100644 packages/svelte/tests/runtime-runes/samples/svg-namespace-if-block/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/svg-namespace-if-block/main.svelte diff --git a/.changeset/giant-moons-accept.md b/.changeset/giant-moons-accept.md new file mode 100644 index 0000000000..7940371d6f --- /dev/null +++ b/.changeset/giant-moons-accept.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure if block paths retain correct template namespacing diff --git a/packages/svelte/src/compiler/phases/3-transform/utils.js b/packages/svelte/src/compiler/phases/3-transform/utils.js index 14fd3aa2e8..ffd07dd26a 100644 --- a/packages/svelte/src/compiler/phases/3-transform/utils.js +++ b/packages/svelte/src/compiler/phases/3-transform/utils.js @@ -347,7 +347,24 @@ export function infer_namespace(namespace, parent, nodes) { } } - return namespace; + /** @type {Namespace | null} */ + let new_namespace = null; + + // Check the elements within the fragment and look for consistent namespaces. + // If we have no namespaces or they are mixed, then fallback to existing namespace + for (const node of nodes) { + if (node.type !== 'RegularElement') continue; + + if (node.metadata.mathml) { + new_namespace = new_namespace === null || new_namespace === 'mathml' ? 'mathml' : 'html'; + } else if (node.metadata.svg) { + new_namespace = new_namespace === null || new_namespace === 'svg' ? 'svg' : 'html'; + } else { + return 'html'; + } + } + + return new_namespace ?? namespace; } /** diff --git a/packages/svelte/tests/runtime-runes/samples/svg-namespace-if-block/Child.svelte b/packages/svelte/tests/runtime-runes/samples/svg-namespace-if-block/Child.svelte new file mode 100644 index 0000000000..53e6203dde --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/svg-namespace-if-block/Child.svelte @@ -0,0 +1,8 @@ + +{#if true} + + + +{:else} +
lol
+{/if} diff --git a/packages/svelte/tests/runtime-runes/samples/svg-namespace-if-block/_config.js b/packages/svelte/tests/runtime-runes/samples/svg-namespace-if-block/_config.js new file mode 100644 index 0000000000..22a2469bfb --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/svg-namespace-if-block/_config.js @@ -0,0 +1,14 @@ +import { test, ok } from '../../test'; + +export default test({ + html: ``, + test({ assert, target }) { + const g = target.querySelector('g'); + const rect = target.querySelector('rect'); + ok(g); + ok(rect); + + assert.equal(g.namespaceURI, 'http://www.w3.org/2000/svg'); + assert.equal(rect.namespaceURI, 'http://www.w3.org/2000/svg'); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/svg-namespace-if-block/main.svelte b/packages/svelte/tests/runtime-runes/samples/svg-namespace-if-block/main.svelte new file mode 100644 index 0000000000..8f6154462f --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/svg-namespace-if-block/main.svelte @@ -0,0 +1,7 @@ + + + + +