1- import { jsx } from "@b9g/crank/standalone" ;
1+ import { jsx , Raw } from "@b9g/crank/standalone" ;
22import { Root } from "../components/root.js" ;
33
44/**
@@ -7,102 +7,106 @@ import {Root} from "../components/root.js";
77 * then receives and executes user code via postMessage.
88 */
99export default function * PlaygroundPreview ( { context} : { context : any } ) {
10- yield jsx `
11- <${ Root }
12- title="Playground Preview"
13- description="Preview iframe for Crank.js playground"
14- context=${ context }
15- path="/playground-preview"
16- >
17- <div id="preview-root"></div>
18- <script type="module">
19- // Listen for code from parent window
20- window.addEventListener("message", async (ev) => {
21- try {
22- const data = JSON.parse(ev.data);
23-
24- if (data.type === "execute-code") {
25- const code = data.code;
26- const id = data.id;
10+ const scriptContent = `
11+ // Listen for code from parent window
12+ window.addEventListener("message", async (ev) => {
13+ try {
14+ const data = JSON.parse(ev.data);
2715
28- try {
29- // Execute user code as a module
30- const blob = new Blob([code], { type: 'application/javascript' });
31- const url = URL.createObjectURL(blob);
32- await import(url);
33- URL.revokeObjectURL(url);
16+ if (data.type === "execute-code") {
17+ const code = data.code;
18+ const id = data.id;
3419
35- // Notify parent of successful execution
36- window.parent.postMessage(
37- JSON.stringify({ type: "executed", id }),
38- window.location.origin
39- );
40- } catch (error) {
41- // Notify parent of error
42- window.parent.postMessage(
43- JSON.stringify({
44- type: "error",
45- id,
46- message: error.message || String(error)
47- }),
48- window.location.origin
49- );
50- }
51- }
52- } catch {
53- // Ignore non-JSON messages
54- }
55- });
56-
57- // Handle errors
58- window.addEventListener("error", (ev) => {
59- if (/ResizeObserver loop completed with undelivered notifications/.test(ev.message)) {
60- return;
61- }
62-
63- window.parent.postMessage(
64- JSON.stringify({ type: "error", message: ev.message }),
65- window.location.origin
66- );
67- });
68-
69- window.addEventListener("unhandledrejection", (ev) => {
70- if (/ResizeObserver loop completed with undelivered notifications/.test(ev.reason?.message)) {
71- return;
72- }
73- window.parent.postMessage(
74- JSON.stringify({
75- type: "error",
76- message: ev.reason?.message || String(ev.reason)
77- }),
78- window.location.origin
79- );
80- });
20+ try {
21+ // Execute user code as a module
22+ const blob = new Blob([code], { type: 'application/javascript' });
23+ const url = URL.createObjectURL(blob);
24+ await import(url);
25+ URL.revokeObjectURL(url);
8126
82- // Set up resize observer
83- const obs = new ResizeObserver((entries) => {
84- const height = Math.max(entries[0].contentRect.height, 100);
85- if (
86- document.documentElement.clientHeight <
87- document.documentElement.scrollHeight
88- ) {
27+ // Notify parent of successful execution
28+ window.parent.postMessage(
29+ JSON.stringify({ type: "executed", id }),
30+ window.location.origin
31+ );
32+ } catch (error) {
33+ // Notify parent of error
8934 window.parent.postMessage(
9035 JSON.stringify({
91- type: "resize",
92- height,
36+ type: "error",
37+ id,
38+ message: error.message || String(error)
9339 }),
9440 window.location.origin
9541 );
9642 }
97- });
43+ }
44+ } catch {
45+ // Ignore non-JSON messages
46+ }
47+ });
48+
49+ // Handle errors
50+ window.addEventListener("error", (ev) => {
51+ if (/ResizeObserver loop completed with undelivered notifications/.test(ev.message)) {
52+ return;
53+ }
54+
55+ window.parent.postMessage(
56+ JSON.stringify({ type: "error", message: ev.message }),
57+ window.location.origin
58+ );
59+ });
9860
99- obs.observe(document.documentElement);
61+ window.addEventListener("unhandledrejection", (ev) => {
62+ if (/ResizeObserver loop completed with undelivered notifications/.test(ev.reason?.message)) {
63+ return;
64+ }
65+ window.parent.postMessage(
66+ JSON.stringify({
67+ type: "error",
68+ message: ev.reason?.message || String(ev.reason)
69+ }),
70+ window.location.origin
71+ );
72+ });
10073
101- // Signal ready
74+ // Set up resize observer
75+ const obs = new ResizeObserver((entries) => {
76+ const height = Math.max(entries[0].contentRect.height, 100);
77+ if (
78+ document.documentElement.clientHeight <
79+ document.documentElement.scrollHeight
80+ ) {
10281 window.parent.postMessage(
103- JSON.stringify({ type: "ready" }),
82+ JSON.stringify({
83+ type: "resize",
84+ height,
85+ }),
10486 window.location.origin
10587 );
88+ }
89+ });
90+
91+ obs.observe(document.documentElement);
92+
93+ // Signal ready
94+ window.parent.postMessage(
95+ JSON.stringify({ type: "ready" }),
96+ window.location.origin
97+ );
98+ ` ;
99+
100+ yield jsx `
101+ <${ Root }
102+ title="Playground Preview"
103+ description="Preview iframe for Crank.js playground"
104+ context=${ context }
105+ path="/playground-preview"
106+ >
107+ <div id="preview-root"></div>
108+ <script type="module">
109+ <${ Raw } value=${ scriptContent } />
106110 </script>
107111 <//>
108112 ` ;
0 commit comments