diff --git a/src/app.js b/src/app.js index f228af3..5adbec9 100644 --- a/src/app.js +++ b/src/app.js @@ -23,6 +23,9 @@ const elements = { taskInstruction: document.getElementById("task-instruction"), codeInput: document.getElementById("code-input"), runBtn: document.getElementById("run-btn"), + undoBtn: document.getElementById("undo-btn"), + redoBtn: document.getElementById("redo-btn"), + resetCodeBtn: document.getElementById("reset-code-btn"), hintArea: document.getElementById("hint-area"), validationIndicators: document.querySelector(".validation-indicators-container"), editorContent: document.querySelector(".editor-content"), @@ -376,6 +379,19 @@ function prevLesson() { // ================= CODE EXECUTION ================= +function resetCode() { + // Reset editor to initial code for current lesson + lessonEngine.reset(); + const engineState = lessonEngine.getCurrentState(); + if (codeEditor && engineState.lesson) { + codeEditor.setValue(engineState.lesson.initialCode || ""); + } + // Clear hints and success indicators + clearHint(); + resetSuccessIndicators(); + elements.validationIndicators.innerHTML = ""; +} + function runCode() { const userCode = codeEditor ? codeEditor.getValue() : ""; @@ -561,6 +577,15 @@ function init() { elements.nextBtn.addEventListener("click", nextLesson); elements.runBtn.addEventListener("click", runCode); + // Editor tools + elements.undoBtn.addEventListener("click", () => { + if (codeEditor) codeEditor.undo(); + }); + elements.redoBtn.addEventListener("click", () => { + if (codeEditor) codeEditor.redo(); + }); + elements.resetCodeBtn.addEventListener("click", resetCode); + // Modals elements.helpBtn.addEventListener("click", showHelp); elements.modalClose.addEventListener("click", closeModal); diff --git a/src/impl/CodeEditor.js b/src/impl/CodeEditor.js index 106d716..d8df4a5 100644 --- a/src/impl/CodeEditor.js +++ b/src/impl/CodeEditor.js @@ -3,7 +3,8 @@ */ import { EditorState, Prec } from "@codemirror/state"; import { EditorView, keymap, placeholder } from "@codemirror/view"; -import { defaultKeymap, indentMore, indentLess } from "@codemirror/commands"; +import { defaultKeymap, historyKeymap, indentMore, indentLess, undo, redo } from "@codemirror/commands"; +import { history } from "@codemirror/commands"; import { oneDark } from "@codemirror/theme-one-dark"; import { html } from "@codemirror/lang-html"; import { css } from "@codemirror/lang-css"; @@ -49,6 +50,8 @@ export class CodeEditor { langExtension, oneDark, editorTheme, + // History for undo/redo + history(), // Emmet abbreviation tracking abbreviationTracker(), // High priority keymap for Emmet @@ -58,8 +61,9 @@ export class CodeEditor { run: expandAbbreviation } ])), - // Standard keymaps + // Standard keymaps including history (Ctrl+Z, Ctrl+Shift+Z) keymap.of([ + ...historyKeymap, { key: "Tab", run: indentMore }, { key: "Shift-Tab", run: indentLess }, ...defaultKeymap @@ -138,6 +142,24 @@ export class CodeEditor { } } + /** + * Undo last change + */ + undo() { + if (this.view) { + undo(this.view); + } + } + + /** + * Redo last undone change + */ + redo() { + if (this.view) { + redo(this.view); + } + } + /** * Destroy the editor */ diff --git a/src/index.html b/src/index.html index ad8a3cb..dbc61e5 100644 --- a/src/index.html +++ b/src/index.html @@ -42,6 +42,11 @@
+
+ + + +