munin/static/preview.js
2026-10-19 10:13:56 +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 btn = event.target.closest("[data-editor-tab]");
if (!btn) {
return;
}
var editor = btn.closest("[data-editor]");
if (!editor) {
return;
}
var dest = btn.getAttribute("data-editor-tab");
editor.querySelectorAll("[data-editor-tab]").forEach(function (b) {
var active = b === btn;
b.classList.toggle("active", active);
b.setAttribute("aria-selected", active ? "true" : "false");
});
editor.querySelectorAll("[data-editor-panel]").forEach(function (p) {
p.hidden = p.getAttribute("data-editor-panel") !== dest;
});
if (dest === "preview") {
loadPreview(editor);
}
});
function loadPreview(editor) {
var textarea = editor.querySelector("textarea[data-editor-panel]");
var preview = editor.querySelector("[data-editor-panel='preview']");
var form = editor.closest("form");
if (!textarea || !preview || !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);
}
preview.textContent = "Wird geladen …";
preview.classList.add("preview-loading");
fetch(url, {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: body,
})
.then(function (answer) {
if (!answer.ok) {
throw new Error("Vorschau fehlgeschlagen");
}
return answer.text();
})
.then(function (html) {
preview.classList.remove("preview-loading");
if (html.trim() === "") {
preview.innerHTML = '<p class="help">Noch kein Inhalt.</p>';
return;
}
preview.innerHTML = html;
})
.catch(function () {
preview.classList.remove("preview-loading");
preview.textContent = "Vorschau konnte nicht geladen werden.";
});
}