From 32ff06b670490e6377a695408530ef3ede7491ae Mon Sep 17 00:00:00 2001 From: Florian Dieminger Date: Sat, 23 Nov 2024 15:57:53 +0100 Subject: [PATCH] fix(playground) use src for path (#12170) --- client/src/playground/index.tsx | 60 ++++++++++++++++----------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/client/src/playground/index.tsx b/client/src/playground/index.tsx index fd9bfd72da4a..142a05f137b9 100644 --- a/client/src/playground/index.tsx +++ b/client/src/playground/index.tsx @@ -80,6 +80,7 @@ export default function Playground() { let [vConsole, setVConsole] = useState([]); let [state, setState] = useState(State.initial); let [codeSrc, setCodeSrc] = useState(); + let [iframeSrc, setIframeSrc] = useState("about:blank"); const [isEmpty, setIsEmpty] = useState(true); const subdomain = useRef(crypto.randomUUID()); const [initialContent, setInitialContent] = useState( @@ -119,16 +120,25 @@ export default function Playground() { const iframe = useRef(null); const diaRef = useRef(null); - const updateWithCode = async (code: EditorContent) => { - const { state } = await compressAndBase64Encode(JSON.stringify(code)); - const sp = new URLSearchParams([["state", state]]); - - if (iframe.current) { - const url = new URL(iframe.current.src); - url.search = sp.toString(); - iframe.current.src = url.href; - } - }; + const updateWithCode = useCallback( + async (code: EditorContent) => { + const { state } = await compressAndBase64Encode(JSON.stringify(code)); + + // We're using a random subdomain for origin isolation. + const url = new URL( + `${window.location.protocol}//${ + PLAYGROUND_BASE_HOST.startsWith("localhost") + ? "" + : `${subdomain.current}.` + }${PLAYGROUND_BASE_HOST}` + ); + setVConsole([]); + url.searchParams.set("state", state); + url.pathname = `${codeSrc || code.src || ""}/runner.html`; + setIframeSrc(url.href); + }, + [codeSrc, setVConsole, setIframeSrc] + ); useEffect(() => { if (initialCode) { @@ -144,17 +154,15 @@ export default function Playground() { html: htmlRef.current?.getContent() || HTML_DEFAULT, css: cssRef.current?.getContent() || CSS_DEFAULT, js: jsRef.current?.getContent() || JS_DEFAULT, - src: initialCode?.src, + src: initialCode?.src || initialContent?.src, }; store(SESSION_KEY, code); return code; - }, [initialCode?.src]); + }, [initialContent?.src, initialCode?.src]); let messageListener = useCallback(({ data: { typ, prop, message } }) => { if (typ === "console") { - if (prop === "clear") { - setVConsole([]); - } else if ( + if ( (prop === "log" || prop === "error" || prop === "warn") && typeof message === "string" ) { @@ -178,7 +186,7 @@ export default function Playground() { cssRef.current?.setContent(css); jsRef.current?.setContent(js); if (src) { - setCodeSrc(src.split("/").slice(0, -1).join("/")); + setCodeSrc(src); } setIsEmpty(!html && !css && !js); }; @@ -210,7 +218,7 @@ export default function Playground() { setState(State.ready); } })(); - }, [initialCode, state, gistId, stateParam]); + }, [initialCode, state, gistId, stateParam, updateWithCode]); useEffect(() => { window.addEventListener("message", messageListener); @@ -222,8 +230,8 @@ export default function Playground() { const clear = async () => { setSearchParams([], { replace: true }); setCodeSrc(undefined); - setEditorContent({ html: HTML_DEFAULT, css: CSS_DEFAULT, js: JS_DEFAULT }); setInitialContent(null); + setEditorContent({ html: HTML_DEFAULT, css: CSS_DEFAULT, js: JS_DEFAULT }); updateWithEditorContent(); }; @@ -253,7 +261,7 @@ export default function Playground() { }; const updateWithEditorContent = () => { - const { html, css, js } = getEditorContent(); + const { html, css, js, src } = getEditorContent(); setIsEmpty(!html && !css && !js); const loading = [ @@ -269,7 +277,7 @@ export default function Playground() { iterations: 1, }; document.getElementById("run")?.firstElementChild?.animate(loading, timing); - updateWithCode({ html, css, js }); + updateWithCode({ html, css, js, src }); }; const format = async () => { @@ -307,16 +315,6 @@ export default function Playground() { setShareUrl(url); }, [setSearchParams, setShareUrl, setShared, getEditorContent]); - // We're using a random subdomain for origin isolation. - const src = new URL( - `${window.location.protocol}//${ - PLAYGROUND_BASE_HOST.startsWith("localhost") - ? "" - : `${subdomain.current}.` - }${PLAYGROUND_BASE_HOST}` - ); - src.pathname = `${codeSrc || ""}/runner.html`; - const cleanDialog = () => { if (dialogState === DialogState.share) { setShareUrl(null); @@ -412,7 +410,7 @@ export default function Playground() {