From d11f5bd4a0bbabdfe56ca698e979714e462aa2eb Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 24 Oct 2024 22:11:43 -0400 Subject: [PATCH 1/5] update hash on mouseleave and before reload --- .../(authed)/playground/[id]/+page.svelte | 47 +++++++++++++------ 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte b/apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte index 9dd1ad8127..b96ef6b760 100644 --- a/apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte +++ b/apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte @@ -13,6 +13,8 @@ let { data } = $props(); + const STORAGE_KEY = 'svelte:playground'; + let repl = $state() as ReturnType; let name = $state(data.gist.name); let modified = $state(false); @@ -60,9 +62,10 @@ } async function set_files() { + const saved = sessionStorage.getItem(STORAGE_KEY); const hash = location.hash.slice(1); - if (!hash) { + if (!hash && !saved) { repl?.set({ // TODO make this munging unnecessary files: structuredClone(data.gist.components).map(munge) @@ -73,7 +76,7 @@ } try { - let files = JSON.parse(await decode_and_decompress_text(hash)).files; + let files = JSON.parse(saved ?? (await decode_and_decompress_text(hash))).files; if (files[0]?.source) { files = files.map(munge); @@ -83,6 +86,11 @@ } catch { alert(`Couldn't load the code from the URL. Make sure you copied the link correctly.`); } + + if (saved) { + sessionStorage.removeItem(STORAGE_KEY); + set_hash(saved); + } } function handle_fork({ gist }: { gist: Gist }) { @@ -93,11 +101,19 @@ // Hide hash from URL const hash = location.hash.slice(1); if (hash) { - change_hash(); + set_hash(); } } - async function change_hash(hash?: string) { + async function update_hash() { + // Only change hash on editor blur to not pollute everyone's browser history + if (modified) { + const json = JSON.stringify({ files: repl.toJSON().files }); + await set_hash(json); + } + } + + async function set_hash(hash?: string) { let url = `${location.pathname}${location.search}`; if (hash) { url += `#${await compress_and_encode_text(hash)}`; @@ -143,13 +159,23 @@ { + onhashchange={() => { if (!setting_hash) { set_files(); } }} + onbeforeunload={() => { + if (modified) { + // we can't save to the hash because it's an async operation, so we use + // a short-lived sessionStorage value instead + const json = JSON.stringify({ files: repl.toJSON().files }); + sessionStorage.setItem(STORAGE_KEY, json); + } + }} /> + +
{#if browser} -
{ - // Only change hash on editor blur to not pollute everyone's browser history - if (modified) { - const json = JSON.stringify({ files: repl.toJSON().files }); - change_hash(json); - } - }} - > +
Date: Thu, 24 Oct 2024 22:17:35 -0400 Subject: [PATCH 2/5] update comment --- .../svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte b/apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte index b96ef6b760..2600594f46 100644 --- a/apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte +++ b/apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte @@ -106,7 +106,7 @@ } async function update_hash() { - // Only change hash on editor blur to not pollute everyone's browser history + // Only change hash when necessary to avoid polluting everyone's browser history if (modified) { const json = JSON.stringify({ files: repl.toJSON().files }); await set_hash(json); From ac2b9a9191f921fd034bda3910604abb7dad7396 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 24 Oct 2024 22:21:20 -0400 Subject: [PATCH 3/5] save name as well --- .../src/routes/(authed)/playground/[id]/+page.svelte | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte b/apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte index 2600594f46..8e7564066f 100644 --- a/apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte +++ b/apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte @@ -76,12 +76,18 @@ } try { - let files = JSON.parse(saved ?? (await decode_and_decompress_text(hash))).files; + const recovered = JSON.parse(saved ?? (await decode_and_decompress_text(hash))); + let files = recovered.files; if (files[0]?.source) { files = files.map(munge); } + // older hashes may be missing a name + if (recovered.name) { + name = recovered.name; + } + repl.set({ files }); } catch { alert(`Couldn't load the code from the URL. Make sure you copied the link correctly.`); @@ -108,7 +114,7 @@ async function update_hash() { // Only change hash when necessary to avoid polluting everyone's browser history if (modified) { - const json = JSON.stringify({ files: repl.toJSON().files }); + const json = JSON.stringify({ name, files: repl.toJSON().files }); await set_hash(json); } } @@ -168,7 +174,7 @@ if (modified) { // we can't save to the hash because it's an async operation, so we use // a short-lived sessionStorage value instead - const json = JSON.stringify({ files: repl.toJSON().files }); + const json = JSON.stringify({ name, files: repl.toJSON().files }); sessionStorage.setItem(STORAGE_KEY, json); } }} From 057d05b5735a114103695501d487cb3ef72e9779 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 24 Oct 2024 22:23:53 -0400 Subject: [PATCH 4/5] simplify --- apps/svelte.dev/src/lib/utils/events.ts | 20 ------------------- .../playground/[id]/AppControls.svelte | 3 +-- 2 files changed, 1 insertion(+), 22 deletions(-) delete mode 100644 apps/svelte.dev/src/lib/utils/events.ts diff --git a/apps/svelte.dev/src/lib/utils/events.ts b/apps/svelte.dev/src/lib/utils/events.ts deleted file mode 100644 index 6d811a0fa4..0000000000 --- a/apps/svelte.dev/src/lib/utils/events.ts +++ /dev/null @@ -1,20 +0,0 @@ -export function keyEvent(code: number) { - return function (node: HTMLInputElement, callback: (event: KeyboardEvent) => void) { - node.addEventListener('keydown', handleKeydown); - - /** @param {KeyboardEvent} event */ - function handleKeydown(event: KeyboardEvent) { - if (event.keyCode === code) { - callback.call(node, event); - } - } - - return { - destroy() { - node.removeEventListener('keydown', handleKeydown); - } - }; - }; -} - -export const enter = keyEvent(13); diff --git a/apps/svelte.dev/src/routes/(authed)/playground/[id]/AppControls.svelte b/apps/svelte.dev/src/routes/(authed)/playground/[id]/AppControls.svelte index f494902032..d72d60e6bb 100644 --- a/apps/svelte.dev/src/routes/(authed)/playground/[id]/AppControls.svelte +++ b/apps/svelte.dev/src/routes/(authed)/playground/[id]/AppControls.svelte @@ -2,7 +2,6 @@ import { goto } from '$app/navigation'; import UserMenu from './UserMenu.svelte'; import { Icon } from '@sveltejs/site-kit/components'; - import { enter } from '$lib/utils/events'; import { isMac } from '$lib/utils/compat.js'; import { get_app_context } from '../../app-context'; import type { Gist, User } from '$lib/db/types'; @@ -202,7 +201,7 @@ bind:value={name} onchange={() => (modified = true)} onfocus={(e) => e.currentTarget.select()} - use:enter={(e) => (e.currentTarget as HTMLInputElement).blur()} + onkeydown={(e) => e.key === 'Enter' && e.currentTarget.blur()} />
From cbdd48e45f4d0f4bf72109bda337fed041a4a590 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 24 Oct 2024 22:29:56 -0400 Subject: [PATCH 5/5] fix --- .../src/routes/(authed)/playground/[id]/AppControls.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/svelte.dev/src/routes/(authed)/playground/[id]/AppControls.svelte b/apps/svelte.dev/src/routes/(authed)/playground/[id]/AppControls.svelte index d72d60e6bb..536f4e1a90 100644 --- a/apps/svelte.dev/src/routes/(authed)/playground/[id]/AppControls.svelte +++ b/apps/svelte.dev/src/routes/(authed)/playground/[id]/AppControls.svelte @@ -199,7 +199,7 @@ (modified = true)} + oninput={() => (modified = true)} onfocus={(e) => e.currentTarget.select()} onkeydown={(e) => e.key === 'Enter' && e.currentTarget.blur()} />