Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
642a4fa2
Commit
642a4fa2
authored
Aug 14, 2013
by
Valera Rozuvan
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #659 from edx/valera/bugfix_tabbing_video_controls
Valera/bugfix tabbing video controls
parents
a2225aad
b583a4e7
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
143 additions
and
41 deletions
+143
-41
common/lib/xmodule/xmodule/js/src/video/07_video_volume_control.js
+48
-14
common/lib/xmodule/xmodule/js/src/video/08_video_speed_control.js
+85
-17
lms/templates/video.html
+10
-10
No files found.
common/lib/xmodule/xmodule/js/src/video/07_video_volume_control.js
View file @
642a4fa2
...
@@ -61,36 +61,70 @@ function () {
...
@@ -61,36 +61,70 @@ function () {
slide
:
state
.
videoVolumeControl
.
onChange
slide
:
state
.
videoVolumeControl
.
onChange
});
});
// Make sure that we can focus the actual volume slider while Tabing.
state
.
videoVolumeControl
.
volumeSliderEl
.
find
(
'a'
).
attr
(
'tabindex'
,
'0'
);
state
.
videoVolumeControl
.
el
.
toggleClass
(
'muted'
,
state
.
videoVolumeControl
.
currentVolume
===
0
);
state
.
videoVolumeControl
.
el
.
toggleClass
(
'muted'
,
state
.
videoVolumeControl
.
currentVolume
===
0
);
}
}
// function _bindHandlers(state)
/**
//
* @desc Bind any necessary function callbacks to DOM events (click,
// Bind any necessary function callbacks to DOM events (click, mousemove, etc.).
* mousemove, etc.).
*
* @type {function}
* @access private
*
* @param {object} state The object containg the state of the video player.
* All other modules, their parameters, public variables, etc. are
* available via this object.
*
* @this {object} The global window object.
*
* @returns {undefined}
*/
function
_bindHandlers
(
state
)
{
function
_bindHandlers
(
state
)
{
state
.
videoVolumeControl
.
buttonEl
.
on
(
'click'
,
state
.
videoVolumeControl
.
toggleMute
);
state
.
videoVolumeControl
.
buttonEl
.
on
(
'click'
,
state
.
videoVolumeControl
.
toggleMute
);
state
.
videoVolumeControl
.
el
.
on
(
'mouseenter'
,
function
()
{
state
.
videoVolumeControl
.
el
.
on
(
'mouseenter'
,
function
()
{
$
(
this
).
addClass
(
'open'
);
state
.
videoVolumeControl
.
el
.
addClass
(
'open'
);
});
state
.
videoVolumeControl
.
buttonEl
.
on
(
'focus'
,
function
()
{
$
(
this
).
parent
().
addClass
(
'open'
);
});
});
state
.
videoVolumeControl
.
el
.
on
(
'mouseleave'
,
function
()
{
state
.
videoVolumeControl
.
el
.
on
(
'mouseleave'
,
function
()
{
$
(
this
)
.
removeClass
(
'open'
);
state
.
videoVolumeControl
.
el
.
removeClass
(
'open'
);
});
});
// Attach a focus event to the volume button.
state
.
videoVolumeControl
.
buttonEl
.
on
(
'blur'
,
function
()
{
state
.
videoVolumeControl
.
buttonEl
.
on
(
'blur'
,
function
()
{
// If the focus is being trasnfered from the volume slider, then we
// don't do anything except for unsetting the special flag.
if
(
state
.
volumeBlur
===
true
)
{
state
.
volumeBlur
=
false
;
}
//If the focus is comming from elsewhere, then we must show the
// volume slider and set focus to it.
else
{
state
.
videoVolumeControl
.
el
.
addClass
(
'open'
);
state
.
videoVolumeControl
.
volumeSliderEl
.
find
(
'a'
).
focus
();
state
.
videoVolumeControl
.
volumeSliderEl
.
find
(
'a'
).
focus
();
}
});
});
state
.
videoVolumeControl
.
volumeSliderEl
.
find
(
'a'
).
on
(
'blur'
,
function
()
{
// Attach a blur event handler (loss of focus) to the volume slider
// element. More specifically, we are attaching to the handle on
// the slider with which you can change the volume.
state
.
videoVolumeControl
.
volumeSliderEl
.
find
(
'a'
)
.
on
(
'blur'
,
function
()
{
// Hide the volume slider. This is done so that we can
// continue to the next (or previous) element by tabbing.
// Otherwise, after next tab we would come back to the volume
// slider because it is the next element visible element that
// we can tab to after the volume button.
state
.
videoVolumeControl
.
el
.
removeClass
(
'open'
);
state
.
videoVolumeControl
.
el
.
removeClass
(
'open'
);
// Set focus to the volume button.
state
.
videoVolumeControl
.
buttonEl
.
focus
();
// We store the fact that previous element that lost focus was
// the volume clontrol.
state
.
volumeBlur
=
true
;
});
});
}
}
...
...
common/lib/xmodule/xmodule/js/src/video/08_video_speed_control.js
View file @
642a4fa2
...
@@ -61,46 +61,116 @@ function () {
...
@@ -61,46 +61,116 @@ function () {
state
.
videoSpeedControl
.
setSpeed
(
state
.
speed
);
state
.
videoSpeedControl
.
setSpeed
(
state
.
speed
);
}
}
// function _bindHandlers(state)
/**
//
* @desc Bind any necessary function callbacks to DOM events (click,
// Bind any necessary function callbacks to DOM events (click,
* mousemove, etc.).
// mousemove, etc.).
*
* @type {function}
* @access private
*
* @param {object} state The object containg the state of the video player.
* All other modules, their parameters, public variables, etc. are
* available via this object.
*
* @this {object} The global window object.
*
* @returns {undefined}
*/
function
_bindHandlers
(
state
)
{
function
_bindHandlers
(
state
)
{
var
speedLinks
;
state
.
videoSpeedControl
.
videoSpeedsEl
.
find
(
'a'
)
state
.
videoSpeedControl
.
videoSpeedsEl
.
find
(
'a'
)
.
on
(
'click'
,
state
.
videoSpeedControl
.
changeVideoSpeed
);
.
on
(
'click'
,
state
.
videoSpeedControl
.
changeVideoSpeed
);
if
(
onTouchBasedDevice
())
{
if
(
onTouchBasedDevice
())
{
state
.
videoSpeedControl
.
el
.
on
(
'click'
,
function
(
event
)
{
state
.
videoSpeedControl
.
el
.
on
(
'click'
,
function
(
event
)
{
// So that you can't highlight this control via a drag
// operation, we disable the default browser actions on a
// click event.
event
.
preventDefault
();
event
.
preventDefault
();
$
(
this
).
toggleClass
(
'open'
);
state
.
videoSpeedControl
.
el
.
toggleClass
(
'open'
);
});
});
}
else
{
}
else
{
state
.
videoSpeedControl
.
el
state
.
videoSpeedControl
.
el
.
on
(
'mouseenter'
,
function
()
{
.
on
(
'mouseenter'
,
function
()
{
$
(
this
)
.
addClass
(
'open'
);
state
.
videoSpeedControl
.
el
.
addClass
(
'open'
);
})
})
.
on
(
'mouseleave'
,
function
()
{
.
on
(
'mouseleave'
,
function
()
{
$
(
this
)
.
removeClass
(
'open'
);
state
.
videoSpeedControl
.
el
.
removeClass
(
'open'
);
})
})
.
on
(
'click'
,
function
(
event
)
{
.
on
(
'click'
,
function
(
event
)
{
// So that you can't highlight this control via a drag
// operation, we disable the default browser actions on a
// click event.
event
.
preventDefault
();
event
.
preventDefault
();
$
(
this
).
removeClass
(
'open'
);
state
.
videoSpeedControl
.
el
.
removeClass
(
'open'
);
});
});
// ******************************
// Attach 'focus', and 'blur' events to the speed button which
// either brings up the speed dialog with individual speed entries,
// or closes it.
state
.
videoSpeedControl
.
el
.
children
(
'a'
)
state
.
videoSpeedControl
.
el
.
children
(
'a'
)
.
on
(
'focus'
,
function
()
{
.
on
(
'focus'
,
function
()
{
$
(
this
).
parent
().
addClass
(
'open'
);
// If the focus is comming from the first speed entry, this
// means we are tabbing backwards. In this case we have to
// hide the speed entries which will allow us to change the
// focus further backwards.
if
(
state
.
firstSpeedBlur
===
true
)
{
state
.
videoSpeedControl
.
el
.
removeClass
(
'open'
);
state
.
firstSpeedBlur
=
false
;
}
// If the focus is comming from some other element, show
// the drop down with the speed entries.
else
{
state
.
videoSpeedControl
.
el
.
addClass
(
'open'
);
}
})
})
.
on
(
'blur'
,
function
()
{
.
on
(
'blur'
,
function
()
{
// When the focus leaves this element, if the speed entries
// dialog is shown (tabbing forwards), then we will set
// focus to the first speed entry.
//
// If the selector does not select anything, then this
// means that the speed entries dialog is closed, and we
// are tabbing backwads. The browser will select the
// previous element to tab to by itself.
state
.
videoSpeedControl
.
videoSpeedsEl
state
.
videoSpeedControl
.
videoSpeedsEl
.
find
(
'a.speed_link:first'
)
.
find
(
'a.speed_link:first'
)
.
focus
();
.
focus
();
});
});
state
.
videoSpeedControl
.
videoSpeedsEl
.
find
(
'a.speed_link:last'
)
.
on
(
'blur'
,
function
()
{
// ******************************
// Attach 'focus', and 'blur' events to elements which represent
// individual speed entries.
speedLinks
=
state
.
videoSpeedControl
.
videoSpeedsEl
.
find
(
'a.speed_link'
);
speedLinks
.
last
().
on
(
'blur'
,
function
()
{
// If we have reached the last speed entry, and the focus
// changes to the next element, we need to hide the speeds
// control drop-down.
state
.
videoSpeedControl
.
el
.
removeClass
(
'open'
);
state
.
videoSpeedControl
.
el
.
removeClass
(
'open'
);
});
});
speedLinks
.
first
().
on
(
'blur'
,
function
()
{
// This flag will indicate that the focus to the next
// element that will receive it is comming from the first
// speed entry.
//
// This flag will be used to correctly handle scenario of
// tabbing backwards.
state
.
firstSpeedBlur
=
true
;
});
speedLinks
.
on
(
'focus'
,
function
()
{
// Clear the flag which is only set when we are un-focusing
// (the blur event) from the first speed entry.
state
.
firstSpeedBlur
=
false
;
});
}
}
}
}
...
@@ -151,7 +221,7 @@ function () {
...
@@ -151,7 +221,7 @@ function () {
$
.
each
(
this
.
videoSpeedControl
.
speeds
,
function
(
index
,
speed
)
{
$
.
each
(
this
.
videoSpeedControl
.
speeds
,
function
(
index
,
speed
)
{
var
link
,
listItem
;
var
link
,
listItem
;
link
=
'<a href="#">'
+
speed
+
'x</a>'
;
link
=
'<a
class="speed_link"
href="#">'
+
speed
+
'x</a>'
;
listItem
=
$
(
'<li data-speed="'
+
speed
+
'">'
+
link
+
'</li>'
);
listItem
=
$
(
'<li data-speed="'
+
speed
+
'">'
+
link
+
'</li>'
);
...
@@ -162,11 +232,9 @@ function () {
...
@@ -162,11 +232,9 @@ function () {
_this
.
videoSpeedControl
.
videoSpeedsEl
.
prepend
(
listItem
);
_this
.
videoSpeedControl
.
videoSpeedsEl
.
prepend
(
listItem
);
});
});
this
.
videoSpeedControl
.
videoSpeedsEl
.
find
(
'a'
)
// Re-attach all events with their appropriate callbacks to the
.
on
(
'click'
,
this
.
videoSpeedControl
.
changeVideoSpeed
);
// newly generated elements.
_bindHandlers
(
this
);
// TODO: After the control was re-rendered, we should attach 'focus'
// and 'blur' events once more.
}
}
});
});
...
...
lms/templates/video.html
View file @
642a4fa2
...
@@ -39,25 +39,25 @@
...
@@ -39,25 +39,25 @@
<div>
<div>
<ul
class=
"vcr"
>
<ul
class=
"vcr"
>
<li><a
class=
"video_control"
href=
"#"
t
abindex=
"0"
t
itle=
"${_('Play')}"
></a></li>
<li><a
class=
"video_control"
href=
"#"
title=
"${_('Play')}"
></a></li>
<li><div
class=
"vidtime"
>
0:00 / 0:00
</div></li>
<li><div
class=
"vidtime"
>
0:00 / 0:00
</div></li>
</ul>
</ul>
<div
class=
"secondary-controls"
>
<div
class=
"secondary-controls"
>
<div
class=
"speeds"
>
<div
class=
"speeds"
>
<a
href=
"#"
t
abindex=
"0"
t
itle=
"Speeds"
>
<a
href=
"#"
title=
"Speeds"
>
<h3
tabindex=
"-1"
>
${_('Speed')}
</h3>
<h3>
${_('Speed')}
</h3>
<p
tabindex=
"-1"
class=
"active"
></p>
<p
class=
"active"
></p>
</a>
</a>
<ol
tabindex=
"-1"
class=
"video_speeds"
></ol>
<ol
class=
"video_speeds"
></ol>
</div>
</div>
<div
class=
"volume"
>
<div
class=
"volume"
>
<a
href=
"#"
t
abindex=
"0"
t
itle=
"Volume"
></a>
<a
href=
"#"
title=
"Volume"
></a>
<div
tabindex=
"-1"
class=
"volume-slider-container"
>
<div
class=
"volume-slider-container"
>
<div
tabindex=
"-1"
class=
"volume-slider"
></div>
<div
class=
"volume-slider"
></div>
</div>
</div>
</div>
</div>
<a
href=
"#"
class=
"add-fullscreen"
t
abindex=
"0"
t
itle=
"${_('Fill browser')}"
>
${_('Fill browser')}
</a>
<a
href=
"#"
class=
"add-fullscreen"
title=
"${_('Fill browser')}"
>
${_('Fill browser')}
</a>
<a
href=
"#"
class=
"quality_control"
t
abindex=
"0"
t
itle=
"${_('HD')}"
>
${_('HD')}
</a>
<a
href=
"#"
class=
"quality_control"
title=
"${_('HD')}"
>
${_('HD')}
</a>
<a
href=
"#"
class=
"hide-subtitles"
title=
"${_('Turn off captions')}"
>
${_('Captions')}
</a>
<a
href=
"#"
class=
"hide-subtitles"
title=
"${_('Turn off captions')}"
>
${_('Captions')}
</a>
</div>
</div>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment