Analyse: Farbfeld der Einstellungen zeigt die tatsächliche Banner-Farbe

Das Farbfeld nutzt bannerColor() wie die Website: eine für weiße Schrift
zu helle Akzentfarbe wird zu #111111 statt der gespeicherten Farbe.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-04 21:34:43 +00:00
1 parent 55e98b038c
commit 1964e5fcca
2 files changed
+6 -3

No files matched your search

+2 -3
View File
@@ -19,10 +19,9 @@
Fehler section.an-card.an-error[role=alert] > p + button.an-btn#an-retry */
import { esc } from './fn-util.js'
import { fmtNum, fmtDuration, periodLabel, shortDay, dayLabel, compareFrom, delta, contactRate, refName, summarize, chartModel, barRows, countryName, flagEmoji, DEVICE_LABELS } from './analyse-view.js'
import { fmtNum, fmtDuration, periodLabel, shortDay, dayLabel, compareFrom, delta, contactRate, refName, summarize, chartModel, barRows, countryName, flagEmoji, DEVICE_LABELS, bannerColor } from './analyse-view.js'
const RANGES = [7, 30, 90]
const HEX_RE = /^#[0-9a-f]{6}$/i
const isNum = (v) => typeof v === 'number' && Number.isFinite(v)
const num = (v) => (Number.isFinite(Number(v)) ? Number(v) : 0)
const round = (n) => Math.round(n * 10) / 10
@@ -250,7 +249,7 @@ const hrefOk = (url) => typeof url === 'string' && /^(\/(?!\/)|https?:\/\/)/i.te
export function settingsHtml(project) {
const a = project?.analyse || {}
const color = HEX_RE.test(a.accentColor || '') ? a.accentColor.toLowerCase() : '#111111'
const color = bannerColor(a.accentColor) // wie auf der Website: zu helle Farbe => #111111
const since = a.activatedAt ? new Date(a.activatedAt) : null
const status = `Analyse aktiv${since && !Number.isNaN(since.getTime()) ? ` seit ${BERLIN_DATE.format(since)}` : ''}`
const rows = [
+4
View File
@@ -303,6 +303,10 @@ test('settingsHtml: aktiv seit TT.MM.JJJJ, Farbfeld, Fassung, Links AVV und Leis
const bad = settingsHtml(project({ analyse: { state: 'active', accentColor: 'red;"><x>', avvVersion: '2026-10-02', legal: {}, activatedAt: null } }))
assert.match(bad, /background:#111111/); assert.doesNotMatch(bad, /<x>|seit|<a /)
assert.match(bad, /id="an-off"/)
// zu helle Farbe: das Banner nutzt Schwarz, das Farbfeld zeigt dasselbe (bannerColor)
const light = settingsHtml(project({ analyse: { state: 'active', accentColor: '#ffee00', avvVersion: '2026-10-02', legal: {}, activatedAt: null } }))
assert.match(light, /class="an-swatch" style="background:#111111"/); assert.doesNotMatch(light, /#ffee00/i)
assert.match(settingsHtml(project({ analyse: { state: 'active', accentColor: '#1D4ED8' } })), /background:#1d4ed8/) // groß geschrieben => klein
// gefährliche Link-Ziele und Namen
const evil = settingsHtml(project({ analyse: { state: 'active', accentColor: '#fff', avvVersion: '<b>', legal: { avv: 'javascript:alert(1)', lb: '/x"onmouseover="y' }, activatedAt: 'kaputt' } }))
assert.doesNotMatch(evil, /javascript:|<b>|onmouseover="y/); assert.doesNotMatch(evil, /NaN|undefined|null|Invalid/)