import { WidgetContent } from "../../plug-api/app_event.ts"; import { WidgetType } from "../deps.ts"; import type { Client } from "../client.ts"; import { createWidgetSandboxIFrame } from "../components/widget_sandbox_iframe.ts"; import type { CodeWidgetCallback } from "$sb/types.ts"; export class IFrameWidget extends WidgetType { iframe?: HTMLIFrameElement; constructor( readonly from: number, readonly to: number, readonly client: Client, readonly bodyText: string, readonly codeWidgetCallback: CodeWidgetCallback, ) { super(); } toDOM(): HTMLElement { const from = this.from; const iframe = createWidgetSandboxIFrame( this.client, this.bodyText, this.codeWidgetCallback(this.bodyText, this.client.currentPage!), (message) => { switch (message.type) { case "blur": this.client.editorView.dispatch({ selection: { anchor: from }, }); this.client.focus(); break; case "reload": this.codeWidgetCallback(this.bodyText, this.client.currentPage!) .then( (widgetContent: WidgetContent) => { iframe.contentWindow!.postMessage({ type: "html", html: widgetContent.html, script: widgetContent.script, theme: document.getElementsByTagName("html")[0].dataset.theme, }); }, ); break; } }, ); const estimatedHeight = this.estimatedHeight; iframe.height = `${estimatedHeight}px`; return iframe; } get estimatedHeight(): number { const cachedHeight = this.client.getCachedWidgetHeight(this.bodyText); console.log("Calling estimated height", this.bodyText, cachedHeight); return cachedHeight > 0 ? cachedHeight : 150; } eq(other: WidgetType): boolean { return ( other instanceof IFrameWidget && other.bodyText === this.bodyText ); } }