Release v2.3.5 — Signatur-Sync: Web-Editor-Edits werden korrekt übernommen

Pull-Lookup für Signatur-Header war case-sensitiv gegen eine lowercase
headerMap → Groß-/Leerzeichen-Namen wurden nie gefunden, Plugin fiel auf
die lokale TB-Signatur zurück und revertierte beim Push die Web-Editor-
Änderung. Jetzt: case-insensitive Lookup, kanonischer sigSlug (= Web-Editor-
Format, lowercase-bindestrich) zum Lesen+Schreiben, Legacy-Format nur noch
lesend, bei mehreren Treffern gewinnt der neueste Commit. Keine git-seitigen
Breaking Changes — alte Plugin-Versionen (Groß-Dateien) bleiben kompatibel.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kendrick Bollens
2026-06-23 11:29:56 +02:00
parent fa817050d8
commit c7383f3a77
4 changed files with 54 additions and 7 deletions

View File

@@ -400,6 +400,19 @@ class SyncManager {
return { success: true, pushed }; return { success: true, pushed };
} }
// Kanonischer Signatur-Slug, identisch zum Web-Editor (slugifyHeaderName):
// toFilename(...) + lowercase + Leerzeichen→Bindestrich. So lesen/schreiben
// Web-Editor und Plugin DIESELBE Datei (z.B. ".kendrick-bollens.html").
get sigSlug() {
return SyncManager.toFilename(this.config.authorName || '')
.toLowerCase()
.replace(/\s+/g, '-');
}
// Altes Plugin-Format (Groß-/Kleinschreibung + Leerzeichen, z.B.
// ".Kendrick Bollens.html"). Nur noch für Lese-Fallback, damit Dateien von
// Clients mit alter Plugin-Version weiterhin angewandt werden. Nicht mehr
// schreiben — sonst entstehen wieder Doppel-Dateien.
get authorSlug() { get authorSlug() {
return SyncManager.toFilename(this.config.authorName || ''); return SyncManager.toFilename(this.config.authorName || '');
} }
@@ -567,11 +580,30 @@ class SyncManager {
if (source.startsWith('=')) continue; if (source.startsWith('=')) continue;
// Try personal header: email.authorslug.html // Personal-Header suchen. headerMap-Keys sind lowercase, daher
let targetFile = null; // Kandidaten ebenfalls lowercase nachschlagen (behebt den Bug,
// dass Groß-Namen NIE gefunden wurden → Plugin fiel auf die lokale
// Signatur zurück und revertierte beim Push die Web-Editor-Änderung).
// Kandidaten:
// • kanonisches Web-Editor-Format (lowercase-bindestrich)
// • altes Plugin-Format (Groß/Leerzeichen) von Clients mit alter Version
// Bei mehreren Treffern gewinnt der NEUESTE Commit — so verdeckt eine
// veraltete Datei keine frische Web-Editor-Änderung, egal welche der
// beiden Dateien zuletzt im Web-Editor bearbeitet wurde.
const candidates = [];
if (this.sigSlug) {
const f = headerMap[`${email}.${this.sigSlug}.html`.toLowerCase()];
if (f) candidates.push(f);
}
if (this.authorSlug) { if (this.authorSlug) {
const personalName = `${email}.${this.authorSlug}.html`; const f = headerMap[`${email}.${this.authorSlug}.html`.toLowerCase()];
targetFile = headerMap[personalName] || null; if (f && !candidates.includes(f)) candidates.push(f);
}
let targetFile = null;
let targetTime = -1;
for (const f of candidates) {
const t = Date.parse(f.last_author_date || f.last_committer_date || '') || 0;
if (t >= targetTime) { targetFile = f; targetTime = t; }
} }
let header = null; let header = null;
@@ -634,7 +666,7 @@ class SyncManager {
async pushSignatures() { async pushSignatures() {
if (!this.isConfigured) throw new Error('Sync nicht konfiguriert'); if (!this.isConfigured) throw new Error('Sync nicht konfiguriert');
if (!this.config.authorName) throw new Error('Bitte Name eintragen (für Commit-Zuordnung)'); if (!this.config.authorName) throw new Error('Bitte Name eintragen (für Commit-Zuordnung)');
if (!this.authorSlug) throw new Error('Name fehlt für Dateiname'); if (!this.sigSlug) throw new Error('Name fehlt für Dateiname');
const sourceResult = await browser.storage.local.get('sig_source_map'); const sourceResult = await browser.storage.local.get('sig_source_map');
const sourceMap = sourceResult.sig_source_map || {}; const sourceMap = sourceResult.sig_source_map || {};
@@ -655,7 +687,12 @@ class SyncManager {
const header = SyncManager.extractHeader(identity.signature); const header = SyncManager.extractHeader(identity.signature);
if (!header.trim()) continue; if (!header.trim()) continue;
const filename = `${email}.${this.authorSlug}.html`; // Ins kanonische Web-Editor-Format schreiben (lowercase-bindestrich),
// damit Plugin und Web-Editor dieselbe Datei pflegen. Alte
// Groß-Dateien bleiben unangetastet (keine Breaking Changes für
// Clients mit alter Plugin-Version), werden aber nicht mehr neu
// geschrieben.
const filename = `${email}.${this.sigSlug}.html`;
const filepath = `signatures/headers/${filename}`; const filepath = `signatures/headers/${filename}`;
const commitMsg = `Signatur-Header ${identity.email} - von ${this.config.authorName}`; const commitMsg = `Signatur-Header ${identity.email} - von ${this.config.authorName}`;

View File

@@ -1,7 +1,7 @@
{ {
"manifest_version": 2, "manifest_version": 2,
"name": "HPS Vorlagen & Signaturen", "name": "HPS Vorlagen & Signaturen",
"version": "2.3.4", "version": "2.3.5",
"description": "Vorlagen- und Signaturverwaltung für Hotel Park Soltau mit Git-Sync", "description": "Vorlagen- und Signaturverwaltung für Hotel Park Soltau mit Git-Sync",
"browser_specific_settings": { "browser_specific_settings": {
"gecko": { "gecko": {

Binary file not shown.

View File

@@ -2,6 +2,16 @@
"addons": { "addons": {
"it@hotel-park-soltau.de": { "it@hotel-park-soltau.de": {
"updates": [ "updates": [
{
"version": "2.3.5",
"update_link": "https://git.hotel-park-soltau.de/hps/hps-thunderbird-templates/releases/download/v2.3.5/templates-reply-hotel.xpi",
"update_hash": "sha256:41335a1b572ee38fe659d716ab7b89754fa997ec532e626930f8e470fac31281",
"applications": {
"gecko": {
"strict_min_version": "109.0"
}
}
},
{ {
"version": "2.3.4", "version": "2.3.4",
"update_link": "https://git.hotel-park-soltau.de/hps/hps-thunderbird-templates/releases/download/v2.3.4/templates-reply-hotel.xpi", "update_link": "https://git.hotel-park-soltau.de/hps/hps-thunderbird-templates/releases/download/v2.3.4/templates-reply-hotel.xpi",