From bb65d094f32b38c2b19b8556f329040379a49a40 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Mon, 24 Mar 2025 22:26:19 +0100 Subject: [PATCH 1/2] chore: output-only embedded mode Embed mode, but with hash support and a new query param that makes it so only the output is shown, nothing else --- .../playground/[id]/embed/+page.svelte | 26 ++++++++++++++++--- packages/repl/src/lib/Output/Output.svelte | 25 ++++++++++-------- packages/repl/src/lib/Repl.svelte | 23 +++++++++++----- 3 files changed, 53 insertions(+), 21 deletions(-) diff --git a/apps/svelte.dev/src/routes/(authed)/playground/[id]/embed/+page.svelte b/apps/svelte.dev/src/routes/(authed)/playground/[id]/embed/+page.svelte index 346f2381ac..c0f37fd55a 100644 --- a/apps/svelte.dev/src/routes/(authed)/playground/[id]/embed/+page.svelte +++ b/apps/svelte.dev/src/routes/(authed)/playground/[id]/embed/+page.svelte @@ -5,6 +5,7 @@ import { Repl } from '@sveltejs/repl'; import { mapbox_setup } from '../../../../../config.js'; import { page } from '$app/state'; + import { decode_and_decompress_text } from '../gzip.js'; let { data } = $props(); @@ -25,10 +26,27 @@ }); } + async function set_files() { + const hash = location.hash.slice(1); + + if (!hash) { + repl?.set({ + files: data.gist.components + }); + + return; + } + + try { + const recovered = JSON.parse(await decode_and_decompress_text(hash)); + repl.set({ files: recovered.files }); + } catch { + alert(`Couldn't load the code from the URL. Make sure you copied the link correctly.`); + } + } + afterNavigate(() => { - repl?.set({ - files: data.gist.components - }); + set_files(); }); const relaxed = $derived(data.gist.relaxed || (data.user && data.user.id === data.gist.owner)); @@ -51,7 +69,7 @@ can_escape injectedJS={mapbox_setup} previewTheme={theme.current} - embedded + embedded={page.url.searchParams.has('output-only') ? 'output-only' : true} /> {/if} diff --git a/packages/repl/src/lib/Output/Output.svelte b/packages/repl/src/lib/Output/Output.svelte index 9d29e4c73a..008511c753 100644 --- a/packages/repl/src/lib/Output/Output.svelte +++ b/packages/repl/src/lib/Output/Output.svelte @@ -12,7 +12,7 @@ interface Props { status: string | null; runtimeError?: Error | null; - embedded?: boolean; + embedded?: boolean | 'output-only'; relaxed?: boolean; can_escape?: boolean; injectedJS: string; @@ -182,16 +182,18 @@ }); -
- {#if workspace.current.name.endsWith('.md')} - - {:else} - - - - - {/if} -
+{#if embedded !== 'output-only'} +
+ {#if workspace.current.name.endsWith('.md')} + + {:else} + + + + + {/if} +
+{/if}
@@ -202,6 +204,7 @@ {can_escape} {injectedJS} {injectedCSS} + onLog={embedded === 'output-only' ? () => {} : undefined} theme={previewTheme} />
diff --git a/packages/repl/src/lib/Repl.svelte b/packages/repl/src/lib/Repl.svelte index 26da2bd72e..021c722a4d 100644 --- a/packages/repl/src/lib/Repl.svelte +++ b/packages/repl/src/lib/Repl.svelte @@ -13,7 +13,7 @@ interface Props { packagesUrl?: string; svelteVersion?: string; - embedded?: boolean; + embedded?: boolean | 'output-only'; orientation?: 'columns' | 'rows'; relaxed?: boolean; can_escape?: boolean; @@ -152,7 +152,7 @@ let mobile = $derived(width < 540); $effect(() => { - $toggleable = mobile && orientation === 'columns'; + $toggleable = mobile && orientation === 'columns' && embedded !== 'output-only'; }); let runes = $derived( @@ -166,13 +166,24 @@ -
+
{#snippet a()} @@ -264,7 +275,7 @@ /* on mobile, override the controls */ @media (max-width: 799px) { - :global { + .container-normal :global { [data-pane='main'] { --pos: 50% !important; } From 6e1c93ce16e94895b7e732c7cc77fdda7ecc5c45 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Mon, 24 Mar 2025 22:40:19 +0100 Subject: [PATCH 2/2] fix --- .../(authed)/playground/[id]/embed/+page.svelte | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/apps/svelte.dev/src/routes/(authed)/playground/[id]/embed/+page.svelte b/apps/svelte.dev/src/routes/(authed)/playground/[id]/embed/+page.svelte index c0f37fd55a..6db54545e2 100644 --- a/apps/svelte.dev/src/routes/(authed)/playground/[id]/embed/+page.svelte +++ b/apps/svelte.dev/src/routes/(authed)/playground/[id]/embed/+page.svelte @@ -6,6 +6,7 @@ import { mapbox_setup } from '../../../../../config.js'; import { page } from '$app/state'; import { decode_and_decompress_text } from '../gzip.js'; + import type { File } from 'editor'; let { data } = $props(); @@ -26,12 +27,25 @@ }); } + // TODO make this munging unnecessary + function munge(data: any): File { + const basename = `${data.name}.${data.type}`; + + return { + type: 'file', + name: basename, + basename, + contents: data.source, + text: true + }; + } + async function set_files() { const hash = location.hash.slice(1); if (!hash) { repl?.set({ - files: data.gist.components + files: data.gist.components.map(munge) }); return;