- Browse dashboard at / with search, framework filter, tag pills, and pagination - Tags system with autocomplete datalist and per-fiddle tag management - Listed/unlisted toggle for visibility control (unlisted still accessible via direct URL) - Export standalone HTML with inlined CSS/JS and framework CDN tags - QR code modal for sharing fiddle URLs - Embed mode at /embed/:id for minimal preview-only rendering - Extract shared loadScript() utility from 4 files into utils.js - Database schema: listed column, tags and fiddle_tags tables with index
44 lines
1.0 KiB
JavaScript
44 lines
1.0 KiB
JavaScript
import { loadScript } from './utils.js';
|
|
|
|
let sassLoaded = false;
|
|
let lessLoaded = false;
|
|
|
|
async function ensureSass() {
|
|
if (sassLoaded) return;
|
|
await loadScript('https://cdnjs.cloudflare.com/ajax/libs/sass.js/0.11.1/sass.sync.min.js');
|
|
sassLoaded = true;
|
|
}
|
|
|
|
async function ensureLess() {
|
|
if (lessLoaded) return;
|
|
window.less = { env: 'production' };
|
|
await loadScript('https://cdnjs.cloudflare.com/ajax/libs/less.js/4.2.0/less.min.js');
|
|
lessLoaded = true;
|
|
}
|
|
|
|
export async function compileCss(code, type) {
|
|
if (type === 'css') return code;
|
|
|
|
if (type === 'scss') {
|
|
await ensureSass();
|
|
return new Promise((resolve, reject) => {
|
|
Sass.compile(code, (result) => {
|
|
if (result.status === 0) resolve(result.text);
|
|
else reject(new Error(result.formatted || result.message));
|
|
});
|
|
});
|
|
}
|
|
|
|
if (type === 'less') {
|
|
await ensureLess();
|
|
try {
|
|
const result = await less.render(code);
|
|
return result.css;
|
|
} catch (e) {
|
|
throw new Error(e.message);
|
|
}
|
|
}
|
|
|
|
return code;
|
|
}
|