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:
parent
e7939ce98e
commit
c517c9281d
42 changed files with 1115 additions and 1341 deletions
|
|
@ -509,9 +509,9 @@ window.Page_settings = (() => {
|
|||
|
||||
// Avatar: Bild oder Buchstabe
|
||||
const avatarInner = u.avatar_url
|
||||
? `<img src="${_esc(u.avatar_url)}" alt="Avatar"
|
||||
? `<img src="${UI.escape(u.avatar_url)}" alt="Avatar"
|
||||
style="width:56px;height:56px;border-radius:50%;object-fit:cover;display:block">`
|
||||
: _esc(u.name.charAt(0).toUpperCase());
|
||||
: UI.escape(u.name.charAt(0).toUpperCase());
|
||||
|
||||
// Mitglied seit
|
||||
const memberSince = (() => {
|
||||
|
|
@ -547,9 +547,9 @@ window.Page_settings = (() => {
|
|||
<input type="file" id="settings-avatar-input" accept="image/*"
|
||||
class="hidden">
|
||||
<div>
|
||||
<div style="font-weight:700;font-size:var(--text-lg)">${_esc(u.name)}</div>
|
||||
<div style="font-weight:700;font-size:var(--text-lg)">${UI.escape(u.name)}</div>
|
||||
<div style="display:flex;align-items:center;gap:var(--space-2);color:var(--c-text-secondary);font-size:var(--text-sm)">
|
||||
${_esc(u.email)}
|
||||
${UI.escape(u.email)}
|
||||
${u.email_verified
|
||||
? `<svg class="ph-icon" aria-hidden="true" style="width:14px;height:14px;color:#22c55e" title="Bestätigt"><use href="/icons/phosphor.svg#check-circle"></use></svg>`
|
||||
: `<span id="settings-verify-chip"
|
||||
|
|
@ -600,26 +600,26 @@ window.Page_settings = (() => {
|
|||
<div style="padding:var(--space-4);display:flex;flex-direction:column;gap:var(--space-3)">
|
||||
${memberSince
|
||||
? `<div class="text-sm-secondary">
|
||||
Mitglied seit ${_esc(memberSince)}
|
||||
Mitglied seit ${UI.escape(memberSince)}
|
||||
</div>`
|
||||
: ''}
|
||||
${u.bio
|
||||
? `<div class="text-sm">${_esc(u.bio)}</div>`
|
||||
? `<div class="text-sm">${UI.escape(u.bio)}</div>`
|
||||
: ''}
|
||||
${u.wohnort
|
||||
? `<div class="text-sm-secondary">
|
||||
📍 ${_esc(u.wohnort)}
|
||||
📍 ${UI.escape(u.wohnort)}
|
||||
</div>`
|
||||
: ''}
|
||||
${u.erfahrung && erfahrungLabel[u.erfahrung]
|
||||
? `<div class="text-sm-secondary">
|
||||
${_esc(erfahrungLabel[u.erfahrung])}
|
||||
${UI.escape(erfahrungLabel[u.erfahrung])}
|
||||
</div>`
|
||||
: ''}
|
||||
${u.social_link
|
||||
? `<div class="text-sm">
|
||||
<a href="${_esc(u.social_link)}" target="_blank" rel="noopener"
|
||||
class="text-primary">${_esc(u.social_link)}</a>
|
||||
<a href="${UI.escape(u.social_link)}" target="_blank" rel="noopener"
|
||||
class="text-primary">${UI.escape(u.social_link)}</a>
|
||||
</div>`
|
||||
: ''}
|
||||
${!u.bio && !u.wohnort && !u.erfahrung && !u.social_link
|
||||
|
|
@ -877,17 +877,17 @@ window.Page_settings = (() => {
|
|||
if (!el || !dogs.length) return;
|
||||
el.innerHTML = dogs.map(d => {
|
||||
const av = d.foto_url
|
||||
? `<img src="${_esc(d.foto_url)}" style="width:36px;height:36px;border-radius:50%;object-fit:cover;flex-shrink:0">`
|
||||
? `<img src="${UI.escape(d.foto_url)}" style="width:36px;height:36px;border-radius:50%;object-fit:cover;flex-shrink:0">`
|
||||
: `<div style="width:36px;height:36px;border-radius:50%;background:var(--c-surface-2);display:flex;align-items:center;justify-content:center;flex-shrink:0">
|
||||
<svg class="ph-icon" style="width:18px;height:18px;color:var(--c-text-muted)" aria-hidden="true"><use href="/icons/phosphor.svg#dog"></use></svg>
|
||||
</div>`;
|
||||
const jahr = d.verstorben_am ? d.verstorben_am.slice(0, 4) : '';
|
||||
return `
|
||||
<div class="sidebar-item settings-erinnerung-btn" data-dog-id="${d.id}" data-dog-name="${_esc(d.name)}"
|
||||
<div class="sidebar-item settings-erinnerung-btn" data-dog-id="${d.id}" data-dog-name="${UI.escape(d.name)}"
|
||||
style="padding:var(--space-3) var(--space-4);border-radius:0;border-bottom:1px solid var(--c-border);cursor:pointer">
|
||||
${av}
|
||||
<div style="display:flex;flex-direction:column;gap:1px;flex:1;min-width:0">
|
||||
<span style="font-weight:600;font-size:var(--text-sm)">${_esc(d.name)}</span>
|
||||
<span style="font-weight:600;font-size:var(--text-sm)">${UI.escape(d.name)}</span>
|
||||
<span class="text-xs-muted">
|
||||
<svg class="ph-icon" style="width:11px;height:11px" aria-hidden="true"><use href="/icons/phosphor.svg#heart-break"></use></svg>
|
||||
Erinnerungen${jahr ? ' · ' + jahr : ''}
|
||||
|
|
@ -1034,7 +1034,7 @@ window.Page_settings = (() => {
|
|||
|
||||
// Alle Stufen als kleine Punkte
|
||||
const dots = (cat.alle_stufen || []).map(s =>
|
||||
`<div title="${_esc(s.name)}" style="width:8px;height:8px;border-radius:50%;
|
||||
`<div title="${UI.escape(s.name)}" style="width:8px;height:8px;border-radius:50%;
|
||||
background:${s.earned ? s.color : 'var(--c-border)'}"></div>`
|
||||
).join('');
|
||||
|
||||
|
|
@ -1046,7 +1046,7 @@ window.Page_settings = (() => {
|
|||
// Fortschrittsbalken
|
||||
const progressBar = nxt ? `
|
||||
<div style="font-size:10px;color:var(--c-text-muted);margin-top:4px">
|
||||
${val}${cat.einheit} / ${nxt.schwelle}${cat.einheit} → ${_esc(nxt.name)}
|
||||
${val}${cat.einheit} / ${nxt.schwelle}${cat.einheit} → ${UI.escape(nxt.name)}
|
||||
</div>
|
||||
<div style="height:4px;background:var(--c-border);border-radius:2px;margin-top:4px;overflow:hidden">
|
||||
<div style="height:100%;width:${cat.progress}%;background:${nxt.color};border-radius:2px;transition:width .4s"></div>
|
||||
|
|
@ -1061,9 +1061,9 @@ window.Page_settings = (() => {
|
|||
${shieldSvg}
|
||||
<div class="flex-1-min">
|
||||
<div style="display:flex;align-items:center;gap:6px;margin-bottom:2px">
|
||||
<span style="font-weight:700;font-size:var(--text-sm)">${_esc(cat.name)}</span>
|
||||
<span style="font-weight:700;font-size:var(--text-sm)">${UI.escape(cat.name)}</span>
|
||||
${cur ? `<span style="font-size:10px;font-weight:600;padding:1px 6px;border-radius:999px;
|
||||
background:${cur.color};color:${cur.text}">${_esc(cur.name)}</span>` : ''}
|
||||
background:${cur.color};color:${cur.text}">${UI.escape(cur.name)}</span>` : ''}
|
||||
</div>
|
||||
<div style="display:flex;gap:4px;margin-bottom:6px">${dots}</div>
|
||||
${progressBar}
|
||||
|
|
@ -1131,7 +1131,7 @@ window.Page_settings = (() => {
|
|||
['trainer', 'Trainer / Ausbilder'],
|
||||
['zuechter', 'Züchter'],
|
||||
].map(([val, label]) =>
|
||||
`<option value="${_esc(val)}" ${u.erfahrung === val ? 'selected' : ''}>${_esc(label)}</option>`
|
||||
`<option value="${UI.escape(val)}" ${u.erfahrung === val ? 'selected' : ''}>${UI.escape(label)}</option>`
|
||||
).join('');
|
||||
|
||||
const sichtbarkeitOpts = [
|
||||
|
|
@ -1139,7 +1139,7 @@ window.Page_settings = (() => {
|
|||
['friends', 'Nur Freunde'],
|
||||
['private', 'Privat'],
|
||||
].map(([val, label]) =>
|
||||
`<option value="${_esc(val)}" ${(u.profil_sichtbarkeit || 'public') === val ? 'selected' : ''}>${_esc(label)}</option>`
|
||||
`<option value="${UI.escape(val)}" ${(u.profil_sichtbarkeit || 'public') === val ? 'selected' : ''}>${UI.escape(label)}</option>`
|
||||
).join('');
|
||||
|
||||
UI.modal.open({
|
||||
|
|
@ -1150,20 +1150,20 @@ window.Page_settings = (() => {
|
|||
<label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Echter Name (privat)</label>
|
||||
<input name="real_name" type="text" maxlength="80"
|
||||
placeholder="z. B. Maria Müller"
|
||||
value="${_esc(u.real_name || '')}"
|
||||
value="${UI.escape(u.real_name || '')}"
|
||||
style="${inputStyle}">
|
||||
</div>
|
||||
<div>
|
||||
<label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Bio</label>
|
||||
<textarea name="bio" maxlength="300" rows="4"
|
||||
placeholder="Kurze Vorstellung (max. 300 Zeichen)"
|
||||
style="${inputStyle};resize:vertical">${_esc(u.bio || '')}</textarea>
|
||||
style="${inputStyle};resize:vertical">${UI.escape(u.bio || '')}</textarea>
|
||||
</div>
|
||||
<div>
|
||||
<label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Wohnort</label>
|
||||
<input name="wohnort" type="text" maxlength="60"
|
||||
placeholder="z.B. München"
|
||||
value="${_esc(u.wohnort || '')}"
|
||||
value="${UI.escape(u.wohnort || '')}"
|
||||
style="${inputStyle}">
|
||||
</div>
|
||||
<div>
|
||||
|
|
@ -1174,7 +1174,7 @@ window.Page_settings = (() => {
|
|||
<label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Social-Link</label>
|
||||
<input name="social_link" type="url" maxlength="120"
|
||||
placeholder="https://instagram.com/dein-hundeaccount"
|
||||
value="${_esc(u.social_link || '')}"
|
||||
value="${UI.escape(u.social_link || '')}"
|
||||
style="${inputStyle}">
|
||||
</div>
|
||||
<div style="border-top:1px solid var(--c-border);padding-top:var(--space-3);margin-top:var(--space-1)">
|
||||
|
|
@ -1182,12 +1182,12 @@ window.Page_settings = (() => {
|
|||
<div style="font-size:var(--text-xs);color:var(--c-text-muted);margin-bottom:var(--space-2)">Wird auf Rechnungen gedruckt. Straße in Zeile 1, PLZ + Ort in Zeile 2.</div>
|
||||
<textarea name="billing_address" rows="2" maxlength="200"
|
||||
placeholder="Musterstraße 1 12345 Berlin"
|
||||
style="${inputStyle};resize:vertical;font-family:inherit">${_esc(u.billing_address || '')}</textarea>
|
||||
style="${inputStyle};resize:vertical;font-family:inherit">${UI.escape(u.billing_address || '')}</textarea>
|
||||
</div>
|
||||
<div>
|
||||
<label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Dein Geburtstag <span style="font-weight:400;color:var(--c-text-secondary)">(optional)</span></label>
|
||||
<input name="geburtstag" type="text" maxlength="5" placeholder="TT.MM"
|
||||
value="${_esc(u.geburtstag || '')}"
|
||||
value="${UI.escape(u.geburtstag || '')}"
|
||||
pattern="\\d{2}\\.\\d{2}"
|
||||
title="Format: TT.MM, z.B. 16.05"
|
||||
style="${inputStyle}">
|
||||
|
|
@ -1525,8 +1525,8 @@ window.Page_settings = (() => {
|
|||
return `
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;
|
||||
padding:var(--space-2) 0;font-size:var(--text-sm)">
|
||||
<span>${_esc(label)}</span>
|
||||
<button class="by-toggle ki-toggle-btn" data-key="${_esc(key)}"
|
||||
<span>${UI.escape(label)}</span>
|
||||
<button class="by-toggle ki-toggle-btn" data-key="${UI.escape(key)}"
|
||||
data-active="${active ? '1' : '0'}"
|
||||
style="position:relative;display:inline-block;width:44px;height:24px;
|
||||
border:none;border-radius:12px;cursor:pointer;flex-shrink:0;
|
||||
|
|
@ -1572,8 +1572,8 @@ window.Page_settings = (() => {
|
|||
</span>`;
|
||||
actionBlock = `
|
||||
<div style="margin-top:var(--space-3);font-size:var(--text-sm);display:flex;flex-direction:column;gap:var(--space-1)">
|
||||
${profile?.zwingername ? `<div class="text-secondary">Zwinger: <strong>${_esc(profile.zwingername)}</strong></div>` : ''}
|
||||
${profile?.rasse_text ? `<div class="text-secondary">Rasse: <strong>${_esc(profile.rasse_text)}</strong></div>` : ''}
|
||||
${profile?.zwingername ? `<div class="text-secondary">Zwinger: <strong>${UI.escape(profile.zwingername)}</strong></div>` : ''}
|
||||
${profile?.rasse_text ? `<div class="text-secondary">Rasse: <strong>${UI.escape(profile.rasse_text)}</strong></div>` : ''}
|
||||
</div>
|
||||
${rolle === 'breeder' && profile ? `
|
||||
<button class="btn btn-secondary btn-sm" id="breeder-edit-profile-btn" class="mt-3">
|
||||
|
|
@ -1700,22 +1700,22 @@ window.Page_settings = (() => {
|
|||
<div>
|
||||
<label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Zwingername</label>
|
||||
<input name="zwingername" type="text" maxlength="100" style="${inputStyle}"
|
||||
value="${_esc(profile?.zwingername || '')}">
|
||||
value="${UI.escape(profile?.zwingername || '')}">
|
||||
</div>
|
||||
<div>
|
||||
<label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Rasse</label>
|
||||
<input name="rasse_text" type="text" maxlength="100" style="${inputStyle}"
|
||||
value="${_esc(profile?.rasse_text || '')}">
|
||||
value="${UI.escape(profile?.rasse_text || '')}">
|
||||
</div>
|
||||
<div>
|
||||
<label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Zuchtverein</label>
|
||||
<input name="verein" type="text" maxlength="100" style="${inputStyle}"
|
||||
value="${_esc(profile?.verein || '')}">
|
||||
value="${UI.escape(profile?.verein || '')}">
|
||||
</div>
|
||||
<div>
|
||||
<label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Stadt</label>
|
||||
<input name="stadt" type="text" maxlength="80" style="${inputStyle}"
|
||||
value="${_esc(profile?.stadt || '')}">
|
||||
value="${UI.escape(profile?.stadt || '')}">
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;gap:var(--space-3)">
|
||||
<input name="vdh_mitglied" type="checkbox" id="edit-breeder-vdh"
|
||||
|
|
@ -1726,12 +1726,12 @@ window.Page_settings = (() => {
|
|||
<div>
|
||||
<label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Website (optional)</label>
|
||||
<input name="website" type="url" maxlength="200" style="${inputStyle}"
|
||||
value="${_esc(profile?.website || '')}" placeholder="https://mein-zwinger.de">
|
||||
value="${UI.escape(profile?.website || '')}" placeholder="https://mein-zwinger.de">
|
||||
</div>
|
||||
<div>
|
||||
<label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Beschreibung (optional)</label>
|
||||
<textarea name="beschreibung" maxlength="500" rows="3"
|
||||
style="${inputStyle};resize:vertical">${_esc(profile?.beschreibung || '')}</textarea>
|
||||
style="${inputStyle};resize:vertical">${UI.escape(profile?.beschreibung || '')}</textarea>
|
||||
</div>
|
||||
</form>`,
|
||||
footer: `
|
||||
|
|
@ -1969,7 +1969,7 @@ window.Page_settings = (() => {
|
|||
// GEDENKSEITE — für verstorbene Hunde
|
||||
// ----------------------------------------------------------
|
||||
async function _openGedenkseite(dogId, dogName) {
|
||||
UI.modal.open({ title: `Erinnerungen an ${_esc(dogName)}`, body: `
|
||||
UI.modal.open({ title: `Erinnerungen an ${UI.escape(dogName)}`, body: `
|
||||
<div style="text-align:center;padding:var(--space-4)">
|
||||
<svg class="ph-icon" style="width:32px;height:32px;color:var(--c-primary);animation:spin 1s linear infinite" aria-hidden="true">
|
||||
<use href="/icons/phosphor.svg#spinner"></use>
|
||||
|
|
@ -1982,12 +1982,12 @@ window.Page_settings = (() => {
|
|||
|
||||
const d = data;
|
||||
const av = d.dog.foto_url
|
||||
? `<img src="${_esc(d.dog.foto_url)}" style="width:100px;height:100px;border-radius:50%;object-fit:cover;border:3px solid var(--c-primary)">`
|
||||
? `<img src="${UI.escape(d.dog.foto_url)}" style="width:100px;height:100px;border-radius:50%;object-fit:cover;border:3px solid var(--c-primary)">`
|
||||
: `<div style="width:100px;height:100px;border-radius:50%;background:var(--c-primary-subtle);display:flex;align-items:center;justify-content:center;border:3px solid var(--c-primary)"><svg class="ph-icon" style="width:48px;height:48px;color:var(--c-primary)" aria-hidden="true"><use href="/icons/phosphor.svg#dog"></use></svg></div>`;
|
||||
|
||||
const photoGrid = d.photos?.length ? `
|
||||
<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:4px;margin:var(--space-4) 0">
|
||||
${d.photos.map(url => `<img src="${_esc(url)}" style="width:100%;aspect-ratio:1;object-fit:cover;border-radius:6px">`).join('')}
|
||||
${d.photos.map(url => `<img src="${UI.escape(url)}" style="width:100%;aspect-ratio:1;object-fit:cover;border-radius:6px">`).join('')}
|
||||
</div>` : '';
|
||||
|
||||
const statsHtml = `
|
||||
|
|
@ -2012,11 +2012,11 @@ window.Page_settings = (() => {
|
|||
: '';
|
||||
|
||||
UI.modal.open({
|
||||
title: `Erinnerungen an ${_esc(d.dog.name)}`,
|
||||
title: `Erinnerungen an ${UI.escape(d.dog.name)}`,
|
||||
body: `
|
||||
<div style="text-align:center;margin-bottom:var(--space-4)">
|
||||
${av}
|
||||
<div style="margin-top:var(--space-3);font-size:var(--text-lg);font-weight:700">${_esc(d.dog.name)}</div>
|
||||
<div style="margin-top:var(--space-3);font-size:var(--text-lg);font-weight:700">${UI.escape(d.dog.name)}</div>
|
||||
${passedStr ? `<div style="font-size:var(--text-sm);color:var(--c-text-muted);margin-top:4px">
|
||||
<svg class="ph-icon" style="width:14px;height:14px" aria-hidden="true"><use href="/icons/phosphor.svg#heart-break"></use></svg>
|
||||
${passedStr}
|
||||
|
|
@ -2033,7 +2033,7 @@ window.Page_settings = (() => {
|
|||
${d.ki_abschied ? `<div style="font-style:italic;font-size:var(--text-sm);color:var(--c-text-secondary);
|
||||
line-height:1.7;padding:var(--space-3);background:var(--c-surface);
|
||||
border-radius:var(--radius-md);border:1px solid var(--c-border)">
|
||||
"${_esc(d.ki_abschied)}"
|
||||
"${UI.escape(d.ki_abschied)}"
|
||||
</div>` : ''}
|
||||
`,
|
||||
});
|
||||
|
|
@ -2591,11 +2591,6 @@ window.Page_settings = (() => {
|
|||
// ----------------------------------------------------------
|
||||
// HELPER
|
||||
// ----------------------------------------------------------
|
||||
function _esc(str) {
|
||||
if (!str) return '';
|
||||
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
|
||||
.replace(/"/g, '"');
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// PUBLIC
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue