UNPKG

tasmota-esp-web-tools

Version:
267 lines (265 loc) 8.57 kB
export class ColoredConsole { constructor(targetElement) { this.targetElement = targetElement; this.state = { bold: false, italic: false, underline: false, strikethrough: false, foregroundColor: null, backgroundColor: null, carriageReturn: false, secret: false, }; } logs() { return this.targetElement.innerText; } addLine(line) { const re = /(?:\x1B|\\x1B)(?:\[(.*?)[@-~]|\].*?(?:\x07|\x1B\\))/g; let i = 0; if (this.state.carriageReturn) { if (line !== "\n") { // don't remove if \r\n this.targetElement.removeChild(this.targetElement.lastChild); } this.state.carriageReturn = false; } if (line.includes("\r")) { this.state.carriageReturn = true; } const lineSpan = document.createElement("span"); lineSpan.classList.add("line"); this.targetElement.appendChild(lineSpan); const addSpan = (content) => { if (content === "") return; const span = document.createElement("span"); if (this.state.bold) span.classList.add("log-bold"); if (this.state.italic) span.classList.add("log-italic"); if (this.state.underline) span.classList.add("log-underline"); if (this.state.strikethrough) span.classList.add("log-strikethrough"); if (this.state.secret) span.classList.add("log-secret"); if (this.state.foregroundColor !== null) span.classList.add(`log-fg-${this.state.foregroundColor}`); if (this.state.backgroundColor !== null) span.classList.add(`log-bg-${this.state.backgroundColor}`); span.appendChild(document.createTextNode(content)); lineSpan.appendChild(span); if (this.state.secret) { const redacted = document.createElement("span"); redacted.classList.add("log-secret-redacted"); redacted.appendChild(document.createTextNode("[redacted]")); lineSpan.appendChild(redacted); } }; while (true) { const match = re.exec(line); if (match === null) break; const j = match.index; addSpan(line.substring(i, j)); i = j + match[0].length; if (match[1] === undefined) continue; for (const colorCode of match[1].split(";")) { switch (parseInt(colorCode)) { case 0: // reset this.state.bold = false; this.state.italic = false; this.state.underline = false; this.state.strikethrough = false; this.state.foregroundColor = null; this.state.backgroundColor = null; this.state.secret = false; break; case 1: this.state.bold = true; break; case 3: this.state.italic = true; break; case 4: this.state.underline = true; break; case 5: this.state.secret = true; break; case 6: this.state.secret = false; break; case 9: this.state.strikethrough = true; break; case 22: this.state.bold = false; break; case 23: this.state.italic = false; break; case 24: this.state.underline = false; break; case 29: this.state.strikethrough = false; break; case 30: this.state.foregroundColor = "black"; break; case 31: this.state.foregroundColor = "red"; break; case 32: this.state.foregroundColor = "green"; break; case 33: this.state.foregroundColor = "yellow"; break; case 34: this.state.foregroundColor = "blue"; break; case 35: this.state.foregroundColor = "magenta"; break; case 36: this.state.foregroundColor = "cyan"; break; case 37: this.state.foregroundColor = "white"; break; case 39: this.state.foregroundColor = null; break; case 41: this.state.backgroundColor = "red"; break; case 42: this.state.backgroundColor = "green"; break; case 43: this.state.backgroundColor = "yellow"; break; case 44: this.state.backgroundColor = "blue"; break; case 45: this.state.backgroundColor = "magenta"; break; case 46: this.state.backgroundColor = "cyan"; break; case 47: this.state.backgroundColor = "white"; break; case 40: case 49: this.state.backgroundColor = null; break; } } } const atBottom = this.targetElement.scrollTop > this.targetElement.scrollHeight - this.targetElement.offsetHeight - 50; addSpan(line.substring(i)); // Keep scroll at bottom if (atBottom) { this.targetElement.scrollTop = this.targetElement.scrollHeight; } } } export const coloredConsoleStyles = ` .log { flex: 1; background-color: #1c1c1c; font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 12px; padding: 16px; overflow: auto; line-height: 1.45; border-radius: 3px; white-space: pre-wrap; overflow-wrap: break-word; color: #ddd; } .log-bold { font-weight: bold; } .log-italic { font-style: italic; } .log-underline { text-decoration: underline; } .log-strikethrough { text-decoration: line-through; } .log-underline.log-strikethrough { text-decoration: underline line-through; } .log-secret { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .log-secret-redacted { opacity: 0; width: 1px; font-size: 1px; } .log-fg-black { color: rgb(128, 128, 128); } .log-fg-red { color: rgb(255, 0, 0); } .log-fg-green { color: rgb(0, 255, 0); } .log-fg-yellow { color: rgb(255, 255, 0); } .log-fg-blue { color: rgb(0, 0, 255); } .log-fg-magenta { color: rgb(255, 0, 255); } .log-fg-cyan { color: rgb(0, 255, 255); } .log-fg-white { color: rgb(187, 187, 187); } .log-bg-black { background-color: rgb(0, 0, 0); } .log-bg-red { background-color: rgb(255, 0, 0); } .log-bg-green { background-color: rgb(0, 255, 0); } .log-bg-yellow { background-color: rgb(255, 255, 0); } .log-bg-blue { background-color: rgb(0, 0, 255); } .log-bg-magenta { background-color: rgb(255, 0, 255); } .log-bg-cyan { background-color: rgb(0, 255, 255); } .log-bg-white { background-color: rgb(255, 255, 255); } `;