From c07b1cc01b3b5ac82113473219448f99fb1ca490 Mon Sep 17 00:00:00 2001 From: rene Date: Thu, 4 Jun 2026 16:22:43 +0200 Subject: [PATCH] =?UTF-8?q?Fix:=20restliche=20CSP-blockierte=20Inline-Hand?= =?UTF-8?q?ler=20=E2=80=94=20Bild-Fallbacks=20(globaler=20data-fb=20Error-?= =?UTF-8?q?Handler)=20+=20Hover-Effekte=20(CSS-Utilities=20+=20data-hover-?= =?UTF-8?q?play)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit App ist jetzt vollständig frei von Inline-Event-Handlern (onerror/onmouseenter/etc.). data-fb Modi: hide/hide-parent/dim-grandparent/sibling/show-el/emoji/initials + data-fb-src. Hover: .by-hover-lift/-surface2/-surface3 in utilities.css. SW v1165 --- VERSION | 2 +- backend/static/css/utilities.css | 11 +++++ backend/static/index.html | 24 +++++----- backend/static/js/app.js | 58 ++++++++++++++++++++++- backend/static/js/pages/admin.js | 4 +- backend/static/js/pages/adoption.js | 18 +++---- backend/static/js/pages/breeder-editor.js | 2 +- backend/static/js/pages/breeder.js | 6 +-- backend/static/js/pages/diary.js | 10 ++-- backend/static/js/pages/forum.js | 2 +- backend/static/js/pages/friends.js | 12 ++--- backend/static/js/pages/laeufi.js | 2 +- backend/static/js/pages/litters.js | 4 +- backend/static/js/pages/moderation.js | 4 +- backend/static/js/pages/partner-profil.js | 2 +- backend/static/js/pages/playdate.js | 2 +- backend/static/js/pages/routes.js | 6 +-- backend/static/js/pages/social.js | 4 +- backend/static/js/pages/walks.js | 4 +- backend/static/js/pages/wiki.js | 8 ++-- backend/static/js/pages/zuchthunde.js | 4 +- backend/static/landing.html | 2 +- backend/static/sw.js | 2 +- 23 files changed, 125 insertions(+), 68 deletions(-) diff --git a/VERSION b/VERSION index b90f375..208e76a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1164 \ No newline at end of file +1165 \ No newline at end of file diff --git a/backend/static/css/utilities.css b/backend/static/css/utilities.css index f9f5ec2..f38a562 100644 --- a/backend/static/css/utilities.css +++ b/backend/static/css/utilities.css @@ -63,3 +63,14 @@ font-weight: 600; margin-bottom: var(--space-1); } + +/* ------------------------------------------------------------------ + Hover-Utilities — ersetzen CSP-blockierte onmouseenter/leave/over. + :hover braucht !important, da Inline-Base-Styles höher spezifisch sind. + ------------------------------------------------------------------ */ +.by-hover-lift { transition: transform .15s, box-shadow .15s; } +.by-hover-lift:hover { transform: translateY(-2px) !important; box-shadow: var(--shadow-md) !important; } +.by-hover-surface2 { transition: background .15s; } +.by-hover-surface2:hover{ background: var(--c-surface-2) !important; } +.by-hover-surface3 { transition: background .15s; } +.by-hover-surface3:hover{ background: var(--c-surface-3) !important; } diff --git a/backend/static/index.html b/backend/static/index.html index b3a37b7..78fd7af 100644 --- a/backend/static/index.html +++ b/backend/static/index.html @@ -86,14 +86,14 @@ Ban Yaro - + - - - - - + + + + + @@ -617,11 +617,11 @@ - - - - - + + + + + @@ -631,7 +631,7 @@ - + diff --git a/backend/static/js/app.js b/backend/static/js/app.js index cfa9be2..1938376 100644 --- a/backend/static/js/app.js +++ b/backend/static/js/app.js @@ -3,7 +3,7 @@ Router, State-Management, Navigation, Initialisierung. ============================================================ */ -const APP_VER = '1164'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen +const APP_VER = '1165'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen const APP_VERSION = '1.6.0'; // ← semantische Version, wird bei make release gesetzt window.APP_VER = APP_VER; // global verfügbar für andere Module (z.B. offline-indicator) window.APP_VERSION = APP_VERSION; @@ -434,6 +434,62 @@ const App = (() => { // NAVIGATION EVENTS // ---------------------------------------------------------- function _bindNavigation() { + // Globaler Bild-Fallback — ersetzt CSP-blockierte onerror-Attribute. + // 'error' bubbelt nicht → Capture-Phase. Greift nur bei [data-fb]/[data-fb-src]. + document.addEventListener('error', e => { + const el = e.target; + if (!el || el.tagName !== 'IMG') return; + const fb = el.dataset.fb, altSrc = el.dataset.fbSrc; + if (fb === undefined && altSrc === undefined) return; + // Schritt 1: Alternative Quelle versuchen (z.B. _preview → Original / Platzhalter) + if (altSrc && !el.dataset.fbTried) { + el.dataset.fbTried = '1'; + el.src = altSrc; + return; + } + // Schritt 2: terminaler Fallback + switch (fb) { + case 'hide-parent': + if (el.parentElement) el.parentElement.style.display = 'none'; + break; + case 'dim-grandparent': + if (el.parentElement?.parentElement) el.parentElement.parentElement.style.opacity = '.4'; + break; + case 'sibling': + el.style.display = 'none'; + if (el.nextElementSibling) el.nextElementSibling.style.display = 'flex'; + break; + case 'show-el': { + el.style.display = 'none'; + const t = el.dataset.fbEl && document.getElementById(el.dataset.fbEl); + if (t) t.style.display = 'flex'; + break; + } + case 'emoji': + if (el.parentElement) el.parentElement.innerHTML = + `
${el.dataset.fbEmoji || '🐾'}
`; + break; + case 'initials': { + const sz = parseInt(el.dataset.fbSize, 10) || 40; + el.outerHTML = + `
${el.dataset.fbInitials || ''}
`; + break; + } + default: // 'hide' + el.style.display = 'none'; + el.classList.add('img-broken'); + } + }, true); + + // Video-Vorschau bei Hover (ersetzt CSP-blockierte onmouseenter/leave). + //