allow multiple values on one line in console

This commit is contained in:
Reimar 2025-10-17 10:12:11 +02:00
parent 245d4b2ad0
commit 2d5f6c17e6
2 changed files with 81 additions and 29 deletions

View File

@ -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 <summary>
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;
}

View File

@ -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 <summary> */
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,