document.addEventListener("DOMContentLoaded", () => { const dropZone = document.getElementById("drop-zone"); const fileInput = document.getElementById("file-input"); const modeBtns = document.querySelectorAll(".mode-btn"); const progress = document.getElementById("progress"); const progressBar = progress.querySelector(".progress-bar"); const progressText = document.getElementById("progress-text"); const result = document.getElementById("result"); let currentMode = "basic"; modeBtns.forEach((btn) => { btn.addEventListener("click", () => { modeBtns.forEach((b) => b.classList.remove("active")); btn.classList.add("active"); currentMode = btn.dataset.mode || "basic"; }); }); ["dragenter", "dragover"].forEach((e) => dropZone.addEventListener(e, (ev) => { ev.preventDefault(); dropZone.classList.add("dragover"); }) ); ["dragleave", "drop"].forEach((e) => dropZone.addEventListener(e, (ev) => { ev.preventDefault(); dropZone.classList.remove("dragover"); }) ); dropZone.addEventListener("drop", (e) => { e.preventDefault(); fileInput.files = e.dataTransfer.files; processFiles(); }); fileInput.addEventListener("change", processFiles); dropZone.querySelector("label")?.addEventListener("click", (e) => { e.preventDefault(); fileInput.click(); }); function processFiles() { const files = fileInput.files; if (!files || !files.length) return; const endpoint = currentMode === "advanced" ? "/api/upload-advanced" : "/api/upload"; const formData = new FormData(); Array.from(files).forEach((file) => formData.append("files", file)); showProgress(currentMode.toUpperCase(), files.length); fetch(endpoint, { method: "POST", body: formData }) .then((r) => r.json()) .then((data) => { hideProgress(); if (data && data.success) showResult(data); else showError(data?.error || "Unknown error"); }) .catch((e) => { hideProgress(); showError(e?.message || "Request failed"); }); } function showProgress(mode, count) { progress.classList.remove("d-none"); progressText.classList.remove("d-none"); progressText.textContent = `${mode} - ${count} files`; progressBar.style.width = "45%"; } function hideProgress() { progress.classList.add("d-none"); progressText.classList.add("d-none"); } async function showResult(data) { const sizeKB = ((data.size || 0) / 1024).toFixed(1); const rawHtml = typeof data.aio_html === "string" ? data.aio_html : String(data.aio_html ?? ""); const formattedHtml = await formatHtml(rawHtml); result.innerHTML = `
${escapeHtml(data.message ?? "Done")}
${escapeHtml(data.original ?? "")}${sizeKB}KB
Save
Preview
Code
${escapeHtml(formattedHtml)}
`; result.classList.remove("d-none"); const frame = result.querySelector("#previewFrame"); if (frame) frame.srcdoc = rawHtml; if (window.Prism) window.Prism.highlightAllUnder(result); result.querySelectorAll(".btn-copy-sm, .btn-copy-all").forEach((btn) => { const originalHtml = btn.innerHTML; btn.addEventListener("click", () => { navigator.clipboard .writeText(rawHtml) .then(() => { btn.innerHTML = 'Copied'; setTimeout(() => (btn.innerHTML = originalHtml), 1200); }) .catch(() => fallbackCopy(rawHtml, btn, originalHtml)); }); }); result.querySelector("#btn-new")?.addEventListener("click", () => { location.reload(); }); result.scrollIntoView({ behavior: "smooth" }); } function fallbackCopy(text, btn, originalHtml) { try { const ta = document.createElement("textarea"); ta.value = text; document.body.appendChild(ta); ta.select(); document.execCommand("copy"); document.body.removeChild(ta); btn.innerHTML = 'Copied'; setTimeout(() => (btn.innerHTML = originalHtml), 1200); } catch { showError("Clipboard blocked by browser"); } } function showError(msg) { result.innerHTML = `
${escapeHtml(msg)}
`; result.classList.remove("d-none"); result.querySelector("#btn-try")?.addEventListener("click", () => location.reload()); } }); async function formatHtml(html) { html = typeof html === "string" ? html : String(html ?? ""); try { if (window.prettier && window.prettierPlugins?.html) { return await window.prettier.format(html, { parser: "html", plugins: [window.prettierPlugins.html], printWidth: 100, tabWidth: 2, useTabs: false, }); } } catch (e) { console.error(e); } return html; } function escapeHtml(text) { text = typeof text === "string" ? text : String(text ?? ""); const map = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }; return text.replace(/[&<>"']/g, (m) => map[m]); }