diff --git a/index.html b/index.html index 9f3ebf3..416ca6f 100644 --- a/index.html +++ b/index.html @@ -110,8 +110,7 @@ function loop(deltaT) { lib.startGameLoop(loop); - + diff --git a/src/playground_console.js b/src/playground_console.js index 04476a9..05e7e8e 100644 --- a/src/playground_console.js +++ b/src/playground_console.js @@ -3,12 +3,76 @@ export class PlaygroundConsole { this.elem = elem; } - log(text) { - const el = document.createElement("span"); - el.className = "log"; - el.textContent = "" + text; - el.dataset.type = typeof text; - this.elem.appendChild(el); + #addKeyValue(entryType, parent, property, arg) { + if (property) { + const keyEl = document.createElement("span"); + keyEl.className = property === "__proto__" ? "prototype" : "property"; + keyEl.textContent = property + ": "; + parent.appendChild(keyEl); + } + + const argString = typeof arg === "function" ? `function ${arg.name}()` : `${arg}`; + + const value = document.createElement("span"); + value.className = entryType; + value.textContent = argString; + value.dataset.type = arg === null ? "null" : typeof arg; + parent.appendChild(value); + } + + #addEntry(entryType, property, parent, ...args) { + for (const arg of args) { + if (typeof arg === "object" && arg !== null) { + const summary = document.createElement("summary"); + summary.className = entryType; + summary.dataset.type = "object"; + summary.style.marginLeft = "-1rem"; + + this.#addKeyValue(entryType, summary, property, arg); + + const details = document.createElement("details"); + details.style.marginLeft = "1rem"; + details.open = entryType === "dir"; + details.appendChild(summary); + + for (const prop in arg) { + if (!arg.hasOwnProperty(prop)) continue; + + this.#addEntry( + entryType, + prop, + details, + arg.__lookupGetter__(prop) ?? arg[prop], + ); + } + + if (Object.getPrototypeOf(arg) && Object.keys(Object.getPrototypeOf(arg)).length) { + this.#addEntry(entryType, "__proto__", details, Object.getPrototypeOf(arg)); + } + + parent.appendChild(details); + } else { + const wrapper = document.createElement("p"); + this.#addKeyValue(entryType, wrapper, property, arg); + parent.appendChild(wrapper); + } + } + } + + log() { + this.#addEntry("log", "", this.elem, ...arguments); + } + + dir() { + this.#addEntry("dir", "", this.elem, ...arguments); + } + + debug() { + this.#addEntry("debug", "", this.elem, ...arguments); + } + + info() { + this.#addEntry("info", "", this.elem, ...arguments); } error(text) { @@ -18,20 +82,6 @@ export class PlaygroundConsole { this.elem.appendChild(el); } - debug(text) { - const el = document.createElement("span"); - el.className = "debug"; - el.textContent = "" + text; - this.elem.appendChild(el); - } - - info(text) { - const el = document.createElement("span"); - el.className = "info"; - el.textContent = "" + text; - this.elem.appendChild(el); - } - clear() { this.elem.textContent = ""; } diff --git a/style.css b/style.css index 81d17a4..6450258 100644 --- a/style.css +++ b/style.css @@ -128,16 +128,43 @@ div#buttons button { white-space: pre-wrap; } +#console p { + margin: 0; +} + #console .error { color: #d32f2f; } -#console .info, #console .debug, #console .log[data-type="undefined"] { +#console .info, +#console .debug, +#console .prototype, +#console [data-type="undefined"], +#console [data-type="object"], +#console [data-type="function"] { color: #bdbdbd; } -#console .log[data-type="number"] { - color: #1976d2; +#console [data-type="boolean"], +#console [data-type="null"] { + color: #ff9800; +} + +#console .property { + color: #9c27b0; +} + +#console .property + [data-type="string"]:before, +#console .property + [data-type="string"]:after { + content: '"'; +} + +#console .property + [data-type="string"] { + color: #4caf50; +} + +#console [data-type="number"] { + color: #2196f3; } #console input {