output-frame.ts

99 lines | 3.125 kB Blame History Raw Download
import { BaseElement } from "../../../shared/_base";
import './output-frame.less';
import { GetOutputFrameUrl } from "../../../shared/url-helpers";
import { GetNotificationBubbles } from "../../../shared/getdom";
import { postMessage } from "../../../shared/post-message";

export class OutputFrame extends BaseElement {
    public Iframe: HTMLIFrameElement | null = null;
    private CurrentIframeScriptRemoveResponseListener: Function | null = null;

    constructor() {
        super();
    }

    private contents: any = {};

    onInit(): void {
        this.reset();
    }

    onUpdate(): void {
    }

    reset(onload: ((ev: Event) => void) | null = null, resetNotificationBubbles: boolean = true, source: string | null = null) {
        if (this.CurrentIframeScriptRemoveResponseListener != null) {
            this.CurrentIframeScriptRemoveResponseListener();
            this.CurrentIframeScriptRemoveResponseListener = null;
        }

        if (this.Iframe && this.hasChild(this.Iframe)) {
            this.Iframe.setAttribute("sandbox", "allow-pointer-lock allow-same-origin");
            this.removeChild(this.Iframe);
        }


        this.Iframe = document.createElement("iframe");
        this.Iframe.setAttribute("sandbox", "allow-pointer-lock allow-same-origin allow-scripts");
        if (onload) {
            this.Iframe.onload = ((ev) => {
                onload(ev);
                if (this.Iframe)
                    this.Iframe.onload = () => { };
            });
        }
        if (source != null) {
            this.Iframe.src = source;
        }
        else {
            this.Iframe.src = GetOutputFrameUrl();
        }

        if (source !== "") {
            this.appendChild(this.Iframe);
        }

        if (resetNotificationBubbles) {
            var bubbles = GetNotificationBubbles();
            if (bubbles && bubbles.reset) {
                bubbles.reset();
            }
        }
    }

    setError() {
        this.reset(() => {
            console.log("ERROR RESET");
            if (this.Iframe) {
                // this.Iframe.contentWindow?.location.reload();
            }
        }, true, "");

    }

    setContent(language: string, value: string) {
        this.contents[language] = value;
        this.reset(() => {
            for (const lang in this.contents) {
                if (lang != "javascript")
                    this.doPostMessage(lang, this.contents[lang]);
            }

            if (this.contents["javascript"])
                this.doPostMessage("javascript", this.contents["javascript"]);
        });
    }

    doPostMessage(language: string, value: string) {
        this.CurrentIframeScriptRemoveResponseListener = postMessage(this.Iframe?.contentWindow, language, this.contents[language], language == 'javascript' ?
            (executeTimeInMs, exceedTimeInMs) => {
                if (executeTimeInMs === -1) {
                    this.setError();
                }
                else {
                    var bubbles = GetNotificationBubbles();
                    bubbles.add(language + " executed in: " + executeTimeInMs + "ms", "info");
                }
            } : undefined);
    }
}