diff --git a/website/src/runner/index.ts b/website/src/runner/index.ts index 590d17cb..8bc551be 100644 --- a/website/src/runner/index.ts +++ b/website/src/runner/index.ts @@ -17,6 +17,11 @@ window.addEventListener("message", (event) => { const e = event.data as IMessage | { kind: undefined }; if (e.kind === "initialize") { initialize(e.state); + } else if (e.kind === "update-css") { + const style = document.getElementById( + "custom-style" + ) as HTMLStyleElement; + style.innerHTML = e.css; } }); @@ -40,6 +45,7 @@ async function initialize(state: IPreviewState) { loadingContainerDiv.remove(); const style = document.createElement("style"); + style.id = "custom-style"; style.innerHTML = state.css; document.body.appendChild(style); diff --git a/website/src/shared.ts b/website/src/shared.ts index e68e708d..71036e39 100644 --- a/website/src/shared.ts +++ b/website/src/shared.ts @@ -5,10 +5,15 @@ import { IMonacoSetup } from "./monaco-loader"; -export type IMessage = { - kind: "initialize"; - state: IPreviewState; -}; +export type IMessage = + | { + kind: "initialize"; + state: IPreviewState; + } + | { + kind: "update-css"; + css: string; + }; export interface IPlaygroundProject { js: string; @@ -17,5 +22,6 @@ export interface IPlaygroundProject { } export interface IPreviewState extends IPlaygroundProject { + key: number; monacoSetup: IMonacoSetup; } diff --git a/website/src/website/pages/playground/PlaygroundModel.ts b/website/src/website/pages/playground/PlaygroundModel.ts index 49918efa..15ae15f8 100644 --- a/website/src/website/pages/playground/PlaygroundModel.ts +++ b/website/src/website/pages/playground/PlaygroundModel.ts @@ -87,7 +87,11 @@ export class PlaygroundModel { @computed public get state(): IPreviewState { - return { ...this.playgroundProject, monacoSetup: this.monacoSetup }; + return { + ...this.playgroundProject, + monacoSetup: this.monacoSetup, + key: this.reloadKey, + }; } @observable @@ -126,7 +130,7 @@ export class PlaygroundModel { constructor() { this.dispose.track({ dispose: reaction( - () => ({ state: this.state, key: this.reloadKey }), + () => ({ state: this.state }), ({ state }) => { this.debouncer.run(() => { for (const handler of this._previewHandlers) { @@ -162,6 +166,8 @@ export class PlaygroundModel { return; } const monacoTypesUrl = this.monacoSetup.monacoTypesUrl; + this.reloadKey; // Allow reload to reload the d.ts file. + let content = ""; if (monacoTypesUrl) { content = await (await fetch(monacoTypesUrl)).text(); diff --git a/website/src/website/pages/playground/Preview.tsx b/website/src/website/pages/playground/Preview.tsx index c2a271b0..93692974 100644 --- a/website/src/website/pages/playground/Preview.tsx +++ b/website/src/website/pages/playground/Preview.tsx @@ -13,6 +13,7 @@ export class Preview @observable private counter = 0; private currentState: IPreviewState | undefined; + private iframe: HTMLIFrameElement | null = null; render() { return ( @@ -30,6 +31,7 @@ export class Preview } handleIframe = (iframe: HTMLIFrameElement | null) => { + this.iframe = iframe; if (!iframe) { return; } @@ -57,7 +59,24 @@ export class Preview } handlePreview(state: IPreviewState): void { - this.currentState = state; - this.counter++; + if ( + JSON.stringify({ ...state, css: "" }) === + JSON.stringify({ ...this.currentState, css: "" }) + ) { + // only css changed + this.iframe?.contentWindow!.postMessage( + { + kind: "update-css", + css: state.css, + } as IMessage, + { + targetOrigin: "*", + } + ); + this.currentState = state; + } else { + this.currentState = state; + this.counter++; + } } }