// URL prefill UI; output is always built with DOM nodes so remote text never becomes markup. const csrf = () => document.cookie.split("; ").find((v) => v.startsWith("rp_csrf="))?.split("=")[1] || ""; function message(target, text, error = false) { const p = document.createElement("p"); p.textContent = text; if (error) p.style.color = "#a8371a"; target.replaceChildren(p); } export function initPrefillPanel({ state, renderFormFromPlan, recompute }) { const urlInput = document.getElementById("prefill-url"), overwriteBox = document.getElementById("prefill-overwrite"), goBtn = document.getElementById("prefill-go"), undoBtn = document.getElementById("prefill-undo"), resultEl = document.getElementById("prefill-result"); let snapshot = null; goBtn.addEventListener("click", async () => { const url = urlInput.value.trim(); if (!url) return; goBtn.disabled = true; message(resultEl, "Fetching…"); try { const res = await fetch("/api/prefill", { method: "POST", headers: { "content-type": "application/json", "x-csrf-token": csrf() }, body: JSON.stringify({ url }) }); const body = await res.json(); if (!body.ok) { message(resultEl, body.error ?? body.code, true); return; } snapshot = structuredClone(state.plan); let applied = 0; for (const [id, value] of Object.entries(body.fields ?? {})) { if (!overwriteBox.checked && (state.plan.fields[id] ?? "") !== "") continue; state.plan.fields[id] = value; applied++; } renderFormFromPlan(); markPrefilled(Object.keys(body.fields ?? {}), body.provenance ?? {}); recompute(); undoBtn.disabled = false; const p = document.createElement("p"), link = document.createElement("a"); link.href = body.source.finalUrl; link.target = "_blank"; link.rel = "noopener"; link.textContent = body.source.finalUrl; p.append(`Applied ${applied} field${applied === 1 ? "" : "s"} from `, link, "."); const children = [p]; if (body.warnings?.length) { const ul=document.createElement("ul"); ul.className="warnings"; for(const warning of body.warnings){const li=document.createElement("li");li.textContent=warning;ul.append(li);} children.push(ul); } resultEl.replaceChildren(...children); } catch (err) { message(resultEl, err.message, true); } finally { goBtn.disabled = false; } }); undoBtn.addEventListener("click", () => { if (!snapshot) return; state.plan = snapshot; snapshot = null; undoBtn.disabled = true; renderFormFromPlan(); for (const el of document.querySelectorAll(".prefilled")) { el.classList.remove("prefilled"); el.removeAttribute("title"); } recompute(); message(resultEl, "Prefill undone."); }); function markPrefilled(ids, provenance) { for (const id of ids) { const el=document.querySelector(`[name="${CSS.escape(id)}"]`); if(el){el.classList.add("prefilled");if(provenance[id])el.title=`from: ${provenance[id]}`;} } } }