commit bcfac47a8a24dc7f95465ec47322702dd2d2b9a0
parent ff024740d81983d6ab1f7a40f89edebd6723a316
Author: Hunter
Date: Mon, 7 Jul 2025 18:45:51 -0400
use codemirror over prism
Diffstat:
| M | index.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