Add editor experience features: auto-run, layouts, resizable panels, Emmet, vim/emacs
- Auto-run toggle with localStorage persistence (toolbar checkbox) - Layout selector: default, top/bottom, editor-only, preview-only - Resizable panels via drag dividers with double-click reset - Emmet abbreviation expansion for HTML, CSS, and JSX - Vim and Emacs keybinding modes with lazy-loaded CDN libraries - Shared preferences module for localStorage management - Editor hooks for tab switch and mode change callbacks
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
initEditors, switchMode, getEditorValues, setEditorValues,
|
||||
setOnChange, getCurrentMode, getCssType, setCssType,
|
||||
relayoutEditors,
|
||||
MODE_TABS, MODE_TO_JS_TYPE, JS_TYPE_TO_MODE,
|
||||
} from './editors.js';
|
||||
import { renderPreview } from './preview.js';
|
||||
@@ -8,6 +9,10 @@ import { initConsole, clearConsole } from './console-panel.js';
|
||||
import { compileCss } from './preprocessors.js';
|
||||
import { compileJs } from './js-preprocessors.js';
|
||||
import { createFiddle, loadFiddle, updateFiddle } from './api.js';
|
||||
import { getPref, setPref } from './preferences.js';
|
||||
import { initEmmet } from './emmet.js';
|
||||
import { initKeybindings } from './keybindings.js';
|
||||
import { initResizer, clearInlineSizes } from './resizer.js';
|
||||
|
||||
let currentId = null;
|
||||
let debounceTimer = null;
|
||||
@@ -67,6 +72,7 @@ async function run() {
|
||||
}
|
||||
|
||||
function scheduleRun() {
|
||||
if (!getPref('autoRun')) return;
|
||||
clearTimeout(debounceTimer);
|
||||
debounceTimer = setTimeout(run, 500);
|
||||
}
|
||||
@@ -155,10 +161,43 @@ function handleModeChange(newMode) {
|
||||
scheduleRun();
|
||||
}
|
||||
|
||||
function init() {
|
||||
function applyLayout(layout) {
|
||||
const grid = $('.grid');
|
||||
// Remove all layout classes
|
||||
grid.classList.remove('layout-top-bottom', 'layout-editor-only', 'layout-preview-only');
|
||||
// Clear resizer inline styles when switching layouts
|
||||
clearInlineSizes();
|
||||
|
||||
if (layout === 'top-bottom') grid.classList.add('layout-top-bottom');
|
||||
else if (layout === 'editor-only') grid.classList.add('layout-editor-only');
|
||||
else if (layout === 'preview-only') grid.classList.add('layout-preview-only');
|
||||
|
||||
setPref('layout', layout);
|
||||
// Give DOM time to reflow then relayout editors
|
||||
requestAnimationFrame(() => relayoutEditors());
|
||||
}
|
||||
|
||||
async function init() {
|
||||
// Load Emmet before editors so completion providers are registered
|
||||
await initEmmet();
|
||||
|
||||
initEditors('html-css-js');
|
||||
setOnChange(scheduleRun);
|
||||
initConsole();
|
||||
initResizer();
|
||||
initKeybindings();
|
||||
|
||||
// Auto-run checkbox
|
||||
const autoRunCb = $('#auto-run-checkbox');
|
||||
autoRunCb.checked = getPref('autoRun');
|
||||
autoRunCb.addEventListener('change', (e) => setPref('autoRun', e.target.checked));
|
||||
|
||||
// Layout selector
|
||||
const layoutSel = $('#layout-mode');
|
||||
const savedLayout = getPref('layout') || 'default';
|
||||
layoutSel.value = savedLayout;
|
||||
if (savedLayout !== 'default') applyLayout(savedLayout);
|
||||
layoutSel.addEventListener('change', (e) => applyLayout(e.target.value));
|
||||
|
||||
// Mode selector
|
||||
$('#framework-mode').addEventListener('change', (e) => {
|
||||
|
||||
Reference in New Issue
Block a user