From 544b18643c42ad3e4a00115a96997a4675b012b7 Mon Sep 17 00:00:00 2001 From: velzie Date: Thu, 24 Oct 2024 15:11:59 -0400 Subject: [PATCH] scramjet playground --- static/playground.html | 62 ++++++++++++ static/playground.js | 217 +++++++++++++++++++++++++++++++++++++++++ static/sw.js | 32 ++++++ static/ui.js | 5 +- 4 files changed, 313 insertions(+), 3 deletions(-) create mode 100644 static/playground.html create mode 100644 static/playground.js diff --git a/static/playground.html b/static/playground.html new file mode 100644 index 0000000..55d703e --- /dev/null +++ b/static/playground.html @@ -0,0 +1,62 @@ + + + + + + Scramjet + + + + + + + + + + + + + + + + + + + + + diff --git a/static/playground.js b/static/playground.js new file mode 100644 index 0000000..bdf8803 --- /dev/null +++ b/static/playground.js @@ -0,0 +1,217 @@ +const scramjet = new ScramjetController({ + files: { + wasm: "/scram/scramjet.wasm.js", + worker: "/scram/scramjet.worker.js", + client: "/scram/scramjet.client.js", + shared: "/scram/scramjet.shared.js", + sync: "/scram/scramjet.sync.js", + }, + siteFlags: { + "https://worker-playground.glitch.me/.*": { + serviceworkers: true, + }, + }, +}); + +scramjet.init("./sw.js"); + +const connection = new BareMux.BareMuxConnection("/baremux/worker.js"); +const flex = css` + display: flex; +`; +const col = css` + flex-direction: column; +`; + +const store = $store( + { + url: "https://google.com", + wispurl: + _CONFIG?.wispurl || + (location.protocol === "https:" ? "wss" : "ws") + + "://" + + location.host + + "/wisp/", + bareurl: + _CONFIG?.bareurl || + (location.protocol === "https:" ? "https" : "http") + + "://" + + location.host + + "/bare/", + proxy: "", + }, + { ident: "settings", backing: "localstorage", autosave: "auto" } +); +connection.setTransport("/epoxy/index.mjs", [{ wisp: store.wispurl }]); + +function PlaygroundApp() { + this.css = ` + width: 100%; + height: 100%; + color: #f0fef4; + display: flex; + padding: 0.5em; + box-sizing: border-box; + gap: 0.5em; + + + .codesplit { + width: 50%; + height: 100%; + display: flex; + flex-direction: column; + + gap: 0.5em; + } + + .mcontainer { + background: #1e1e1e; + h2 { + margin: 0.1em; + } + + border: 1px solid #313131; + flex-basis: 100%; + display: flex; + flex-direction: column; + } + .monaco { + flex: 1; + } + + .frame { + height: 100%; + display: flex; + flex-direction: column; + gap: 0.5em; + iframe { + width: 100%; + + border: 1px solid #313131; + } + } + .config { + border: 1px solid #313131; + background: #1e1e1e; + padding: 0.5em; + } + `; + + this.fakeorigin = "https://sandboxedorigin.com"; + this.mount = async () => { + const monaco = await import( + "https://cdn.jsdelivr.net/npm/monaco-editor/+esm" + ); + + monaco.editor.setTheme("vs-dark"); + const html = monaco.editor.create(this.htmlbox, { + value: ` + + + + + + + + + +

Scramjet Sandbox Playground

+

+ Scramjet allows any webpage to be run on the same origin in an isolated manner +

+ + + + + +`, + language: "html", + }); + const js = monaco.editor.create(this.jsbox, { + value: `function checkOrigin() { + alert("origin: " + window.origin); +} + +// external resources fetched will be re- +// directed to the WISP server +function loadResource(url) { + fetch(url).then(r => { + console.log("loaded", r); + }) +}`, + language: "javascript", + }); + const css = monaco.editor.create(this.cssbox, { + value: `body, html { + background: #1e1e1e; + color: white; + width: 100%; + height: 100%; +}`, + language: "css", + }); + let oldjs; + let oldhtml; + let oldcss; + + setInterval(async () => { + if ( + oldjs !== js.getValue() || + oldhtml !== html.getValue() || + oldcss !== css.getValue() + ) { + oldjs = js.getValue(); + oldhtml = html.getValue(); + oldcss = css.getValue(); + + (await navigator.serviceWorker.ready).active.postMessage({ + type: "playgroundData", + html: html.getValue(), + css: css.getValue(), + js: js.getValue(), + origin: this.fakeorigin, + }); + + this.frame.src = scramjet.encodeUrl(this.fakeorigin); + } + }, 1000); + }; + + return html` +
+
+
+

HTML

+
+
+ +
+

JS

+
+
+ +
+

CSS

+
+
+
+
+ +
+

Config

+
+ + + + + +
+
+
+
+ `; +} + +window.addEventListener("load", async () => { + document.body.appendChild(h(PlaygroundApp)); +}); diff --git a/static/sw.js b/static/sw.js index 613e50c..ad960d3 100644 --- a/static/sw.js +++ b/static/sw.js @@ -18,3 +18,35 @@ async function handleRequest(event) { self.addEventListener("fetch", (event) => { event.respondWith(handleRequest(event)); }); + +let playgroundData; +self.addEventListener("message", ({ data }) => { + if (data.type === "playgroundData") { + playgroundData = data; + } +}); + +scramjet.addEventListener("request", (e) => { + let headers = {}; + if (e.url.href === playgroundData.origin + "/") { + headers["content-type"] = "text/html"; + e.response = new Response(playgroundData.html, { + headers, + }); + } else if (e.url.href === playgroundData.origin + "/style.css") { + headers["content-type"] = "text/css"; + e.response = new Response(playgroundData.css, { + headers, + }); + } else if (e.url.href === playgroundData.origin + "/script.js") { + headers["content-type"] = "application/javascript"; + e.response = new Response(playgroundData.js, { + headers, + }); + } else { + return; + } + + e.response.rawHeaders = headers; + e.response.finalURL = e.url; +}); diff --git a/static/ui.js b/static/ui.js index dd3b10e..a4da0d8 100644 --- a/static/ui.js +++ b/static/ui.js @@ -122,7 +122,7 @@ function Config() { `; } -function App() { +function BrowserApp() { this.urlencoded = ""; this.css = ` width: 100%; @@ -253,9 +253,8 @@ function App() { `; } - window.addEventListener("load", async () => { - document.body.appendChild(h(App)); + document.body.appendChild(h(BrowserApp)); function b64(buffer) { let binary = ""; const bytes = new Uint8Array(buffer);