Add Python REPL, instant deploy, Gist import, presentation mode, and CSS visual tools

- Python mode via Pyodide WASM runtime with stdout/stderr console integration
- Publish fiddles to clean /p/:slug URLs as standalone HTML pages
- Import code from GitHub Gist URLs with auto-detection of language/mode
- Presentation mode with slide management, fullscreen viewer, and keyboard nav
- Enable Monaco color decorators for inline CSS color pickers
- Extract reusable generateStandaloneHtml from export module
This commit is contained in:
root
2026-02-27 15:50:55 -06:00
parent 26e232fd41
commit ae8dbafb20
11 changed files with 666 additions and 6 deletions

View File

@@ -89,6 +89,9 @@ export async function compileJs(code, mode) {
return { js: code, isModule: hasModuleSyntax || hasTopLevelAwait };
}
case 'python':
return compilePython(code);
default:
return { js: code };
}
@@ -188,6 +191,34 @@ async function compileSvelte(code) {
return { js, warnings, isModule: true };
}
function compilePython(code) {
// Wrap Python code in a JS loader that runs it via Pyodide in the iframe
const escapedCode = JSON.stringify(code);
const js = `
(async function() {
const status = document.getElementById('pyodide-status');
try {
if (status) status.textContent = 'Loading Python runtime...';
const pyodide = await loadPyodide();
pyodide.setStdout({ batched: (text) => {
if (window.__fiddle_console) window.__fiddle_console('log', text);
else console.log(text);
}});
pyodide.setStderr({ batched: (text) => {
if (window.__fiddle_console) window.__fiddle_console('error', text);
else console.error(text);
}});
if (status) status.textContent = '';
await pyodide.runPythonAsync(${escapedCode});
} catch(e) {
if (status) status.textContent = '';
console.error('Python error: ' + e.message);
}
})();
`;
return { js, isModule: false };
}
/**
* Get runtime scripts and body HTML to inject into the preview iframe.
*/
@@ -223,6 +254,12 @@ export function getFrameworkRuntime(mode) {
case 'wasm':
return { scripts: [], bodyHtml: '' };
case 'python':
return {
scripts: ['https://cdn.jsdelivr.net/pyodide/v0.27.2/full/pyodide.js'],
bodyHtml: '<div id="pyodide-status" style="font-family:monospace;color:#888;padding:12px">Loading Python...</div>',
};
default:
return { scripts: [], bodyHtml: '' };
}