From ca3f35bf7d3eeea6d0b5f477d208c3fd9c19988c Mon Sep 17 00:00:00 2001 From: OfirHaf Date: Mon, 18 May 2026 18:54:31 +0300 Subject: [PATCH] fix(print): handle svelte:body and fix keyframe percentage double-printing (#18234) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #18206 and fixes #18207 — both are printer bugs in `packages/svelte/src/compiler/print/index.js`. ## Changes ### Fix 1: `svelte:body` crashes the printer (#18206) `SvelteBody` was missing from the visitor map, causing a crash with `Error: Not implemented: SvelteBody`. Added the handler (same one-liner pattern as `SvelteDocument`, `SvelteHead`, etc.) and added `SvelteBody` to the `is_block_element` check so whitespace is handled consistently. ### Fix 2: Keyframe percent stops print as `0%%` (#18207) `Percentage.value` already includes the `%` sign (captured by `/\d+(\.\d+)?%/y`), but the printer was writing `` `${node.value}%` `` — appending a second `%`. Changed to `context.write(node.value)` to match the `Nth` printer pattern directly above it. Also updated the existing `style` snapshot which had `50%%` (the bug was silently baked in), and added dedicated test samples for both fixes. --- .../fix-printer-svelte-body-keyframe-percent.md | 5 +++++ packages/svelte/src/compiler/print/index.js | 7 ++++++- .../samples/css-keyframes-percent/input.svelte | 7 +++++++ .../samples/css-keyframes-percent/output.svelte | 13 +++++++++++++ .../svelte/tests/print/samples/style/output.svelte | 2 +- .../tests/print/samples/svelte-body/input.svelte | 1 + .../tests/print/samples/svelte-body/output.svelte | 1 + 7 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 .changeset/fix-printer-svelte-body-keyframe-percent.md create mode 100644 packages/svelte/tests/print/samples/css-keyframes-percent/input.svelte create mode 100644 packages/svelte/tests/print/samples/css-keyframes-percent/output.svelte create mode 100644 packages/svelte/tests/print/samples/svelte-body/input.svelte create mode 100644 packages/svelte/tests/print/samples/svelte-body/output.svelte diff --git a/.changeset/fix-printer-svelte-body-keyframe-percent.md b/.changeset/fix-printer-svelte-body-keyframe-percent.md new file mode 100644 index 0000000000..6854468835 --- /dev/null +++ b/.changeset/fix-printer-svelte-body-keyframe-percent.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix(print): handle `svelte:body` and fix keyframe percentage double-printing diff --git a/packages/svelte/src/compiler/print/index.js b/packages/svelte/src/compiler/print/index.js index 26dc1b88e8..c511ee6da0 100644 --- a/packages/svelte/src/compiler/print/index.js +++ b/packages/svelte/src/compiler/print/index.js @@ -247,7 +247,7 @@ const css_visitors = { }, Percentage(node, context) { - context.write(`${node.value}%`); + context.write(node.value); }, PseudoClassSelector(node, context) { @@ -417,6 +417,7 @@ const svelte_visitors = (comments) => ({ const is_block_element = child_node.type === 'RegularElement' || child_node.type === 'Component' || + child_node.type === 'SvelteBody' || child_node.type === 'SvelteHead' || child_node.type === 'SvelteFragment' || child_node.type === 'SvelteBoundary' || @@ -821,6 +822,10 @@ const svelte_visitors = (comments) => ({ context.write(''); }, + SvelteBody(node, context) { + base_element(node, context, comments); + }, + SvelteBoundary(node, context) { base_element(node, context, comments); }, diff --git a/packages/svelte/tests/print/samples/css-keyframes-percent/input.svelte b/packages/svelte/tests/print/samples/css-keyframes-percent/input.svelte new file mode 100644 index 0000000000..b2a0e3aa7a --- /dev/null +++ b/packages/svelte/tests/print/samples/css-keyframes-percent/input.svelte @@ -0,0 +1,7 @@ + diff --git a/packages/svelte/tests/print/samples/css-keyframes-percent/output.svelte b/packages/svelte/tests/print/samples/css-keyframes-percent/output.svelte new file mode 100644 index 0000000000..e35a5780fa --- /dev/null +++ b/packages/svelte/tests/print/samples/css-keyframes-percent/output.svelte @@ -0,0 +1,13 @@ + diff --git a/packages/svelte/tests/print/samples/style/output.svelte b/packages/svelte/tests/print/samples/style/output.svelte index 03168cccae..9fc5e3fbba 100644 --- a/packages/svelte/tests/print/samples/style/output.svelte +++ b/packages/svelte/tests/print/samples/style/output.svelte @@ -19,7 +19,7 @@ from { opacity: 0; } - 50%% { + 50% { opacity: 0.5; } to { diff --git a/packages/svelte/tests/print/samples/svelte-body/input.svelte b/packages/svelte/tests/print/samples/svelte-body/input.svelte new file mode 100644 index 0000000000..a4c26db5ce --- /dev/null +++ b/packages/svelte/tests/print/samples/svelte-body/input.svelte @@ -0,0 +1 @@ + diff --git a/packages/svelte/tests/print/samples/svelte-body/output.svelte b/packages/svelte/tests/print/samples/svelte-body/output.svelte new file mode 100644 index 0000000000..e13eaae979 --- /dev/null +++ b/packages/svelte/tests/print/samples/svelte-body/output.svelte @@ -0,0 +1 @@ +