From 632f348349a208a2ec2f39ab3cf8d776120ea38f Mon Sep 17 00:00:00 2001 From: xRangerDE Date: Mon, 11 May 2026 08:17:05 +0200 Subject: [PATCH] a11y: aria-hidden on the 6 decorative SVG icons rendered from TS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Continuing the SVG aria-hidden pass from 4.6.110 (which covered index.html). The renderer modules build six more decorative SVG icons into their template strings: - renderer-profile.ts: followers icon, vods icon, last-stream clock, live-viewers eye - renderer-queue.ts: merge-group icon next to merge-bundled queue rows - renderer-streamers.ts: empty-state VOD icon shown when a streamer has no VODs All 6 are pure decoration — each sits next to a textual label or value (e.g. "1.2K followers", "5 VODs", a viewer count, etc.). Screen readers were either announcing them as "image/graphic" or silently traversing — adding aria-hidden="true" cleanly skips them so the assistive-tech read-out is just the meaningful text. The data-URL SVG fallback in renderer-streamers.ts:257 (used as an onerror src for VOD thumbnails) is intentionally not touched — it's an image fallback inside a URL-encoded string, not an actual SVG element in the DOM. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/renderer-profile.ts | 8 ++++---- src/renderer-queue.ts | 2 +- src/renderer-streamers.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/renderer-profile.ts b/src/renderer-profile.ts index 940beb2..8faaf75 100644 --- a/src/renderer-profile.ts +++ b/src/renderer-profile.ts @@ -96,17 +96,17 @@ function renderStreamerProfileCard(p: StreamerProfile): void { const followersStat = `
- + ${escapeProfileHtml(formatProfileFollowers(p.followerCount))} ${escapeProfileHtml(UI_TEXT.profile.followers)}
`; const vodsStat = `
- + ${p.vodCount} ${escapeProfileHtml(UI_TEXT.profile.vods)}
`; const lastStreamStat = `
- + ${escapeProfileHtml(UI_TEXT.profile.lastStream)}: ${escapeProfileHtml(formatLastStreamAgo(p.lastStreamAt))}
`; @@ -128,7 +128,7 @@ function renderStreamerProfileCard(p: StreamerProfile): void {
${escapeProfileHtml(UI_TEXT.profile.liveBadge)} - ${typeof p.currentStreamViewers === 'number' ? ` ${escapeProfileHtml(formatProfileFollowers(p.currentStreamViewers))}` : ''} + ${typeof p.currentStreamViewers === 'number' ? ` ${escapeProfileHtml(formatProfileFollowers(p.currentStreamViewers))}` : ''}
${p.currentTitle ? `
${escapeProfileHtml(p.currentTitle)}
` : ''} ${p.currentGame ? `
${escapeProfileHtml(p.currentGame)}
` : ''} diff --git a/src/renderer-queue.ts b/src/renderer-queue.ts index 2493e0b..14cac13 100644 --- a/src/renderer-queue.ts +++ b/src/renderer-queue.ts @@ -536,7 +536,7 @@ function renderQueue(): void { const selectionIndex = selectedQueueIds.indexOf(item.id); const isSelected = selectionIndex >= 0; const mergeIcon = isMergeGroup - ? ' ' + ? ' ' : ''; const liveBadge = item.isLive ? `REC ` diff --git a/src/renderer-streamers.ts b/src/renderer-streamers.ts index 4e56619..2eca46c 100644 --- a/src/renderer-streamers.ts +++ b/src/renderer-streamers.ts @@ -725,7 +725,7 @@ async function removeStreamer(name: string): Promise { if (typeof hide === 'function') hide(); byId('vodGrid').innerHTML = `
- +

${UI_TEXT.vods.noneTitle}

${UI_TEXT.vods.noneText}