/** * LessonEngine - Core class for managing lessons and applying/testing user code * This file is the implementation of the LessonEngine class declaration from app.js */ import { validateUserCode } from './validator.js'; import { showFeedback } from './renderer.js'; export class LessonEngine { constructor() { this.currentLesson = null; this.userCode = ''; this.currentModule = null; this.currentLessonIndex = 0; } /** * Set the current module * @param {Object} module - The module object from the config */ setModule(module) { this.currentModule = module; this.currentLessonIndex = 0; if (module && module.lessons && module.lessons.length > 0) { this.setLesson(module.lessons[0]); } } /** * Set the current lesson * @param {Object} lesson - The lesson object from the config */ setLesson(lesson) { this.currentLesson = lesson; this.userCode = lesson.initialCode || ''; this.renderPreview(); } /** * Set lesson by index within the current module * @param {number} index - The lesson index * @returns {boolean} Whether the operation was successful */ setLessonByIndex(index) { if (!this.currentModule || !this.currentModule.lessons) { return false; } if (index < 0 || index >= this.currentModule.lessons.length) { return false; } this.currentLessonIndex = index; this.setLesson(this.currentModule.lessons[index]); return true; } /** * Move to the next lesson * @returns {boolean} Whether the operation was successful */ nextLesson() { return this.setLessonByIndex(this.currentLessonIndex + 1); } /** * Move to the previous lesson * @returns {boolean} Whether the operation was successful */ previousLesson() { return this.setLessonByIndex(this.currentLessonIndex - 1); } /** * Apply user-written CSS to the preview area * @param {string} code - User CSS code */ applyUserCode(code) { if (!this.currentLesson) return; this.userCode = code; this.renderPreview(); } /** * Render the preview for the current lesson */ renderPreview() { if (!this.currentLesson) return; const { previewHTML, previewBaseCSS, previewContainer, sandboxCSS } = this.currentLesson; // Create an iframe for isolated preview rendering const iframe = document.createElement('iframe'); iframe.style.width = '100%'; iframe.style.height = '100%'; iframe.style.border = 'none'; iframe.title = 'Preview'; // Get the preview container const container = document.getElementById(previewContainer || 'preview-area'); // Clear the container and add the iframe container.innerHTML = ''; container.appendChild(iframe); // Create the complete CSS by combining base CSS with user code and sandbox CSS const combinedCSS = ` /* Base CSS */ ${previewBaseCSS || ''} /* User Code */ ${this.userCode || ''} /* Sandbox CSS (for visualizing the exercise) */ ${sandboxCSS || ''} `; // Write the content to the iframe const iframeDoc = iframe.contentDocument || iframe.contentWindow.document; iframeDoc.open(); iframeDoc.write(`
${previewHTML || '