- variant=full: kleiner Footer-Trigger ("Impressum"), Klick öffnet Overlay
mit § 5 TMG-Block. Schließen via × / ESC / Backdrop-Klick. Fade-in.
- variant=minimal: bleibt unveränderter Inline-Einzeiler.
- API unverändert: data-owner / data-variant am Script-Tag.
- Alles inline (kein neues Stylesheet, keine Abhängigkeiten).
236 lines
8.0 KiB
JavaScript
236 lines
8.0 KiB
JavaScript
/**
|
|
* Modulares Impressum — Single Source of Truth für alle Onepager-Sites.
|
|
*
|
|
* Einbinden:
|
|
* <script src="/shared/impressum.js"></script>
|
|
* <script src="/shared/impressum.js" data-owner="flexsiebels"></script>
|
|
* <script src="/shared/impressum.js" data-owner="flexsiebels" data-variant="full"></script>
|
|
*
|
|
* Konfiguration via data-Attribute am Script-Tag:
|
|
* data-owner="msbls" (default) — Kurzverweis auf msbls.de
|
|
* data-owner="flexsiebels" — Kurzverweis auf flexsiebels.de
|
|
* data-owner="martinsiebels" — volles Impressum Martin Siebels (separate Person, Osnabrück)
|
|
* data-variant="minimal" (default) — Einzeiler im Footer (inline)
|
|
* data-variant="full" — kleiner Trigger im Footer, voller § 5 TMG-Block im Overlay
|
|
*
|
|
* Legacy-Alias: data-style (gleiche Werte wie data-variant).
|
|
*
|
|
* Render-Ziel: Element mit id="impressum" falls vorhanden, sonst <footer>, sonst body.
|
|
*/
|
|
(function () {
|
|
const script = document.currentScript;
|
|
const owner = script?.getAttribute('data-owner') || 'msbls';
|
|
const variant = script?.getAttribute('data-variant')
|
|
|| script?.getAttribute('data-style')
|
|
|| 'minimal';
|
|
|
|
// Gemeinsamer Block für Matthias Siebels (m) — beide Domains, gleiche Anschrift.
|
|
const matthiasAddress = 'Matthias Siebels<br>'
|
|
+ 'c/o Online-Impressum.de #5892<br>'
|
|
+ 'Europaring 90<br>'
|
|
+ '53757 Sankt Augustin';
|
|
|
|
const owners = {
|
|
msbls: {
|
|
minimal: 'Ein Projekt von <a href="https://msbls.de" target="_blank" rel="noopener">msbls.de</a>',
|
|
full: '<strong>Angaben gemäß § 5 TMG:</strong><br>'
|
|
+ matthiasAddress + '<br>'
|
|
+ 'E-Mail: <a href="mailto:mail@msbls.de">mail@msbls.de</a>',
|
|
},
|
|
flexsiebels: {
|
|
minimal: 'Ein Projekt von <a href="https://flexsiebels.de" target="_blank" rel="noopener">flexsiebels.de</a>',
|
|
full: '<strong>Angaben gemäß § 5 TMG:</strong><br>'
|
|
+ matthiasAddress + '<br>'
|
|
+ 'E-Mail: <a href="mailto:mail@flexsiebels.de">mail@flexsiebels.de</a>',
|
|
},
|
|
martinsiebels: {
|
|
minimal: 'Ein Projekt von <a href="https://martinsiebels.de" target="_blank" rel="noopener">Martin Siebels</a>',
|
|
full: '<strong>Angaben gemäß § 5 TMG:</strong><br>'
|
|
+ 'Martin Siebels<br>'
|
|
+ 'Leyer Str. 38<br>'
|
|
+ '49076 Osnabrück<br>'
|
|
+ 'E-Mail: <a href="mailto:Martin_Siebels@web.de">Martin_Siebels@web.de</a>',
|
|
},
|
|
};
|
|
|
|
const config = owners[owner] || owners.msbls;
|
|
|
|
const target = document.getElementById('impressum')
|
|
|| document.querySelector('footer .container')
|
|
|| document.querySelector('footer')
|
|
|| document.body;
|
|
|
|
if (variant === 'full') {
|
|
renderOverlay(config.full, target);
|
|
} else {
|
|
renderInline(config.minimal, target);
|
|
}
|
|
|
|
function renderInline(html, target) {
|
|
const el = document.createElement('div');
|
|
el.className = 'onepager-impressum';
|
|
el.innerHTML = html;
|
|
el.style.cssText = 'text-align:center;font-size:0.75rem;opacity:0.6;padding:12px 0;margin-top:4px;line-height:1.7;';
|
|
el.querySelectorAll('a').forEach(a => {
|
|
a.style.color = 'inherit';
|
|
a.style.textDecoration = 'underline';
|
|
a.style.textDecorationThickness = '1px';
|
|
a.style.textUnderlineOffset = '2px';
|
|
});
|
|
target.appendChild(el);
|
|
}
|
|
|
|
function renderOverlay(html, target) {
|
|
// Trigger im Footer — klein, dezent, erbt Farben.
|
|
const trigger = document.createElement('button');
|
|
trigger.type = 'button';
|
|
trigger.className = 'onepager-impressum-trigger';
|
|
trigger.textContent = 'Impressum';
|
|
trigger.style.cssText = [
|
|
'display:inline-block',
|
|
'background:none',
|
|
'border:none',
|
|
'padding:12px 8px',
|
|
'margin-top:4px',
|
|
'font:inherit',
|
|
'font-size:0.75rem',
|
|
'color:inherit',
|
|
'opacity:0.6',
|
|
'cursor:pointer',
|
|
'text-decoration:underline',
|
|
'text-decoration-thickness:1px',
|
|
'text-underline-offset:2px',
|
|
'transition:opacity 0.2s ease',
|
|
].join(';');
|
|
trigger.addEventListener('mouseenter', () => { trigger.style.opacity = '1'; });
|
|
trigger.addEventListener('mouseleave', () => { trigger.style.opacity = '0.6'; });
|
|
trigger.addEventListener('focus', () => { trigger.style.opacity = '1'; });
|
|
trigger.addEventListener('blur', () => { trigger.style.opacity = '0.6'; });
|
|
|
|
const wrap = document.createElement('div');
|
|
wrap.className = 'onepager-impressum';
|
|
wrap.style.cssText = 'text-align:center;padding:8px 0;margin-top:4px;';
|
|
wrap.appendChild(trigger);
|
|
target.appendChild(wrap);
|
|
|
|
let backdrop = null;
|
|
let lastFocus = null;
|
|
|
|
trigger.addEventListener('click', open);
|
|
|
|
function open() {
|
|
if (backdrop) return;
|
|
lastFocus = document.activeElement;
|
|
|
|
backdrop = document.createElement('div');
|
|
backdrop.className = 'onepager-impressum-backdrop';
|
|
backdrop.style.cssText = [
|
|
'position:fixed',
|
|
'inset:0',
|
|
'background:rgba(0,0,0,0.55)',
|
|
'display:flex',
|
|
'align-items:center',
|
|
'justify-content:center',
|
|
'padding:24px',
|
|
'z-index:99999',
|
|
'opacity:0',
|
|
'transition:opacity 0.18s ease',
|
|
].join(';');
|
|
|
|
const card = document.createElement('div');
|
|
card.className = 'onepager-impressum-card';
|
|
card.setAttribute('role', 'dialog');
|
|
card.setAttribute('aria-modal', 'true');
|
|
card.setAttribute('aria-label', 'Impressum');
|
|
card.style.cssText = [
|
|
'position:relative',
|
|
'max-width:420px',
|
|
'width:100%',
|
|
'background:#fff',
|
|
'color:#111',
|
|
'padding:32px 28px 28px',
|
|
'border-radius:8px',
|
|
'box-shadow:0 20px 60px rgba(0,0,0,0.35)',
|
|
'font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif',
|
|
'font-size:0.9rem',
|
|
'line-height:1.55',
|
|
'transform:translateY(8px)',
|
|
'transition:transform 0.18s ease',
|
|
'box-sizing:border-box',
|
|
].join(';');
|
|
|
|
const close = document.createElement('button');
|
|
close.type = 'button';
|
|
close.setAttribute('aria-label', 'Schließen');
|
|
close.innerHTML = '×';
|
|
close.style.cssText = [
|
|
'position:absolute',
|
|
'top:6px',
|
|
'right:10px',
|
|
'background:none',
|
|
'border:none',
|
|
'font-size:1.6rem',
|
|
'line-height:1',
|
|
'color:#666',
|
|
'cursor:pointer',
|
|
'padding:6px 10px',
|
|
'border-radius:4px',
|
|
'transition:color 0.15s ease',
|
|
].join(';');
|
|
close.addEventListener('mouseenter', () => { close.style.color = '#000'; });
|
|
close.addEventListener('mouseleave', () => { close.style.color = '#666'; });
|
|
close.addEventListener('click', dismiss);
|
|
|
|
const content = document.createElement('div');
|
|
content.innerHTML = html;
|
|
content.style.cssText = 'margin-top:4px;';
|
|
content.querySelectorAll('a').forEach(a => {
|
|
a.style.color = '#0057b8';
|
|
a.style.textDecoration = 'underline';
|
|
});
|
|
content.querySelectorAll('strong').forEach(s => {
|
|
s.style.display = 'block';
|
|
s.style.marginBottom = '8px';
|
|
});
|
|
|
|
card.appendChild(close);
|
|
card.appendChild(content);
|
|
backdrop.appendChild(card);
|
|
document.body.appendChild(backdrop);
|
|
|
|
// Trigger fade-in nach dem Mounten.
|
|
requestAnimationFrame(() => {
|
|
backdrop.style.opacity = '1';
|
|
card.style.transform = 'translateY(0)';
|
|
});
|
|
|
|
backdrop.addEventListener('click', (e) => {
|
|
if (e.target === backdrop) dismiss();
|
|
});
|
|
document.addEventListener('keydown', onKey);
|
|
close.focus();
|
|
}
|
|
|
|
function dismiss() {
|
|
if (!backdrop) return;
|
|
document.removeEventListener('keydown', onKey);
|
|
const node = backdrop;
|
|
backdrop = null;
|
|
node.style.opacity = '0';
|
|
setTimeout(() => {
|
|
if (node.parentNode) node.parentNode.removeChild(node);
|
|
if (lastFocus && typeof lastFocus.focus === 'function') {
|
|
lastFocus.focus();
|
|
}
|
|
}, 180);
|
|
}
|
|
|
|
function onKey(e) {
|
|
if (e.key === 'Escape') {
|
|
e.preventDefault();
|
|
dismiss();
|
|
}
|
|
}
|
|
}
|
|
})();
|