diff --git a/documentation/docs/98-reference/.generated/shared-errors.md b/documentation/docs/98-reference/.generated/shared-errors.md index 4c81d7b89452..6c31aaafd0df 100644 --- a/documentation/docs/98-reference/.generated/shared-errors.md +++ b/documentation/docs/98-reference/.generated/shared-errors.md @@ -60,6 +60,43 @@ Certain lifecycle methods can only be used during component initialisation. To f ``` +### snippet_without_render_tag + +``` +Attempted to render a snippet without a `{@render}` block. This would cause the snippet code to be stringified instead of its content being rendered to the DOM. To fix this, change `{snippet}` to `{@render snippet()}`. +``` + +A component throwing this error will look something like this (`children` is not being rendered): + +```svelte + + +{children} +``` + +...or like this (a parent component is passing a snippet where a non-snippet value is expected): + +```svelte + + + {#snippet label()} + Hi! + {/snippet} + +``` + +```svelte + + + + +

{label}

+``` + ### store_invalid_shape ``` diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index c8f0ad7ed964..4ffcb263abb5 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,17 @@ # svelte +## 5.27.1 + +### Patch Changes + +- chore: default params for html blocks ([#15778](https://github.com/sveltejs/svelte/pull/15778)) + +- fix: correct suggested type for custom events without detail ([#15763](https://github.com/sveltejs/svelte/pull/15763)) + +- fix: Throw on unrendered snippets in `dev` ([#15766](https://github.com/sveltejs/svelte/pull/15766)) + +- fix: avoid unnecessary read version increments ([#15777](https://github.com/sveltejs/svelte/pull/15777)) + ## 5.27.0 ### Minor Changes diff --git a/packages/svelte/messages/shared-errors/errors.md b/packages/svelte/messages/shared-errors/errors.md index 20f3d193d928..4b4d3322028d 100644 --- a/packages/svelte/messages/shared-errors/errors.md +++ b/packages/svelte/messages/shared-errors/errors.md @@ -52,6 +52,41 @@ Certain lifecycle methods can only be used during component initialisation. To f ``` +## snippet_without_render_tag + +> Attempted to render a snippet without a `{@render}` block. This would cause the snippet code to be stringified instead of its content being rendered to the DOM. To fix this, change `{snippet}` to `{@render snippet()}`. + +A component throwing this error will look something like this (`children` is not being rendered): + +```svelte + + +{children} +``` + +...or like this (a parent component is passing a snippet where a non-snippet value is expected): + +```svelte + + + {#snippet label()} + Hi! + {/snippet} + +``` + +```svelte + + + + +

{label}

+``` + ## store_invalid_shape > `%name%` is not a store with a `subscribe` method diff --git a/packages/svelte/package.json b/packages/svelte/package.json index af78d2679ab8..7ad4835a9a41 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -2,7 +2,7 @@ "name": "svelte", "description": "Cybernetically enhanced web apps", "license": "MIT", - "version": "5.27.0", + "version": "5.27.1", "type": "module", "types": "./types/index.d.ts", "engines": { diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/HtmlTag.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/HtmlTag.js index 32439879de38..ace73691d164 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/HtmlTag.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/HtmlTag.js @@ -11,17 +11,22 @@ import * as b from '../../../../utils/builders.js'; export function HtmlTag(node, context) { context.state.template.push(''); - // push into init, so that bindings run afterwards, which might trigger another run and override hydration - context.state.init.push( - b.stmt( - b.call( - '$.html', - context.state.node, - b.thunk(/** @type {Expression} */ (context.visit(node.expression))), - b.literal(context.state.metadata.namespace === 'svg'), - b.literal(context.state.metadata.namespace === 'mathml'), - is_ignored(node, 'hydration_html_changed') && b.true - ) + const expression = /** @type {Expression} */ (context.visit(node.expression)); + + const is_svg = context.state.metadata.namespace === 'svg'; + const is_mathml = context.state.metadata.namespace === 'mathml'; + + const statement = b.stmt( + b.call( + '$.html', + context.state.node, + b.thunk(expression), + is_svg && b.true, + is_mathml && b.true, + is_ignored(node, 'hydration_html_changed') && b.true ) ); + + // push into init, so that bindings run afterwards, which might trigger another run and override hydration + context.state.init.push(statement); } diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/SnippetBlock.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/SnippetBlock.js index cae3e7d79c94..a67fcc888510 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/SnippetBlock.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/SnippetBlock.js @@ -1,4 +1,4 @@ -/** @import { BlockStatement } from 'estree' */ +/** @import { ArrowFunctionExpression, BlockStatement, CallExpression } from 'estree' */ /** @import { AST } from '#compiler' */ /** @import { ComponentContext } from '../types.js' */ import { dev } from '../../../../state.js'; @@ -9,20 +9,27 @@ import * as b from '../../../../utils/builders.js'; * @param {ComponentContext} context */ export function SnippetBlock(node, context) { - const fn = b.function_declaration( - node.expression, - [b.id('$$payload'), ...node.parameters], - /** @type {BlockStatement} */ (context.visit(node.body)) - ); + const body = /** @type {BlockStatement} */ (context.visit(node.body)); + if (dev) { - fn.body.body.unshift(b.stmt(b.call('$.validate_snippet_args', b.id('$$payload')))); + body.body.unshift(b.stmt(b.call('$.validate_snippet_args', b.id('$$payload')))); } + + /** @type {ArrowFunctionExpression | CallExpression} */ + let fn = b.arrow([b.id('$$payload'), ...node.parameters], body); + + if (dev) { + fn = b.call('$.prevent_snippet_stringification', fn); + } + + const declaration = b.declaration('const', [b.declarator(node.expression, fn)]); + // @ts-expect-error - TODO remove this hack once $$render_inner for legacy bindings is gone fn.___snippet = true; if (node.metadata.can_hoist) { - context.state.hoisted.push(fn); + context.state.hoisted.push(declaration); } else { - context.state.init.push(fn); + context.state.init.push(declaration); } } diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js index 695161ff9b60..f4b3dd1b09aa 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js @@ -4,6 +4,7 @@ import { empty_comment, build_attribute_value } from './utils.js'; import * as b from '../../../../../utils/builders.js'; import { is_element_node } from '../../../../nodes.js'; +import { dev } from '../../../../../state.js'; /** * @param {AST.Component | AST.SvelteComponent | AST.SvelteSelf} node @@ -238,7 +239,13 @@ export function build_inline_component(node, expression, context) { ) ) { // create `children` prop... - push_prop(b.prop('init', b.id('children'), slot_fn)); + push_prop( + b.prop( + 'init', + b.id('children'), + dev ? b.call('$.prevent_snippet_stringification', slot_fn) : slot_fn + ) + ); // and `$$slots.default: true` so that `` on the child works serialized_slots.push(b.init(slot_name, b.true)); diff --git a/packages/svelte/src/index-client.js b/packages/svelte/src/index-client.js index fd8e999da763..efd5628ae951 100644 --- a/packages/svelte/src/index-client.js +++ b/packages/svelte/src/index-client.js @@ -114,7 +114,7 @@ function create_custom_event(type, detail, { bubbles = false, cancelable = false * The event dispatcher can be typed to narrow the allowed event names and the type of the `detail` argument: * ```ts * const dispatch = createEventDispatcher<{ - * loaded: never; // does not take a detail argument + * loaded: null; // does not take a detail argument * change: string; // takes a detail argument of type string, which is required * optional: number | null; // takes an optional detail argument of type number * }>(); diff --git a/packages/svelte/src/internal/client/dev/debug.js b/packages/svelte/src/internal/client/dev/debug.js new file mode 100644 index 000000000000..f449dfa2ccd1 --- /dev/null +++ b/packages/svelte/src/internal/client/dev/debug.js @@ -0,0 +1,109 @@ +/** @import { Derived, Effect, Value } from '#client' */ + +import { + BLOCK_EFFECT, + BOUNDARY_EFFECT, + BRANCH_EFFECT, + CLEAN, + DERIVED, + EFFECT, + MAYBE_DIRTY, + RENDER_EFFECT, + ROOT_EFFECT +} from '../constants.js'; + +/** + * + * @param {Effect} effect + */ +export function root(effect) { + while (effect.parent !== null) { + effect = effect.parent; + } + + return effect; +} + +/** + * + * @param {Effect} effect + */ +export function log_effect_tree(effect, depth = 0) { + const flags = effect.f; + + let label = '(unknown)'; + + if ((flags & ROOT_EFFECT) !== 0) { + label = 'root'; + } else if ((flags & BOUNDARY_EFFECT) !== 0) { + label = 'boundary'; + } else if ((flags & BLOCK_EFFECT) !== 0) { + label = 'block'; + } else if ((flags & BRANCH_EFFECT) !== 0) { + label = 'branch'; + } else if ((flags & RENDER_EFFECT) !== 0) { + label = 'render effect'; + } else if ((flags & EFFECT) !== 0) { + label = 'effect'; + } + + let status = + (flags & CLEAN) !== 0 ? 'clean' : (flags & MAYBE_DIRTY) !== 0 ? 'maybe dirty' : 'dirty'; + + // eslint-disable-next-line no-console + console.group(`%c${label} (${status})`, `font-weight: ${status === 'clean' ? 'normal' : 'bold'}`); + + if (depth === 0) { + const callsite = new Error().stack + ?.split('\n')[2] + .replace(/\s+at (?: \w+\(?)?(.+)\)?/, (m, $1) => $1.replace(/\?[^:]+/, '')); + + // eslint-disable-next-line no-console + console.log(callsite); + } + + if (effect.deps !== null) { + // eslint-disable-next-line no-console + console.groupCollapsed('%cdeps', 'font-weight: normal'); + + for (const dep of effect.deps) { + log_dep(dep); + } + + // eslint-disable-next-line no-console + console.groupEnd(); + } + + let child = effect.first; + while (child !== null) { + log_effect_tree(child, depth + 1); + child = child.next; + } + + // eslint-disable-next-line no-console + console.groupEnd(); +} + +/** + * + * @param {Value} dep + */ +function log_dep(dep) { + if ((dep.f & DERIVED) !== 0) { + const derived = /** @type {Derived} */ (dep); + + // eslint-disable-next-line no-console + console.groupCollapsed('%cderived', 'font-weight: normal', derived.v); + if (derived.deps) { + for (const d of derived.deps) { + log_dep(d); + } + } + + // eslint-disable-next-line no-console + console.groupEnd(); + } else { + // eslint-disable-next-line no-console + console.log('state', dep.v); + } +} diff --git a/packages/svelte/src/internal/client/dom/blocks/html.js b/packages/svelte/src/internal/client/dom/blocks/html.js index b3fc5a9c725d..92c824347894 100644 --- a/packages/svelte/src/internal/client/dom/blocks/html.js +++ b/packages/svelte/src/internal/client/dom/blocks/html.js @@ -1,6 +1,6 @@ /** @import { Effect, TemplateNode } from '#client' */ import { FILENAME, HYDRATION_ERROR } from '../../../../constants.js'; -import { block, branch, destroy_effect } from '../../reactivity/effects.js'; +import { remove_effect_dom, template_effect } from '../../reactivity/effects.js'; import { hydrate_next, hydrate_node, hydrating, set_hydrate_node } from '../hydration.js'; import { create_fragment_from_html } from '../reconciler.js'; import { assign_nodes } from '../template.js'; @@ -9,6 +9,7 @@ import { hash, sanitize_location } from '../../../../utils.js'; import { DEV } from 'esm-env'; import { dev_current_component_function } from '../../context.js'; import { get_first_child, get_next_sibling } from '../operations.js'; +import { active_effect } from '../../runtime.js'; /** * @param {Element} element @@ -34,89 +35,81 @@ function check_hash(element, server_hash, value) { /** * @param {Element | Text | Comment} node * @param {() => string} get_value - * @param {boolean} svg - * @param {boolean} mathml + * @param {boolean} [svg] + * @param {boolean} [mathml] * @param {boolean} [skip_warning] * @returns {void} */ -export function html(node, get_value, svg, mathml, skip_warning) { +export function html(node, get_value, svg = false, mathml = false, skip_warning = false) { var anchor = node; var value = ''; - /** @type {Effect | undefined} */ - var effect; + template_effect(() => { + var effect = /** @type {Effect} */ (active_effect); - block(() => { if (value === (value = get_value() ?? '')) { - if (hydrating) { - hydrate_next(); - } + if (hydrating) hydrate_next(); return; } - if (effect !== undefined) { - destroy_effect(effect); - effect = undefined; + if (effect.nodes_start !== null) { + remove_effect_dom(effect.nodes_start, /** @type {TemplateNode} */ (effect.nodes_end)); + effect.nodes_start = effect.nodes_end = null; } if (value === '') return; - effect = branch(() => { - if (hydrating) { - // We're deliberately not trying to repair mismatches between server and client, - // as it's costly and error-prone (and it's an edge case to have a mismatch anyway) - var hash = /** @type {Comment} */ (hydrate_node).data; - var next = hydrate_next(); - var last = next; - - while ( - next !== null && - (next.nodeType !== 8 || /** @type {Comment} */ (next).data !== '') - ) { - last = next; - next = /** @type {TemplateNode} */ (get_next_sibling(next)); - } - - if (next === null) { - w.hydration_mismatch(); - throw HYDRATION_ERROR; - } - - if (DEV && !skip_warning) { - check_hash(/** @type {Element} */ (next.parentNode), hash, value); - } - - assign_nodes(hydrate_node, last); - anchor = set_hydrate_node(next); - return; - } + if (hydrating) { + // We're deliberately not trying to repair mismatches between server and client, + // as it's costly and error-prone (and it's an edge case to have a mismatch anyway) + var hash = /** @type {Comment} */ (hydrate_node).data; + var next = hydrate_next(); + var last = next; - var html = value + ''; - if (svg) html = `${html}`; - else if (mathml) html = `${html}`; + while (next !== null && (next.nodeType !== 8 || /** @type {Comment} */ (next).data !== '')) { + last = next; + next = /** @type {TemplateNode} */ (get_next_sibling(next)); + } - // Don't use create_fragment_with_script_from_html here because that would mean script tags are executed. - // @html is basically `.innerHTML = ...` and that doesn't execute scripts either due to security reasons. - /** @type {DocumentFragment | Element} */ - var node = create_fragment_from_html(html); + if (next === null) { + w.hydration_mismatch(); + throw HYDRATION_ERROR; + } - if (svg || mathml) { - node = /** @type {Element} */ (get_first_child(node)); + if (DEV && !skip_warning) { + check_hash(/** @type {Element} */ (next.parentNode), hash, value); } - assign_nodes( - /** @type {TemplateNode} */ (get_first_child(node)), - /** @type {TemplateNode} */ (node.lastChild) - ); - - if (svg || mathml) { - while (get_first_child(node)) { - anchor.before(/** @type {Node} */ (get_first_child(node))); - } - } else { - anchor.before(node); + assign_nodes(hydrate_node, last); + anchor = set_hydrate_node(next); + return; + } + + var html = value + ''; + if (svg) html = `${html}`; + else if (mathml) html = `${html}`; + + // Don't use create_fragment_with_script_from_html here because that would mean script tags are executed. + // @html is basically `.innerHTML = ...` and that doesn't execute scripts either due to security reasons. + /** @type {DocumentFragment | Element} */ + var node = create_fragment_from_html(html); + + if (svg || mathml) { + node = /** @type {Element} */ (get_first_child(node)); + } + + assign_nodes( + /** @type {TemplateNode} */ (get_first_child(node)), + /** @type {TemplateNode} */ (node.lastChild) + ); + + if (svg || mathml) { + while (get_first_child(node)) { + anchor.before(/** @type {Node} */ (get_first_child(node))); } - }); + } else { + anchor.before(node); + } }); } diff --git a/packages/svelte/src/internal/client/dom/blocks/snippet.js b/packages/svelte/src/internal/client/dom/blocks/snippet.js index b916a02ce55f..a48153900fde 100644 --- a/packages/svelte/src/internal/client/dom/blocks/snippet.js +++ b/packages/svelte/src/internal/client/dom/blocks/snippet.js @@ -15,6 +15,7 @@ import * as e from '../../errors.js'; import { DEV } from 'esm-env'; import { get_first_child, get_next_sibling } from '../operations.js'; import { noop } from '../../../shared/utils.js'; +import { prevent_snippet_stringification } from '../../../shared/validate.js'; /** * @template {(node: TemplateNode, ...args: any[]) => void} SnippetFn @@ -60,7 +61,7 @@ export function snippet(node, get_snippet, ...args) { * @param {(node: TemplateNode, ...args: any[]) => void} fn */ export function wrap_snippet(component, fn) { - return (/** @type {TemplateNode} */ node, /** @type {any[]} */ ...args) => { + const snippet = (/** @type {TemplateNode} */ node, /** @type {any[]} */ ...args) => { var previous_component_function = dev_current_component_function; set_dev_current_component_function(component); @@ -70,6 +71,10 @@ export function wrap_snippet(component, fn) { set_dev_current_component_function(previous_component_function); } }; + + prevent_snippet_stringification(snippet); + + return snippet; } /** diff --git a/packages/svelte/src/internal/client/index.js b/packages/svelte/src/internal/client/index.js index e977bf3b0fe9..14d6e29f5bb4 100644 --- a/packages/svelte/src/internal/client/index.js +++ b/packages/svelte/src/internal/client/index.js @@ -157,7 +157,8 @@ export { invalid_default_snippet, validate_dynamic_element_tag, validate_store, - validate_void_dynamic_element + validate_void_dynamic_element, + prevent_snippet_stringification } from '../shared/validate.js'; export { strict_equals, equals } from './dev/equality.js'; export { log_if_contains_state } from './dev/console-log.js'; diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index 468bb94ab428..76b014c916c6 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -427,18 +427,7 @@ export function destroy_effect(effect, remove_dom = true) { var removed = false; if ((remove_dom || (effect.f & HEAD_EFFECT) !== 0) && effect.nodes_start !== null) { - /** @type {TemplateNode | null} */ - var node = effect.nodes_start; - var end = effect.nodes_end; - - while (node !== null) { - /** @type {TemplateNode | null} */ - var next = node === end ? null : /** @type {TemplateNode} */ (get_next_sibling(node)); - - node.remove(); - node = next; - } - + remove_effect_dom(effect.nodes_start, /** @type {TemplateNode} */ (effect.nodes_end)); removed = true; } @@ -480,6 +469,21 @@ export function destroy_effect(effect, remove_dom = true) { null; } +/** + * + * @param {TemplateNode | null} node + * @param {TemplateNode} end + */ +export function remove_effect_dom(node, end) { + while (node !== null) { + /** @type {TemplateNode | null} */ + var next = node === end ? null : /** @type {TemplateNode} */ (get_next_sibling(node)); + + node.remove(); + node = next; + } +} + /** * Detach an effect from the effect tree, freeing up memory and * reducing the amount of work that happens on subsequent traversals diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 2acad3d2580d..e621536055b5 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -469,7 +469,7 @@ export function update_reaction(reaction) { // we need to increment the read version to ensure that // any dependencies in this reaction aren't marked with // the same version - if (previous_reaction !== reaction) { + if (previous_reaction !== null && previous_reaction !== reaction) { read_version++; if (untracked_writes !== null) { diff --git a/packages/svelte/src/internal/server/index.js b/packages/svelte/src/internal/server/index.js index d711778a44ea..b58a1d4372a6 100644 --- a/packages/svelte/src/internal/server/index.js +++ b/packages/svelte/src/internal/server/index.js @@ -509,7 +509,8 @@ export { fallback } from '../shared/utils.js'; export { invalid_default_snippet, validate_dynamic_element_tag, - validate_void_dynamic_element + validate_void_dynamic_element, + prevent_snippet_stringification } from '../shared/validate.js'; export { escape_html as escape }; diff --git a/packages/svelte/src/internal/shared/errors.js b/packages/svelte/src/internal/shared/errors.js index 2e89dc1ad109..b8606fbf6f7d 100644 --- a/packages/svelte/src/internal/shared/errors.js +++ b/packages/svelte/src/internal/shared/errors.js @@ -48,6 +48,21 @@ export function lifecycle_outside_component(name) { } } +/** + * Attempted to render a snippet without a `{@render}` block. This would cause the snippet code to be stringified instead of its content being rendered to the DOM. To fix this, change `{snippet}` to `{@render snippet()}`. + * @returns {never} + */ +export function snippet_without_render_tag() { + if (DEV) { + const error = new Error(`snippet_without_render_tag\nAttempted to render a snippet without a \`{@render}\` block. This would cause the snippet code to be stringified instead of its content being rendered to the DOM. To fix this, change \`{snippet}\` to \`{@render snippet()}\`.\nhttps://svelte.dev/e/snippet_without_render_tag`); + + error.name = 'Svelte error'; + throw error; + } else { + throw new Error(`https://svelte.dev/e/snippet_without_render_tag`); + } +} + /** * `%name%` is not a store with a `subscribe` method * @param {string} name diff --git a/packages/svelte/src/internal/shared/validate.js b/packages/svelte/src/internal/shared/validate.js index 852c0e83bfb1..bbb237594bec 100644 --- a/packages/svelte/src/internal/shared/validate.js +++ b/packages/svelte/src/internal/shared/validate.js @@ -35,3 +35,15 @@ export function validate_store(store, name) { e.store_invalid_shape(name); } } + +/** + * @template {() => unknown} T + * @param {T} fn + */ +export function prevent_snippet_stringification(fn) { + fn.toString = () => { + e.snippet_without_render_tag(); + return ''; + }; + return fn; +} diff --git a/packages/svelte/src/version.js b/packages/svelte/src/version.js index 27a39136f8c2..b0424e82325a 100644 --- a/packages/svelte/src/version.js +++ b/packages/svelte/src/version.js @@ -4,5 +4,5 @@ * The current version, as set in package.json. * @type {string} */ -export const VERSION = '5.27.0'; +export const VERSION = '5.27.1'; export const PUBLIC_VERSION = '5'; diff --git a/packages/svelte/tests/runtime-runes/samples/snippet-block-without-render-tag-dev/_config.js b/packages/svelte/tests/runtime-runes/samples/snippet-block-without-render-tag-dev/_config.js new file mode 100644 index 000000000000..94c5de10af60 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/snippet-block-without-render-tag-dev/_config.js @@ -0,0 +1,8 @@ +import { test } from '../../test'; + +export default test({ + compileOptions: { + dev: true + }, + runtime_error: 'snippet_without_render_tag' +}); diff --git a/packages/svelte/tests/runtime-runes/samples/snippet-block-without-render-tag-dev/main.svelte b/packages/svelte/tests/runtime-runes/samples/snippet-block-without-render-tag-dev/main.svelte new file mode 100644 index 000000000000..3f8edfe4fafc --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/snippet-block-without-render-tag-dev/main.svelte @@ -0,0 +1,5 @@ +{testSnippet} + +{#snippet testSnippet()} +

hi again

+{/snippet} diff --git a/packages/svelte/tests/runtime-runes/samples/snippet-block-without-render-tag-prod/_config.js b/packages/svelte/tests/runtime-runes/samples/snippet-block-without-render-tag-prod/_config.js new file mode 100644 index 000000000000..f47bee71df87 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/snippet-block-without-render-tag-prod/_config.js @@ -0,0 +1,3 @@ +import { test } from '../../test'; + +export default test({}); diff --git a/packages/svelte/tests/runtime-runes/samples/snippet-block-without-render-tag-prod/main.svelte b/packages/svelte/tests/runtime-runes/samples/snippet-block-without-render-tag-prod/main.svelte new file mode 100644 index 000000000000..3f8edfe4fafc --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/snippet-block-without-render-tag-prod/main.svelte @@ -0,0 +1,5 @@ +{testSnippet} + +{#snippet testSnippet()} +

hi again

+{/snippet} diff --git a/packages/svelte/tests/runtime-runes/samples/snippet-children-without-render-tag-dev-prod/_config.js b/packages/svelte/tests/runtime-runes/samples/snippet-children-without-render-tag-dev-prod/_config.js new file mode 100644 index 000000000000..f47bee71df87 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/snippet-children-without-render-tag-dev-prod/_config.js @@ -0,0 +1,3 @@ +import { test } from '../../test'; + +export default test({}); diff --git a/packages/svelte/tests/runtime-runes/samples/snippet-children-without-render-tag-dev-prod/main.svelte b/packages/svelte/tests/runtime-runes/samples/snippet-children-without-render-tag-dev-prod/main.svelte new file mode 100644 index 000000000000..4a4ed3176f24 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/snippet-children-without-render-tag-dev-prod/main.svelte @@ -0,0 +1,5 @@ + + +Hi diff --git a/packages/svelte/tests/runtime-runes/samples/snippet-children-without-render-tag-dev-prod/unrendered-children.svelte b/packages/svelte/tests/runtime-runes/samples/snippet-children-without-render-tag-dev-prod/unrendered-children.svelte new file mode 100644 index 000000000000..6b7154a5a406 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/snippet-children-without-render-tag-dev-prod/unrendered-children.svelte @@ -0,0 +1,5 @@ + + +{children} diff --git a/packages/svelte/tests/runtime-runes/samples/snippet-children-without-render-tag-dev/_config.js b/packages/svelte/tests/runtime-runes/samples/snippet-children-without-render-tag-dev/_config.js new file mode 100644 index 000000000000..94c5de10af60 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/snippet-children-without-render-tag-dev/_config.js @@ -0,0 +1,8 @@ +import { test } from '../../test'; + +export default test({ + compileOptions: { + dev: true + }, + runtime_error: 'snippet_without_render_tag' +}); diff --git a/packages/svelte/tests/runtime-runes/samples/snippet-children-without-render-tag-dev/main.svelte b/packages/svelte/tests/runtime-runes/samples/snippet-children-without-render-tag-dev/main.svelte new file mode 100644 index 000000000000..4a4ed3176f24 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/snippet-children-without-render-tag-dev/main.svelte @@ -0,0 +1,5 @@ + + +Hi diff --git a/packages/svelte/tests/runtime-runes/samples/snippet-children-without-render-tag-dev/unrendered-children.svelte b/packages/svelte/tests/runtime-runes/samples/snippet-children-without-render-tag-dev/unrendered-children.svelte new file mode 100644 index 000000000000..6b7154a5a406 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/snippet-children-without-render-tag-dev/unrendered-children.svelte @@ -0,0 +1,5 @@ + + +{children} diff --git a/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/server/index.svelte.js b/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/server/index.svelte.js index cadae2cf15c0..04bfbf6ae47b 100644 --- a/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/server/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/server/index.svelte.js @@ -1,9 +1,9 @@ import * as $ from 'svelte/internal/server'; import TextInput from './Child.svelte'; -function snippet($$payload) { +const snippet = ($$payload) => { $$payload.out += `Something`; -} +}; export default function Bind_component_snippet($$payload) { let value = ''; diff --git a/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js index b341d39f28fb..541b56a407ba 100644 --- a/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js @@ -13,7 +13,7 @@ export default function Skip_static_subtree($$anchor, $$props) { var node = $.sibling(h1, 10); - $.html(node, () => $$props.content, false, false); + $.html(node, () => $$props.content); $.next(14); $.reset(main); diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts index 6f12daf18778..8fc174b0a944 100644 --- a/packages/svelte/types/index.d.ts +++ b/packages/svelte/types/index.d.ts @@ -381,7 +381,7 @@ declare module 'svelte' { * The event dispatcher can be typed to narrow the allowed event names and the type of the `detail` argument: * ```ts * const dispatch = createEventDispatcher<{ - * loaded: never; // does not take a detail argument + * loaded: null; // does not take a detail argument * change: string; // takes a detail argument of type string, which is required * optional: number | null; // takes an optional detail argument of type number * }>(); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy