Files
mesh-catalog/modules/mesh-mail-web/internal/web/static/app.js
T
jochen af89a69670 issue 1859: the page shown after an act records nothing, so each act leaves one line
Review round 1 F1 (ADR 0517 §3, §5): a form act went back to the list or the pane, which recorded page
opened or opened again, and the script's refresh did too, so last looked became the last act and opened
counts grew. The redirect after an act carries acted=1 and the refresh an X-Mail-Refresh header; that page
records nothing. The 1860 test now follows each redirect and counts every line, and reminds the task (F2,
1858/AC9), which the store's own integration test also reads back as a date.
2026-10-22 20:26:54 +02:00

72 lines
2.5 KiB
JavaScript

// The mail page's one script (novox/hq ADR 0515 §6; issue 1859). It talks only to the page's own origin:
// ticking, undoing, reminding and correcting post their form without a reload and put the list (and the
// reading pane) back as the page now answers it. Without it, every form still works by an ordinary post.
// An act that fails is said on the page, with its cause (ADR 0517 §5).
"use strict";
(function () {
function say(text) {
var list = document.getElementById("list");
if (!list) {
return;
}
var p = document.createElement("p");
p.className = "notice failed";
p.setAttribute("role", "alert");
p.textContent = text;
list.insertBefore(p, list.firstChild);
}
// Put back the parts of the page this address answers now. The refresh says it is one, so the page
// records nothing: the act already wrote its one line.
function refresh() {
return fetch(location.href, { credentials: "same-origin", headers: { "X-Mail-Refresh": "1" } })
.then(function (r) { return r.text(); })
.then(function (html) {
var fresh = new DOMParser().parseFromString(html, "text/html");
["list", "pane"].forEach(function (id) {
var now = document.getElementById(id);
var next = fresh.getElementById(id);
if (now && next) {
now.replaceWith(document.importNode(next, true));
}
});
});
}
document.addEventListener("submit", function (event) {
var form = event.target;
if (!form.classList || !form.classList.contains("act")) {
return;
}
event.preventDefault();
var buttons = form.querySelectorAll("button");
buttons.forEach(function (b) { b.disabled = true; });
fetch(form.getAttribute("action"), {
method: "POST",
credentials: "same-origin",
headers: { "X-Requested-With": "fetch" },
body: new URLSearchParams(new FormData(form))
})
.then(function (r) {
return r.json().catch(function () { return { failed: "the page answered " + r.status }; });
})
.then(function (answer) {
if (answer.failed) {
buttons.forEach(function (b) { b.disabled = false; });
say(answer.failed);
return;
}
if (answer.go) {
location.assign(answer.go);
return;
}
return refresh();
})
.catch(function (err) {
buttons.forEach(function (b) { b.disabled = false; });
say("That did not reach the page: " + err);
});
});
}());