diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 7c3969cd54..45e754b35d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -55,6 +55,8 @@ jobs:
- name: type check
run: pnpm check
- name: lint
+ if: (${{ success() }} || ${{ failure() }}) # ensures this step runs even if previous steps fail (avoids multiple runs uncovering different issues at different steps)
run: pnpm lint
- name: build and check generated types
+ if: (${{ success() }} || ${{ failure() }}) # ensures this step runs even if previous steps fail
run: pnpm build && { [ "`git status --porcelain=v1`" == "" ] || (echo "Generated types have changed — please regenerate types locally and commit the changes after you have reviewed them"; git diff; exit 1); }
diff --git a/packages/svelte/src/compiler/phases/1-parse/read/options.js b/packages/svelte/src/compiler/phases/1-parse/read/options.js
index 31e81c7c71..69ca025f58 100644
--- a/packages/svelte/src/compiler/phases/1-parse/read/options.js
+++ b/packages/svelte/src/compiler/phases/1-parse/read/options.js
@@ -1,3 +1,4 @@
+import { namespace_svg } from '../../../../constants.js';
import { error } from '../../../errors.js';
const regex_valid_tag_name = /^[a-zA-Z][a-zA-Z0-9]*-[a-zA-Z0-9-]+$/;
@@ -156,7 +157,7 @@ export default function read_options(node) {
error(attribute, 'invalid-svelte-option-namespace');
}
- if (value === 'http://www.w3.org/2000/svg') {
+ if (value === namespace_svg) {
component_options.namespace = 'svg';
} else if (value === 'html' || value === 'svg' || value === 'foreign') {
component_options.namespace = value;
diff --git a/packages/svelte/src/compiler/phases/1-parse/state/element.js b/packages/svelte/src/compiler/phases/1-parse/state/element.js
index 5f2eda1f17..da177f596a 100644
--- a/packages/svelte/src/compiler/phases/1-parse/state/element.js
+++ b/packages/svelte/src/compiler/phases/1-parse/state/element.js
@@ -139,7 +139,10 @@ export default function tag(parser) {
name,
attributes: [],
fragment: create_fragment(true),
- parent: null
+ parent: null,
+ metadata: {
+ svg: false
+ }
};
parser.allow_whitespace();
diff --git a/packages/svelte/src/compiler/phases/2-analyze/index.js b/packages/svelte/src/compiler/phases/2-analyze/index.js
index 2f7cd0da04..e3ab2b8539 100644
--- a/packages/svelte/src/compiler/phases/2-analyze/index.js
+++ b/packages/svelte/src/compiler/phases/2-analyze/index.js
@@ -20,7 +20,7 @@ import { warn } from '../../warnings.js';
import check_graph_for_cycles from './utils/check_graph_for_cycles.js';
import { regex_starts_with_newline } from '../patterns.js';
import { create_attribute, is_element_node } from '../nodes.js';
-import { DelegatedEvents } from '../../../constants.js';
+import { DelegatedEvents, namespace_svg } from '../../../constants.js';
import { should_proxy_or_freeze } from '../3-transform/client/utils.js';
/**
@@ -1104,8 +1104,47 @@ const common_visitors = {
context.state.analysis.elements.push(node);
},
- SvelteElement(node, { state }) {
- state.analysis.elements.push(node);
+ SvelteElement(node, context) {
+ context.state.analysis.elements.push(node);
+
+ if (
+ context.state.options.namespace !== 'foreign' &&
+ node.tag.type === 'Literal' &&
+ typeof node.tag.value === 'string' &&
+ SVGElements.includes(node.tag.value)
+ ) {
+ node.metadata.svg = true;
+ return;
+ }
+
+ for (const attribute of node.attributes) {
+ if (attribute.type === 'Attribute') {
+ if (attribute.name === 'xmlns' && is_text_attribute(attribute)) {
+ node.metadata.svg = attribute.value[0].data === namespace_svg;
+ return;
+ }
+ }
+ }
+
+ for (let i = context.path.length - 1; i >= 0; i--) {
+ const ancestor = context.path[i];
+ if (
+ ancestor.type === 'Component' ||
+ ancestor.type === 'SvelteComponent' ||
+ ancestor.type === 'SvelteFragment' ||
+ ancestor.type === 'SnippetBlock'
+ ) {
+ // Inside a slot or a snippet -> this resets the namespace, so we can't determine it
+ return;
+ }
+ if (ancestor.type === 'SvelteElement' || ancestor.type === 'RegularElement') {
+ node.metadata.svg =
+ ancestor.type === 'RegularElement' && ancestor.name === 'foreignObject'
+ ? false
+ : ancestor.metadata.svg;
+ return;
+ }
+ }
}
};
diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js
index 19b9d3f244..61d426a798 100644
--- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js
+++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js
@@ -9,7 +9,7 @@ import {
import { binding_properties } from '../../../bindings.js';
import {
clean_nodes,
- determine_element_namespace,
+ determine_namespace_for_children,
escape_html,
infer_namespace
} from '../../utils.js';
@@ -43,11 +43,7 @@ import { sanitize_template_string } from '../../../../utils/sanitize_template_st
*/
function get_attribute_name(element, attribute, context) {
let name = attribute.name;
- if (
- element.type === 'RegularElement' &&
- !element.metadata.svg &&
- context.state.metadata.namespace !== 'foreign'
- ) {
+ if (!element.metadata.svg && context.state.metadata.namespace !== 'foreign') {
name = name.toLowerCase();
if (name in AttributeAliases) {
name = AttributeAliases[name];
@@ -1854,7 +1850,7 @@ export const template_visitors = {
const metadata = context.state.metadata;
const child_metadata = {
...context.state.metadata,
- namespace: determine_element_namespace(node, context.state.metadata.namespace, context.path)
+ namespace: determine_namespace_for_children(node, context.state.metadata.namespace)
};
context.state.template.push(`<${node.name}`);
@@ -2079,9 +2075,6 @@ export const template_visitors = {
/** @type {import('estree').ExpressionStatement[]} */
const lets = [];
- /** @type {string | null} */
- let namespace = null;
-
// Create a temporary context which picks up the init/update statements.
// They'll then be added to the function parameter of $.element
const element_id = b.id(context.state.scope.generate('$$element'));
@@ -2102,9 +2095,6 @@ export const template_visitors = {
for (const attribute of node.attributes) {
if (attribute.type === 'Attribute') {
attributes.push(attribute);
- if (attribute.name === 'xmlns' && is_text_attribute(attribute)) {
- namespace = attribute.value[0].data;
- }
} else if (attribute.type === 'SpreadAttribute') {
attributes.push(attribute);
} else if (attribute.type === 'ClassDirective') {
@@ -2153,19 +2143,32 @@ export const template_visitors = {
}
}
inner.push(...inner_context.state.after_update);
- inner.push(...create_block(node, 'dynamic_element', node.fragment.nodes, context));
+ inner.push(
+ ...create_block(node, 'dynamic_element', node.fragment.nodes, {
+ ...context,
+ state: {
+ ...context.state,
+ metadata: {
+ ...context.state.metadata,
+ namespace: determine_namespace_for_children(node, context.state.metadata.namespace)
+ }
+ }
+ })
+ );
context.state.after_update.push(
b.stmt(
b.call(
'$.element',
context.state.node,
get_tag,
+ node.metadata.svg === true
+ ? b.true
+ : node.metadata.svg === false
+ ? b.false
+ : b.literal(null),
inner.length === 0
? /** @type {any} */ (undefined)
- : b.arrow([element_id, b.id('$$anchor')], b.block(inner)),
- namespace === 'http://www.w3.org/2000/svg'
- ? b.literal(true)
- : /** @type {any} */ (undefined)
+ : b.arrow([element_id, b.id('$$anchor')], b.block(inner))
)
)
);
diff --git a/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js b/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js
index 14b8cd2105..5c92d4e906 100644
--- a/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js
+++ b/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js
@@ -15,7 +15,7 @@ import {
} from '../../constants.js';
import {
clean_nodes,
- determine_element_namespace,
+ determine_namespace_for_children,
escape_html,
infer_namespace,
transform_inspect_rune
@@ -482,11 +482,7 @@ function serialize_set_binding(node, context, fallback) {
*/
function get_attribute_name(element, attribute, context) {
let name = attribute.name;
- if (
- element.type === 'RegularElement' &&
- !element.metadata.svg &&
- context.state.metadata.namespace !== 'foreign'
- ) {
+ if (!element.metadata.svg && context.state.metadata.namespace !== 'foreign') {
name = name.toLowerCase();
// don't lookup boolean aliases here, the server runtime function does only
// check for the lowercase variants of boolean attributes
@@ -761,10 +757,10 @@ function serialize_element_spread_attributes(
}
const lowercase_attributes =
- element.type !== 'RegularElement' || element.metadata.svg || is_custom_element_node(element)
+ element.metadata.svg || (element.type === 'RegularElement' && is_custom_element_node(element))
? b.false
: b.true;
- const is_svg = element.type === 'RegularElement' && element.metadata.svg ? b.true : b.false;
+ const is_svg = element.metadata.svg ? b.true : b.false;
/** @type {import('estree').Expression[]} */
const args = [
b.array(values),
@@ -1165,7 +1161,7 @@ const template_visitors = {
RegularElement(node, context) {
const metadata = {
...context.state.metadata,
- namespace: determine_element_namespace(node, context.state.metadata.namespace, context.path)
+ namespace: determine_namespace_for_children(node, context.state.metadata.namespace)
};
context.state.template.push(t_string(`<${node.name}`));
@@ -1255,11 +1251,16 @@ const template_visitors = {
context.state.init.push(b.stmt(b.call('$.validate_dynamic_element_tag', b.thunk(tag))));
}
+ const metadata = {
+ ...context.state.metadata,
+ namespace: determine_namespace_for_children(node, context.state.metadata.namespace)
+ };
/** @type {import('./types').ComponentContext} */
const inner_context = {
...context,
state: {
...context.state,
+ metadata,
template: [],
init: []
}
@@ -1276,7 +1277,10 @@ const template_visitors = {
inner_context.state.template.push(t_string('>'));
const before = serialize_template(inner_context.state.template);
- const main = create_block(node, node.fragment.nodes, context);
+ const main = create_block(node, node.fragment.nodes, {
+ ...context,
+ state: { ...context.state, metadata }
+ });
const after = serialize_template([
t_expression(inner_id),
t_string(''),
diff --git a/packages/svelte/src/compiler/phases/3-transform/utils.js b/packages/svelte/src/compiler/phases/3-transform/utils.js
index a924a59e1a..ceb8838c90 100644
--- a/packages/svelte/src/compiler/phases/3-transform/utils.js
+++ b/packages/svelte/src/compiler/phases/3-transform/utils.js
@@ -188,7 +188,7 @@ export function clean_nodes(
}
/**
- * Infers the new namespace for the children of a node.
+ * Infers the namespace for the children of a node that should be used when creating the `$.template(...)`.
* @param {import('#compiler').Namespace} namespace
* @param {import('#compiler').SvelteNode} parent
* @param {import('#compiler').SvelteNode[]} nodes
@@ -201,19 +201,28 @@ export function infer_namespace(namespace, parent, nodes, path) {
path.at(-1)
: parent;
- if (
- namespace !== 'foreign' &&
+ if (namespace !== 'foreign') {
+ if (parent_node?.type === 'RegularElement' && parent_node.name === 'foreignObject') {
+ return 'html';
+ }
+
+ if (parent_node?.type === 'RegularElement' || parent_node?.type === 'SvelteElement') {
+ return parent_node.metadata.svg ? 'svg' : 'html';
+ }
+
// Re-evaluate the namespace inside slot nodes that reset the namespace
- (parent_node === undefined ||
+ if (
+ parent_node === undefined ||
parent_node.type === 'Root' ||
parent_node.type === 'Component' ||
parent_node.type === 'SvelteComponent' ||
parent_node.type === 'SvelteFragment' ||
- parent_node.type === 'SnippetBlock')
- ) {
- const new_namespace = check_nodes_for_namespace(nodes, 'keep');
- if (new_namespace !== 'keep' && new_namespace !== 'maybe_html') {
- namespace = new_namespace;
+ parent_node.type === 'SnippetBlock'
+ ) {
+ const new_namespace = check_nodes_for_namespace(nodes, 'keep');
+ if (new_namespace !== 'keep' && new_namespace !== 'maybe_html') {
+ return new_namespace;
+ }
}
}
@@ -229,7 +238,7 @@ export function infer_namespace(namespace, parent, nodes, path) {
*/
function check_nodes_for_namespace(nodes, namespace) {
for (const node of nodes) {
- if (node.type === 'RegularElement') {
+ if (node.type === 'RegularElement' || node.type === 'SvelteElement') {
if (!node.metadata.svg) {
namespace = 'html';
break;
@@ -279,36 +288,21 @@ function check_nodes_for_namespace(nodes, namespace) {
}
/**
- * @param {import('#compiler').RegularElement} node
+ * Determines the namespace the children of this node are in.
+ * @param {import('#compiler').RegularElement | import('#compiler').SvelteElement} node
* @param {import('#compiler').Namespace} namespace
- * @param {import('#compiler').SvelteNode[]} path
* @returns {import('#compiler').Namespace}
*/
-export function determine_element_namespace(node, namespace, path) {
- if (namespace !== 'foreign') {
- let parent = path.at(-1);
- if (parent?.type === 'Fragment') {
- parent = path.at(-2);
- }
+export function determine_namespace_for_children(node, namespace) {
+ if (namespace === 'foreign') {
+ return namespace;
+ }
- if (node.name === 'foreignObject') {
- return 'html';
- } else if (
- namespace !== 'svg' ||
- parent?.type === 'Component' ||
- parent?.type === 'SvelteComponent' ||
- parent?.type === 'SvelteFragment' ||
- parent?.type === 'SnippetBlock'
- ) {
- if (node.metadata.svg) {
- return 'svg';
- } else {
- return 'html';
- }
- }
+ if (node.name === 'foreignObject') {
+ return 'html';
}
- return namespace;
+ return node.metadata.svg ? 'svg' : 'html';
}
/**
diff --git a/packages/svelte/src/compiler/types/template.d.ts b/packages/svelte/src/compiler/types/template.d.ts
index 76a579ae5a..f63fb369a7 100644
--- a/packages/svelte/src/compiler/types/template.d.ts
+++ b/packages/svelte/src/compiler/types/template.d.ts
@@ -308,6 +308,13 @@ export interface SvelteElement extends BaseElement {
type: 'SvelteElement';
name: 'svelte:element';
tag: Expression;
+ metadata: {
+ /**
+ * `true`/`false` if this is definitely (not) an svg element.
+ * `null` means we can't know statically.
+ */
+ svg: boolean | null;
+ };
}
export interface SvelteFragment extends BaseElement {
diff --git a/packages/svelte/src/constants.js b/packages/svelte/src/constants.js
index 3da2f9e4f2..ae49627c88 100644
--- a/packages/svelte/src/constants.js
+++ b/packages/svelte/src/constants.js
@@ -85,3 +85,6 @@ export const DOMBooleanAttributes = [
'seamless',
'selected'
];
+
+export const namespace_svg = 'http://www.w3.org/2000/svg';
+export const namespace_html = 'http://www.w3.org/1999/xhtml';
diff --git a/packages/svelte/src/internal/client/render.js b/packages/svelte/src/internal/client/render.js
index a0051c6b53..f8cd1a0505 100644
--- a/packages/svelte/src/internal/client/render.js
+++ b/packages/svelte/src/internal/client/render.js
@@ -19,7 +19,13 @@ import {
create_dynamic_component_block,
create_snippet_block
} from './block.js';
-import { PassiveDelegatedEvents, DelegatedEvents, AttributeAliases } from '../../constants.js';
+import {
+ PassiveDelegatedEvents,
+ DelegatedEvents,
+ AttributeAliases,
+ namespace_svg,
+ namespace_html
+} from '../../constants.js';
import { create_fragment_from_html, insert, reconcile_html, remove } from './reconciler.js';
import {
render_effect,
@@ -1595,11 +1601,11 @@ function swap_block_dom(block, from, to) {
/**
* @param {Comment} anchor_node
* @param {() => string} tag_fn
+ * @param {boolean | null} is_svg `null` == not statically known
* @param {undefined | ((element: Element, anchor: Node) => void)} render_fn
- * @param {any} is_svg
* @returns {void}
*/
-export function element(anchor_node, tag_fn, render_fn, is_svg = false) {
+export function element(anchor_node, tag_fn, is_svg, render_fn) {
const block = create_dynamic_element_block();
hydrate_block_anchor(anchor_node);
let has_mounted = false;
@@ -1607,7 +1613,7 @@ export function element(anchor_node, tag_fn, render_fn, is_svg = false) {
/** @type {string} */
let tag;
- /** @type {null | HTMLElement | SVGElement} */
+ /** @type {null | Element} */
let element = null;
const element_effect = render_effect(
() => {
@@ -1623,11 +1629,20 @@ export function element(anchor_node, tag_fn, render_fn, is_svg = false) {
// Managed effect
const render_effect_signal = render_effect(
() => {
+ // We try our best infering the namespace in case it's not possible to determine statically,
+ // but on the first render on the client (without hydration) the parent will be undefined,
+ // since the anchor is not attached to its parent / the dom yet.
+ const ns =
+ is_svg || tag === 'svg'
+ ? namespace_svg
+ : is_svg === false || anchor_node.parentElement?.tagName === 'foreignObject'
+ ? null
+ : anchor_node.parentElement?.namespaceURI ?? null;
const next_element = tag
? current_hydration_fragment !== null
- ? /** @type {HTMLElement | SVGElement} */ (current_hydration_fragment[0])
- : is_svg
- ? document.createElementNS('http://www.w3.org/2000/svg', tag)
+ ? /** @type {Element} */ (current_hydration_fragment[0])
+ : ns
+ ? document.createElementNS(ns, tag)
: document.createElement(tag)
: null;
const prev_element = element;
@@ -2098,7 +2113,7 @@ export function cssProps(anchor, is_html, props, component) {
tag = document.createElement('div');
tag.style.display = 'contents';
} else {
- tag = document.createElementNS('http://www.w3.org/2000/svg', 'g');
+ tag = document.createElementNS(namespace_svg, 'g');
}
insert(tag, null, anchor);
component_anchor = empty();
@@ -2629,7 +2644,7 @@ export function spread_dynamic_element_attributes(node, prev, attrs, css_hash) {
/** @type {Element & ElementCSSInlineStyle} */ (node),
prev,
attrs,
- node.namespaceURI !== 'http://www.w3.org/2000/svg',
+ node.namespaceURI !== namespace_svg,
css_hash
);
}
diff --git a/packages/svelte/src/internal/index.js b/packages/svelte/src/internal/index.js
index 10ab1ef432..a3a2a92933 100644
--- a/packages/svelte/src/internal/index.js
+++ b/packages/svelte/src/internal/index.js
@@ -40,15 +40,12 @@ export {
unwrap,
freeze
} from './client/runtime.js';
-
export * from './client/each.js';
export * from './client/render.js';
export * from './client/validate.js';
export { raf } from './client/timing.js';
export { proxy, readonly, unstate } from './client/proxy.js';
-
export { create_custom_element } from './client/custom-element.js';
-
export {
child,
child_frag,
diff --git a/packages/svelte/tests/runtime-legacy/samples/dynamic-element-svg-implicit-namespace/_config.js b/packages/svelte/tests/runtime-legacy/samples/dynamic-element-svg-implicit-namespace/_config.js
new file mode 100644
index 0000000000..12a0960d87
--- /dev/null
+++ b/packages/svelte/tests/runtime-legacy/samples/dynamic-element-svg-implicit-namespace/_config.js
@@ -0,0 +1,16 @@
+import { test } from '../../test';
+
+export default test({
+ // This is skipped for now, because it's not clear how to make this work on client-side initial run:
+ // The anchor isn't connected to its parent at the time we can do a runtime check for the namespace, and we
+ // need the parent for this check. (this didn't work in Svelte 4 either)
+ skip: true,
+ html: '',
+
+ test({ assert, target }) {
+ const svg = target.querySelector('svg');
+ const rect = target.querySelector('path');
+ assert.equal(svg?.namespaceURI, 'http://www.w3.org/2000/svg');
+ assert.equal(rect?.namespaceURI, 'http://www.w3.org/2000/svg');
+ }
+});
diff --git a/packages/svelte/tests/runtime-legacy/samples/dynamic-element-svg-implicit-namespace/main.svelte b/packages/svelte/tests/runtime-legacy/samples/dynamic-element-svg-implicit-namespace/main.svelte
new file mode 100644
index 0000000000..00069f711c
--- /dev/null
+++ b/packages/svelte/tests/runtime-legacy/samples/dynamic-element-svg-implicit-namespace/main.svelte
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/packages/svelte/tests/runtime-legacy/samples/dynamic-element-svg-inherit-namespace/_config.js b/packages/svelte/tests/runtime-legacy/samples/dynamic-element-svg-inherit-namespace/_config.js
new file mode 100644
index 0000000000..999b8fc9b5
--- /dev/null
+++ b/packages/svelte/tests/runtime-legacy/samples/dynamic-element-svg-inherit-namespace/_config.js
@@ -0,0 +1,20 @@
+import { test } from '../../test';
+
+export default test({
+ test({ assert, target }) {
+ const [svg1, svg2] = target.querySelectorAll('svg');
+ const [path1, path2] = target.querySelectorAll('path');
+ const [fO1, fO2] = target.querySelectorAll('foreignObject');
+ const [span1, span2] = target.querySelectorAll('span');
+
+ assert.equal(svg1.namespaceURI, 'http://www.w3.org/2000/svg');
+ assert.equal(path1.namespaceURI, 'http://www.w3.org/2000/svg');
+
+ assert.equal(svg2.namespaceURI, 'http://www.w3.org/2000/svg');
+ assert.equal(path2.namespaceURI, 'http://www.w3.org/2000/svg');
+ assert.equal(fO1.namespaceURI, 'http://www.w3.org/2000/svg');
+ assert.equal(span1.namespaceURI, 'http://www.w3.org/1999/xhtml');
+ assert.equal(fO2.namespaceURI, 'http://www.w3.org/2000/svg');
+ assert.equal(span2.namespaceURI, 'http://www.w3.org/1999/xhtml');
+ }
+});
diff --git a/packages/svelte/tests/runtime-legacy/samples/dynamic-element-svg-inherit-namespace/main.svelte b/packages/svelte/tests/runtime-legacy/samples/dynamic-element-svg-inherit-namespace/main.svelte
new file mode 100644
index 0000000000..8d62a862e8
--- /dev/null
+++ b/packages/svelte/tests/runtime-legacy/samples/dynamic-element-svg-inherit-namespace/main.svelte
@@ -0,0 +1,22 @@
+
+
+
+
+
diff --git a/packages/svelte/tests/snapshot/samples/svelte-element/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/svelte-element/_expected/client/index.svelte.js
index 6fcc18c0c4..b2734b8c46 100644
--- a/packages/svelte/tests/snapshot/samples/svelte-element/_expected/client/index.svelte.js
+++ b/packages/svelte/tests/snapshot/samples/svelte-element/_expected/client/index.svelte.js
@@ -11,7 +11,7 @@ export default function Svelte_element($$anchor, $$props) {
var fragment = $.comment($$anchor);
var node = $.child_frag(fragment);
- $.element(node, tag);
+ $.element(node, tag, false);
$.close_frag($$anchor, fragment);
$.pop();
}
\ No newline at end of file
diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts
index 494ca3c5d2..72248b8124 100644
--- a/packages/svelte/types/index.d.ts
+++ b/packages/svelte/types/index.d.ts
@@ -1342,6 +1342,13 @@ declare module 'svelte/compiler' {
type: 'SvelteElement';
name: 'svelte:element';
tag: Expression;
+ metadata: {
+ /**
+ * `true`/`false` if this is definitely (not) an svg element.
+ * `null` means we can't know statically.
+ */
+ svg: boolean | null;
+ };
}
interface SvelteFragment extends BaseElement {