Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions apps/svelte.dev/src/lib/utils/events.ts

This file was deleted.

53 changes: 38 additions & 15 deletions apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

let { data } = $props();

const STORAGE_KEY = 'svelte:playground';

let repl = $state() as ReturnType<typeof Repl>;
let name = $state(data.gist.name);
let modified = $state(false);
Expand Down Expand Up @@ -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)
Expand All @@ -73,16 +76,27 @@
}

try {
let files = JSON.parse(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.`);
}

if (saved) {
sessionStorage.removeItem(STORAGE_KEY);
set_hash(saved);
}
}

function handle_fork({ gist }: { gist: Gist }) {
Expand All @@ -93,11 +107,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 when necessary to avoid polluting everyone's browser history
if (modified) {
const json = JSON.stringify({ name, 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)}`;
Expand Down Expand Up @@ -143,13 +165,23 @@
</svelte:head>

<svelte:window
on:hashchange={() => {
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({ name, files: repl.toJSON().files });
sessionStorage.setItem(STORAGE_KEY, json);
}
}}
/>

<svelte:body onmouseleave={update_hash} />

<div class="repl-outer">
<AppControls
examples={data.examples}
Expand All @@ -163,16 +195,7 @@
/>

{#if browser}
<div
style="display: contents"
onfocusout={() => {
// 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);
}
}}
>
<div style="display: contents" onfocusout={update_hash}>
<Repl
bind:this={repl}
{svelteUrl}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -200,9 +199,9 @@

<input
bind:value={name}
onchange={() => (modified = true)}
oninput={() => (modified = true)}
onfocus={(e) => e.currentTarget.select()}
use:enter={(e) => (e.currentTarget as HTMLInputElement).blur()}
onkeydown={(e) => e.key === 'Enter' && e.currentTarget.blur()}
/>

<div class="buttons">
Expand Down
Loading