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 {