a11y: 14 more labels linked to their inputs via for=

Continuing the label-for pass from 4.6.79 + 4.6.83. The Settings tab, Twitch-API card, Discord card, Clips template guide, and the main cutter time-input row all had label elements sitting right next to their inputs/selects with no programmatic for=/id pairing — screen readers couldn't announce the label on focus, and clicking the label text didn't focus the control.

Fixed labels (label-id → target-input-id):
- themeLabel → themeSelect
- clientIdLabel → clientId
- clientSecretLabel → clientSecret
- storageLabel → downloadPath
- modeLabel → downloadMode
- partMinutesLabel → partMinutes
- parallelDownloadsLabel → parallelDownloads
- streamlinkQualityLabel → streamlinkQuality
- performanceModeLabel → performanceMode
- metadataCacheMinutesLabel → metadataCacheMinutes
- discordWebhookUrlLabel → discordWebhookUrl
- templateGuideTemplateLabel → templateGuideInput
- cutterStartLabel → startTime
- cutterEndLabel → endTime

Together with the prior passes (clip-cutter modal labels in 4.6.79, filename-template labels in 4.6.83), every plain label-above-input pair in static HTML now uses for=. Remaining unattached labels (languageLabel, vodHideDownloadedLabel) are intentional — the first targets a custom button-pair language picker, the second wraps its own checkbox via .inline-toggle.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
xRangerDE 2026-05-11 06:43:01 +02:00
parent 5c0378582e
commit 6946c34395

View File

