Convert: NEW
<!DOCTYPE html>
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>✨ Perfect In-Browser Code Converter</title> <style> :root { --primary: #7c3aed; --primary-dark: #5b21b6; --bg-dark: #0f172a; --bg-light: #1e293b; --text-light: #f8fafc; --success: #10b981; --error: #ef4444; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Segoe UI', system-ui, sans-serif; background: var(--bg-dark); color: var(--text-light); line-height: 1.6; min-height: 100vh; padding: 2rem; } .container { max-width: 1400px; margin: 0 auto; } header { text-align: center; margin-bottom: 2rem; } h1 { font-size: 2.5rem; background: linear-gradient(90deg, #7c3aed, #10b981); -webkit-background-clip: text; background-clip: text; color: transparent; margin-bottom: 0.5rem; } .subtitle { opacity: 0.9; font-weight: 300; } .editor-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; height: 65vh; margin-bottom: 1.5rem; } .editor-container { border: 2px solid var(--bg-light); border-radius: 0.75rem; overflow: hidden; display: flex; flex-direction: column; } .editor-header { background: var(--bg-light); padding: 0.75rem 1rem; display: flex; justify-content: space-between; align-items: center; } .editor-body { flex: 1; position: relative; } .editor { position: absolute; width: 100%; height: 100%; } .controls { display: flex; gap: 0.75rem; margin-bottom: 1.5rem; flex-wrap: wrap; } select, button { padding: 0.75rem 1.25rem; border-radius: 0.5rem; border: none; font-size: 1rem; cursor: pointer; transition: all 0.2s; } select { background: var(--bg-light); color: var(--text-light); min-width: 120px; } button { background: var(--primary); color: white; font-weight: 600; display: flex; align-items: center; gap: 0.5rem; } button:hover { background: var(--primary-dark); transform: translateY(-1px); } button:active { transform: translateY(0); } button.secondary { background: var(--bg-light); } .output-container { background: black; border-radius: 0.75rem; padding: 1rem; font-family: 'Courier New', monospace; min-height: 100px; max-height: 200px; overflow-y: auto; white-space: pre-wrap; } .success { color: var(--success); } .error { color: var(--error); } .loading { display: inline-block; width: 1rem; height: 1rem; border: 2px solid rgba(255,255,255,0.3); border-radius: 50%; border-top-color: white; animation: spin 1s ease-in-out infinite; } @keyframes spin { to { transform: rotate(360deg); } } @media (max-width: 768px) { .editor-grid { grid-template-columns: 1fr; height: auto; } .editor-container { height: 40vh; } } </style> </head> <body> <div class="container"> <header> <h1>Perfect In-Browser Code Converter</h1> <p class="subtitle">Zero APIs • Pure Browser Magic • 100% Client-Side</p> </header> <div class="editor-grid"> <div class="editor-container"> <div class="editor-header"> <span>Source Code</span> <select id="sourceLanguage"> <option value="javascript">JavaScript</option> <option value="python">Python</option> <option value="html">HTML</option> <option value="css">CSS</option> </select> </div> <div class="editor-body"> <div id="sourceEditor" class="editor"></div> </div> </div> <div class="editor-container"> <div class="editor-header"> <span>Converted Code</span> <select id="targetLanguage"> <option value="python">Python</option> <option value="javascript">JavaScript</option> <option value="html">HTML</option> <option value="css">CSS</option> </select> </div> <div class="editor-body"> <div id="targetEditor" class="editor"></div> </div> </div> </div> <div class="controls"> <button id="convertBtn"> <span id="convertIcon">✨</span> <span>Convert</span> </button> <button id="runBtn"> <span>▶️</span> <span>Run</span> </button> <button id="shareBtn" class="secondary"> <span>🔗</span> <span>Share</span> </button> <button id="formatBtn" class="secondary"> <span>🛠️</span> <span>Format</span> </button> </div> <div class="output-container" id="output"> <div>Output will appear here...</div> </div> </div> <!-- Monaco Editor Loader --> <script> // Self-contained Monaco loader to avoid external config (function() { const loaderScript = document.createElement('script'); loaderScript.src = 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.40.0/min/vs/loader.min.js'; loaderScript.onload = initializeApp; document.head.appendChild(loaderScript); function initializeApp() { require.config({ paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.40.0/min/vs', 'pyodide': 'https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide' } }); require(['vs/editor/editor.main', 'pyodide'], function(_, pyodide) { setupEditors(); setupEventListeners(); setupPyodide(pyodide); }); } function setupEditors() { window.sourceEditor = monaco.editor.create(document.getElementById('sourceEditor'), { value: [ '// Try converting this JavaScript to Python', 'function fibonacci(n) {', ' if (n <= 1) return n;', ' return fibonacci(n - 1) + fibonacci(n - 2);', '}', '', 'console.log(fibonacci(5));' ].join('\n'), language: 'javascript', theme: 'vs-dark', automaticLayout: true, minimap: { enabled: false } }); window.targetEditor = monaco.editor.create(document.getElementById('targetEditor'), { value: '# Converted code will appear here', language: 'python', theme: 'vs-dark', automaticLayout: true, readOnly: false, minimap: { enabled: false } }); } function setupEventListeners() { document.getElementById('convertBtn').addEventListener('click', convertCode); document.getElementById('runBtn').addEventListener('click', runCode); document.getElementById('shareBtn').addEventListener('click', shareCode); document.getElementById('formatBtn').addEventListener('click', formatCode); document.getElementById('sourceLanguage').addEventListener('change', function() { monaco.editor.setModelLanguage(sourceEditor.getModel(), this.value); }); document.getElementById('targetLanguage').addEventListener('change', function() { monaco.editor.setModelLanguage(targetEditor.getModel(), this.value); }); } function setupPyodide(pyodide) { window.pyodide = null; document.getElementById('runBtn').addEventListener('click', async function() { if (!pyodide) { showOutput("Loading Python runtime... (this may take a moment)", "info"); try { window.pyodide = await loadPyodide({ indexURL: "https://cdn.jsdelivr.net/pyodide/v0.24.1/full/" }); showOutput("Python runtime ready!", "success"); } catch (err) { showOutput(`Failed to load Python: ${err}`, "error"); return; } } runCode(); }); } function convertCode() { const sourceCode = sourceEditor.getValue(); const sourceLang = document.getElementById('sourceLanguage').value; const targetLang = document.getElementById('targetLanguage').value; const btn = document.getElementById('convertBtn'); btn.disabled = true; document.getElementById('convertIcon').className = 'loading'; // Simulate conversion delay setTimeout(() => { try { const converted = pseudoConvert(sourceCode, sourceLang, targetLang); targetEditor.setValue(converted); monaco.editor.setModelLanguage(targetEditor.getModel(), targetLang); showOutput(`Successfully converted ${sourceLang} to ${targetLang}`, "success"); } catch (err) { showOutput(`Conversion error: ${err}`, "error"); } finally { btn.disabled = false; document.getElementById('convertIcon').textContent = '✨'; } }, 800); } function pseudoConvert(code, from, to) { // This is a mock converter - in a real app you'd use proper parsing/transformation const converters = { 'javascript-python': jsToPython, 'python-javascript': pythonToJs, default: (code) => `# Mock conversion from ${from} to ${to}\n# TODO: Implement proper conversion\n${code}` }; return converters[`${from}-${to}`]?.(code) || converters.default(code); } function jsToPython(jsCode) { // Extremely basic JS → Python conversion return jsCode .replace(/\/\/.*/g, '# $&') // Convert comments .replace(/function (\w+)/g, 'def $1') // Functions .replace(/console.log/g, 'print') // Console to print .replace(/===/g, '==') // Strict equality .replace(/&&/g, 'and') // Logical AND .replace(/\|\|/g, 'or') // Logical OR .replace(/;/g, '') // Remove semicolons .replace(/{/g, ':') // Blocks to indentation .replace(/}/g, '') // Remove closing braces .replace(/true/g, 'True') // Booleans .replace(/false/g, 'False') .replace(/null/g, 'None'); } function pythonToJs(pyCode) { // Extremely basic Python → JS conversion return pyCode .replace(/#.*/g, '// $&') // Convert comments .replace(/def (\w+)/g, 'function $1') // Functions .replace(/print/g, 'console.log') // Print to console .replace(/==/g, '===') // Strict equality .replace(/\bnot\b/g, '!') // Logical NOT .replace(/\band\b/g, '&&') // Logical AND .replace(/\bor\b/g, '||') // Logical OR .replace(/True/g, 'true') // Booleans .replace(/False/g, 'false') .replace(/None/g, 'null'); } async function runCode() { if (!pyodide) { showOutput("Python runtime not loaded yet. Click Run again.", "error"); return; } const code = targetEditor.getValue(); const lang = document.getElementById('targetLanguage').value; if (lang !== 'python') { showOutput(`Cannot run ${lang} in browser. Only Python is supported.`, "error"); return; } try { const result = await pyodide.runPythonAsync(code); showOutput(result || "Code executed successfully!", "success"); } catch (err) { showOutput(`Execution error: ${err}`, "error"); } } function formatCode() { try { const model = sourceEditor.getModel(); const edits = monaco.editor.getDocumentFormattingEdits(model.uri, { tabSize: 4, insertSpaces: true, trimTrailingWhitespace: true, insertFinalNewline: true, trimFinalNewlines: true }); model.applyEdits(edits); showOutput("Code formatted successfully!", "success"); } catch (err) { showOutput(`Formatting error: ${err}`, "error"); } } function shareCode() { const code = sourceEditor.getValue(); const lang = document.getElementById('sourceLanguage').value; const url = new URL(window.location.href); // Compress code for URL try { const compressed = btoa(unescape(encodeURIComponent(code))); url.searchParams.set('code', compressed); url.searchParams.set('lang', lang); navigator.clipboard.writeText(url.toString()).then(() => { showOutput("Sharable URL copied to clipboard!", "success"); }).catch(() => { prompt("Copy this URL to share:", url.toString()); }); } catch (err) { showOutput("Failed to generate share URL", "error"); } } function showOutput(message, type = "info") { const output = document.getElementById('output'); output.innerHTML = ''; const pre = document.createElement('pre'); pre.textContent = message; pre.className = type; output.appendChild(pre); output.scrollTop = output.scrollHeight; } // Load any shared code from URL function loadSharedCode() { const params = new URLSearchParams(window.location.search); const code = params.get('code'); const lang = params.get('lang'); if (code && lang) { try { const decompressed = decodeURIComponent(escape(atob(code))); sourceEditor.setValue(decompressed); document.getElementById('sourceLanguage').value = lang; monaco.editor.setModelLanguage(sourceEditor.getModel(), lang); showOutput("Loaded shared code", "success"); } catch (err) { showOutput("Failed to load shared code", "error"); } } } // Initialize shared code if any window.addEventListener('load', loadSharedCode); })(); </script> </body> </html>
Comments
Post a Comment