import { Decoration, EditorState, WidgetType } from "../deps.ts"; import type { Client } from "../client.ts"; import { decoratorStateField } from "./util.ts"; import { PanelConfig } from "../types.ts"; import { createWidgetSandboxIFrame } from "../components/widget_sandbox_iframe.ts"; class IFrameWidget extends WidgetType { widgetHeightCacheKey: string; constructor( readonly editor: Client, readonly panel: PanelConfig, readonly className: string, ) { super(); this.widgetHeightCacheKey = `${this.editor.currentPage!}#${this.className}`; } toDOM(): HTMLElement { const iframe = createWidgetSandboxIFrame( this.editor, this.widgetHeightCacheKey, this.panel, ); iframe.classList.add(this.className); return iframe; } get estimatedHeight(): number { return this.editor.space.getCachedWidgetHeight( this.widgetHeightCacheKey, ); } eq(other: WidgetType): boolean { return this.panel.html === (other as IFrameWidget).panel.html && this.panel.script === (other as IFrameWidget).panel.script; } } export function postScriptPrefacePlugin(editor: Client) { return decoratorStateField((state: EditorState) => { const widgets: any[] = []; if (editor.ui.viewState.panels.top.html) { widgets.push( Decoration.widget({ widget: new IFrameWidget( editor, editor.ui.viewState.panels.top, "sb-top-iframe", ), side: -1, block: true, }).range(0), ); } if (editor.ui.viewState.panels.bottom.html) { widgets.push( Decoration.widget({ widget: new IFrameWidget( editor, editor.ui.viewState.panels.bottom, "sb-bottom-iframe", ), side: 1, block: true, }).range(state.doc.length), ); } return Decoration.set(widgets); }); }