munin/static/preview.js
Thomas Adamek 466f1e40af Workspaces, Änderungshistorie, Papierkorb, Nutzungsübersicht, Hilfe
Umsetzung der Ausbaustufen 2.1, 3.6, 3.8, 3.9, 4.1, 4.2, 4.4, 4.6,
5.1–5.4 (Details in AUSBAUSTUFEN.md).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 07:44:52 +02:00

86 lines
2.9 KiB
JavaScript

// Schaltet im Bearbeitungsformular zwischen "Schreiben" und "Vorschau" um.
//
// Die Vorschau wird nicht im Browser aus Markdown erzeugt — das bräuchte eine
// zweite Rendering-Implementierung (und eine externe Bibliothek, die die
// Content-Security-Policy zulassen müsste, siehe SecurityHeaders in
// internal/web/middleware.go). Stattdessen schickt ein kurzer Aufruf den
// Inhalt an den Server, der denselben goldmark-Renderer benutzt wie die
// Detailansicht (siehe entry.RenderHTML) — Vorschau und späteres Ergebnis
// können so nie auseinanderlaufen.
//
// Ein Klick auf "Vorschau" lädt neu, kein Live-Rendern beim Tippen: Das hält
// die Zahl der Aufrufe klein und macht unnötig, über Verzögerung
// (Debouncing) nachzudenken.
document.addEventListener("click", function (event) {
var knopf = event.target.closest("[data-editor-tab]");
if (!knopf) {
return;
}
var editor = knopf.closest("[data-editor]");
if (!editor) {
return;
}
var ziel = knopf.getAttribute("data-editor-tab");
editor.querySelectorAll("[data-editor-tab]").forEach(function (b) {
var aktiv = b === knopf;
b.classList.toggle("aktiv", aktiv);
b.setAttribute("aria-selected", aktiv ? "true" : "false");
});
editor.querySelectorAll("[data-editor-panel]").forEach(function (p) {
p.hidden = p.getAttribute("data-editor-panel") !== ziel;
});
if (ziel === "vorschau") {
ladeVorschau(editor);
}
});
function ladeVorschau(editor) {
var textarea = editor.querySelector("textarea[data-editor-panel]");
var vorschau = editor.querySelector("[data-editor-panel='vorschau']");
var form = editor.closest("form");
if (!textarea || !vorschau || !form) {
return;
}
var csrf = form.querySelector("input[name=csrf_token]");
var url = form.getAttribute("data-preview-url");
if (!url) {
return;
}
var body = "content=" + encodeURIComponent(textarea.value);
if (csrf) {
body += "&csrf_token=" + encodeURIComponent(csrf.value);
}
vorschau.textContent = "Wird geladen …";
vorschau.classList.add("vorschau-laedt");
fetch(url, {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: body,
})
.then(function (antwort) {
if (!antwort.ok) {
throw new Error("Vorschau fehlgeschlagen");
}
return antwort.text();
})
.then(function (html) {
vorschau.classList.remove("vorschau-laedt");
if (html.trim() === "") {
vorschau.innerHTML = '<p class="hilfe">Noch kein Inhalt.</p>';
return;
}
vorschau.innerHTML = html;
})
.catch(function () {
vorschau.classList.remove("vorschau-laedt");
vorschau.textContent = "Vorschau konnte nicht geladen werden.";
});
}