From 2d5f6c17e6bdbc7f34162c7b5fdce1fdc4f91641 Mon Sep 17 00:00:00 2001 From: Reimar Date: Fri, 17 Oct 2025 10:12:11 +0200 Subject: [PATCH] allow multiple values on one line in console --- src/playground_console.js | 38 ++++++++++++--------- style.css | 72 ++++++++++++++++++++++++++++++++------- 2 files changed, 81 insertions(+), 29 deletions(-) diff --git a/src/playground_console.js b/src/playground_console.js index 7e48f09..7a13760 100644 --- a/src/playground_console.js +++ b/src/playground_console.js @@ -31,6 +31,10 @@ export class PlaygroundConsole { } getValueString(value) { + if (value instanceof Error) { + return value.message; + } + if (typeof value === "function") { return `function ${value.name}()`; } @@ -56,7 +60,7 @@ export class PlaygroundConsole { return " ]"; } - if (typeof value === "object" && value !== null) { + if (typeof value === "object" && value !== null && !(value instanceof Error)) { return " }"; } @@ -73,9 +77,7 @@ export class PlaygroundConsole { } const valueEl = document.createElement("span"); - valueEl.style.display = "list-item"; // Re-add arrow that was removed by applying flex on - valueEl.style.overflowX = "hidden"; - valueEl.style.textOverflow = "ellipsis"; + valueEl.className = "base-value"; valueEl.textContent = this.getValueString(value); valueEl.dataset.type = this.getTypeName(value); parent.appendChild(valueEl); @@ -93,20 +95,19 @@ export class PlaygroundConsole { // For objects, show a collapsed list of properties if (typeof arg === "object" && arg !== null) { const summary = document.createElement("summary"); - summary.style.display = "flex"; - summary.style.whiteSpace = "nowrap"; - summary.className = entryType; + summary.className = "value"; summary.dataset.type = "object"; - summary.style.marginLeft = "-1rem"; this.addKeyValue(entryType, summary, property, arg); const details = document.createElement("details"); details.className = entryType; - details.style.marginLeft = "1rem"; details.open = entryType === "dir"; // Expand if console.dir() is used details.appendChild(summary); + const object = document.createElement("div"); + object.style.marginLeft = "1rem"; + if (arg instanceof Error) { // On Chrome, the first line of the stack trace is the error message repeated if (globalThis.chrome) { @@ -117,14 +118,14 @@ export class PlaygroundConsole { const el = document.createElement("p"); el.innerHTML = this.formatStacktrace(arg.stack); - details.appendChild(el); + object.appendChild(el); } else { // Add object properties for (const prop of Object.getOwnPropertyNames(arg)) { this.addEntry( entryType, prop, - details, + object, arg.__lookupGetter__(prop) ?? arg[prop], ); } @@ -132,20 +133,19 @@ export class PlaygroundConsole { // Add prototype if one exists const prototype = Object.getPrototypeOf(arg); if (prototype && Object.getOwnPropertyNames(prototype).length > 0) { - this.addEntry(entryType, "__proto__", details, prototype); + this.addEntry(entryType, "__proto__", object, prototype); } } + details.appendChild(object); parent.appendChild(details); return details; } // For non-object values, show it directly - const wrapper = document.createElement("p"); - wrapper.style.display = "flex"; - wrapper.style.whiteSpace = "nowrap"; - wrapper.className = entryType; + const wrapper = document.createElement("span"); + wrapper.className = "value"; this.addKeyValue(entryType, wrapper, property, arg); parent.appendChild(wrapper); @@ -153,8 +153,11 @@ export class PlaygroundConsole { } addTopLevelEntry(entryType, ...args) { + const container = document.createElement("p"); + container.className = entryType; + for (const arg of args) { - const elem = this.addEntry(entryType, "", this.elem, ...args); + const elem = this.addEntry(entryType, "", container, arg); elem.addEventListener("contextmenu", (ev) => { // TODO add context menu @@ -163,6 +166,7 @@ export class PlaygroundConsole { }); } + this.elem.appendChild(container); this.elem.scrollTop = this.elem.scrollHeight; } diff --git a/style.css b/style.css index 6f813b7..bf2d877 100644 --- a/style.css +++ b/style.css @@ -104,13 +104,6 @@ div#buttons button { overflow-y: hidden; } -#console-code { - display: flex; - flex-direction: column; - gap: 5px; - scroll-behavior: smooth; -} - #console pre { color: white; background-color: black; @@ -121,6 +114,9 @@ div#buttons button { font-size: 1rem; flex: 1; overflow-y: auto; + display: flex; + flex-direction: column; + scroll-behavior: smooth; } #console pre { @@ -130,13 +126,50 @@ div#buttons button { #console p, #console summary { margin: 0; - padding: 0.125rem 0.5rem; + padding: 0.125rem 0.5rem 0.125rem 0; +} + +#console summary { + white-space: nowrap; } #console a { color: #2196f3; } +#console p { + padding: 0.25rem 0.5rem; + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 0.5rem; +} + +#console p ~ p { + border-top: 1px solid #242424; +} + +#console p + .warn, #console .warn + p { + border-color: #fbc02d; +} + +#console p + .error, #console .error + p { + border-color: #d32f2f; +} + +#console p > *:last-child { + flex: 1; +} + +#console p > details { + min-width: 130px; + overflow-x: hidden; +} + +#console p > details[open] { + min-width: 100%; +} + #console .error { background-color: #4a1305; } @@ -152,7 +185,7 @@ div#buttons button { } #console .input:before { - content: "> "; + content: ">"; } #console .input { @@ -174,14 +207,29 @@ div#buttons button { color: #ff9800; } -#console .log:hover, -#console .info:hover, -#console .debug:hover { +#console .log .value:hover, +#console .info .value:hover, +#console .debug .value:hover { background-color: #242424; } +#console .value { + display: flex; +} + +#console .base-value { + display: list-item; /* Re-add arrow that was removed by applying flex on */ + overflow-x: hidden; + text-overflow: ellipsis; +} + +#console .property + .base-value { + white-space: nowrap; +} + #console .property { color: #9c27b0; + white-space: nowrap; } #console .property + [data-type="string"]:before,