commit bcfac47a8a24dc7f95465ec47322702dd2d2b9a0
parent ff024740d81983d6ab1f7a40f89edebd6723a316
Author: Hunter
Date:   Mon,  7 Jul 2025 18:45:51 -0400

use codemirror over prism

Diffstat:
Mindex.html | 121++++++++++++++++++++++++++++++++++++++++++-------------------------------------
1 file changed, 64 insertions(+), 57 deletions(-)

diff --git a/index.html b/index.html @@ -4,6 +4,15 @@ <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>HTML Laboratory</title> + <script type="module"> + import {EditorView, keymap} from "https://esm.sh/@codemirror/view@6" + import {EditorState} from "https://esm.sh/@codemirror/state@6" + import {defaultKeymap} from "https://esm.sh/@codemirror/commands@6" + import {html} from "https://esm.sh/@codemirror/lang-html@6" + import {oneDark} from "https://esm.sh/@codemirror/theme-one-dark@6" + + window.CodeMirror = {EditorView, EditorState, keymap, defaultKeymap, html, oneDark}; + </script> <style> :root { --bg-color: #2d2d2d; @@ -45,24 +54,26 @@ #editor { width: 100%; height: 100%; - border: none; - outline: none; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 21px; - padding: 15px; - overflow: auto; + } + + /* CodeMirror styling */ + .cm-editor { + width: 100%; + height: 100%; background: var(--editor-bg); color: var(--text-color); - tab-size: 4; - white-space: pre-wrap; - overflow-x: auto; - display: block; + } + + .cm-content { + padding: 15px; + font-size: 21px; line-height: 1.5; } - #editor:empty:before { - content: attr(data-placeholder); - color: #666; + .cm-focused { + outline: none; } #preview { @@ -102,21 +113,21 @@ </head> <body> <div class="editor-pane"> - <div id="editor" contenteditable="true" spellcheck="false" data-placeholder="Type your HTML, CSS, and JavaScript here..."></div> + <div id="editor"></div> </div> <div class="preview-pane"> <iframe id="preview" sandbox="allow-scripts"></iframe> </div> - <script> + <script type="module"> let updateTimer; - const editor = document.getElementById('editor'); + let editorView; const preview = document.getElementById('preview'); const storageKey = 'html-lab-content'; function updatePreview() { - const code = editor.textContent; + const code = editorView.state.doc.toString(); const blob = new Blob([code], { type: 'text/html' }); const url = URL.createObjectURL(blob); preview.src = url; @@ -127,12 +138,8 @@ function saveToStorage() { try { - // Save both the inner HTML (for whitespace preservation) and text content - const data = { - html: editor.innerHTML, - text: editor.textContent - }; - localStorage.setItem(storageKey, JSON.stringify(data)); + const code = editorView.state.doc.toString(); + localStorage.setItem(storageKey, code); } catch (e) { // Handle localStorage errors silently console.warn('Could not save to localStorage:', e); @@ -143,45 +150,21 @@ try { const saved = localStorage.getItem(storageKey); if (saved !== null) { + // Handle old format that might be JSON try { - // Try to parse as JSON first (new format) const data = JSON.parse(saved); - if (data.html) { - editor.innerHTML = data.html; - } else if (data.text) { - editor.textContent = data.text; - } + return data.text || data.html || saved; } catch (parseError) { - // Fallback to old format (plain text) - editor.textContent = saved; + return saved; } - return true; } } catch (e) { // Handle localStorage errors silently console.warn('Could not load from localStorage:', e); } - return false; + return ''; } - - // Handle Tab key to insert tab character - editor.addEventListener('keydown', function(e) { - if (e.key === 'Tab') { - e.preventDefault(); - document.execCommand('insertText', false, '\t'); - } - }); - - // Update preview after 0.5 seconds of no typing - editor.addEventListener('input', function() { - clearTimeout(updateTimer); - updateTimer = setTimeout(updatePreview, 500); - - // Save to localStorage on every change - saveToStorage(); - }); - // Save functionality with Cmd+S document.addEventListener('keydown', function(e) { if ((e.metaKey || e.ctrlKey) && e.key === 's') { @@ -191,7 +174,7 @@ }); function saveFile() { - const code = editor.textContent; + const code = editorView.state.doc.toString(); const blob = new Blob([code], { type: 'text/html' }); const url = URL.createObjectURL(blob); @@ -203,20 +186,44 @@ URL.revokeObjectURL(url); } - // Initialize the editor content and render - function initialize() { - // Always try to load from localStorage regardless of refresh type - loadFromStorage(); + // Wait for CodeMirror to be available + function initializeCodeMirror() { + if (!window.CodeMirror) { + setTimeout(initializeCodeMirror, 100); + return; + } + + const {EditorView, EditorState, keymap, defaultKeymap, html, oneDark} = window.CodeMirror; - // Focus the editor - editor.focus(); + // Load saved content + const savedContent = loadFromStorage(); + // Create CodeMirror editor + editorView = new EditorView({ + state: EditorState.create({ + doc: savedContent, + extensions: [ + keymap.of(defaultKeymap), + html(), + oneDark, + EditorView.updateListener.of((update) => { + if (update.docChanged) { + clearTimeout(updateTimer); + updateTimer = setTimeout(updatePreview, 500); + saveToStorage(); + } + }) + ] + }), + parent: document.getElementById('editor') + }); + // Initial render updatePreview(); } // Initialize when page loads - initialize(); + initializeCodeMirror(); </script> </body> </html> \ No newline at end of file