@ -149,7 +149,7 @@
<button class="btn-secondary" id="templateGuideUseClip" onclick="setTemplateGuidePreset('clip')">Clip Template</button> <button class="btn-secondary" id="templateGuideUseClip" onclick="setTemplateGuidePreset('clip')">Clip Template</button>
</div> </div>
<label id="templateGuideTemplateLabel" class="template-guide-label">Template</label> <label id="templateGuideTemplateLabel" for="templateGuideInput" class="template-guide-label">Template</label>
<input type="text" id="templateGuideInput" class="template-guide-input" oninput="updateTemplateGuidePreview()" placeholder="{title}.mp4"> <input type="text" id="templateGuideInput" class="template-guide-input" oninput="updateTemplateGuidePreview()" placeholder="{title}.mp4">
<div class="template-guide-preview-box"> <div class="template-guide-preview-box">
@ -361,11 +361,11 @@
<div class="time-inputs"> <div class="time-inputs">
<div class="time-input-group"> <div class="time-input-group">
<label id="cutterStartLabel">Start:</label> <label id="cutterStartLabel" for="startTime">Start:</label>
<input type="text" id="startTime" value="00:00:00" onchange="updateTimeFromInput()"> <input type="text" id="startTime" value="00:00:00" onchange="updateTimeFromInput()">
</div> </div>
<div class="time-input-group"> <div class="time-input-group">
<label id="cutterEndLabel">Ende:</label> <label id="cutterEndLabel" for="endTime">Ende:</label>
<input type="text" id="endTime" value="00:00:00" onchange="updateTimeFromInput()"> <input type="text" id="endTime" value="00:00:00" onchange="updateTimeFromInput()">
</div> </div>
</div> </div>
@ -486,7 +486,7 @@
<div class="settings-card"> <div class="settings-card">
<h3 id="designTitle">Design</h3> <h3 id="designTitle">Design</h3>
<div class="form-group"> <div class="form-group">
<label id="themeLabel">Theme</label> <label id="themeLabel" for="themeSelect">Theme</label>
<select id="themeSelect" onchange="changeTheme(this.value)"> <select id="themeSelect" onchange="changeTheme(this.value)">
<option value="twitch">Twitch</option> <option value="twitch">Twitch</option>
<option value="discord">Discord</option> <option value="discord">Discord</option>
@ -521,11 +521,11 @@
<a href="#" id="apiHelpLink" onclick="event.preventDefault(); openTwitchDevConsole()" style="color: var(--accent); text-decoration: underline; cursor: pointer;">dev.twitch.tv/console/apps</a> <a href="#" id="apiHelpLink" onclick="event.preventDefault(); openTwitchDevConsole()" style="color: var(--accent); text-decoration: underline; cursor: pointer;">dev.twitch.tv/console/apps</a>
</p> </p>
<div class="form-group"> <div class="form-group">
<label id="clientIdLabel">Client ID</label> <label id="clientIdLabel" for="clientId">Client ID</label>
<input type="text" id="clientId" placeholder="Twitch Client ID"> <input type="text" id="clientId" placeholder="Twitch Client ID">
</div> </div>
<div class="form-group"> <div class="form-group">
<label id="clientSecretLabel">Client Secret</label> <label id="clientSecretLabel" for="clientSecret">Client Secret</label>
<input type="password" id="clientSecret" placeholder="Twitch Client Secret"> <input type="password" id="clientSecret" placeholder="Twitch Client Secret">
</div> </div>
<button class="btn-primary" id="saveSettingsBtn" onclick="saveSettings()">Speichern & Verbinden</button> <button class="btn-primary" id="saveSettingsBtn" onclick="saveSettings()">Speichern & Verbinden</button>
@ -534,7 +534,7 @@
<div class="settings-card"> <div class="settings-card">
<h3 id="downloadSettingsTitle">Download-Einstellungen</h3> <h3 id="downloadSettingsTitle">Download-Einstellungen</h3>
<div class="form-group"> <div class="form-group">
<label id="storageLabel">Speicherort</label> <label id="storageLabel" for="downloadPath">Speicherort</label>
<div class="form-row"> <div class="form-row">
<input type="text" id="downloadPath" readonly> <input type="text" id="downloadPath" readonly>
<button class="btn-secondary" onclick="selectFolder()">Ordner</button> <button class="btn-secondary" onclick="selectFolder()">Ordner</button>
@ -542,25 +542,25 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label id="modeLabel">Download-Modus</label> <label id="modeLabel" for="downloadMode">Download-Modus</label>
<select id="downloadMode"> <select id="downloadMode">
<option value="full" id="modeFullText">Ganzes VOD</option> <option value="full" id="modeFullText">Ganzes VOD</option>
<option value="parts" id="modePartsText">In Teile splitten</option> <option value="parts" id="modePartsText">In Teile splitten</option>
</select> </select>
</div> </div>
<div class="form-group"> <div class="form-group">
<label id="partMinutesLabel">Teil-Lange (Minuten)</label> <label id="partMinutesLabel" for="partMinutes">Teil-Lange (Minuten)</label>
<input type="number" id="partMinutes" value="120" min="10" max="480"> <input type="number" id="partMinutes" value="120" min="10" max="480">
</div> </div>
<div class="form-group"> <div class="form-group">
<label id="parallelDownloadsLabel">Parallele Downloads</label> <label id="parallelDownloadsLabel" for="parallelDownloads">Parallele Downloads</label>
<select id="parallelDownloads"> <select id="parallelDownloads">
<option value="1" id="parallelDownloads1">1 (Standard)</option> <option value="1" id="parallelDownloads1">1 (Standard)</option>
<option value="2" id="parallelDownloads2">2 (Parallel)</option> <option value="2" id="parallelDownloads2">2 (Parallel)</option>
</select> </select>
</div> </div>
<div class="form-group"> <div class="form-group">
<label id="streamlinkQualityLabel">Stream-Qualitaet</label> <label id="streamlinkQualityLabel" for="streamlinkQuality">Stream-Qualitaet</label>
<select id="streamlinkQuality"> <select id="streamlinkQuality">
<option value="best" id="streamlinkQualityBest">Best (Standard)</option> <option value="best" id="streamlinkQualityBest">Best (Standard)</option>
<option value="source" id="streamlinkQualitySource">Source (Original)</option> <option value="source" id="streamlinkQualitySource">Source (Original)</option>
@ -572,7 +572,7 @@
</select> </select>
</div> </div>
<div class="form-group"> <div class="form-group">
<label id="performanceModeLabel">Performance-Profil</label> <label id="performanceModeLabel" for="performanceMode">Performance-Profil</label>
<select id="performanceMode"> <select id="performanceMode">
<option value="stability" id="performanceModeStability">Max Stabilitat</option> <option value="stability" id="performanceModeStability">Max Stabilitat</option>
<option value="balanced" id="performanceModeBalanced">Ausgewogen</option> <option value="balanced" id="performanceModeBalanced">Ausgewogen</option>
@ -630,7 +630,7 @@
</label> </label>
</div> </div>
<div class="form-group"> <div class="form-group">
<label id="metadataCacheMinutesLabel">Metadata-Cache (Minuten)</label> <label id="metadataCacheMinutesLabel" for="metadataCacheMinutes">Metadata-Cache (Minuten)</label>
<input type="number" id="metadataCacheMinutes" value="10" min="1" max="120"> <input type="number" id="metadataCacheMinutes" value="10" min="1" max="120">
</div> </div>
<div class="form-group"> <div class="form-group">
@ -736,7 +736,7 @@
<h3 id="discordCardTitle">Discord-Webhook</h3> <h3 id="discordCardTitle">Discord-Webhook</h3>
<p id="discordCardIntro" class="card-intro">Sende Benachrichtigungen an einen Discord-Channel via Webhook — nuetzlich fuer Multi-Device-Setups oder eine dedizierte Archiv-Maschine.</p> <p id="discordCardIntro" class="card-intro">Sende Benachrichtigungen an einen Discord-Channel via Webhook — nuetzlich fuer Multi-Device-Setups oder eine dedizierte Archiv-Maschine.</p>
<div class="form-group"> <div class="form-group">
<label id="discordWebhookUrlLabel">Webhook-URL</label> <label id="discordWebhookUrlLabel" for="discordWebhookUrl">Webhook-URL</label>
<input type="text" id="discordWebhookUrl" placeholder="https://discord.com/api/webhooks/..."> <input type="text" id="discordWebhookUrl" placeholder="https://discord.com/api/webhooks/...">
</div> </div>
<div class="form-group"> <div class="form-group">