mirror of https://github.com/sveltejs/svelte
fix: dynamic namespace fixes and enhancements (#11219)
* fix: fall back to component namespace when not statically determinable In #10006 we added more elaborate mechanisms to determine which namespace a given element is in. For `<svelte:element>` we added a "can't know at compile time" case and introduced a limited heuristic into the runtime. This doesn't work for a few reasons: - we're checking the parent's namespace to determine the current namespace, but the element itself could be the one that _changes_ the namespace - as mentioned in the previous comment already, on the first render we can't do any parent analysis - it does not take into account the static component namespace The last point is the crucial one: In Svelte 4, we're falling back to the component namespace if we can't know statically - e.g. if someone added `<svelte:options namespace="svg">` then `<svelte:element>` should fall back to that namespace instead. We were not doing that up until now, which introduced a regression. Fixing this also means getting rid of the (flawed) "can't know statically" heuristic. Fixes #10858, though for a complete solution we likely need some way to tell `<svelte:element>` the namespace at runtime through a special attribute. Maybe we can use `xmlns` for that like we do in the static case * support dynamic svelte:element namespace through xmlns attribute * fixpull/11223/head
parent
43d13e92a0
commit
27eb91bbce
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"svelte": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: fall back to component namespace when not statically determinable, add way to tell `<svelte:element>` the namespace at runtime
|
@ -0,0 +1,9 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
test({ assert, target }) {
|
||||||
|
const path = target.querySelector('path');
|
||||||
|
|
||||||
|
assert.equal(path?.namespaceURI, 'http://www.w3.org/2000/svg');
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,11 @@
|
|||||||
|
<svelte:options namespace="svg" />
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Svg from "./svg.svelte";
|
||||||
|
|
||||||
|
let tag = "path";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Svg>
|
||||||
|
<svelte:element this="{tag}" d="M21 12a9 9 0 1 1-6.219-8.56"/>
|
||||||
|
</Svg>
|
After Width: | Height: | Size: 24 B |
@ -0,0 +1,10 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target }) {
|
||||||
|
assert.equal(target.querySelector('path')?.namespaceURI, 'http://www.w3.org/2000/svg');
|
||||||
|
|
||||||
|
await target.querySelector('button')?.click();
|
||||||
|
assert.equal(target.querySelector('div')?.namespaceURI, 'http://www.w3.org/1999/xhtml');
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,14 @@
|
|||||||
|
<script>
|
||||||
|
let tag = $state('path');
|
||||||
|
let xmlns = $state('http://www.w3.org/2000/svg');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={() => {
|
||||||
|
tag = 'div';
|
||||||
|
xmlns = null;
|
||||||
|
}}>change</button>
|
||||||
|
|
||||||
|
<!-- wrapper necessary or else jsdom says this is always an xhtml namespace -->
|
||||||
|
<svg>
|
||||||
|
<svelte:element this={tag} xmlns={xmlns} />
|
||||||
|
</svg>
|
Loading…
Reference in new issue