From 4e1b004357500f22d9284f6e602ceca68fa63678 Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Thu, 15 Jan 2026 18:32:56 -0600 Subject: [PATCH 1/2] js: Always set ARIA attributes on time scrubber This is a backport of https://github.com/mediaelement/mediaelement/pull/2986, which is described in https://github.com/mediaelement/mediaelement/issues/2908. Co-authored-by: Raphael Krusenbaum Ref: ADA-667 --- .../javascripts/mediaelement-and-player.js | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/app/assets/javascripts/mediaelement-and-player.js b/app/assets/javascripts/mediaelement-and-player.js index 292768f..d895af0 100644 --- a/app/assets/javascripts/mediaelement-and-player.js +++ b/app/assets/javascripts/mediaelement-and-player.js @@ -1896,19 +1896,11 @@ Object.assign(_player2.default.prototype, { t.slider.setAttribute('role', 'slider'); t.slider.tabIndex = 0; - if (media.paused) { - t.slider.setAttribute('aria-label', timeSliderText); - t.slider.setAttribute('aria-valuemin', 0); - t.slider.setAttribute('aria-valuemax', isNaN(duration) ? 0 : duration); - t.slider.setAttribute('aria-valuenow', seconds); - t.slider.setAttribute('aria-valuetext', time); - } else { - t.slider.removeAttribute('aria-label'); - t.slider.removeAttribute('aria-valuemin'); - t.slider.removeAttribute('aria-valuemax'); - t.slider.removeAttribute('aria-valuenow'); - t.slider.removeAttribute('aria-valuetext'); - } + t.slider.setAttribute('aria-label', timeSliderText); + t.slider.setAttribute('aria-valuemin', 0); + t.slider.setAttribute('aria-valuemax', isNaN(duration) ? 0 : duration); + t.slider.setAttribute('aria-valuenow', seconds); + t.slider.setAttribute('aria-valuetext', time); }, restartPlayer = function restartPlayer() { if (new Date() - lastKeyPressTime >= 1000) { From 87c478781aa7c6e796a10d225f08b83b79ed77a6 Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Thu, 15 Jan 2026 19:27:51 -0600 Subject: [PATCH 2/2] js: Add volume status element to volume slider This fixes https://github.com/mediaelement/mediaelement/issues/2950 and https://github.com/mediaelement/mediaelement/issues/2976, and is a full backport of https://github.com/mediaelement/mediaelement/pull/2988. Co-authored-by: Raphael Krusenbaum Ref: ADA-667 --- app/assets/javascripts/mediaelement-and-player.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/mediaelement-and-player.js b/app/assets/javascripts/mediaelement-and-player.js index d895af0..2bfc53c 100644 --- a/app/assets/javascripts/mediaelement-and-player.js +++ b/app/assets/javascripts/mediaelement-and-player.js @@ -3037,7 +3037,7 @@ Object.assign(_player2.default.prototype, { mute = _document2.default.createElement('div'); mute.className = t.options.classPrefix + 'button ' + t.options.classPrefix + 'volume-button ' + t.options.classPrefix + 'mute'; - mute.innerHTML = mode === 'horizontal' ? (0, _generate.generateControlButton)(t.id, muteText, muteText, '' + t.media.options.iconSprite, ['icon-mute', 'icon-unmute'], '' + t.options.classPrefix, '', t.options.classPrefix + 'horizontal-volume-slider') : (0, _generate.generateControlButton)(t.id, muteText, muteText, '' + t.media.options.iconSprite, ['icon-mute', 'icon-unmute'], '' + t.options.classPrefix, '', t.options.classPrefix + 'volume-slider') + ('' + ('' + volumeControlText + '') + ('
') + ('
') + ('
') + '
' + '
'; + mute.innerHTML = mode === 'horizontal' ? (0, _generate.generateControlButton)(t.id, muteText, muteText, '' + t.media.options.iconSprite, ['icon-mute', 'icon-unmute'], '' + t.options.classPrefix, '', t.id + '_volume-slider') : (0, _generate.generateControlButton)(t.id, muteText, muteText, '' + t.media.options.iconSprite, ['icon-mute', 'icon-unmute'], '' + t.options.classPrefix, '', t.id + '_volume-slider') + ('' + ('' + volumeControlText + '') + ('
') + ('
') + ('
') + '
' + '
' + ('') + ''; t.addControlElement(mute, 'volume'); @@ -3115,9 +3115,14 @@ Object.assign(_player2.default.prototype, { mouseIsOver = false, modified = false, updateVolumeSlider = function updateVolumeSlider() { - var volume = Math.floor(media.volume * 100); + const volume = Math.floor(media.volume * 100); volumeSlider.setAttribute('aria-valuenow', volume); volumeSlider.setAttribute('aria-valuetext', volume + '%'); + + const statusRegion = mute.querySelector('.' + t.options.classPrefix + 'volume-status'); + if (statusRegion) { + statusRegion.innerHTML = 'Volume ' + volume + '%'; + } }; var volumeSlider = mode === 'vertical' ? t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'volume-slider') : t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'horizontal-volume-slider'), @@ -3228,6 +3233,7 @@ Object.assign(_player2.default.prototype, { mute.addEventListener('focusin', function () { volumeSlider.style.display = 'block'; mouseIsOver = true; + setTimeout(updateVolumeSlider, 0); }); mute.addEventListener('focusout', function (e) {