Skip to content

Commit 38bb65c

Browse files
committed
Fix JSX syntax error in playground-preview view
The JavaScript code inside the JSX template literal was causing parse errors due to dot notation (ev.data, ev.message, etc). Extracted the script content into a separate template literal and used the Raw component to inject it, following the same pattern as ColorSchemeScript in root.ts. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent ec38a97 commit 38bb65c

File tree

1 file changed

+87
-83
lines changed

1 file changed

+87
-83
lines changed

website/src/views/playground-preview.ts

Lines changed: 87 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {jsx} from "@b9g/crank/standalone";
1+
import {jsx, Raw} from "@b9g/crank/standalone";
22
import {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
*/
99
export 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

Comments
 (0)