You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte/site/src/routes/repl/embed.html

120 lines
2.3 KiB

<script context="module">
export function preload({ query }) {
return {
version: query.version || 'beta',
gist: query.gist,
demo: query.demo
};
}
</script>
<script>
import { onMount } from 'svelte';
import * as fleece from 'golden-fleece';
import Repl from './_components/Repl.html';
export let version, gist, demo;
let app = {
components: [],
values: {}
};
let name = 'loading...';
onMount(() => {
if (version !== 'local') {
fetch(`https://unpkg.com/svelte@${version}/package.json`)
.then(r => r.json())
.then(pkg => {
version = pkg.version;
});
}
if (gist) {
fetch(`gist/${gist}`).then(r => r.json()).then(data => {
const { id, description, files } = data;
name = description;
let values = {};
const components = Object.keys(files)
.map(file => {
const dot = file.lastIndexOf('.');
if (!~dot) return;
const source = files[file].content;
// while we're here...
if (file === 'data.json' || file === 'data.json5') {
values = tryParseData(source) || {};
}
return {
name: file.slice(0, dot),
type: file.slice(dot + 1),
source
};
})
.filter(x => x.type === 'html' || x.type === 'js')
.sort((a, b) => {
if (a.name === 'App' && a.type === 'html') return -1;
if (b.name === 'App' && b.type === 'html') return 1;
if (a.type !== b.type) return a.type === 'html' ? -1 : 1;
return a.name < b.name ? -1 : 1;
});
app = { components, values };
});
} else if (demo) {
const url = `api/examples/${demo}`;
fetch(url).then(async response => {
if (response.ok) {
const data = await response.json();
app = {
values: tryParseData(data.json5) || {}, // TODO make this more error-resistant
components: data.components
};
}
});
}
});
function tryParseData(json5) {
try {
return fleece.evaluate(json5);
} catch (err) {
return null;
}
}
</script>
<style>
.repl-outer {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: var(--back);
overflow: hidden;
box-sizing: border-box;
--pane-controls-h: 4.2rem;
}
</style>
<svelte:head>
<title>{name} • Svelte REPL</title>
</svelte:head>
<div class="repl-outer">
{#if process.browser}
<Repl {version} {app} embedded={true}/>
{/if}
</div>