From e675749bad97c09dad57a89da2523c24e1918a37 Mon Sep 17 00:00:00 2001 From: d2du Date: Tue, 14 Jul 2026 17:14:53 +0530 Subject: [PATCH 1/2] fix: support mixed interpolation in quoted attributes Preserve safety checks for event handlers and structural interpolation, and improve SvelteKit example responsiveness. --- .changeset/slow-mugs-matter.md | 5 ++ examples/sveltekit/src/app.css | 18 +++++-- .../lib/components/photoship/AppShell.svelte | 19 ++++--- examples/sveltekit/src/routes/+page.svelte | 48 ++++++++++++----- .../src/routes/customers/+page.svelte | 52 +++++++++++++------ .../sveltekit/src/routes/menus/+page.svelte | 12 +++-- .../sveltekit/src/routes/orders/+page.svelte | 14 ++--- .../sveltekit/src/routes/users/+page.svelte | 50 ++++++++++++------ src/ui-runtime.ts | 47 ++++++++++++----- tests/ui-runtime.test.ts | 29 +++++++++++ 10 files changed, 214 insertions(+), 80 deletions(-) create mode 100644 .changeset/slow-mugs-matter.md diff --git a/.changeset/slow-mugs-matter.md b/.changeset/slow-mugs-matter.md new file mode 100644 index 0000000..73c26de --- /dev/null +++ b/.changeset/slow-mugs-matter.md @@ -0,0 +1,5 @@ +--- +"gruntend-sdk": patch +--- + +safely escaped values can be combined inside quoted attributes while event handlers and tag diff --git a/examples/sveltekit/src/app.css b/examples/sveltekit/src/app.css index bca8c0a..65ff7d7 100644 --- a/examples/sveltekit/src/app.css +++ b/examples/sveltekit/src/app.css @@ -117,13 +117,19 @@ html, body { width: 100%; + min-width: 0; height: 100%; margin: 0; padding: 0; } + html { + overflow-x: clip; + } + body { - overflow: auto; + overflow-x: clip; + overflow-y: auto; background: var(--color-surface); color: var(--color-text-primary); font-family: var(--font-sans); @@ -138,6 +144,12 @@ box-sizing: border-box; } + img, + svg, + video { + max-width: 100%; + } + a { color: inherit; } @@ -885,10 +897,6 @@ } @media (max-width: 1000px) { - body { - overflow: auto; - } - .ps-app-shell { min-height: 100vh; height: auto; diff --git a/examples/sveltekit/src/lib/components/photoship/AppShell.svelte b/examples/sveltekit/src/lib/components/photoship/AppShell.svelte index 7c88475..5ec4594 100644 --- a/examples/sveltekit/src/lib/components/photoship/AppShell.svelte +++ b/examples/sveltekit/src/lib/components/photoship/AppShell.svelte @@ -58,15 +58,17 @@ } -
+
-
+
{@render children?.()}
diff --git a/examples/sveltekit/src/routes/+page.svelte b/examples/sveltekit/src/routes/+page.svelte index 27cb8e2..d9b2fc8 100644 --- a/examples/sveltekit/src/routes/+page.svelte +++ b/examples/sveltekit/src/routes/+page.svelte @@ -503,7 +503,7 @@
-
+
@@ -513,32 +513,34 @@ > Restaurant operations

-

+

What do you want to do?

-
+
Menus
{menuCount ?? "…"}
-
+
Items
{itemCount ?? "…"}
-
+
Orders
{orderCount ?? "…"}
-
+
Staff
{teamCount ?? "…"} @@ -566,11 +568,11 @@ placeholder="Move selected dinner items to a new seasonal menu..." >
`, + ); + + expect(Result.isError(compiled)).toBe(true); + expect(compiled.unwrapError()).toEqual({ + code: "unsafe_interpolation", + message: "Interpolations cannot change tag or attribute structure.", + }); +}); + test("compileUiTemplate rejects unsafe tags", () => { const html = createUiTemplateTag(); From 7bb153f9fab4b13b2e2e70657542b5f5dd6153e6 Mon Sep 17 00:00:00 2001 From: d2du Date: Tue, 14 Jul 2026 17:36:00 +0530 Subject: [PATCH 2/2] format --- examples/sveltekit/src/routes/+page.svelte | 16 ++++++++++++---- .../sveltekit/src/routes/orders/+page.svelte | 3 +-- src/ui-runtime.ts | 4 +--- tests/ui-runtime.test.ts | 6 +++++- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/examples/sveltekit/src/routes/+page.svelte b/examples/sveltekit/src/routes/+page.svelte index d9b2fc8..b4a0de7 100644 --- a/examples/sveltekit/src/routes/+page.svelte +++ b/examples/sveltekit/src/routes/+page.svelte @@ -522,25 +522,33 @@
-
+
Menus
{menuCount ?? "…"}
-
+
Items
{itemCount ?? "…"}
-
+
Orders
{orderCount ?? "…"}
-
+
Staff
{teamCount ?? "…"} diff --git a/examples/sveltekit/src/routes/orders/+page.svelte b/examples/sveltekit/src/routes/orders/+page.svelte index 91bc617..c24cafe 100644 --- a/examples/sveltekit/src/routes/orders/+page.svelte +++ b/examples/sveltekit/src/routes/orders/+page.svelte @@ -209,8 +209,7 @@
  • {line.quantity}× {line.itemName}${(line.unitPrice * line.quantity).toFixed(2)}
  • diff --git a/src/ui-runtime.ts b/src/ui-runtime.ts index 1124b9c..9a8dd08 100644 --- a/src/ui-runtime.ts +++ b/src/ui-runtime.ts @@ -415,9 +415,7 @@ function interpolationContext( ): TemplateInterpolationContext { if (!endsInsideTag(before)) return { kind: "text" }; - const quotedAttr = before.match( - /([:@A-Za-z0-9_-]+)\s*=\s*(["'])([^"']*)$/, - ); + const quotedAttr = before.match(/([:@A-Za-z0-9_-]+)\s*=\s*(["'])([^"']*)$/); if (quotedAttr) { const attr = quotedAttr[1]; const quote = quotedAttr[2]; diff --git a/tests/ui-runtime.test.ts b/tests/ui-runtime.test.ts index cb4c92f..9f754ad 100644 --- a/tests/ui-runtime.test.ts +++ b/tests/ui-runtime.test.ts @@ -70,7 +70,11 @@ test("compileUiTemplate supports mixed quoted attribute interpolation", () => { const period = "this week"; const compiled = compileUiTemplate( - html``, + html``, ).unwrap(); expect(compiled.html).toBe(