✦ Editor de Código

Pronto
\n\n\n
\n
\n

Minha Nova Página

\n

Edite este conteúdo!

\n
\n \n
\n
\n
\n\n'; const r = await fetch('/editores/save.php', { method: 'POST', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: new URLSearchParams({ action: 'save', file: sitePath + '/' + name, content: template }) }); const data = await r.json(); if (data.success) { loadFileList(); openFile(sitePath + '/' + name); } else { alert('Erro: ' + data.error); } } // Editor initialization require.config({ paths: { vs: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.52.0/min/vs' }}); require(['vs/editor/editor.main'], function() { editor = monaco.editor.create(document.getElementById('editor-container'), { value: '// Selecione um arquivo para editar\n', language: 'html', theme: 'vs-dark', fontSize: 14, fontFamily: '"Cascadia Code", "Fira Code", monospace', minimap: { enabled: false }, automaticLayout: true, wordWrap: 'on', tabSize: 2, scrollBeyondLastLine: false, formatOnPaste: true, formatOnType: true }); document.getElementById('editor-container').style.display = 'block'; loadFileList(); }); // Open file async function openFile(path) { if (!path) return; setStatus('Abrindo...'); const r = await fetch('/editores/save.php?action=read&file=' + encodeURIComponent(path)); const data = await r.json(); if (data.success) { currentFile = path; editor.setValue(data.content); setStatus('✏️ Editando: ' + data.name); // Update active state document.querySelectorAll('.file-item').forEach(el => { el.classList.toggle('active', el.dataset.path === path); }); document.getElementById('fileSelect').value = path; } else { setStatus('Erro: ' + data.error, true); } } // Save file async function saveFile() { if (!currentFile) { alert('Selecione um arquivo primeiro!'); return; } const content = editor.getValue(); setStatus('💾 Salvando...'); const r = await fetch('/editores/save.php', { method: 'POST', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: new URLSearchParams({ action: 'save', file: currentFile, content: content }) }); const data = await r.json(); if (data.success) { setStatus('✅ Salvo! ' + new Date().toLocaleTimeString()); // Update preview if open if (previewMode) updatePreview(); } else { setStatus('❌ Erro: ' + data.error, true); } } // Preview toggle function togglePreview() { previewMode = !previewMode; document.getElementById('editor-container').style.display = previewMode ? 'none' : 'block'; document.getElementById('preview-frame').style.display = previewMode ? 'block' : 'none'; if (previewMode) updatePreview(); } function updatePreview() { const content = editor.getValue(); const frame = document.getElementById('preview-frame'); const blob = new Blob([content], { type: 'text/html' }); frame.src = URL.createObjectURL(blob); } // Keyboard shortcuts document.addEventListener('keydown', function(e) { if ((e.ctrlKey || e.metaKey) && e.key === 's') { e.preventDefault(); saveFile(); } if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { e.preventDefault(); togglePreview(); } }); function setStatus(msg, error) { const el = document.getElementById('status'); el.textContent = msg; el.style.color = error ? '#ef4444' : '#64748b'; }