const scramjet = new ScramjetController({
files: {
wasm: "/scram/scramjet.wasm.wasm",
worker: "/scram/scramjet.worker.js",
client: "/scram/scramjet.client.js",
shared: "/scram/scramjet.shared.js",
sync: "/scram/scramjet.sync.js",
},
flags: {
serviceworkers: true,
syncxhr: true,
scramitize: true,
},
});
scramjet.init();
navigator.serviceWorker.register("./sw.js");
const connection = new BareMux.BareMuxConnection("/baremux/worker.js");
const flex = css`
display: flex;
`;
const col = css`
flex-direction: column;
`;
connection.setTransport(store.transport, [{ 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"
);
const dedent = (await import("https://cdn.jsdelivr.net/npm/dedent/+esm"))
.default;
monaco.editor.setTheme("vs-dark");
const html = monaco.editor.create(this.htmlbox, {
value: dedent`
Scramjet Sandbox Playground
Scramjet allows any webpage to be run on the same origin in an isolated manner
iframe test
`,
language: "html",
automaticLayout: true,
});
const css = monaco.editor.create(this.cssbox, {
value: dedent`
/* resources loaded by css are intercepted by service worker */
@import url('https://fonts.googleapis.com/css2?family=Hind:wght@300;400;500;600;700&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');
body, html {
background: #1e1e1e;
color: white;
width: 100%;
height: 100%;
font-family: "Roboto";
}
iframe {
zoom: 0.75;
width: 50%;
height: 50%;
}
`,
language: "css",
automaticLayout: true,
});
const js = monaco.editor.create(this.jsbox, {
value: dedent`
function checkOrigin() {
// real origin is hidden from the page
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);
})
}
function loadiframe() {
if (document.getElementById("nested-frame")) return;
let frame = document.createElement("iframe");
frame.id = "nested-frame";
frame.src = "https://google.com";
document.body.appendChild(frame);
}
`,
language: "javascript",
automaticLayout: true,
});
const recompile = async () => {
(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);
};
recompile();
html.getModel().onDidChangeContent(recompile);
css.getModel().onDidChangeContent(recompile);
js.getModel().onDidChangeContent(recompile);
};
return html`
`;
}
window.addEventListener("load", async () => {
const root = document.getElementById("app");
try {
root.replaceWith(h(PlaygroundApp));
} catch (e) {
root.replaceWith(document.createTextNode("" + e));
throw e;
}
});