feature: alte Versionen direkt auf openbureau anzeigen
- API (öffentlich): /api/history listet Git-Versionen eines Beitrags, /api/history/version rendert eine alte Fassung (marked + Fußnoten-Support), on-demand via git im CMS-Container — kein Vorbauen. Pfad/rev validiert. - Versions-Marke neben dem Kopf jedes Library-Beitrags (zeigt bewusst die Fassung); öffnet den Verlauf, Auswahl ersetzt den Text + Rücksprung-Banner. - CSS für Badge/Panel/Banner; marked als Dependency. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
/* OPENBUREAU — Versionsverlauf eines Beitrags direkt auf der Seite.
|
||||
Die Marke „Version xxx" neben dem Kopf öffnet die Liste der Fassungen
|
||||
(aus /api/history); Auswahl ersetzt den Beitragstext mit der alten Fassung
|
||||
(aus /api/history/version) und zeigt einen Banner mit Rücksprung. */
|
||||
(function () {
|
||||
var badge = document.getElementById('version-badge');
|
||||
if (!badge) return;
|
||||
var path = badge.dataset.path;
|
||||
var content = document.querySelector('.single-content');
|
||||
var article = document.querySelector('article.single');
|
||||
if (!path || !content || !article) return;
|
||||
|
||||
var originalHTML = content.innerHTML;
|
||||
var originalLabel = badge.textContent;
|
||||
var panel = null, banner = null;
|
||||
|
||||
function api(p) {
|
||||
return fetch(p).then(function (r) { return r.ok ? r.json() : null; }).catch(function () { return null; });
|
||||
}
|
||||
function fmt(d) { try { return new Date(d).toLocaleDateString('de-CH'); } catch (e) { return d || ''; } }
|
||||
|
||||
function closePanel() {
|
||||
if (panel) { panel.remove(); panel = null; }
|
||||
badge.setAttribute('aria-expanded', 'false');
|
||||
}
|
||||
function restore() {
|
||||
content.innerHTML = originalHTML;
|
||||
badge.textContent = originalLabel;
|
||||
if (banner) { banner.remove(); banner = null; }
|
||||
}
|
||||
function showBanner(v) {
|
||||
if (banner) banner.remove();
|
||||
banner = document.createElement('div');
|
||||
banner.className = 'version-banner';
|
||||
banner.append('Ältere Fassung vom ' + fmt(v.date) + ' · Version ' + v.short + ' ');
|
||||
var back = document.createElement('button');
|
||||
back.type = 'button'; back.className = 'version-back'; back.textContent = '→ Zur aktuellen Fassung';
|
||||
back.addEventListener('click', restore);
|
||||
banner.appendChild(back);
|
||||
article.insertBefore(banner, article.firstChild);
|
||||
}
|
||||
function loadVersion(v) {
|
||||
closePanel();
|
||||
content.innerHTML = '<p class="version-loading">Lade Fassung …</p>';
|
||||
api('/api/history/version?path=' + encodeURIComponent(path) + '&rev=' + encodeURIComponent(v.rev)).then(function (data) {
|
||||
if (!data || !data.html) { restore(); return; }
|
||||
content.innerHTML = data.html;
|
||||
badge.textContent = 'Version ' + v.short;
|
||||
showBanner(v);
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
});
|
||||
}
|
||||
function openPanel() {
|
||||
api('/api/history?path=' + encodeURIComponent(path)).then(function (list) {
|
||||
panel = document.createElement('div');
|
||||
panel.className = 'version-panel';
|
||||
if (!list || !list.length) {
|
||||
panel.innerHTML = '<p class="version-empty">Kein Verlauf verfügbar.</p>';
|
||||
} else {
|
||||
var ol = document.createElement('ol');
|
||||
ol.className = 'version-list';
|
||||
list.forEach(function (v, i) {
|
||||
var li = document.createElement('li');
|
||||
var b = document.createElement('button');
|
||||
b.type = 'button';
|
||||
var date = document.createElement('span'); date.className = 'v-date'; date.textContent = fmt(v.date);
|
||||
var subj = document.createElement('span'); subj.className = 'v-subject'; subj.textContent = v.subject || '';
|
||||
var hash = document.createElement('span'); hash.className = 'v-hash'; hash.textContent = v.short + (i === 0 ? ' · aktuell' : '');
|
||||
b.append(date, subj, hash);
|
||||
if (i === 0) b.addEventListener('click', function () { restore(); closePanel(); });
|
||||
else b.addEventListener('click', function () { loadVersion(v); });
|
||||
li.appendChild(b);
|
||||
ol.appendChild(li);
|
||||
});
|
||||
panel.appendChild(ol);
|
||||
}
|
||||
badge.parentNode.insertBefore(panel, badge.nextSibling);
|
||||
badge.setAttribute('aria-expanded', 'true');
|
||||
});
|
||||
}
|
||||
|
||||
badge.addEventListener('click', function () { panel ? closePanel() : openPanel(); });
|
||||
})();
|
||||
Reference in New Issue
Block a user