From a9b2f2dea0e80d48592e362a22250b45730c9b64 Mon Sep 17 00:00:00 2001 From: jmclaus Date: Sun, 29 Sep 2013 01:50:34 +0200 Subject: [PATCH] Volume slider announces its name and value to screen readers --- .../xmodule/xmodule/css/video/display.scss | 1 + .../xmodule/js/src/video/04_video_control.js | 3 ++ .../js/src/video/07_video_volume_control.js | 50 +++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/common/lib/xmodule/xmodule/css/video/display.scss b/common/lib/xmodule/xmodule/css/video/display.scss index c087d18098..a0b514ab0f 100644 --- a/common/lib/xmodule/xmodule/css/video/display.scss +++ b/common/lib/xmodule/xmodule/css/video/display.scss @@ -109,6 +109,7 @@ div.video { -webkit-transition: -webkit-transform 0.7s ease-in-out; -moz-transition: -moz-transform 0.7s ease-in-out; -ms-transition: -ms-transform 0.7s ease-in-out; + tabindex: -1; transition: transform 0.7s ease-in-out; @include transform(scaleY(0.5) translate3d(0, 50%, 0)); diff --git a/common/lib/xmodule/xmodule/js/src/video/04_video_control.js b/common/lib/xmodule/xmodule/js/src/video/04_video_control.js index f31ed1caee..5272a3fb64 100644 --- a/common/lib/xmodule/xmodule/js/src/video/04_video_control.js +++ b/common/lib/xmodule/xmodule/js/src/video/04_video_control.js @@ -70,10 +70,13 @@ function () { // these anchors behaves like buttons state.videoControl.playPauseEl.attr('role', gettext('button')); state.videoControl.fullScreenEl.attr('role', gettext('button')); + // and this one as a slider + state.videoControl.sliderEl.find('.ui-slider-handle').attr('role', gettext('slider')); // what their names are: (title attribute are set in video.html template): // Play, Pause // Fill browser + state.videoControl.sliderEl.find('.ui-slider-handle').attr('title', gettext('video slider')); // what their states are: state.videoControl.playPauseEl.attr('aria-disabled', 'false'); diff --git a/common/lib/xmodule/xmodule/js/src/video/07_video_volume_control.js b/common/lib/xmodule/xmodule/js/src/video/07_video_volume_control.js index 9eda8eade7..d7116f24dc 100644 --- a/common/lib/xmodule/xmodule/js/src/video/07_video_volume_control.js +++ b/common/lib/xmodule/xmodule/js/src/video/07_video_volume_control.js @@ -74,6 +74,18 @@ function () { // what its state is: state.videoVolumeControl.buttonEl.attr('aria-disabled', 'false'); + + // Volume slider + state.videoVolumeControl.volumeSliderHandleEl = state.videoVolumeControl.volumeSliderEl.find('.ui-slider-handle'); + state.videoVolumeControl.volumeSliderHandleEl.attr({ + 'role': gettext('slider'), + 'title': 'volume', + 'aria-disabled': 'false', + 'aria-valuetext': getVolumeDescription(state.videoVolumeControl.slider.slider('option', 'value')), + 'aria-valuenow': state.videoVolumeControl.slider.slider('option', 'value'), + 'aria-valuemin': state.videoVolumeControl.slider.slider('option', 'min'), + 'aria-valuemax': state.videoVolumeControl.slider.slider('option', 'max') + }); } /** @@ -159,6 +171,9 @@ function () { }); this.trigger('videoPlayer.onVolumeChange', ui.value); + // ARIA + this.videoVolumeControl.volumeSliderHandleEl.attr('aria-valuenow', ui.value); + this.videoVolumeControl.volumeSliderHandleEl.attr('aria-valuetext', getVolumeDescription(ui.value)); } function toggleMute(event) { @@ -167,8 +182,43 @@ function () { if (this.videoVolumeControl.currentVolume > 0) { this.videoVolumeControl.previousVolume = this.videoVolumeControl.currentVolume; this.videoVolumeControl.slider.slider('option', 'value', 0); + // ARIA + state.videoVolumeControl.volumeSliderHandleEl.attr({ + 'aria-valuetext': getVolumeDescription(0), + 'aria-valuenow': 0 + }); } else { this.videoVolumeControl.slider.slider('option', 'value', this.videoVolumeControl.previousVolume); + // ARIA + state.videoVolumeControl.volumeSliderHandleEl.attr({ + 'aria-valuetext': getVolumeDescription(this.videoVolumeControl.previousVolume), + 'aria-valuenow': this.videoVolumeControl.previousVolume + }); + } + } + + // ARIA + function getVolumeDescription(vol) { + if (vol === 0) { + return 'silent'; + } + else if (vol <= 20) { + return 'very low'; + } + else if (vol <= 40) { + return 'low'; + } + else if (vol <= 60) { + return 'average'; + } + else if (vol <= 80) { + return 'loud'; + } + else if (vol <= 99) { + return 'very loud'; + } + else { + return 'maximum'; } }