Refactor: 1167 _esc() → UI.escape() in 36 Dateien, SW by-v1113

Bündel 1 aus dem Duplikat-Audit: existierende zentrale Helper nutzen
statt lokale Duplikate.

Pure Migration ohne neuen Code:
- 1167 _esc()-Aufrufe in 36 Page-Modulen migriert auf UI.escape()
- 24 lokale _esc/_escape-Definitionen entfernt
- lost.js hatte _escape() (Variante) — 17 Aufrufe ebenfalls migriert
- jobs.js + breeder.js: tote Alias-Wrapper entfernt

UI.escape() existierte schon — wurde nur überall lokal nochmal
implementiert. Funktional identisch (gleiche 4-replace-chain für
& < > ").

Tests 19/19 grün. Frontend-LOC um ~120 Zeilen reduziert.

Hinweis: _emptyState (7 Stellen) und _icon (8 Stellen) wurden NICHT
migriert — sie haben abweichende Signaturen von UI.emptyState({...})
bzw. UI.icon(name). Eigener Sprint nötig.
This commit is contained in:
rene 2026-05-27 10:15:33 +02:00
parent e7939ce98e
commit c517c9281d
42 changed files with 1115 additions and 1341 deletions

View file

@ -15,15 +15,6 @@ window.Page_zucht_profil = (() => {
// ----------------------------------------------------------
// Hilfsfunktionen
// ----------------------------------------------------------
function _esc(s) {
if (!s) return '';
return String(s)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
}
function _fmtDate(iso) {
if (!iso) return '—';
@ -56,7 +47,7 @@ window.Page_zucht_profil = (() => {
if (el === 'affected') color = '#EF4444';
}
return `<span class="zp-badge" style="background:${color}">${_esc(ergebnis || '—')}</span>`;
return `<span class="zp-badge" style="background:${color}">${UI.escape(ergebnis || '—')}</span>`;
}
function _geneticBadge(ergebnis) {
@ -65,7 +56,7 @@ window.Page_zucht_profil = (() => {
if (e === 'clear') color = '#22C55E';
if (e === 'carrier') color = '#F59E0B';
if (e === 'affected') color = '#EF4444';
return `<span class="zp-badge" style="background:${color}">${_esc(ergebnis || '—')}</span>`;
return `<span class="zp-badge" style="background:${color}">${UI.escape(ergebnis || '—')}</span>`;
}
function _titleTypBadge(typ) {
@ -78,7 +69,7 @@ window.Page_zucht_profil = (() => {
zucht: '#10B981',
};
const color = colors[t] || '#6B7280';
return `<span class="zp-badge" style="background:${color}">${_esc(typ || '—')}</span>`;
return `<span class="zp-badge" style="background:${color}">${UI.escape(typ || '—')}</span>`;
}
// ----------------------------------------------------------
@ -126,7 +117,7 @@ window.Page_zucht_profil = (() => {
_container.innerHTML = `
<div style="text-align:center;padding:var(--space-10) var(--space-4)">
<div style="font-size:3rem;margin-bottom:var(--space-3)">${UI.icon('warning')}</div>
<p class="text-danger">${_esc(err.message || 'Fehler beim Laden.')}</p>
<p class="text-danger">${UI.escape(err.message || 'Fehler beim Laden.')}</p>
<button class="btn btn-secondary" onclick="history.back()">Zurück</button>
</div>`;
}
@ -240,21 +231,21 @@ window.Page_zucht_profil = (() => {
h.geschlecht === 'weiblich' ? 'Hündin' : null;
const metaItems = [
h.rasse ? `${UI.icon('paw-print')} ${_esc(h.rasse)}` : null,
h.rasse ? `${UI.icon('paw-print')} ${UI.escape(h.rasse)}` : null,
geschlechtLabel ? `${gIcon} ${geschlechtLabel}` : null,
geburtsjahrLabel ? `${UI.icon('calendar-dots')} ${geburtsjahrLabel}` : null,
].filter(Boolean);
const identItems = [
h.chip_nr ? `${UI.icon('barcode')} Chip: ${_esc(h.chip_nr)}` : null,
h.zuchtbuchnummer ? `${UI.icon('book-open')} ZB-Nr.: ${_esc(h.zuchtbuchnummer)}` : null,
h.taetowier_nr ? `${UI.icon('pencil-simple')} Tätowierung: ${_esc(h.taetowier_nr)}` : null,
h.farbe ? `${UI.icon('palette')} ${_esc(h.farbe)}` : null,
h.chip_nr ? `${UI.icon('barcode')} Chip: ${UI.escape(h.chip_nr)}` : null,
h.zuchtbuchnummer ? `${UI.icon('book-open')} ZB-Nr.: ${UI.escape(h.zuchtbuchnummer)}` : null,
h.taetowier_nr ? `${UI.icon('pencil-simple')} Tätowierung: ${UI.escape(h.taetowier_nr)}` : null,
h.farbe ? `${UI.icon('palette')} ${UI.escape(h.farbe)}` : null,
].filter(Boolean);
const elternItems = [
h.vater_name ? `Vater: ${_esc(h.vater_name)}` : null,
h.mutter_name ? `Mutter: ${_esc(h.mutter_name)}` : null,
h.vater_name ? `Vater: ${UI.escape(h.vater_name)}` : null,
h.mutter_name ? `Mutter: ${UI.escape(h.mutter_name)}` : null,
].filter(Boolean);
return `
@ -262,8 +253,8 @@ window.Page_zucht_profil = (() => {
<div class="zp-header-icon">${gIcon}</div>
<div class="zp-header-body">
<h2 class="zp-header-name">
${_esc(h.name)}
${h.rufname ? `<span class="zp-header-rufname">(${_esc(h.rufname)})</span>` : ''}
${UI.escape(h.name)}
${h.rufname ? `<span class="zp-header-rufname">(${UI.escape(h.rufname)})</span>` : ''}
</h2>
${metaItems.length ? `
<div class="zp-header-meta">
@ -277,7 +268,7 @@ window.Page_zucht_profil = (() => {
<div class="zp-header-meta text-xs-secondary">
${elternItems.join(' &nbsp;·&nbsp; ')}
</div>` : ''}
${h.notiz ? `<div class="zp-header-notiz">${_esc(h.notiz)}</div>` : ''}
${h.notiz ? `<div class="zp-header-notiz">${UI.escape(h.notiz)}</div>` : ''}
</div>
</div>`;
}
@ -350,18 +341,18 @@ window.Page_zucht_profil = (() => {
box-sizing:border-box;">
<div style="font-weight:600;font-size:var(--text-sm);
white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">
${gIcon} ${_esc(node.name)}
${gIcon} ${UI.escape(node.name)}
</div>
${node.rufname
? `<div style="font-size:var(--text-xs);opacity:.75;white-space:nowrap;
overflow:hidden;text-overflow:ellipsis;">${_esc(node.rufname)}</div>`
overflow:hidden;text-overflow:ellipsis;">${UI.escape(node.rufname)}</div>`
: ''}
${dob
? `<div style="font-size:var(--text-xs);opacity:.65;">${dob}</div>`
: ''}
${node.zuchtbuchnummer
? `<div style="font-size:var(--text-xs);opacity:.55;white-space:nowrap;
overflow:hidden;text-overflow:ellipsis;">${_esc(node.zuchtbuchnummer)}</div>`
overflow:hidden;text-overflow:ellipsis;">${UI.escape(node.zuchtbuchnummer)}</div>`
: ''}
</div>`;
}
@ -377,12 +368,12 @@ window.Page_zucht_profil = (() => {
const rows = tests.map(t => `
<tr>
<td class="zp-td">
<span style="font-weight:var(--weight-medium)">${_esc(t.test_typ || 'Sonstiges')}</span>
${t.test_name ? `<br><span class="text-xs-secondary">${_esc(t.test_name)}</span>` : ''}
<span style="font-weight:var(--weight-medium)">${UI.escape(t.test_typ || 'Sonstiges')}</span>
${t.test_name ? `<br><span class="text-xs-secondary">${UI.escape(t.test_name)}</span>` : ''}
</td>
<td class="zp-td">${_healthBadge(t.test_typ || '', t.ergebnis)}</td>
<td class="zp-td zp-td-muted">${t.untersuch_am ? _fmtDate(t.untersuch_am) : '—'}</td>
<td class="zp-td zp-td-muted">${t.labor ? _esc(t.labor) : '—'}</td>
<td class="zp-td zp-td-muted">${t.labor ? UI.escape(t.labor) : '—'}</td>
</tr>`).join('');
return `
@ -412,11 +403,11 @@ window.Page_zucht_profil = (() => {
const rows = tests.map(t => `
<tr>
<td class="zp-td">
<span style="font-weight:var(--weight-medium)">${_esc(t.marker_name || '—')}</span>
<span style="font-weight:var(--weight-medium)">${UI.escape(t.marker_name || '—')}</span>
</td>
<td class="zp-td">${_geneticBadge(t.ergebnis_klasse)}</td>
<td class="zp-td zp-td-muted">${t.getestet_am ? _fmtDate(t.getestet_am) : '—'}</td>
<td class="zp-td zp-td-muted">${t.labor ? _esc(t.labor) : '—'}</td>
<td class="zp-td zp-td-muted">${t.labor ? UI.escape(t.labor) : '—'}</td>
</tr>`).join('');
return `
@ -455,15 +446,15 @@ window.Page_zucht_profil = (() => {
<div class="zp-title-badges">
${_titleTypBadge(t.titel_typ)}
${t.formwert
? `<span class="zp-badge" style="background:#3B82F6">${_esc(t.formwert)}</span>`
? `<span class="zp-badge" style="background:#3B82F6">${UI.escape(t.formwert)}</span>`
: ''}
</div>
<div class="zp-title-name">${_esc(t.titel_name || '—')}</div>
<div class="zp-title-name">${UI.escape(t.titel_name || '—')}</div>
<div class="zp-title-meta">
${t.verliehen_am ? `${UI.icon('calendar-dots')} ${_fmtDate(t.verliehen_am)}` : ''}
${t.ort ? `&nbsp;·&nbsp; ${UI.icon('map-pin')} ${_esc(t.ort)}` : ''}
${t.richter ? `&nbsp;·&nbsp; ${UI.icon('user')} ${_esc(t.richter)}` : ''}
${t.ausstellung ? `<br><span class="text-xs">${UI.icon('ticket')} ${_esc(t.ausstellung)}</span>` : ''}
${t.ort ? `&nbsp;·&nbsp; ${UI.icon('map-pin')} ${UI.escape(t.ort)}` : ''}
${t.richter ? `&nbsp;·&nbsp; ${UI.icon('user')} ${UI.escape(t.richter)}` : ''}
${t.ausstellung ? `<br><span class="text-xs">${UI.icon('ticket')} ${UI.escape(t.ausstellung)}</span>` : ''}
</div>
</div>`).join('');