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