74 lines
1.9 KiB
TypeScript
74 lines
1.9 KiB
TypeScript
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);
|
|
});
|
|
}
|