Complete main UI #37
@@ -4,7 +4,6 @@ import iframeRaw from '@/components/Playground/Output/Preview/iframe.html?raw'
|
|||||||
interface RenderProps {
|
interface RenderProps {
|
||||||
iframeKey: string
|
iframeKey: string
|
||||||
compiledCode: string
|
compiledCode: string
|
||||||
onError?: (errorMsg: string) => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IMessage {
|
interface IMessage {
|
||||||
@@ -30,38 +29,19 @@ const getIframeUrl = (iframeRaw: string) => {
|
|||||||
|
|
||||||
const iframeUrl = getIframeUrl(iframeRaw)
|
const iframeUrl = getIframeUrl(iframeRaw)
|
||||||
|
|
||||||
const Render = ({ iframeKey, compiledCode, onError }: RenderProps) => {
|
const Render = ({ iframeKey, compiledCode }: RenderProps) => {
|
||||||
const iframeRef = useRef<HTMLIFrameElement>(null)
|
const iframeRef = useRef<HTMLIFrameElement>(null)
|
||||||
const [loaded, setLoaded] = useState(false)
|
const [loaded, setLoaded] = useState(false)
|
||||||
|
|
||||||
const handleMessage = ({ data }: { data: IMessage }) => {
|
|
||||||
const { type, msg } = data
|
|
||||||
switch (type) {
|
|
||||||
case 'LOADED':
|
|
||||||
setLoaded(true)
|
|
||||||
break
|
|
||||||
case 'ERROR':
|
|
||||||
onError?.(msg)
|
|
||||||
break
|
|
||||||
case 'DONE':
|
|
||||||
onError?.('')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
window.addEventListener('message', handleMessage)
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
window.removeEventListener('message', handleMessage)
|
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (loaded) {
|
if (loaded) {
|
||||||
iframeRef.current?.contentWindow?.postMessage({
|
iframeRef.current?.contentWindow?.postMessage(
|
||||||
type: 'UPDATE',
|
{
|
||||||
data: { compiledCode }
|
type: 'UPDATE',
|
||||||
} as IMessage)
|
data: { compiledCode }
|
||||||
|
} as IMessage,
|
||||||
|
'*'
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}, [compiledCode, loaded])
|
}, [compiledCode, loaded])
|
||||||
|
|
||||||
@@ -71,7 +51,8 @@ const Render = ({ iframeKey, compiledCode, onError }: RenderProps) => {
|
|||||||
key={iframeKey}
|
key={iframeKey}
|
||||||
ref={iframeRef}
|
ref={iframeRef}
|
||||||
src={iframeUrl}
|
src={iframeUrl}
|
||||||
sandbox="allow-popups-to-escape-sandbox allow-scripts allow-popups allow-forms allow-pointer-lock allow-top-navigation allow-modals allow-same-origin"
|
onLoad={() => setLoaded(true)}
|
||||||
|
sandbox="allow-downloads allow-forms allow-modals allow-scripts"
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,14 +8,6 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script>
|
<script>
|
||||||
window.addEventListener("error", (e) => {
|
|
||||||
window.parent.postMessage({ type: "ERROR", msg: e.message });
|
|
||||||
});
|
|
||||||
|
|
||||||
window.addEventListener("load", () => {
|
|
||||||
window.parent.postMessage({ type: "LOADED", msg: "" });
|
|
||||||
});
|
|
||||||
|
|
||||||
window.addEventListener("message", ({ data }) => {
|
window.addEventListener("message", ({ data }) => {
|
||||||
if (data?.type === "UPDATE") {
|
if (data?.type === "UPDATE") {
|
||||||
// Record old styles that need to be removed
|
// Record old styles that need to be removed
|
||||||
@@ -43,7 +35,6 @@
|
|||||||
};
|
};
|
||||||
document.body.appendChild(script);
|
document.body.appendChild(script);
|
||||||
URL.revokeObjectURL(oldSrc);
|
URL.revokeObjectURL(oldSrc);
|
||||||
window.parent.postMessage({ type: "DONE", msg: "" });
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -23,10 +23,6 @@ const Preview = ({
|
|||||||
const [errorMsg, setErrorMsg] = useState('')
|
const [errorMsg, setErrorMsg] = useState('')
|
||||||
const [compiledCode, setCompiledCode] = useState('')
|
const [compiledCode, setCompiledCode] = useState('')
|
||||||
|
|
||||||
const handleOnError = (errorMsg: string) => {
|
|
||||||
setErrorMsg(errorMsg)
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!Object.keys(files).length || !importMap || !entryPoint.length) {
|
if (!Object.keys(files).length || !importMap || !entryPoint.length) {
|
||||||
return
|
return
|
||||||
@@ -36,6 +32,7 @@ const Preview = ({
|
|||||||
setCompiledCode(
|
setCompiledCode(
|
||||||
`${preExpansionCode}\n${result.outputFiles[0].text}\n${postExpansionCode}`
|
`${preExpansionCode}\n${result.outputFiles[0].text}\n${postExpansionCode}`
|
||||||
)
|
)
|
||||||
|
setErrorMsg('')
|
||||||
})
|
})
|
||||||
.catch((e: Error) => {
|
.catch((e: Error) => {
|
||||||
setErrorMsg(`编译失败:${e.message}`)
|
setErrorMsg(`编译失败:${e.message}`)
|
||||||
@@ -44,7 +41,7 @@ const Preview = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div data-component={'playground-preview'}>
|
<div data-component={'playground-preview'}>
|
||||||
<Render iframeKey={iframeKey} compiledCode={compiledCode} onError={handleOnError} />
|
<Render iframeKey={iframeKey} compiledCode={compiledCode} />
|
||||||
{errorMsg && <div className={'playground-error-message'}>{errorMsg}</div>}
|
{errorMsg && <div className={'playground-error-message'}>{errorMsg}</div>}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user