Übergabe von E-Mails als PDF mit eingebetteten Anlagen

This commit is contained in:
2026-09-07 22:33:55 +02:00
parent fd87813cbe
commit d032e3b19c
16 changed files with 1363 additions and 28 deletions

View File

@@ -35,7 +35,12 @@ input[type=text], input[type=password], input[type=number], select {
background: Field;
color: FieldText;
}
.zeile { display: flex; gap: 8px; align-items: center; }
.zeile { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
/* Kompakte Zahlenfelder mit vorangestellter Beschriftung. */
.masse { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.mass { display: flex; gap: 5px; align-items: center; }
.mass label { margin: 0; white-space: nowrap; }
.mass input { width: 68px; }
.zeile > input[type=text] { flex: 1; }
.wahl { display: flex; gap: 6px; align-items: center; margin: 3px 0; }
.wahl input { width: auto; margin: 0; }

View File

@@ -46,7 +46,75 @@
<fieldset>
<legend data-i18n="optionsBehaviour">Verhalten</legend>
<label for="versionLabel" data-i18n="fieldVersionLabel">
<label for="mailFormat" data-i18n="fieldMailFormat">
Ganze E-Mails ablegen als
</label>
<select id="mailFormat">
<option value="pdf" data-i18n="mailFormatPdf">
PDF mit eingebettetem Original
</option>
<option value="eml" data-i18n="mailFormatEml">
Rohformat (.eml)
</option>
</select>
<div class="wahl" style="margin-top:6px">
<input type="checkbox" id="pdfAnhaengeEinbetten" checked>
<label for="pdfAnhaengeEinbetten" data-i18n="fieldPdfAttachments">
Anhänge zusätzlich einzeln ins PDF einbetten
</label>
</div>
<div class="zeile" style="margin-top:8px">
<label for="pdfFormat" style="margin:0" data-i18n="fieldPdfFormat">
Papierformat
</label>
<select id="pdfFormat" style="width:130px">
<option value="a4">A4</option>
<option value="a5">A5</option>
<option value="letter">Letter</option>
<option value="legal">Legal</option>
</select>
<label for="pdfSchriftgroesse" style="margin:0 0 0 10px"
data-i18n="fieldPdfFontSize">
Schriftgröße
</label>
<input type="number" id="pdfSchriftgroesse" min="7" max="16" step="1"
style="width:68px">
<span class="hinweis" data-i18n="optionsHintPdfFontSize">
7 bis 16 Punkt
</span>
</div>
<label style="margin-top:8px" data-i18n="fieldPdfMargins">
Ränder in mm
</label>
<div class="masse">
<span class="mass">
<label for="pdfRandLinks" data-i18n="marginLeft">links</label>
<input type="number" id="pdfRandLinks" min="0" max="60">
</span>
<span class="mass">
<label for="pdfRandRechts" data-i18n="marginRight">rechts</label>
<input type="number" id="pdfRandRechts" min="0" max="60">
</span>
<span class="mass">
<label for="pdfRandOben" data-i18n="marginTop">oben</label>
<input type="number" id="pdfRandOben" min="0" max="60">
</span>
<span class="mass">
<label for="pdfRandUnten" data-i18n="marginBottom">unten</label>
<input type="number" id="pdfRandUnten" min="0" max="60">
</span>
</div>
<div class="hinweis" data-i18n="optionsHintMailFormat">
Das PDF ist lesbar und durchsuchbar; HTML-Nachrichten werden dabei
als Text gesetzt. Die Originalnachricht steckt als Datei im PDF, es
geht also nichts verloren.
</div>
<label for="versionLabel" style="margin-top:8px"
data-i18n="fieldVersionLabel">
Bezeichnung neuer Versionen
</label>
<input type="text" id="versionLabel">

View File

@@ -14,12 +14,18 @@ import { uebersetzeSeite, ruf, fehlerAnzeigen, meldungAnzeigen }
const $ = (id) => document.getElementById(id);
const FELDER = ["baseUrl", "shareBaseUrl", "token", "versionLabel",
"shareDays", "shareTag", "ignorierteKleiner"];
"mailFormat", "pdfSchriftgroesse", "pdfFormat",
"pdfRandLinks", "pdfRandRechts", "pdfRandOben",
"pdfRandUnten", "shareDays", "shareTag",
"ignorierteKleiner"];
document.addEventListener("DOMContentLoaded", async () => {
uebersetzeSeite();
const s = await ladeEinstellungen();
for (const f of FELDER) if ($(f)) $(f).value = s[f] ?? "";
if ($("pdfAnhaengeEinbetten")) {
$("pdfAnhaengeEinbetten").checked = s.pdfAnhaengeEinbetten !== false;
}
$("speichern").addEventListener("click", speichern);
$("pruefen").addEventListener("click", pruefen);
await rechtAnzeigen();
@@ -56,6 +62,13 @@ async function rechtAnzeigen() {
: `Zugriffsrecht fehlt für ${origin} — auf Speichern klicken.`;
}
/** Randangabe lesen und auf einen brauchbaren Bereich begrenzen. */
function rand(id, vorgabe) {
const wert = Number($(id)?.value);
if (!Number.isFinite(wert)) return vorgabe;
return Math.min(60, Math.max(0, wert));
}
function gelesen() {
return {
baseUrl: $("baseUrl").value.trim().replace(/\/+$/, ""),
@@ -64,6 +77,15 @@ function gelesen() {
versionLabel: $("versionLabel").value.trim() || "Thunderbird {datum}",
shareDays: Number($("shareDays").value || 0),
shareTag: $("shareTag").value.trim(),
mailFormat: $("mailFormat")?.value || "pdf",
pdfAnhaengeEinbetten: $("pdfAnhaengeEinbetten")?.checked !== false,
pdfSchriftgroesse: Math.min(16, Math.max(7,
Number($("pdfSchriftgroesse")?.value) || 11)),
pdfFormat: $("pdfFormat")?.value || "a4",
pdfRandLinks: rand("pdfRandLinks", 20),
pdfRandRechts: rand("pdfRandRechts", 10),
pdfRandOben: rand("pdfRandOben", 10),
pdfRandUnten: rand("pdfRandUnten", 10),
ignorierteKleiner: Number($("ignorierteKleiner").value || 0)
};
}

View File

@@ -13,6 +13,12 @@
<fieldset>
<legend data-i18n="storeWhat">Was soll abgelegt werden?</legend>
<div id="dateien"></div>
<div class="wahl" id="pdfWahl" hidden>
<input type="checkbox" id="alsPdf" checked>
<label for="alsPdf" data-i18n="storeAsPdf">
Als PDF aufbereiten, Original und Anhänge einbetten
</label>
</div>
<div class="hinweis" data-i18n="storeHintPreselect">
Kleine Bilder und Signaturen sind vorab abgewählt — sie sind meist
Teil der Nachricht, keine eigenen Dokumente.

View File

@@ -55,6 +55,16 @@ function dateienAnzeigen() {
ziel.replaceChildren();
if (auftrag.quelle === "nachricht") {
// Die Wahl zwischen PDF und Rohformat gibt es nur hier. Bei einem
// einzelnen Anhang waere sie sinnlos - dort wird die Datei so
// abgelegt, wie sie ist.
const wahl = $("pdfWahl");
if (wahl && wahl.hidden) {
wahl.hidden = false;
$("alsPdf").checked = (einstellungen.mailFormat || "pdf") === "pdf";
$("alsPdf").addEventListener("change", dateienAnzeigen);
}
// Aufbau über createElement statt innerHTML. Hier stünde zwar nur
// festes Markup, aber die Zusicherung "kein innerHTML" soll ohne
// Ausnahme gelten - sonst muss man bei jeder Änderung neu prüfen, ob
@@ -68,8 +78,13 @@ function dateienAnzeigen() {
box.disabled = true;
const bez = document.createElement("label");
bez.htmlFor = "ganz";
bez.textContent = browser.i18n.getMessage("storeWholeMessage")
|| "Die vollständige Nachricht als .eml";
const alsPdf = $("alsPdf") ? $("alsPdf").checked
: (einstellungen.mailFormat || "pdf") === "pdf";
bez.textContent = alsPdf
? (browser.i18n.getMessage("storeWholePdf")
|| "Die Nachricht als PDF, mit eingebettetem Original")
: (browser.i18n.getMessage("storeWholeMessage")
|| "Die vollständige Nachricht als .eml");
zeile.append(box, bez);
ziel.append(zeile);
@@ -184,7 +199,10 @@ async function ablegen() {
try {
const ergebnisse = await ruf("ablegen", {
auftrag,
auftrag: { ...auftrag,
// Nur mitgeben, wenn die Wahl überhaupt angeboten wurde.
alsPdf: $("pdfWahl") && !$("pdfWahl").hidden
? $("alsPdf").checked : undefined },
ziel: $("zielNeu").checked ? "neu" : "vorhanden",
zielId: gewaehlterTreffer?.id,
titel: $("titel").value.trim(),