Source: xxe/part/StatusTool.js

/**
 * {@link XMLEditor} part used to display status messages.
 */
class StatusTool extends HTMLElement {
    constructor() {
        super();

        this._xmlEditor = null;
        this._maxLogSize = 100;
        this._log = [];
        this._timeout = null;
        this._logPopup = null;
        this._onLogPopupClosed = this.onLogPopupClosed.bind(this);
    }

    get maxLogSize() {
        return this._maxLogSize;
    }

    set maxLogSize(size) {
        if (size <= 0) {
            size = 100;
        }
        this._maxLogSize = size;
        
        while (this._log.length > size) {
            this._log.pop();
        }
    }
    
    // -----------------------------------------------------------------------
    // Custom element
    // -----------------------------------------------------------------------

    connectedCallback() {
        if (this.firstChild === null) {
            this._messageText = document.createElement("span");
            this._messageText.className = "xxe-status-tool-text";
            this.appendChild(this._messageText);

            this._logButton = document.createElement("span");
            this._logButton.className ="xxe-tool-button xxe-status-tool-button";
            this._logButton.setAttribute("title", `Show message log.
(${(PLATFORM_IS_MAC_OS? "Command" : "Ctrl")}-click to clear log.)`);
            this._logButton.textContent = XUI.StockIcon["up-dir"];
            this.appendChild(this._logButton);

            let handler = this.onClick.bind(this);
            this._logButton.addEventListener("click", handler);
            this._logButton.addEventListener("contextmenu", handler);
            this._messageText.addEventListener("contextmenu", handler);
        }
        // Otherwise, already connected.
    }

    disconnectedCallback() {
        this.cancelTimeout();
    }

    cancelTimeout() {
        if (this._timeout !== null) {
            clearTimeout(this._timeout);
            this._timeout = null;
        }
    }
    
    // -----------------------------------------------------------------------
    // Event handlers
    // -----------------------------------------------------------------------

    onClick(event) {
        XUI.Util.consumeEvent(event);

        if (this._logPopup === null) {
            const mod = PLATFORM_IS_MAC_OS? event.metaKey : event.ctrlKey;
            if (mod) { // Clear log.
                this._log = [];
            }
            
            this._logButton.textContent = XUI.StockIcon["down-dir"];
            
            this._logPopup = XUI.Dialogs.open({
                form: this.createLogPopup(), type: "popup",
                classes:
                "xui-control xui-dialog xxe-tool-popup xxe-status-tool-log",
                position: "startmenu", reference: this
            });
            this._logPopup.addEventListener("dialogclosed",
                                            this._onLogPopupClosed);
        } else {
            XUI.Dialogs.close(this._logPopup);
        }
    }

    createLogPopup() {
        let list = document.createElement("xui-list");
        list.classList.add("xxe-tool-popup-list", "xxe-status-tool-log-list");
        list.style.width =
            String(this._messageText.getBoundingClientRect().width) + "px";
        
        list.setAll(this._log);
        
        return list;
    }
    
    onLogPopupClosed(event) {
        this._logPopup = null;
        this._logButton.textContent = XUI.StockIcon["up-dir"];
        
        if (this._xmlEditor !== null) {
            this._xmlEditor.documentView.requestFocus();
        }
    }
    
    // -----------------------------------------------------------------------
    // Used by XMLEditor
    // -----------------------------------------------------------------------

    set xmlEditor(editor) {
        this._xmlEditor = editor;
    }
    
    showStatus(text, autoErase=true) {
        this.cancelTimeout();
        
        if (text === null || (text = text.trim()).length === 0) {
            text = "";
            autoErase = false;
        } else {
            while (this._log.length >= this._maxLogSize) {
                this._log.pop();
            }
            this._log.unshift(text);
        }
        this._messageText.textContent = XUI.Util.shortenText(text, 256);

        if (autoErase) {
            this._timeout = setTimeout(() => {
                this._messageText.textContent = "";
            }, 10000 /*ms*/);
        }
    }
}

window.customElements.define("xxe-status-tool", StatusTool);