fix errors and warnings in console

This commit is contained in:
Reimar 2025-10-13 13:37:21 +02:00
parent 544a9f3663
commit fbc53fe448
3 changed files with 102 additions and 43 deletions

View File

@ -15,8 +15,25 @@ import { ConsoleInput } from "./console_input.js";
import { downloadFile, slugify } from "./utils.js";
import { HtmlExporter } from "./html_exporter.js";
const editor = ace.edit("editor");
editor.setTheme("ace/theme/gruvbox");
editor.session.setMode("ace/mode/javascript");
const langTools = ace.require("ace/ext/language_tools");
editor.setOptions({
enableBasicAutocompletion: true,
enableLiveAutocompletion: true,
copyWithEmptySelection: true,
});
langTools.setCompleters([new GamelibCompleter(), new TextCompleter()]);
editor.setValue(sessionStorage.getItem("code") ?? editor.getValue(), -1);
const playgroundConsole = new PlaygroundConsole(
document.querySelector("#console-code"),
editor,
);
window.addEventListener("DOMContentLoaded", () => {
@ -47,22 +64,6 @@ globalThis.karlkoder = {
},
};
const editor = ace.edit("editor");
editor.setTheme("ace/theme/gruvbox");
editor.session.setMode("ace/mode/javascript");
const langTools = ace.require("ace/ext/language_tools");
editor.setOptions({
enableBasicAutocompletion: true,
enableLiveAutocompletion: true,
copyWithEmptySelection: true,
});
langTools.setCompleters([new GamelibCompleter(), new TextCompleter()]);
editor.setValue(sessionStorage.getItem("code") ?? editor.getValue(), -1);
const runButton = document.querySelector("#run-button");
const toggleSpriteEditorButton = document.querySelector("#toggle-sprite-editor-button");
const projectName = document.querySelector("#project-name");

View File

@ -1,6 +1,33 @@
export class PlaygroundConsole {
constructor(elem) {
constructor(elem, editor) {
this.elem = elem;
// Used within error stack traces
window.gotoLine = (line, col) => {
editor.gotoLine(line, col, true);
editor.focus();
};
}
#formatStacktrace(stack) {
return stack
.replaceAll(window.origin + "/", "")
.replace(
/data:text\/javascript;charset=utf-8,[^:]+:(\d+):(\d+)/,
"<a href='javascript:gotoLine($1,$2)'>karlkoder-playground:$1:$2</a>",
);
}
#getTypeName(arg) {
if (arg instanceof Error) {
return "error";
}
if (arg === null) {
return "null";
}
return typeof arg;
}
#addKeyValue(entryType, parent, property, arg) {
@ -16,12 +43,13 @@ export class PlaygroundConsole {
const value = document.createElement("span");
value.className = entryType;
value.textContent = argString;
value.dataset.type = arg === null ? "null" : typeof arg;
value.dataset.type = this.#getTypeName(arg);
parent.appendChild(value);
}
#addEntry(entryType, property, parent, ...args) {
for (const arg of args) {
// For objects, show a collapsed list of properties
if (typeof arg === "object" && arg !== null) {
const summary = document.createElement("summary");
summary.className = entryType;
@ -31,31 +59,47 @@ export class PlaygroundConsole {
this.#addKeyValue(entryType, summary, property, arg);
const details = document.createElement("details");
details.className = entryType;
details.style.marginLeft = "1rem";
details.open = entryType === "dir";
details.open = entryType === "dir"; // Expand if console.dir() is used
details.appendChild(summary);
for (const prop in arg) {
if (!arg.hasOwnProperty(prop)) continue;
if (arg instanceof Error) {
// Add error stack trace
const el = document.createElement("p");
el.innerHTML = this.#formatStacktrace(arg.stack);
details.appendChild(el);
} else {
// Add object properties
for (const prop in arg) {
if (!arg.hasOwnProperty(prop)) continue;
this.#addEntry(
entryType,
prop,
details,
arg.__lookupGetter__(prop) ?? arg[prop],
);
}
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));
// Add prototype if one exists
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);
return;
}
// For non-object values, show it directly
const wrapper = document.createElement("p");
wrapper.className = entryType;
this.#addKeyValue(entryType, wrapper, property, arg);
parent.appendChild(wrapper);
}
}
@ -75,11 +119,12 @@ export class PlaygroundConsole {
this.#addEntry("info", "", this.elem, ...arguments);
}
error(text) {
const el = document.createElement("span");
el.className = "error";
el.textContent = "" + text;
this.elem.appendChild(el);
warn() {
this.#addEntry("warn", "", this.elem, ...arguments);
}
error() {
this.#addEntry("error", "", this.elem, ...arguments);
}
clear() {

View File

@ -118,7 +118,6 @@ div#buttons button {
overflow-wrap: break-word;
word-break: break-all;
font-size: 1rem;
padding: 4px 8px;
flex: 1;
overflow-y: auto;
}
@ -128,12 +127,27 @@ div#buttons button {
white-space: pre-wrap;
}
#console p {
#console p, #console summary {
margin: 0;
padding: 0.125rem 0.5rem;
}
#console a {
color: #2196f3;
}
#console .error {
color: #d32f2f;
background-color: #4a1305;
}
#console [data-type="error"] {
color: #ff8a65;
background-color: #4a1305;
}
#console .warn {
color: #fff176;
background-color: #413d07;
}
#console .info,
@ -171,7 +185,6 @@ div#buttons button {
width: 100%;
margin: 0;
outline: none;
padding: none;
color: white;
border: none;
background-color: #222;