// Wires the "Prefill from URL" panel. Applies the returned field patch only into empty // fields by default (checkbox to overwrite), tracks a snapshot for undo, and never touches // the form on any error. export function initPrefillPanel({ state, renderFormFromPlan, recompute }) { const urlInput = document.getElementById("prefill-url"); const overwriteBox = document.getElementById("prefill-overwrite"); const goBtn = document.getElementById("prefill-go"); const undoBtn = document.getElementById("prefill-undo"); const resultEl = document.getElementById("prefill-result"); let snapshot = null; goBtn.addEventListener("click", async () => { const url = urlInput.value.trim(); if (!url) return; goBtn.disabled = true; resultEl.innerHTML = `
Fetching…
`; try { const res = await fetch("/api/prefill", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ url }), }); const body = await res.json(); if (!body.ok) { resultEl.innerHTML = `${escapeHtml(body.error ?? body.code)}
`; return; } snapshot = JSON.parse(JSON.stringify(state.plan)); const overwrite = overwriteBox.checked; let applied = 0; for (const [id, value] of Object.entries(body.fields ?? {})) { const current = state.plan.fields[id] ?? ""; if (!overwrite && current !== "") continue; state.plan.fields[id] = value; applied++; } renderFormFromPlan(); markPrefilled(Object.keys(body.fields ?? {}), body.provenance ?? {}); recompute(); undoBtn.disabled = false; const warnings = (body.warnings ?? []).map((w) => `Applied ${applied} field${applied === 1 ? "" : "s"} from ${escapeHtml(body.source.finalUrl)}.
${warnings ? `${escapeHtml(err.message)}
`; } finally { goBtn.disabled = false; } }); undoBtn.addEventListener("click", () => { if (!snapshot) return; state.plan = snapshot; snapshot = null; undoBtn.disabled = true; renderFormFromPlan(); clearPrefilledMarks(); recompute(); resultEl.innerHTML = "Prefill undone.
"; }); function markPrefilled(ids, provenance) { for (const id of ids) { const el = document.querySelector(`[name="${CSS.escape(id)}"]`); if (!el) continue; el.classList.add("prefilled"); const prov = provenance[id]; if (prov) el.title = `from: ${prov}`; } } function clearPrefilledMarks() { for (const el of document.querySelectorAll(".prefilled")) { el.classList.remove("prefilled"); el.removeAttribute("title"); } } } function escapeHtml(s) { return String(s ?? "").replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[c])); }