1
0
silverbullet/web/cm_plugins/iframe_widget.ts

72 lines
2.0 KiB
TypeScript
Raw Normal View History

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
);
}
}