Initial commit: code playground with multi-framework support
Express + SQLite backend with Monaco editor frontend. Supports HTML/CSS/JS, TypeScript, React (JSX/TSX), Vue SFC, and Svelte with live preview, console output, save/fork/share. Includes CSS preprocessors (SCSS, Less), framework-specific compilation (Babel, TypeScript, Svelte compiler), and CDN-loaded runtime libraries for preview rendering.
This commit is contained in:
70
public/index.html
Normal file
70
public/index.html
Normal file
@@ -0,0 +1,70 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Fiddle</title>
|
||||
<link rel="stylesheet" href="/css/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="toolbar">
|
||||
<div class="toolbar-left">
|
||||
<a href="/" class="logo">Fiddle</a>
|
||||
<select id="framework-mode">
|
||||
<option value="html-css-js">HTML / CSS / JS</option>
|
||||
<option value="typescript">TypeScript</option>
|
||||
<option value="react">React (JSX)</option>
|
||||
<option value="react-ts">React + TS</option>
|
||||
<option value="vue">Vue</option>
|
||||
<option value="svelte">Svelte</option>
|
||||
</select>
|
||||
<input type="text" id="title-input" placeholder="Untitled" spellcheck="false">
|
||||
</div>
|
||||
<div class="toolbar-right">
|
||||
<button id="btn-run" title="Run (Ctrl+Enter)">Run</button>
|
||||
<button id="btn-save" title="Save (Ctrl+S)">Save</button>
|
||||
<button id="btn-fork" title="Fork">Fork</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="grid">
|
||||
<div class="panel panel-editor">
|
||||
<div class="tab-bar" id="tab-bar"></div>
|
||||
<div id="editor-area" class="editor-area"></div>
|
||||
</div>
|
||||
<div class="panel panel-preview">
|
||||
<div class="panel-label">Preview</div>
|
||||
<iframe id="preview-frame" sandbox="allow-scripts allow-same-origin"></iframe>
|
||||
</div>
|
||||
<div class="panel panel-console">
|
||||
<div class="panel-label">Console <button id="btn-clear-console" class="btn-small">Clear</button></div>
|
||||
<div id="console-output"></div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div id="share-toast" class="toast hidden"></div>
|
||||
|
||||
<script>
|
||||
// Monaco AMD loader
|
||||
const MONACO_CDN = 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.52.2';
|
||||
const script = document.createElement('script');
|
||||
script.src = `${MONACO_CDN}/min/vs/loader.min.js`;
|
||||
script.onload = () => {
|
||||
require.config({ paths: { vs: `${MONACO_CDN}/min/vs` } });
|
||||
// Cross-origin worker proxy
|
||||
window.MonacoEnvironment = {
|
||||
getWorkerUrl: function (_workerId, label) {
|
||||
return `data:text/javascript;charset=utf-8,${encodeURIComponent(`
|
||||
self.MonacoEnvironment = { baseUrl: '${MONACO_CDN}/min/' };
|
||||
importScripts('${MONACO_CDN}/min/vs/base/worker/workerMain.js');
|
||||
`)}`;
|
||||
}
|
||||
};
|
||||
require(['vs/editor/editor.main'], () => {
|
||||
import('/js/app.js');
|
||||
});
|
||||
};
|
||||
document.head.appendChild(script);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user