diff --git a/.changeset/tiny-taxis-whisper.md b/.changeset/tiny-taxis-whisper.md new file mode 100644 index 0000000000..6fc4175c86 --- /dev/null +++ b/.changeset/tiny-taxis-whisper.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +feat: simpler string normalization 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 fa96cfe296..72f51390bc 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 @@ -1337,10 +1337,7 @@ function process_children(nodes, expression, is_element, { visit, state }) { b.assignment( '=', b.member(text_id, b.id('nodeValue')), - b.call( - '$.stringify', - /** @type {import('estree').Expression} */ (visit(node.expression)) - ) + /** @type {import('estree').Expression} */ (visit(node.expression)) ) ) ); @@ -1524,7 +1521,7 @@ function serialize_template_literal(values, visit, state) { ); expressions.push(b.call('$.get', id)); } else { - expressions.push(b.call('$.stringify', visit(node.expression, state))); + expressions.push(b.logical('??', visit(node.expression, state), b.literal(''))); } quasis.push(b.quasi('', i + 1 === values.length)); } diff --git a/packages/svelte/src/internal/client/dom/elements/bindings/input.js b/packages/svelte/src/internal/client/dom/elements/bindings/input.js index 85296fd3f4..471a21dbce 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/input.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/input.js @@ -1,6 +1,5 @@ import { DEV } from 'esm-env'; import { render_effect, effect, teardown } from '../../../reactivity/effects.js'; -import { stringify } from '../../../render.js'; import { listen_to_event_and_reset_event } from './shared.js'; import * as e from '../../../errors.js'; import { get_proxied_value, is } from '../../../proxy.js'; @@ -43,7 +42,8 @@ export function bind_value(input, get_value, update) { return; } - input.value = stringify(value); + // @ts-expect-error the value is coerced on assignment + input.value = value ?? ''; }); } diff --git a/packages/svelte/src/internal/client/index.js b/packages/svelte/src/internal/client/index.js index 1194570c87..2a747dda90 100644 --- a/packages/svelte/src/internal/client/index.js +++ b/packages/svelte/src/internal/client/index.js @@ -118,7 +118,7 @@ export { update_pre_store, update_store } from './reactivity/store.js'; -export { append_styles, sanitize_slots, set_text, slot, stringify } from './render.js'; +export { append_styles, sanitize_slots, set_text, slot } from './render.js'; export { get, invalidate_inner_signals, diff --git a/packages/svelte/src/internal/client/render.js b/packages/svelte/src/internal/client/render.js index 4bb17930ab..82d2c6bd57 100644 --- a/packages/svelte/src/internal/client/render.js +++ b/packages/svelte/src/internal/client/render.js @@ -66,14 +66,6 @@ export function slot(anchor, slot_fn, slot_props, fallback_fn) { } } -/** - * @param {unknown} value - * @returns {string} - */ -export function stringify(value) { - return typeof value === 'string' ? value : value == null ? '' : value + ''; -} - /** * Mounts a component to the given target and returns the exports and potentially the props (if compiled with `accessors: true`) of the component * diff --git a/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/client/index.svelte.js index 2b7704e154..0e193af12d 100644 --- a/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/client/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/client/index.svelte.js @@ -28,6 +28,6 @@ export default function Bind_component_snippet($$anchor) { var text = $.sibling(node, true); - $.template_effect(() => $.set_text(text, ` value: ${$.stringify($.get(value))}`)); + $.template_effect(() => $.set_text(text, ` value: ${$.get(value) ?? ""}`)); $.append($$anchor, fragment_1); } \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/each-string-template/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/each-string-template/_expected/client/index.svelte.js index 2be257634c..5d5e47faf2 100644 --- a/packages/svelte/tests/snapshot/samples/each-string-template/_expected/client/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/each-string-template/_expected/client/index.svelte.js @@ -8,7 +8,7 @@ export default function Each_string_template($$anchor) { $.each(node, 1, () => ['foo', 'bar', 'baz'], $.index, ($$anchor, thing, $$index) => { var text = $.text($$anchor); - $.template_effect(() => $.set_text(text, `${$.stringify($.unwrap(thing))}, `)); + $.template_effect(() => $.set_text(text, `${$.unwrap(thing) ?? ""}, `)); $.append($$anchor, text); }); diff --git a/packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/client/index.svelte.js index c44f9f1433..2d25ba9fd2 100644 --- a/packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/client/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/client/index.svelte.js @@ -19,7 +19,7 @@ export default function Function_prop_no_getter($$anchor) { children: ($$anchor, $$slotProps) => { var text = $.text($$anchor); - $.template_effect(() => $.set_text(text, `clicks: ${$.stringify($.get(count))}`)); + $.template_effect(() => $.set_text(text, `clicks: ${$.get(count) ?? ""}`)); $.append($$anchor, text); }, $$slots: { default: true }