class LogTerminal extends HTMLElement { #maxlines = 10; #maxstoredlines = 100; #rootdoc = null; #lines = []; #index = null; static get observedAttributes() { return ['index']; } constructor(){ super() this.#maxlines = this.getAttribute("maxlines") this.#rootdoc = this.attachShadow({ "mode" : "open"}) this.render() } connectedCallback(){ this.reloadLines() this.refresh() } attributeChangedCallback(name, oldValue, newValue) { if(name === "index"){ this.#index = newValue this.reloadLines() } } get lines(){ return this.#lines } addLines(lines){ this.#lines = this.#lines.concat(lines) this.refresh() this.storeLines() } reloadLines(){ if(this.#index == null) return; if(sessionStorage.getItem("logs-" + this.#index)){ this.#lines = JSON.parse(sessionStorage.getItem("logs-" + this.#index)) }else{ this.#lines = [] } } storeLines(){ if(this.#lines.length > this.#maxstoredlines){ this.#lines.splice(0, this.#lines.length - this.#maxstoredlines) } sessionStorage.setItem("logs-" + this.#index, JSON.stringify(this.#lines)) } render(){ this.#rootdoc.innerHTML = `
` } refresh(){ BSS.apply(this.#terminal_bss, this.#rootdoc) const lt = this.#rootdoc.querySelector("div.terminal") lt.scrollTop = lt.scrollHeight; } #terminal_bss = { template : "#TERMINAL_TEMPLATE", target : "div[name=terminal]", in : ()=>this, recurse : { target : "div.line", in: (e,d)=>d.lines, apply: (e,d,i)=>{ if(d.source === "stderr") e.classList.add("error"); if(d.source === "infrastructure") e.classList.add("infrastructure"); e.innerHTML = `${d.line}` } } } } window.customElements.define('d4s-ccp-logterminal', LogTerminal);