From 5380b5cfc35d05d80d99c9d11bec17a37e250c4b Mon Sep 17 00:00:00 2001 From: Valera Rozuvan Date: Thu, 8 Aug 2013 13:36:13 +0300 Subject: [PATCH] Making it possible to tab through individual speeds. In speed control, when it is focused, a drop down becomes available which contains all of the available speeds that the player can switch to. When using the Tab button to tab through all of the controls, it should be possible to select individual speed with the keyboard. --- .../videoalpha/video_volume_control_spec.js | 1 - .../src/videoalpha/08_video_speed_control.js | 71 +++++++++++++------ 2 files changed, 49 insertions(+), 23 deletions(-) diff --git a/common/lib/xmodule/xmodule/js/spec/videoalpha/video_volume_control_spec.js b/common/lib/xmodule/xmodule/js/spec/videoalpha/video_volume_control_spec.js index f7f6c6c583..872b1fe18e 100644 --- a/common/lib/xmodule/xmodule/js/spec/videoalpha/video_volume_control_spec.js +++ b/common/lib/xmodule/xmodule/js/spec/videoalpha/video_volume_control_spec.js @@ -39,7 +39,6 @@ range: "min", min: 0, max: 100, - /* value: 100, */ value: videoVolumeControl.currentVolume, change: videoVolumeControl.onChange, slide: videoVolumeControl.onChange diff --git a/common/lib/xmodule/xmodule/js/src/videoalpha/08_video_speed_control.js b/common/lib/xmodule/xmodule/js/src/videoalpha/08_video_speed_control.js index c54c65fc59..b0f55d49a1 100644 --- a/common/lib/xmodule/xmodule/js/src/videoalpha/08_video_speed_control.js +++ b/common/lib/xmodule/xmodule/js/src/videoalpha/08_video_speed_control.js @@ -21,34 +21,41 @@ function () { // function _makeFunctionsPublic(state) // - // Functions which will be accessible via 'state' object. When called, these functions will - // get the 'state' object as a context. + // Functions which will be accessible via 'state' object. When called, + // these functions will get the 'state' object as a context. function _makeFunctionsPublic(state) { - state.videoSpeedControl.changeVideoSpeed = _.bind(changeVideoSpeed, state); + state.videoSpeedControl.changeVideoSpeed = _.bind( + changeVideoSpeed, state + ); state.videoSpeedControl.setSpeed = _.bind(setSpeed, state); state.videoSpeedControl.reRender = _.bind(reRender, state); } // function _renderElements(state) // - // Create any necessary DOM elements, attach them, and set their initial configuration. Also - // make the created DOM elements available via the 'state' object. Much easier to work this - // way - you don't have to do repeated jQuery element selects. + // Create any necessary DOM elements, attach them, and set their + // initial configuration. Also make the created DOM elements available + // via the 'state' object. Much easier to work this way - you don't + // have to do repeated jQuery element selects. function _renderElements(state) { state.videoSpeedControl.speeds = state.speeds; state.videoSpeedControl.el = state.el.find('div.speeds'); - state.videoSpeedControl.videoSpeedsEl = state.videoSpeedControl.el.find('.video_speeds'); + state.videoSpeedControl.videoSpeedsEl = state.videoSpeedControl.el + .find('.video_speeds'); - state.videoControl.secondaryControlsEl.prepend(state.videoSpeedControl.el); + state.videoControl.secondaryControlsEl.prepend( + state.videoSpeedControl.el + ); $.each(state.videoSpeedControl.speeds, function(index, speed) { + var link = '' + speed + 'x'; - //var link = $('' + speed + 'x'); - var link = '' + speed + 'x'; - - state.videoSpeedControl.videoSpeedsEl.prepend($('
  • ' + link + '
  • ')); + state.videoSpeedControl.videoSpeedsEl + .prepend( + $('
  • ' + link + '
  • ') + ); }); state.videoSpeedControl.setSpeed(state.speed); @@ -56,9 +63,11 @@ function () { // function _bindHandlers(state) // - // Bind any necessary function callbacks to DOM events (click, mousemove, etc.). + // Bind any necessary function callbacks to DOM events (click, + // mousemove, etc.). function _bindHandlers(state) { - state.videoSpeedControl.videoSpeedsEl.find('a').on('click', state.videoSpeedControl.changeVideoSpeed); + state.videoSpeedControl.videoSpeedsEl.find('a') + .on('click', state.videoSpeedControl.changeVideoSpeed); if (onTouchBasedDevice()) { state.videoSpeedControl.el.on('click', function(event) { @@ -83,20 +92,30 @@ function () { $(this).parent().addClass('open'); }) .on('blur', function () { - $(this).parent().removeClass('open'); + state.videoSpeedControl.videoSpeedsEl + .find('a.speed_link:first') + .focus(); + }); + + state.videoSpeedControl.videoSpeedsEl.find('a.speed_link:last') + .on('blur', function () { + state.videoSpeedControl.el.removeClass('open'); }); } } // *************************************************************** // Public functions start here. - // These are available via the 'state' object. Their context ('this' keyword) is the 'state' object. - // The magic private function that makes them available and sets up their context is makeFunctionsPublic(). + // These are available via the 'state' object. Their context ('this' + // keyword) is the 'state' object. The magic private function that makes + // them available and sets up their context is makeFunctionsPublic(). // *************************************************************** function setSpeed(speed) { this.videoSpeedControl.videoSpeedsEl.find('li').removeClass('active'); - this.videoSpeedControl.videoSpeedsEl.find("li[data-speed='" + speed + "']").addClass('active'); + this.videoSpeedControl.videoSpeedsEl + .find("li[data-speed='" + speed + "']") + .addClass('active'); this.videoSpeedControl.el.find('p.active').html('' + speed + 'x'); } @@ -110,10 +129,15 @@ function () { this.videoSpeedControl.setSpeed( // To meet the API expected format. - parseFloat(this.videoSpeedControl.currentSpeed).toFixed(2).replace(/\.00$/, '.0') + parseFloat(this.videoSpeedControl.currentSpeed) + .toFixed(2) + .replace(/\.00$/, '.0') ); - this.trigger('videoPlayer.onSpeedChange', this.videoSpeedControl.currentSpeed); + this.trigger( + 'videoPlayer.onSpeedChange', + this.videoSpeedControl.currentSpeed + ); } } @@ -127,7 +151,6 @@ function () { $.each(this.videoSpeedControl.speeds, function(index, speed) { var link, listItem; - //link = $('' + speed + 'x'); link = '' + speed + 'x'; listItem = $('
  • ' + link + '
  • '); @@ -139,7 +162,11 @@ function () { _this.videoSpeedControl.videoSpeedsEl.prepend(listItem); }); - this.videoSpeedControl.videoSpeedsEl.find('a').on('click', this.videoSpeedControl.changeVideoSpeed); + this.videoSpeedControl.videoSpeedsEl.find('a') + .on('click', this.videoSpeedControl.changeVideoSpeed); + + // TODO: After the control was re-rendered, we should attach 'focus' + // and 'blur' events once more. } });