72 lines
2.0 KiB
TypeScript
72 lines
2.0 KiB
TypeScript
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
|
|
);
|
|
}
|
|
}
|