blob: 3a2957c3134a4a32127ef477c9447c4c2428c98c [file] [log] [blame]
// SPDX-FileCopyrightText: 2020 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
// SPDX-License-Identifier: AGPL-3.0-or-later
// Nimmt die Dateien aus dem Formular entgegen, reicht sie an den Worker und zeigt die Synopse.
// Es gibt keinen Server: Alles läuft im Browser.
const formular = document.querySelector("#synopse-formular");
const knopf = formular.querySelector("button");
const meldung = document.querySelector("#meldung");
let worker = null;
function zeige(text, art) {
meldung.textContent = text;
meldung.className = art ? "meldung " + art : "meldung";
meldung.hidden = !text;
}
/**
* Der Dateiinhalt geht als Base64 an das Wasm-Modul: Die Umsetzung typisierter Felder nach
* byte[] ist in Web Image derzeit defekt, Zeichenketten überqueren die Grenze zuverlässig.
*/
async function alsBase64(datei) {
const bytes = new Uint8Array(await datei.arrayBuffer());
let roh = "";
const block = 0x8000; // btoa verträgt keine beliebig langen Argumentlisten.
for (let i = 0; i < bytes.length; i += block) {
roh += String.fromCharCode.apply(null, bytes.subarray(i, i + block));
}
return { name: datei.name, base64: btoa(roh) };
}
formular.addEventListener("submit", async (ereignis) => {
ereignis.preventDefault();
const stammDatei = document.querySelector("#stamm").files[0];
const patchDateien = Array.from(document.querySelector("#aenderung").files);
if (!stammDatei || patchDateien.length === 0) {
zeige("Bitte ein Stammgesetz und mindestens ein Änderungsdokument wählen.", "fehler");
return;
}
knopf.disabled = true;
zeige("Lade das Rechenwerk (einmalig einige Megabyte) und werte aus …", "arbeit");
try {
const [stamm, patches] = await Promise.all([
alsBase64(stammDatei),
Promise.all(patchDateien.map(alsBase64)),
]);
if (!worker) {
worker = new Worker("worker.js");
}
const ergebnis = await new Promise((aufloesen, ablehnen) => {
worker.onmessage = (nachricht) => aufloesen(nachricht.data);
worker.onerror = (fehler) => ablehnen(new Error(fehler.message || "Worker-Fehler"));
worker.postMessage({
stamm,
patches,
vollstaendig: document.querySelector("#vollstaendig").checked,
artikel: null,
});
});
if (ergebnis.fehler) {
zeige("Verarbeitung fehlgeschlagen: " + ergebnis.fehler, "fehler");
return;
}
const blob = new Blob([ergebnis.html], { type: "text/html;charset=utf-8" });
const adresse = URL.createObjectURL(blob);
// Kein window.open: Der Aufruf käme nach dem Warten auf den Worker und gälte dem Browser
// nicht mehr als Nutzerhandlung — er würde als Popup blockiert. Stattdessen ein Link, der
// sich öffnen und ebenso gut speichern lässt.
zeige(
`${ergebnis.angewandt} Befehle angewandt, ${ergebnis.manuell} manuell zu prüfen, ` +
`${ergebnis.normen} geänderte Normen. `,
"fertig",
);
const verweis = document.createElement("a");
verweis.href = adresse;
verweis.target = "_blank";
verweis.textContent = "Synopse öffnen";
meldung.append(verweis);
} catch (e) {
zeige("Verarbeitung fehlgeschlagen: " + (e && e.message ? e.message : e), "fehler");
} finally {
knopf.disabled = false;
}
});