1// Operation forms stream their subprocess into the console pane instead of2// navigating away, so a long crawl reads as progress on the page that asked3// for it. Without scripting the same forms still work: the browser shows the4// raw text stream.5for (const form of document.querySelectorAll("form[data-op]")) {6 form.addEventListener("submit", async (event) => {7 event.preventDefault();8 const output = document.getElementById("op-output");9 const buttons = document.querySelectorAll("form[data-op] button");10 output.textContent = "";11 for (const button of buttons) button.disabled = true;12 try {13 const response = await fetch(form.action, {14 method: "POST",15 body: new URLSearchParams(new FormData(form)),16 });17 const reader = response.body.getReader();18 const decoder = new TextDecoder();19 for (;;) {20 const { done, value } = await reader.read();21 if (done) break;22 output.textContent += decoder.decode(value, { stream: true });23 output.scrollTop = output.scrollHeight;24 }25 } catch (error) {26 output.textContent += "\n" + error;27 } finally {28 for (const button of buttons) button.disabled = false;29 }30 });31}