InstantCode

Multi-language playground — Publish your page instantly
HTML
CSS
JavaScript
Live: on
Errors: 0
Preview
Sandboxed iframe of created page
\n`); } else { out += `\n\n`; } return out; } function updatePreview(){ const full = buildFullHTML(); const blob = new Blob([full], {type:'text/html'}); const url = URL.createObjectURL(blob); previewFrame.src = url; setTimeout(()=>URL.revokeObjectURL(url), 10000); } document.getElementById('runBtn').addEventListener('click', ()=>{ updatePreview(); }); /* Live auto-update option */ let liveOn = true; document.getElementById('liveStatus').textContent = 'Live: on'; function maybeLiveUpdate(){ if(liveOn) updatePreview(); } htmlEditor.on('change', ()=>{ maybeLiveUpdate(); }); cssEditor.on('change', ()=>{ maybeLiveUpdate(); }); jsEditor.on('change', ()=>{ maybeLiveUpdate(); }); /* Save (copy full site HTML to clipboard) */ document.getElementById('saveBtn').addEventListener('click', async ()=>{ const full = buildFullHTML(); try{ await navigator.clipboard.writeText(full); alert('Full site HTML copied to clipboard — paste into index.html or open as site.'); }catch(e){ // fallback: create temp area and copy const ta = document.createElement('textarea'); ta.value = full; document.body.appendChild(ta); ta.select(); try{ document.execCommand('copy'); alert('Copied (fallback).'); } catch(e2){ alert('Copy failed — open as site or download instead.'); } ta.remove(); } }); /* Open as Site: open index.html in new tab with blob (can be saved by user) */ document.getElementById('openBtn').addEventListener('click', ()=>{ const full = buildFullHTML(); const blob = new Blob([full], {type:'text/html'}); const url = URL.createObjectURL(blob); window.open(url, '_blank'); // revoke later automatically but keep to allow saving by user setTimeout(()=>URL.revokeObjectURL(url), 60_000); }); /* Download index.html */ document.getElementById('downloadBtn').addEventListener('click', ()=>{ const full = buildFullHTML(); const blob = new Blob([full], {type:'text/html'}); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'index.html'; document.body.appendChild(a); a.click(); a.remove(); setTimeout(()=>URL.revokeObjectURL(a.href), 5000); }); /* Copy Current editor content */ document.getElementById('copyBtn').addEventListener('click', async ()=>{ const active = document.querySelector('.tab.active').dataset.lang; let txt = ''; if(active==='html') txt = htmlEditor.getValue(); if(active==='css') txt = cssEditor.getValue(); if(active==='js') txt = jsEditor.getValue(); try{ await navigator.clipboard.writeText(txt); alert('Copied content of '+active+' to clipboard.'); }catch(e){ alert('Copy failed.'); } }); /* Format (very simple) */ document.getElementById('formatBtn').addEventListener('click', ()=>{ const active = document.querySelector('.tab.active').dataset.lang; if(active==='html'){ // basic tidy: replace multiple spaces and ensure newline after tags (very naive) let v = htmlEditor.getValue(); v = v.replace(/>\s+\n<'); htmlEditor.setValue(v); } else if(active==='css'){ let v = cssEditor.getValue(); v = v.replace(/\s*{\s*/g,' {\n ').replace(/\s*}\s*/g,'\n}\n').replace(/;\s*/g,';\n '); cssEditor.setValue(v); } else { let v = jsEditor.getValue(); v = v.replace(/;\s*/g,';\n').replace(/{\s*/g,'{\n').replace(/\n\s*\n/g,'\n'); jsEditor.setValue(v); } }); /* Open preview in new tab */ document.getElementById('openPreviewBtn').addEventListener('click', ()=>{ const full = buildFullHTML(); const blob = new Blob([full], {type:'text/html'}); const url = URL.createObjectURL(blob); window.open(url, '_blank'); setTimeout(()=>URL.revokeObjectURL(url), 60000); }); /* Settings: theme and light/dark */ document.getElementById('themeSelect').addEventListener('change', (e)=>{ const t = e.target.value; htmlEditor.setOption('theme', t); cssEditor.setOption('theme', t); jsEditor.setOption('theme', t); }); document.getElementById('modeSelect').addEventListener('change', (e)=>{ const m = e.target.value; if(m==='light'){ document.body.classList.add('light'); } else { document.body.classList.remove('light'); } htmlEditor.refresh(); cssEditor.refresh(); jsEditor.refresh(); }); /* --- Linting: use JSHint for JS, and simple checks for HTML/CSS --- */ const errorPanel = document.getElementById('errorPanel'); const errorCountEl = document.getElementById('errorCount'); function clearMarks(){ [htmlEditor, cssEditor, jsEditor].forEach(ed=>{ ed.getAllMarks().forEach(m=>m.clear()); }); errorPanel.style.display = 'none'; errorPanel.innerHTML = ''; errorCountEl.textContent = '0'; } function showErrors(list){ errorPanel.style.display = list.length ? 'block' : 'none'; errorPanel.innerHTML = list.map(it=>`
❌ ${it}
`).join(''); errorCountEl.textContent = list.length; } /* highlight specific line in editor */ function markEditorLine(editor, line, msg){ const from = {line: Math.max(0,line-1), ch:0}; const to = {line: Math.max(0,line-1), ch:1000}; editor.markText(from, to, {className:'cm-error', title:msg, css: 'background: rgba(255,0,0,0.08);'}); } /* run lint */ document.getElementById('lintBtn').addEventListener('click', runLint); function runLint(){ clearMarks(); const errors = []; // JS lint via JSHint const js = jsEditor.getValue(); try{ JSHINT(js, {esversion: 2020}); const jErrs = JSHINT.errors || []; jErrs.forEach(e=>{ if(!e) return; const msg = `JS Lint: line ${e.line} col ${e.character}: ${e.reason}`; errors.push(msg); if(e.line) markEditorLine(jsEditor, e.line, e.reason); }); }catch(e){ errors.push('JSHint runtime error: '+e.message); } // simple HTML check: count angle brackets const html = htmlEditor.getValue(); const lt = (html.match(//g)||[]).length; if(lt !== gt){ errors.push('HTML: mismatched "<" and ">" characters (quick check)'); // try to find a rough line to mark const lines = html.split('\\n'); for(let i=0;i')){ markEditorLine(htmlEditor, i+1, 'Possible unclosed tag'); break; } } } // simple CSS check: unmatched braces const css = cssEditor.getValue(); const opens = (css.match(/{/g)||[]).length; const closes = (css.match(/}/g)||[]).length; if(opens !== closes){ errors.push('CSS: mismatched "{" and "}" (quick check)'); // mark first problematic line const lines = css.split('\\n'); for(let i=0;i{ ed.on('change', ()=>{ if(lintTimer) clearTimeout(lintTimer); lintTimer = setTimeout(()=>{ runLint(); }, 1000); }); }); /* initial preview */ updatePreview(); /* small extra: toggle live on click of liveStatus */ document.getElementById('liveStatus').addEventListener('click', ()=>{ liveOn = !liveOn; document.getElementById('liveStatus').textContent = 'Live: ' + (liveOn ? 'on' : 'off'); });