From 4df6e7bac00db391c2e1b2c36a98f91f15f2124d Mon Sep 17 00:00:00 2001 From: Reimar Date: Sat, 11 Oct 2025 21:00:15 +0200 Subject: [PATCH] allow running code in console --- index.html | 1 + src/code_runner.js | 37 ++++++++++++++++++++++++++++++++++++- src/index.js | 11 +++++++++++ src/playground_console.js | 10 ++++++---- style.css | 12 +++++++++++- 5 files changed, 65 insertions(+), 6 deletions(-) diff --git a/index.html b/index.html index 8d0ec6c..2567be4 100644 --- a/index.html +++ b/index.html @@ -75,6 +75,7 @@
Karlkode 1.0
diff --git a/src/code_runner.js b/src/code_runner.js index 2bcfb42..0051079 100644 --- a/src/code_runner.js +++ b/src/code_runner.js @@ -3,6 +3,7 @@ export class CodeRunner { this.console = console; this.codeStopper = codeStopper; this.isRunning = false; + this.evalScope = {}; window.playgroundConsole = this.console; } @@ -24,7 +25,8 @@ export class CodeRunner { ); try { - await import(`data:text/javascript;charset=utf-8,${encodedText}`); + const module = await import(`data:text/javascript;charset=utf-8,${encodedText}`); + this.evalScope = Object.assign(this.evalScope, module); } catch (error) { this.console.error(error); } @@ -43,4 +45,37 @@ export class CodeRunner { this.run(); } } + + evaluateCode(code) { + // Move evalScope to window + const oldWindow = {}; + for (const prop in this.evalScope) { + if (!this.evalScope.hasOwnProperty(prop)) continue; + + oldWindow[prop] = window[prop]; + window[prop] = this.evalScope[prop]; + } + + // Evaluate code + const func = new Function(`"use strict";return ${code}`); + + try { + const result = func(); + + this.console.log(result); + } catch (e) { + this.console.error(e); + + if (e instanceof ReferenceError) { + this.console.info("Note: use `export` to allow use of variables within the console"); + } + } + + // Restore old window props + for (const prop in oldWindow) { + if (!oldWindow.hasOwnProperty(prop)) continue; + + window[prop] = oldWindow[prop]; + } + } } diff --git a/src/index.js b/src/index.js index a6a342a..f703e29 100644 --- a/src/index.js +++ b/src/index.js @@ -66,6 +66,7 @@ const saveJsButton = document.querySelector("#save-js"); const saveHtmlButton = document.querySelector("#save-html"); const saveKarlkoderButton = document.querySelector("#save-karlkoder"); const toggleSpriteEditorButton = document.querySelector("#toggle-sprite-editor-button"); +const consoleInput = document.querySelector("#console-input"); const sessionSaveDebounce = new Debounce(1000); editor.addEventListener("change", () => { @@ -217,3 +218,13 @@ saveKarlkoderButton.onclick = () => { }; toggleSpriteEditorButton.addEventListener("click", () => spriteEditor.toggleEditor()); + +consoleInput.onkeydown = (ev) => { + if (ev.key !== "Enter") return; + + const code = ev.target.value; + ev.target.value = ""; + + codeRunner.evaluateCode(code); +}; + diff --git a/src/playground_console.js b/src/playground_console.js index 06b4c42..b3b510f 100644 --- a/src/playground_console.js +++ b/src/playground_console.js @@ -5,28 +5,30 @@ export class PlaygroundConsole { log(text) { const el = document.createElement("span"); - el.textContent = `\n${text}\n`; + el.className = "log"; + el.textContent = "" + text; + el.dataset.type = typeof text; this.elem.appendChild(el); } error(text) { const el = document.createElement("span"); el.className = "error"; - el.textContent = `\n${text}\n`; + el.textContent = "" + text; this.elem.appendChild(el); } debug(text) { const el = document.createElement("span"); el.className = "debug"; - el.textContent = `\n${text}\n`; + el.textContent = "" + text; this.elem.appendChild(el); } info(text) { const el = document.createElement("span"); el.className = "info"; - el.textContent = `\n${text}\n`; + el.textContent = "" + text; this.elem.appendChild(el); } } diff --git a/style.css b/style.css index 2ba6b2d..2933c91 100644 --- a/style.css +++ b/style.css @@ -104,6 +104,12 @@ div#buttons button { overflow-y: hidden; } +#console-code { + display: flex; + flex-direction: column; + gap: 5px; +} + #console pre { color: white; background-color: black; @@ -126,10 +132,14 @@ div#buttons button { color: #D32F2F; } -#console .info, #console .debug { +#console .info, #console .debug, #console .log[data-type=undefined] { color: #BDBDBD; } +#console .log[data-type=number] { + color: #1976D2; +} + #console input { width: 100%; margin: 0;