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
0b58c22b
Commit
0b58c22b
authored
Aug 09, 2013
by
Valera Rozuvan
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #593 from edx/valera/captions_keyboard_access_2
Valera/captions keyboard access 2
parents
bc2a9fc2
1efea116
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
220 additions
and
368 deletions
+220
-368
common/lib/xmodule/xmodule/css/videoalpha/display.scss
+11
-18
common/lib/xmodule/xmodule/js/fixtures/video.html
+2
-2
common/lib/xmodule/xmodule/js/fixtures/videoalpha.html
+1
-1
common/lib/xmodule/xmodule/js/fixtures/videoalpha_all.html
+1
-1
common/lib/xmodule/xmodule/js/fixtures/videoalpha_html5.html
+1
-1
common/lib/xmodule/xmodule/js/fixtures/videoalpha_no_captions.html
+1
-1
common/lib/xmodule/xmodule/js/spec/helper.coffee
+11
-8
common/lib/xmodule/xmodule/js/spec/video/display/video_caption_spec.coffee
+1
-1
common/lib/xmodule/xmodule/js/spec/video/display/video_player_spec.coffee
+4
-4
common/lib/xmodule/xmodule/js/spec/video/display_spec.coffee
+12
-12
common/lib/xmodule/xmodule/js/spec/videoalpha/general_spec.js
+9
-9
common/lib/xmodule/xmodule/js/spec/videoalpha/readme.md
+2
-1
common/lib/xmodule/xmodule/js/spec/videoalpha/video_caption_spec.js
+12
-29
common/lib/xmodule/xmodule/js/spec/videoalpha/video_player_spec.js
+7
-68
common/lib/xmodule/xmodule/js/spec/videoalpha/video_progress_slider_spec.js
+0
-72
common/lib/xmodule/xmodule/js/spec/videoalpha/video_speed_control_spec.js
+1
-13
common/lib/xmodule/xmodule/js/spec/videoalpha/video_volume_control_spec.js
+0
-1
common/lib/xmodule/xmodule/js/src/videoalpha/01_initialize.js
+1
-8
common/lib/xmodule/xmodule/js/src/videoalpha/04_video_control.js
+2
-4
common/lib/xmodule/xmodule/js/src/videoalpha/05_video_quality_control.js
+0
-4
common/lib/xmodule/xmodule/js/src/videoalpha/06_video_progress_slider.js
+0
-28
common/lib/xmodule/xmodule/js/src/videoalpha/07_video_volume_control.js
+15
-0
common/lib/xmodule/xmodule/js/src/videoalpha/08_video_speed_control.js
+56
-21
common/lib/xmodule/xmodule/js/src/videoalpha/09_video_caption.js
+5
-0
lms/templates/videoalpha.html
+65
-61
No files found.
common/lib/xmodule/xmodule/css/videoalpha/display.scss
View file @
0b58c22b
...
@@ -133,7 +133,6 @@ div.videoalpha {
...
@@ -133,7 +133,6 @@ div.videoalpha {
line-height
:
46px
;
line-height
:
46px
;
padding
:
0
lh
(
.75
);
padding
:
0
lh
(
.75
);
text-indent
:
-9999px
;
text-indent
:
-9999px
;
@include
transition
(
background-color
0
.75s
linear
0s
,
opacity
0
.75s
linear
0s
);
width
:
14px
;
width
:
14px
;
background
:
url('../images/vcr.png')
15px
15px
no-repeat
;
background
:
url('../images/vcr.png')
15px
15px
no-repeat
;
outline
:
0
;
outline
:
0
;
...
@@ -150,7 +149,7 @@ div.videoalpha {
...
@@ -150,7 +149,7 @@ div.videoalpha {
&
.play
{
&
.play
{
background-position
:
17px
-114px
;
background-position
:
17px
-114px
;
&
:hover
{
&
:hover
,
&
:focus
{
background-color
:
#444
;
background-color
:
#444
;
}
}
}
}
...
@@ -158,7 +157,7 @@ div.videoalpha {
...
@@ -158,7 +157,7 @@ div.videoalpha {
&
.pause
{
&
.pause
{
background-position
:
16px
-50px
;
background-position
:
16px
-50px
;
&
:hover
{
&
:hover
,
&
:focus
{
background-color
:
#444
;
background-color
:
#444
;
}
}
}
}
...
@@ -300,12 +299,15 @@ div.videoalpha {
...
@@ -300,12 +299,15 @@ div.videoalpha {
&
.muted
{
&
.muted
{
&
>
a
{
&
>
a
{
background
:
url('../images/mute.png')
10px
center
no-repeat
;
background
-image
:
url('../images/mute.png')
;
}
}
}
}
>
a
{
>
a
{
background
:
url('../images/volume.png')
10px
center
no-repeat
;
background-image
:
url('../images/volume.png')
;
background-position
:
10px
center
;
background-repeat
:
no-repeat
;
border-right
:
1px
solid
#000
;
border-right
:
1px
solid
#000
;
box-shadow
:
1px
0
0
#555
,
inset
1px
0
0
#555
;
box-shadow
:
1px
0
0
#555
,
inset
1px
0
0
#555
;
@include
clearfix
();
@include
clearfix
();
...
@@ -382,7 +384,7 @@ div.videoalpha {
...
@@ -382,7 +384,7 @@ div.videoalpha {
@include
transition
(
none
);
@include
transition
(
none
);
width
:
30px
;
width
:
30px
;
&
:hover
{
&
:hover
,
&
:active
,
&
:focus
{
background-color
:
#444
;
background-color
:
#444
;
color
:
#fff
;
color
:
#fff
;
text-decoration
:
none
;
text-decoration
:
none
;
...
@@ -403,7 +405,7 @@ div.videoalpha {
...
@@ -403,7 +405,7 @@ div.videoalpha {
@include
transition
(
none
);
@include
transition
(
none
);
width
:
30px
;
width
:
30px
;
&
:hover
{
&
:hover
,
&
:focus
{
background-color
:
#444
;
background-color
:
#444
;
color
:
#fff
;
color
:
#fff
;
text-decoration
:
none
;
text-decoration
:
none
;
...
@@ -419,7 +421,6 @@ div.videoalpha {
...
@@ -419,7 +421,6 @@ div.videoalpha {
a
.hide-subtitles
{
a
.hide-subtitles
{
background
:
url('../images/cc.png')
center
no-repeat
;
background
:
url('../images/cc.png')
center
no-repeat
;
display
:
block
;
float
:
left
;
float
:
left
;
font-weight
:
800
;
font-weight
:
800
;
line-height
:
46px
;
//height of play pause buttons
line-height
:
46px
;
//height of play pause buttons
...
@@ -432,7 +433,7 @@ div.videoalpha {
...
@@ -432,7 +433,7 @@ div.videoalpha {
-webkit-font-smoothing
:
antialiased
;
-webkit-font-smoothing
:
antialiased
;
width
:
30px
;
width
:
30px
;
&
:hover
{
&
:hover
,
&
:focus
{
background-color
:
#444
;
background-color
:
#444
;
color
:
#fff
;
color
:
#fff
;
text-decoration
:
none
;
text-decoration
:
none
;
...
@@ -442,9 +443,7 @@ div.videoalpha {
...
@@ -442,9 +443,7 @@ div.videoalpha {
opacity
:
0
.7
;
opacity
:
0
.7
;
}
}
background-color
:
#444
;
color
:
#797979
;
color
:
#fff
;
text-decoration
:
none
;
}
}
}
}
}
}
...
@@ -513,12 +512,6 @@ div.videoalpha {
...
@@ -513,12 +512,6 @@ div.videoalpha {
z-index
:
1
;
z-index
:
1
;
}
}
article
.video-wrapper
section
.video-controls
div
.secondary-controls
a
.hide-subtitles
{
background-color
:
inherit
;
color
:
#797979
;
text-decoration
:
inherit
;
}
article
.video-wrapper
div
.video-player-pre
,
article
.video-wrapper
div
.video-player-post
{
article
.video-wrapper
div
.video-player-pre
,
article
.video-wrapper
div
.video-player-post
{
height
:
0px
;
height
:
0px
;
}
}
...
...
common/lib/xmodule/xmodule/js/fixtures/video.html
View file @
0b58c22b
...
@@ -2,8 +2,8 @@
...
@@ -2,8 +2,8 @@
<div
id=
"video_example"
>
<div
id=
"video_example"
>
<div
id=
"example"
>
<div
id=
"example"
>
<div
id=
"video_id"
class=
"video"
<div
id=
"video_id"
class=
"video"
data-youtube-id-0-75=
"
slowerSpeedYoutubeId
"
data-youtube-id-0-75=
"
7tqY6eQzVhE
"
data-youtube-id-1-0=
"
normalSpeedYoutubeId
"
data-youtube-id-1-0=
"
cogebirgzzM
"
data-show-captions=
"true"
data-show-captions=
"true"
data-start=
""
data-start=
""
data-end=
""
data-end=
""
...
...
common/lib/xmodule/xmodule/js/fixtures/videoalpha.html
View file @
0b58c22b
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
<div
<div
id=
"video_id"
id=
"video_id"
class=
"videoalpha"
class=
"videoalpha"
data-streams=
"0.75:
slowerSpeedYoutubeId,1.0:normalSpeedYoutubeId
"
data-streams=
"0.75:
7tqY6eQzVhE,1.0:cogebirgzzM
"
data-show-captions=
"true"
data-show-captions=
"true"
data-start=
""
data-start=
""
data-end=
""
data-end=
""
...
...
common/lib/xmodule/xmodule/js/fixtures/videoalpha_all.html
View file @
0b58c22b
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
data-start=
""
data-start=
""
data-end=
""
data-end=
""
data-caption-asset-path=
"/static/subs/"
data-caption-asset-path=
"/static/subs/"
data-sub=
"
test_name_of_the_subtitles
"
data-sub=
"
Z5KLxerq05Y
"
data-mp4-source=
"test_files/test.mp4"
data-mp4-source=
"test_files/test.mp4"
data-webm-source=
"test_files/test.webm"
data-webm-source=
"test_files/test.webm"
data-ogg-source=
"test_files/test.ogv"
data-ogg-source=
"test_files/test.ogv"
...
...
common/lib/xmodule/xmodule/js/fixtures/videoalpha_html5.html
View file @
0b58c22b
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
data-start=
""
data-start=
""
data-end=
""
data-end=
""
data-caption-asset-path=
"/static/subs/"
data-caption-asset-path=
"/static/subs/"
data-sub=
"
test_name_of_the_subtitles
"
data-sub=
"
Z5KLxerq05Y
"
data-mp4-source=
"test_files/test.mp4"
data-mp4-source=
"test_files/test.mp4"
data-webm-source=
"test_files/test.webm"
data-webm-source=
"test_files/test.webm"
data-ogg-source=
"test_files/test.ogv"
data-ogg-source=
"test_files/test.ogv"
...
...
common/lib/xmodule/xmodule/js/fixtures/videoalpha_no_captions.html
View file @
0b58c22b
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
<div
<div
id=
"video_id"
id=
"video_id"
class=
"videoalpha"
class=
"videoalpha"
data-streams=
"0.75:
slowerSpeedYoutubeId,1.0:normalSpeedYoutubeId
"
data-streams=
"0.75:
7tqY6eQzVhE,1.0:cogebirgzzM
"
data-show-captions=
"false"
data-show-captions=
"false"
data-start=
""
data-start=
""
data-end=
""
data-end=
""
...
...
common/lib/xmodule/xmodule/js/spec/helper.coffee
View file @
0b58c22b
...
@@ -12,6 +12,9 @@ window.STATUS = window.YT.PlayerState
...
@@ -12,6 +12,9 @@ window.STATUS = window.YT.PlayerState
oldAjaxWithPrefix
=
window
.
jQuery
.
ajaxWithPrefix
oldAjaxWithPrefix
=
window
.
jQuery
.
ajaxWithPrefix
window
.
onTouchBasedDevice
=
->
navigator
.
userAgent
.
match
/iPhone|iPod|iPad/i
jasmine
.
stubbedCaption
=
jasmine
.
stubbedCaption
=
end
:
[
3120
,
6270
,
8490
,
21620
,
24920
,
25750
,
27900
,
34380
,
35550
,
40250
]
end
:
[
3120
,
6270
,
8490
,
21620
,
24920
,
25750
,
27900
,
34380
,
35550
,
40250
]
start
:
[
1180
,
3120
,
6270
,
14910
,
21620
,
24920
,
25750
,
27900
,
34380
,
35550
]
start
:
[
1180
,
3120
,
6270
,
14910
,
21620
,
24920
,
25750
,
27900
,
34380
,
35550
]
...
@@ -36,7 +39,7 @@ jasmine.stubbedCaption =
...
@@ -36,7 +39,7 @@ jasmine.stubbedCaption =
#
#
# We will replace it with a function that does:
# We will replace it with a function that does:
#
#
# 1.) Return a hard coded captions object if the file name contains '
test_name_of_the_subtitles
'.
# 1.) Return a hard coded captions object if the file name contains '
Z5KLxerq05Y
'.
# 2.) Behaves the same a as the origianl in all other cases.
# 2.) Behaves the same a as the origianl in all other cases.
window
.
jQuery
.
ajaxWithPrefix
=
(
url
,
settings
)
->
window
.
jQuery
.
ajaxWithPrefix
=
(
url
,
settings
)
->
...
@@ -46,7 +49,7 @@ window.jQuery.ajaxWithPrefix = (url, settings) ->
...
@@ -46,7 +49,7 @@ window.jQuery.ajaxWithPrefix = (url, settings) ->
success
=
settings
.
success
success
=
settings
.
success
data
=
settings
.
data
data
=
settings
.
data
if
url
.
match
(
/
test_name_of_the_subtitles/g
)
isnt
null
or
url
.
match
(
/slowerSpeedYoutubeId/g
)
isnt
null
or
url
.
match
(
/normalSpeedYoutubeId
/g
)
isnt
null
if
url
.
match
(
/
Z5KLxerq05Y/g
)
isnt
null
or
url
.
match
(
/7tqY6eQzVhE/g
)
isnt
null
or
url
.
match
(
/cogebirgzzM
/g
)
isnt
null
if
window
.
jQuery
.
isFunction
(
success
)
is
true
if
window
.
jQuery
.
isFunction
(
success
)
is
true
success
jasmine
.
stubbedCaption
success
jasmine
.
stubbedCaption
else
if
window
.
jQuery
.
isFunction
(
data
)
is
true
else
if
window
.
jQuery
.
isFunction
(
data
)
is
true
...
@@ -60,11 +63,11 @@ window.WAIT_TIMEOUT = 1000
...
@@ -60,11 +63,11 @@ window.WAIT_TIMEOUT = 1000
jasmine
.
getFixtures
().
fixturesPath
=
'xmodule/js/fixtures'
jasmine
.
getFixtures
().
fixturesPath
=
'xmodule/js/fixtures'
jasmine
.
stubbedMetadata
=
jasmine
.
stubbedMetadata
=
slowerSpeedYoutubeId
:
'7tqY6eQzVhE'
:
id
:
'
slowerSpeedYoutubeId
'
id
:
'
7tqY6eQzVhE
'
duration
:
300
duration
:
300
normalSpeedYoutubeId
:
'cogebirgzzM'
:
id
:
'
normalSpeedYoutubeId
'
id
:
'
cogebirgzzM
'
duration
:
200
duration
:
200
bogus
:
bogus
:
duration
:
100
duration
:
100
...
@@ -117,7 +120,7 @@ jasmine.stubVideoPlayer = (context, enableParts, createPlayer=true) ->
...
@@ -117,7 +120,7 @@ jasmine.stubVideoPlayer = (context, enableParts, createPlayer=true) ->
loadFixtures
'video.html'
loadFixtures
'video.html'
jasmine
.
stubRequests
()
jasmine
.
stubRequests
()
YT
.
Player
=
undefined
YT
.
Player
=
undefined
videosDefinition
=
'0.75:
slowerSpeedYoutubeId,1.0:normalSpeedYoutubeId
'
videosDefinition
=
'0.75:
7tqY6eQzVhE,1.0:cogebirgzzM
'
context
.
video
=
new
Video
'#example'
,
videosDefinition
context
.
video
=
new
Video
'#example'
,
videosDefinition
jasmine
.
stubYoutubePlayer
()
jasmine
.
stubYoutubePlayer
()
if
createPlayer
if
createPlayer
...
@@ -135,7 +138,7 @@ jasmine.stubVideoPlayerAlpha = (context, enableParts, html5=false) ->
...
@@ -135,7 +138,7 @@ jasmine.stubVideoPlayerAlpha = (context, enableParts, html5=false) ->
YT
.
Player
=
undefined
YT
.
Player
=
undefined
window
.
OldVideoPlayerAlpha
=
undefined
window
.
OldVideoPlayerAlpha
=
undefined
jasmine
.
stubYoutubePlayer
()
jasmine
.
stubYoutubePlayer
()
return
new
VideoAlpha
'#example'
,
'.75:
slowerSpeedYoutubeId,1.0:normalSpeedYoutubeId
'
return
new
VideoAlpha
'#example'
,
'.75:
7tqY6eQzVhE,1.0:cogebirgzzM
'
# Stub jQuery.cookie
# Stub jQuery.cookie
...
...
common/lib/xmodule/xmodule/js/spec/video/display/video_caption_spec.coffee
View file @
0b58c22b
...
@@ -19,7 +19,7 @@ describe 'VideoCaption', ->
...
@@ -19,7 +19,7 @@ describe 'VideoCaption', ->
@
caption
=
@
player
.
caption
@
caption
=
@
player
.
caption
it
'set the youtube id'
,
->
it
'set the youtube id'
,
->
expect
(
@
caption
.
youtubeId
).
toEqual
'
normalSpeedYoutubeId
'
expect
(
@
caption
.
youtubeId
).
toEqual
'
cogebirgzzM
'
it
'create the caption element'
,
->
it
'create the caption element'
,
->
expect
(
$
(
'.video'
)).
toContain
'ol.subtitles'
expect
(
$
(
'.video'
)).
toContain
'ol.subtitles'
...
...
common/lib/xmodule/xmodule/js/spec/video/display/video_player_spec.coffee
View file @
0b58c22b
...
@@ -35,7 +35,7 @@ describe 'VideoPlayer', ->
...
@@ -35,7 +35,7 @@ describe 'VideoPlayer', ->
expect
(
window
.
VideoCaption
.
prototype
.
initialize
).
toHaveBeenCalled
()
expect
(
window
.
VideoCaption
.
prototype
.
initialize
).
toHaveBeenCalled
()
expect
(
@
player
.
caption
).
toBeDefined
()
expect
(
@
player
.
caption
).
toBeDefined
()
expect
(
@
player
.
caption
.
el
).
toBe
@
player
.
el
expect
(
@
player
.
caption
.
el
).
toBe
@
player
.
el
expect
(
@
player
.
caption
.
youtubeId
).
toEqual
'
normalSpeedYoutubeId
'
expect
(
@
player
.
caption
.
youtubeId
).
toEqual
'
cogebirgzzM
'
expect
(
@
player
.
caption
.
currentSpeed
).
toEqual
'1.0'
expect
(
@
player
.
caption
.
currentSpeed
).
toEqual
'1.0'
expect
(
@
player
.
caption
.
captionAssetPath
).
toEqual
'/static/subs/'
expect
(
@
player
.
caption
.
captionAssetPath
).
toEqual
'/static/subs/'
...
@@ -60,7 +60,7 @@ describe 'VideoPlayer', ->
...
@@ -60,7 +60,7 @@ describe 'VideoPlayer', ->
showinfo
:
0
showinfo
:
0
enablejsapi
:
1
enablejsapi
:
1
modestbranding
:
1
modestbranding
:
1
videoId
:
'
normalSpeedYoutubeId
'
videoId
:
'
cogebirgzzM
'
events
:
events
:
onReady
:
@
player
.
onReady
onReady
:
@
player
.
onReady
onStateChange
:
@
player
.
onStateChange
onStateChange
:
@
player
.
onStateChange
...
@@ -290,7 +290,7 @@ describe 'VideoPlayer', ->
...
@@ -290,7 +290,7 @@ describe 'VideoPlayer', ->
@
player
.
onSpeedChange
{},
'0.75'
@
player
.
onSpeedChange
{},
'0.75'
it
'load the video'
,
->
it
'load the video'
,
->
expect
(
@
player
.
player
.
loadVideoById
).
toHaveBeenCalledWith
'
slowerSpeedYoutubeId
'
,
'80.000'
expect
(
@
player
.
player
.
loadVideoById
).
toHaveBeenCalledWith
'
7tqY6eQzVhE
'
,
'80.000'
it
'trigger updatePlayTime event'
,
->
it
'trigger updatePlayTime event'
,
->
expect
(
@
player
.
updatePlayTime
).
toHaveBeenCalledWith
'80.000'
expect
(
@
player
.
updatePlayTime
).
toHaveBeenCalledWith
'80.000'
...
@@ -301,7 +301,7 @@ describe 'VideoPlayer', ->
...
@@ -301,7 +301,7 @@ describe 'VideoPlayer', ->
@
player
.
onSpeedChange
{},
'0.75'
@
player
.
onSpeedChange
{},
'0.75'
it
'cue the video'
,
->
it
'cue the video'
,
->
expect
(
@
player
.
player
.
cueVideoById
).
toHaveBeenCalledWith
'
slowerSpeedYoutubeId
'
,
'80.000'
expect
(
@
player
.
player
.
cueVideoById
).
toHaveBeenCalledWith
'
7tqY6eQzVhE
'
,
'80.000'
it
'trigger updatePlayTime event'
,
->
it
'trigger updatePlayTime event'
,
->
expect
(
@
player
.
updatePlayTime
).
toHaveBeenCalledWith
'80.000'
expect
(
@
player
.
updatePlayTime
).
toHaveBeenCalledWith
'80.000'
...
...
common/lib/xmodule/xmodule/js/spec/video/display_spec.coffee
View file @
0b58c22b
...
@@ -5,14 +5,14 @@ describe 'Video', ->
...
@@ -5,14 +5,14 @@ describe 'Video', ->
loadFixtures
'video.html'
loadFixtures
'video.html'
jasmine
.
stubRequests
()
jasmine
.
stubRequests
()
@
slowerSpeedYoutubeId
=
'slowerSpeedYoutubeId
'
@
[
'7tqY6eQzVhE'
]
=
'7tqY6eQzVhE
'
@
normalSpeedYoutubeId
=
'normalSpeedYoutubeId
'
@
[
'cogebirgzzM'
]
=
'cogebirgzzM
'
metadata
=
metadata
=
slowerSpeedYoutubeId
:
'7tqY6eQzVhE'
:
id
:
@
slowerSpeedYoutubeId
id
:
@
[
'7tqY6eQzVhE'
]
duration
:
300
duration
:
300
normalSpeedYoutubeId
:
'cogebirgzzM'
:
id
:
@
normalSpeedYoutubeId
id
:
@
[
'cogebirgzzM'
]
duration
:
200
duration
:
200
afterEach
->
afterEach
->
...
@@ -38,8 +38,8 @@ describe 'Video', ->
...
@@ -38,8 +38,8 @@ describe 'Video', ->
it
'parse the videos'
,
->
it
'parse the videos'
,
->
expect
(
@
video
.
videos
).
toEqual
expect
(
@
video
.
videos
).
toEqual
'0.75'
:
@
slowerSpeedYoutubeId
'0.75'
:
@
[
'7tqY6eQzVhE'
]
'1.0'
:
@
normalSpeedYoutubeId
'1.0'
:
@
[
'cogebirgzzM'
]
it
'fetch the video metadata'
,
->
it
'fetch the video metadata'
,
->
expect
(
@
video
.
fetchMetadata
).
toHaveBeenCalled
expect
(
@
video
.
fetchMetadata
).
toHaveBeenCalled
...
@@ -102,12 +102,12 @@ describe 'Video', ->
...
@@ -102,12 +102,12 @@ describe 'Video', ->
describe
'with speed'
,
->
describe
'with speed'
,
->
it
'return the video id for given speed'
,
->
it
'return the video id for given speed'
,
->
expect
(
@
video
.
youtubeId
(
'0.75'
)).
toEqual
@
slowerSpeedYoutubeId
expect
(
@
video
.
youtubeId
(
'0.75'
)).
toEqual
@
[
'7tqY6eQzVhE'
]
expect
(
@
video
.
youtubeId
(
'1.0'
)).
toEqual
@
normalSpeedYoutubeId
expect
(
@
video
.
youtubeId
(
'1.0'
)).
toEqual
@
[
'cogebirgzzM'
]
describe
'without speed'
,
->
describe
'without speed'
,
->
it
'return the video id for current speed'
,
->
it
'return the video id for current speed'
,
->
expect
(
@
video
.
youtubeId
()).
toEqual
@
normalSpeedYoutubeId
expect
(
@
video
.
youtubeId
()).
toEqual
@
cogebirgzzM
describe
'setSpeed'
,
->
describe
'setSpeed'
,
->
beforeEach
->
beforeEach
->
...
@@ -148,6 +148,6 @@ describe 'Video', ->
...
@@ -148,6 +148,6 @@ describe 'Video', ->
it
'call the logger with valid parameters'
,
->
it
'call the logger with valid parameters'
,
->
expect
(
Logger
.
log
).
toHaveBeenCalledWith
'someEvent'
,
expect
(
Logger
.
log
).
toHaveBeenCalledWith
'someEvent'
,
id
:
'id'
id
:
'id'
code
:
@
normalSpeedYoutubeId
code
:
@
cogebirgzzM
currentTime
:
25
currentTime
:
25
speed
:
'1.0'
speed
:
'1.0'
common/lib/xmodule/xmodule/js/spec/videoalpha/general_spec.js
View file @
0b58c22b
...
@@ -6,9 +6,9 @@
...
@@ -6,9 +6,9 @@
jasmine
.
stubRequests
();
jasmine
.
stubRequests
();
oldOTBD
=
window
.
onTouchBasedDevice
;
oldOTBD
=
window
.
onTouchBasedDevice
;
window
.
onTouchBasedDevice
=
jasmine
.
createSpy
(
'onTouchBasedDevice'
).
andReturn
(
false
);
window
.
onTouchBasedDevice
=
jasmine
.
createSpy
(
'onTouchBasedDevice'
).
andReturn
(
false
);
this
.
videosDefinition
=
'0.75:
slowerSpeedYoutubeId,1.0:normalSpeedYoutubeId
'
;
this
.
videosDefinition
=
'0.75:
7tqY6eQzVhE,1.0:cogebirgzzM
'
;
this
.
slowerSpeedYoutubeId
=
'slowerSpeedYoutubeId
'
;
this
[
'7tqY6eQzVhE'
]
=
'7tqY6eQzVhE
'
;
this
.
normalSpeedYoutubeId
=
'normalSpeedYoutubeId
'
;
this
[
'cogebirgzzM'
]
=
'cogebirgzzM
'
;
});
});
afterEach
(
function
()
{
afterEach
(
function
()
{
...
@@ -45,8 +45,8 @@
...
@@ -45,8 +45,8 @@
it
(
'parse the videos'
,
function
()
{
it
(
'parse the videos'
,
function
()
{
expect
(
this
.
state
.
videos
).
toEqual
({
expect
(
this
.
state
.
videos
).
toEqual
({
'0.75'
:
this
.
slowerSpeedYoutubeId
,
'0.75'
:
this
[
'7tqY6eQzVhE'
]
,
'1.0'
:
this
.
normalSpeedYoutubeId
'1.0'
:
this
[
'cogebirgzzM'
]
});
});
});
});
...
@@ -91,7 +91,7 @@
...
@@ -91,7 +91,7 @@
});
});
it
(
'parse the videos if subtitles exist'
,
function
()
{
it
(
'parse the videos if subtitles exist'
,
function
()
{
var
sub
=
'
test_name_of_the_subtitles
'
;
var
sub
=
'
Z5KLxerq05Y
'
;
expect
(
state
.
videos
).
toEqual
({
expect
(
state
.
videos
).
toEqual
({
'0.75'
:
sub
,
'0.75'
:
sub
,
...
@@ -165,14 +165,14 @@
...
@@ -165,14 +165,14 @@
describe
(
'with speed'
,
function
()
{
describe
(
'with speed'
,
function
()
{
it
(
'return the video id for given speed'
,
function
()
{
it
(
'return the video id for given speed'
,
function
()
{
expect
(
state
.
youtubeId
(
'0.75'
)).
toEqual
(
this
.
slowerSpeedYoutubeId
);
expect
(
state
.
youtubeId
(
'0.75'
)).
toEqual
(
this
[
'7tqY6eQzVhE'
]
);
expect
(
state
.
youtubeId
(
'1.0'
)).
toEqual
(
this
.
normalSpeedYoutubeId
);
expect
(
state
.
youtubeId
(
'1.0'
)).
toEqual
(
this
[
'cogebirgzzM'
]
);
});
});
});
});
describe
(
'without speed'
,
function
()
{
describe
(
'without speed'
,
function
()
{
it
(
'return the video id for current speed'
,
function
()
{
it
(
'return the video id for current speed'
,
function
()
{
expect
(
state
.
youtubeId
()).
toEqual
(
this
.
normalSpeedYoutubeId
);
expect
(
state
.
youtubeId
()).
toEqual
(
this
.
cogebirgzzM
);
});
});
});
});
});
});
...
...
common/lib/xmodule/xmodule/js/spec/videoalpha/readme.md
View file @
0b58c22b
Jasmine JavaScript tests status
Jasmine JavaScript tests status
-------------------------------
-------------------------------
As of 22.07.2013, all the tests in this directory pass. To disable each of them, change the top level "describe(" to "xdescribe(".
As of 22.07.2013, all the tests in this directory pass. To enable a test file, change
the top level "xdescribe(" to "describe(".
PS: When you are running the tests in chrome locally, make sure that chrome is started
PS: When you are running the tests in chrome locally, make sure that chrome is started
with the option "--allow-file-access-from-files".
with the option "--allow-file-access-from-files".
common/lib/xmodule/xmodule/js/spec/videoalpha/video_caption_spec.js
View file @
0b58c22b
...
@@ -130,7 +130,6 @@
...
@@ -130,7 +130,6 @@
describe
(
'mouse movement'
,
function
()
{
describe
(
'mouse movement'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
//initialize();
window
.
setTimeout
.
andReturn
(
100
);
window
.
setTimeout
.
andReturn
(
100
);
spyOn
(
window
,
'clearTimeout'
);
spyOn
(
window
,
'clearTimeout'
);
});
});
...
@@ -221,10 +220,6 @@
...
@@ -221,10 +220,6 @@
});
});
describe
(
'search'
,
function
()
{
describe
(
'search'
,
function
()
{
beforeEach
(
function
()
{
//initialize();
});
it
(
'return a correct caption index'
,
function
()
{
it
(
'return a correct caption index'
,
function
()
{
expect
(
videoCaption
.
search
(
0
)).
toEqual
(
0
);
expect
(
videoCaption
.
search
(
0
)).
toEqual
(
0
);
expect
(
videoCaption
.
search
(
3120
)).
toEqual
(
1
);
expect
(
videoCaption
.
search
(
3120
)).
toEqual
(
1
);
...
@@ -277,7 +272,6 @@
...
@@ -277,7 +272,6 @@
describe
(
'pause'
,
function
()
{
describe
(
'pause'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
//initialize();
videoCaption
.
playing
=
true
;
videoCaption
.
playing
=
true
;
videoCaption
.
pause
();
videoCaption
.
pause
();
});
});
...
@@ -288,10 +282,6 @@
...
@@ -288,10 +282,6 @@
});
});
describe
(
'updatePlayTime'
,
function
()
{
describe
(
'updatePlayTime'
,
function
()
{
/*beforeEach(function() {
initialize();
});*/
describe
(
'when the video speed is 1.0x'
,
function
()
{
describe
(
'when the video speed is 1.0x'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
videoSpeedControl
.
currentSpeed
=
'1.0'
;
videoSpeedControl
.
currentSpeed
=
'1.0'
;
...
@@ -369,16 +359,21 @@
...
@@ -369,16 +359,21 @@
});
});
it
(
'when CC button is disabled '
,
function
()
{
it
(
'when CC button is disabled '
,
function
()
{
var
realHeight
=
parseInt
(
$
(
'.subtitles'
).
css
(
'maxHeight'
),
10
),
var
realHeight
,
videoWrapperHeight
,
progressSliderHeight
,
videoWrapperHeight
=
$
(
'.video-wrapper'
).
height
(),
controlHeight
,
shouldBeHeight
;
controlsHeight
=
videoControl
.
el
.
height
(),
progressSliderHeight
=
videoControl
.
sliderEl
.
height
(),
shouldBeHeight
=
videoWrapperHeight
-
controlsHeight
\
-
0.5
*
controlsHeight
;
state
.
captionsHidden
=
true
;
state
.
captionsHidden
=
true
;
videoCaption
.
setSubtitlesHeight
();
videoCaption
.
setSubtitlesHeight
();
expect
(
realHeight
).
toBeCloseTo
(
$
(
'.video-wrapper'
).
height
(
shouldBeHeight
,
2
));
realHeight
=
parseInt
(
$
(
'.subtitles'
).
css
(
'maxHeight'
),
10
);
videoWrapperHeight
=
$
(
'.video-wrapper'
).
height
();
progressSliderHeight
=
videoControl
.
sliderEl
.
height
();
controlHeight
=
videoControl
.
el
.
height
();
shouldBeHeight
=
videoWrapperHeight
-
0.5
*
progressSliderHeight
-
controlHeight
;
expect
(
realHeight
).
toBe
(
shouldBeHeight
);
});
});
});
});
...
@@ -434,17 +429,6 @@
...
@@ -434,17 +429,6 @@
});
});
it
(
'scroll to current caption'
,
function
()
{
it
(
'scroll to current caption'
,
function
()
{
// Check for calledWith(parameters) for some reason fails...
//
// var offset = -0.5 * ($('.video-wrapper').height() - $('.subtitles .current:first').height());
//
// expect($.fn.scrollTo).toHaveBeenCalledWith(
// $('.subtitles .current:first', videoCaption.el),
// {
// offset: offset
// }
// );
expect
(
$
.
fn
.
scrollTo
).
toHaveBeenCalled
();
expect
(
$
.
fn
.
scrollTo
).
toHaveBeenCalled
();
});
});
});
});
...
@@ -454,7 +438,6 @@
...
@@ -454,7 +438,6 @@
describe
(
'seekPlayer'
,
function
()
{
describe
(
'seekPlayer'
,
function
()
{
describe
(
'when the video speed is 1.0x'
,
function
()
{
describe
(
'when the video speed is 1.0x'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
//initialize();
videoSpeedControl
.
currentSpeed
=
'1.0'
;
videoSpeedControl
.
currentSpeed
=
'1.0'
;
$
(
'.subtitles li[data-start="14910"]'
).
trigger
(
'click'
);
$
(
'.subtitles li[data-start="14910"]'
).
trigger
(
'click'
);
});
});
...
...
common/lib/xmodule/xmodule/js/spec/videoalpha/video_player_spec.js
View file @
0b58c22b
...
@@ -34,12 +34,6 @@
...
@@ -34,12 +34,6 @@
});
});
describe
(
'constructor'
,
function
()
{
describe
(
'constructor'
,
function
()
{
beforeEach
(
function
()
{
$
.
fn
.
qtip
.
andCallFake
(
function
()
{
$
(
this
).
data
(
'qtip'
,
true
);
});
});
describe
(
'always'
,
function
()
{
describe
(
'always'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
initialize
();
initialize
();
...
@@ -60,7 +54,7 @@
...
@@ -60,7 +54,7 @@
it
(
'create video caption'
,
function
()
{
it
(
'create video caption'
,
function
()
{
expect
(
videoCaption
).
toBeDefined
();
expect
(
videoCaption
).
toBeDefined
();
expect
(
state
.
youtubeId
()).
toEqual
(
'
test_name_of_the_subtitles
'
);
expect
(
state
.
youtubeId
()).
toEqual
(
'
Z5KLxerq05Y
'
);
expect
(
state
.
speed
).
toEqual
(
'1.0'
);
expect
(
state
.
speed
).
toEqual
(
'1.0'
);
expect
(
state
.
config
.
caption_asset_path
).
toEqual
(
'/static/subs/'
);
expect
(
state
.
config
.
caption_asset_path
).
toEqual
(
'/static/subs/'
);
});
});
...
@@ -80,38 +74,6 @@
...
@@ -80,38 +74,6 @@
// All the toHandleWith() expect tests are not necessary for this version of Video Alpha.
// All the toHandleWith() expect tests are not necessary for this version of Video Alpha.
// jQuery event system is not used to trigger and invoke methods. This is an artifact from
// jQuery event system is not used to trigger and invoke methods. This is an artifact from
// previous version of Video Alpha.
// previous version of Video Alpha.
//
// xit('bind to video control play event', function() {
// expect($(videoControl)).toHandleWith('play', player.play);
// });
//
// xit('bind to video control pause event', function() {
// expect($(videoControl)).toHandleWith('pause', player.pause);
// });
//
// xit('bind to video caption seek event', function() {
// expect($(videoCaption)).toHandleWith('caption_seek', player.onSeek);
// });
//
// xit('bind to video speed control speedChange event', function() {
// expect($(videoSpeedControl)).toHandleWith('speedChange', player.onSpeedChange);
// });
//
// xit('bind to video progress slider seek event', function() {
// expect($(videoProgressSlider)).toHandleWith('slide_seek', player.onSeek);
// });
//
// xit('bind to video volume control volumeChange event', function() {
// expect($(videoVolumeControl)).toHandleWith('volumeChange', player.onVolumeChange);
// });
//
// xit('bind to key press', function() {
// expect($(document.documentElement)).toHandleWith('keyup', player.bindExitFullScreen);
// });
//
// xit('bind to fullscreen switching button', function() {
// expect($('.add-fullscreen')).toHandleWith('click', player.toggleFullScreen);
// });
});
});
it
(
'create Youtube player'
,
function
()
{
it
(
'create Youtube player'
,
function
()
{
...
@@ -136,7 +98,7 @@
...
@@ -136,7 +98,7 @@
modestbranding
:
1
,
modestbranding
:
1
,
html5
:
1
html5
:
1
},
},
videoId
:
'
normalSpeedYoutubeId
'
,
videoId
:
'
cogebirgzzM
'
,
events
:
{
events
:
{
onReady
:
videoPlayer
.
onReady
,
onReady
:
videoPlayer
.
onReady
,
onStateChange
:
videoPlayer
.
onStateChange
,
onStateChange
:
videoPlayer
.
onStateChange
,
...
@@ -149,20 +111,6 @@
...
@@ -149,20 +111,6 @@
// We can't test the invocation of HTML5Video because it is not available
// We can't test the invocation of HTML5Video because it is not available
// globally. It is defined within the scope of Require JS.
// globally. It is defined within the scope of Require JS.
//
// xit('create HTML5 player', function() {
// spyOn(state.HTML5Video, 'Player').andCallThrough();
// initialize();
//
// expect(window.HTML5Video.Player).toHaveBeenCalledWith(this.video.el, {
// playerVars: playerVars,
// videoSources: this.video.html5Sources,
// events: {
// onReady: player.onReady,
// onStateChange: player.onStateChange
// }
// });
// });
describe
(
'when not on a touch based device'
,
function
()
{
describe
(
'when not on a touch based device'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
...
@@ -170,10 +118,6 @@
...
@@ -170,10 +118,6 @@
initialize
();
initialize
();
});
});
it
(
'does not add the tooltip to fullscreen button'
,
function
()
{
expect
(
$
(
'.add-fullscreen'
)).
not
.
toHaveData
(
'qtip'
);
});
it
(
'create video volume control'
,
function
()
{
it
(
'create video volume control'
,
function
()
{
expect
(
videoVolumeControl
).
toBeDefined
();
expect
(
videoVolumeControl
).
toBeDefined
();
expect
(
videoVolumeControl
.
el
).
toHaveClass
(
'volume'
);
expect
(
videoVolumeControl
.
el
).
toHaveClass
(
'volume'
);
...
@@ -187,10 +131,6 @@
...
@@ -187,10 +131,6 @@
initialize
();
initialize
();
});
});
it
(
'add the tooltip to fullscreen button'
,
function
()
{
expect
(
$
(
'.add-fullscreen'
)).
toHaveData
(
'qtip'
);
});
it
(
'controls are in paused state'
,
function
()
{
it
(
'controls are in paused state'
,
function
()
{
expect
(
videoControl
.
isPlaying
).
toBe
(
false
);
expect
(
videoControl
.
isPlaying
).
toBe
(
false
);
});
});
...
@@ -433,11 +373,9 @@
...
@@ -433,11 +373,9 @@
expect
(
state
.
setSpeed
).
toHaveBeenCalledWith
(
'0.75'
,
false
);
expect
(
state
.
setSpeed
).
toHaveBeenCalledWith
(
'0.75'
,
false
);
});
});
// Not relevant any more
.
// Not relevant any more
:
//
//
// it('tell video caption that the speed has changed', function() {
// expect( "tell video caption that the speed has changed" ) ...
// expect(this.player.caption.currentSpeed).toEqual('0.75');
// });
});
});
describe
(
'when the video is playing'
,
function
()
{
describe
(
'when the video is playing'
,
function
()
{
...
@@ -548,8 +486,9 @@
...
@@ -548,8 +486,9 @@
expect
(
true
).
toBe
(
false
);
expect
(
true
).
toBe
(
false
);
}
}
// The below test has been replaced by above trickery.
// The below test has been replaced by above trickery:
// expect($('.vidtime')).toHaveHtml('1:00 / 1:01');
//
// expect($('.vidtime')).toHaveHtml('1:00 / 1:01');
});
});
});
});
...
...
common/lib/xmodule/xmodule/js/spec/videoalpha/video_progress_slider_spec.js
View file @
0b58c22b
...
@@ -39,21 +39,6 @@
...
@@ -39,21 +39,6 @@
it
(
'build the seek handle'
,
function
()
{
it
(
'build the seek handle'
,
function
()
{
expect
(
videoProgressSlider
.
handle
).
toBe
(
'.slider .ui-slider-handle'
);
expect
(
videoProgressSlider
.
handle
).
toBe
(
'.slider .ui-slider-handle'
);
expect
(
$
.
fn
.
qtip
).
toHaveBeenCalledWith
({
content
:
"0:00"
,
position
:
{
my
:
'bottom center'
,
at
:
'top center'
,
container
:
videoProgressSlider
.
handle
},
hide
:
{
delay
:
700
},
style
:
{
classes
:
'ui-tooltip-slider'
,
widget
:
true
}
});
});
});
});
});
...
@@ -69,7 +54,6 @@
...
@@ -69,7 +54,6 @@
// We can't expect $.fn.slider not to have been called,
// We can't expect $.fn.slider not to have been called,
// because sliders are used in other parts of VideoAlpha.
// because sliders are used in other parts of VideoAlpha.
// expect($.fn.slider).not.toHaveBeenCalled();
});
});
});
});
});
});
...
@@ -94,43 +78,6 @@
...
@@ -94,43 +78,6 @@
});
});
// Currently, the slider is not rebuilt if it does not exist.
// Currently, the slider is not rebuilt if it does not exist.
//
// describe('when the slider was not already built', function() {
// beforeEach(function() {
// spyOn($.fn, 'slider').andCallThrough();
// videoProgressSlider.slider = null;
// videoPlayer.play();
// });
//
// it('build the slider', function() {
// expect(videoProgressSlider.slider).toBe('.slider');
// expect($.fn.slider).toHaveBeenCalledWith({
// range: 'min',
// change: videoProgressSlider.onChange,
// slide: videoProgressSlider.onSlide,
// stop: videoProgressSlider.onStop
// });
// });
//
// it('build the seek handle', function() {
// expect(videoProgressSlider.handle).toBe('.ui-slider-handle');
// expect($.fn.qtip).toHaveBeenCalledWith({
// content: "0:00",
// position: {
// my: 'bottom center',
// at: 'top center',
// container: videoProgressSlider.handle
// },
// hide: {
// delay: 700
// },
// style: {
// classes: 'ui-tooltip-slider',
// widget: true
// }
// });
// });
// });
});
});
describe
(
'updatePlayTime'
,
function
()
{
describe
(
'updatePlayTime'
,
function
()
{
...
@@ -181,10 +128,6 @@
...
@@ -181,10 +128,6 @@
expect
(
videoProgressSlider
.
frozen
).
toBeTruthy
();
expect
(
videoProgressSlider
.
frozen
).
toBeTruthy
();
});
});
it
(
'update the tooltip'
,
function
()
{
expect
(
$
.
fn
.
qtip
).
toHaveBeenCalled
();
});
it
(
'trigger seek event'
,
function
()
{
it
(
'trigger seek event'
,
function
()
{
expect
(
videoPlayer
.
onSlideSeek
).
toHaveBeenCalled
();
expect
(
videoPlayer
.
onSlideSeek
).
toHaveBeenCalled
();
expect
(
videoPlayer
.
currentTime
).
toEqual
(
20
);
expect
(
videoPlayer
.
currentTime
).
toEqual
(
20
);
...
@@ -199,9 +142,6 @@
...
@@ -199,9 +142,6 @@
value
:
20
value
:
20
});
});
});
});
it
(
'update the tooltip'
,
function
()
{
expect
(
$
.
fn
.
qtip
).
toHaveBeenCalled
();
});
});
});
describe
(
'onStop'
,
function
()
{
describe
(
'onStop'
,
function
()
{
...
@@ -228,18 +168,6 @@
...
@@ -228,18 +168,6 @@
expect
(
videoProgressSlider
.
frozen
).
toBeFalsy
();
expect
(
videoProgressSlider
.
frozen
).
toBeFalsy
();
});
});
});
});
describe
(
'updateTooltip'
,
function
()
{
beforeEach
(
function
()
{
initialize
();
spyOn
(
$
.
fn
,
'slider'
).
andCallThrough
();
videoProgressSlider
.
updateTooltip
(
90
);
});
it
(
'set the tooltip value'
,
function
()
{
expect
(
$
.
fn
.
qtip
).
toHaveBeenCalledWith
(
'option'
,
'content.text'
,
'1:30'
);
});
});
});
});
}).
call
(
this
);
}).
call
(
this
);
common/lib/xmodule/xmodule/js/spec/videoalpha/video_speed_control_spec.js
View file @
0b58c22b
...
@@ -90,19 +90,7 @@
...
@@ -90,19 +90,7 @@
// detect (and do not do anything) if there is a request for a speed that
// detect (and do not do anything) if there is a request for a speed that
// is already set.
// is already set.
//
//
// describe('when new speed is the same', function() {
// describe("when new speed is the same") ...
// beforeEach(function() {
// initialize();
// videoSpeedControl.setSpeed(1.0);
// spyOn(videoPlayer, 'onSpeedChange').andCallThrough();
//
// $('li[data-speed="1.0"] a').click();
// });
//
// it('does not trigger speedChange event', function() {
// expect(videoPlayer.onSpeedChange).not.toHaveBeenCalled();
// });
// });
describe
(
'when new speed is not the same'
,
function
()
{
describe
(
'when new speed is not the same'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
...
...
common/lib/xmodule/xmodule/js/spec/videoalpha/video_volume_control_spec.js
View file @
0b58c22b
...
@@ -39,7 +39,6 @@
...
@@ -39,7 +39,6 @@
range
:
"min"
,
range
:
"min"
,
min
:
0
,
min
:
0
,
max
:
100
,
max
:
100
,
/* value: 100, */
value
:
videoVolumeControl
.
currentVolume
,
value
:
videoVolumeControl
.
currentVolume
,
change
:
videoVolumeControl
.
onChange
,
change
:
videoVolumeControl
.
onChange
,
slide
:
videoVolumeControl
.
onChange
slide
:
videoVolumeControl
.
onChange
...
...
common/lib/xmodule/xmodule/js/src/videoalpha/01_initialize.js
View file @
0b58c22b
...
@@ -93,14 +93,7 @@ function (VideoPlayer) {
...
@@ -93,14 +93,7 @@ function (VideoPlayer) {
fadeOutTimeout
:
1400
,
fadeOutTimeout
:
1400
,
availableQualities
:
[
'hd720'
,
'hd1080'
,
'highres'
],
availableQualities
:
[
'hd720'
,
'hd1080'
,
'highres'
]
qTipConfig
:
{
position
:
{
my
:
'top right'
,
at
:
'top center'
}
}
};
};
if
(
!
(
_parseYouTubeIDs
(
state
)))
{
if
(
!
(
_parseYouTubeIDs
(
state
)))
{
...
...
common/lib/xmodule/xmodule/js/src/videoalpha/04_video_control.js
View file @
0b58c22b
...
@@ -53,9 +53,6 @@ function () {
...
@@ -53,9 +53,6 @@ function () {
if
(
!
onTouchBasedDevice
())
{
if
(
!
onTouchBasedDevice
())
{
state
.
videoControl
.
pause
();
state
.
videoControl
.
pause
();
state
.
videoControl
.
playPauseEl
.
qtip
(
state
.
config
.
qTipConfig
);
state
.
videoControl
.
fullScreenEl
.
qtip
(
state
.
config
.
qTipConfig
);
}
else
{
}
else
{
state
.
videoControl
.
play
();
state
.
videoControl
.
play
();
}
}
...
@@ -77,7 +74,8 @@ function () {
...
@@ -77,7 +74,8 @@ function () {
$
(
document
).
on
(
'keyup'
,
state
.
videoControl
.
exitFullScreen
);
$
(
document
).
on
(
'keyup'
,
state
.
videoControl
.
exitFullScreen
);
if
(
state
.
videoType
===
'html5'
)
{
if
(
state
.
videoType
===
'html5'
)
{
state
.
el
.
on
(
'mousemove'
,
state
.
videoControl
.
showControls
)
state
.
el
.
on
(
'mousemove'
,
state
.
videoControl
.
showControls
);
state
.
el
.
on
(
'keydown'
,
state
.
videoControl
.
showControls
);
}
}
}
}
...
...
common/lib/xmodule/xmodule/js/src/videoalpha/05_video_quality_control.js
View file @
0b58c22b
...
@@ -43,10 +43,6 @@ function () {
...
@@ -43,10 +43,6 @@ function () {
state
.
videoQualityControl
.
el
.
show
();
state
.
videoQualityControl
.
el
.
show
();
state
.
videoQualityControl
.
quality
=
null
;
state
.
videoQualityControl
.
quality
=
null
;
if
(
!
onTouchBasedDevice
())
{
state
.
videoQualityControl
.
el
.
qtip
(
state
.
config
.
qTipConfig
);
}
}
}
// function _bindHandlers(state)
// function _bindHandlers(state)
...
...
common/lib/xmodule/xmodule/js/src/videoalpha/06_video_progress_slider.js
View file @
0b58c22b
...
@@ -32,9 +32,7 @@ function () {
...
@@ -32,9 +32,7 @@ function () {
// get the 'state' object as a context.
// get the 'state' object as a context.
function
_makeFunctionsPublic
(
state
)
{
function
_makeFunctionsPublic
(
state
)
{
state
.
videoProgressSlider
.
onSlide
=
_
.
bind
(
onSlide
,
state
);
state
.
videoProgressSlider
.
onSlide
=
_
.
bind
(
onSlide
,
state
);
state
.
videoProgressSlider
.
onChange
=
_
.
bind
(
onChange
,
state
);
state
.
videoProgressSlider
.
onStop
=
_
.
bind
(
onStop
,
state
);
state
.
videoProgressSlider
.
onStop
=
_
.
bind
(
onStop
,
state
);
state
.
videoProgressSlider
.
updateTooltip
=
_
.
bind
(
updateTooltip
,
state
);
state
.
videoProgressSlider
.
updatePlayTime
=
_
.
bind
(
updatePlayTime
,
state
);
state
.
videoProgressSlider
.
updatePlayTime
=
_
.
bind
(
updatePlayTime
,
state
);
//Added for tests -- JM
//Added for tests -- JM
state
.
videoProgressSlider
.
buildSlider
=
_
.
bind
(
buildSlider
,
state
);
state
.
videoProgressSlider
.
buildSlider
=
_
.
bind
(
buildSlider
,
state
);
...
@@ -56,22 +54,6 @@ function () {
...
@@ -56,22 +54,6 @@ function () {
function
_buildHandle
(
state
)
{
function
_buildHandle
(
state
)
{
state
.
videoProgressSlider
.
handle
=
state
.
videoProgressSlider
.
el
.
find
(
'.ui-slider-handle'
);
state
.
videoProgressSlider
.
handle
=
state
.
videoProgressSlider
.
el
.
find
(
'.ui-slider-handle'
);
state
.
videoProgressSlider
.
handle
.
qtip
({
content
:
''
+
Time
.
format
(
state
.
videoProgressSlider
.
slider
.
slider
(
'value'
)),
position
:
{
my
:
'bottom center'
,
at
:
'top center'
,
container
:
state
.
videoProgressSlider
.
handle
},
hide
:
{
delay
:
700
},
style
:
{
classes
:
'ui-tooltip-slider'
,
widget
:
true
}
});
}
}
// ***************************************************************
// ***************************************************************
...
@@ -83,7 +65,6 @@ function () {
...
@@ -83,7 +65,6 @@ function () {
function
buildSlider
(
state
)
{
function
buildSlider
(
state
)
{
state
.
videoProgressSlider
.
slider
=
state
.
videoProgressSlider
.
el
.
slider
({
state
.
videoProgressSlider
.
slider
=
state
.
videoProgressSlider
.
el
.
slider
({
range
:
'min'
,
range
:
'min'
,
change
:
state
.
videoProgressSlider
.
onChange
,
slide
:
state
.
videoProgressSlider
.
onSlide
,
slide
:
state
.
videoProgressSlider
.
onSlide
,
stop
:
state
.
videoProgressSlider
.
onStop
stop
:
state
.
videoProgressSlider
.
onStop
});
});
...
@@ -91,15 +72,10 @@ function () {
...
@@ -91,15 +72,10 @@ function () {
function
onSlide
(
event
,
ui
)
{
function
onSlide
(
event
,
ui
)
{
this
.
videoProgressSlider
.
frozen
=
true
;
this
.
videoProgressSlider
.
frozen
=
true
;
this
.
videoProgressSlider
.
updateTooltip
(
ui
.
value
);
this
.
trigger
(
'videoPlayer.onSlideSeek'
,
{
'type'
:
'onSlideSeek'
,
'time'
:
ui
.
value
});
this
.
trigger
(
'videoPlayer.onSlideSeek'
,
{
'type'
:
'onSlideSeek'
,
'time'
:
ui
.
value
});
}
}
function
onChange
(
event
,
ui
)
{
this
.
videoProgressSlider
.
updateTooltip
(
ui
.
value
);
}
function
onStop
(
event
,
ui
)
{
function
onStop
(
event
,
ui
)
{
var
_this
=
this
;
var
_this
=
this
;
...
@@ -112,10 +88,6 @@ function () {
...
@@ -112,10 +88,6 @@ function () {
},
200
);
},
200
);
}
}
function
updateTooltip
(
value
)
{
this
.
videoProgressSlider
.
handle
.
qtip
(
'option'
,
'content.text'
,
''
+
Time
.
format
(
value
));
}
//Changed for tests -- JM: Check if it is the cause of Chrome Bug Valera noticed
//Changed for tests -- JM: Check if it is the cause of Chrome Bug Valera noticed
function
updatePlayTime
(
params
)
{
function
updatePlayTime
(
params
)
{
if
((
this
.
videoProgressSlider
.
slider
)
&&
(
!
this
.
videoProgressSlider
.
frozen
))
{
if
((
this
.
videoProgressSlider
.
slider
)
&&
(
!
this
.
videoProgressSlider
.
frozen
))
{
...
...
common/lib/xmodule/xmodule/js/src/videoalpha/07_video_volume_control.js
View file @
0b58c22b
...
@@ -61,6 +61,9 @@ function () {
...
@@ -61,6 +61,9 @@ 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
);
}
}
...
@@ -74,9 +77,21 @@ function () {
...
@@ -74,9 +77,21 @@ function () {
$
(
this
).
addClass
(
'open'
);
$
(
this
).
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'
);
$
(
this
).
removeClass
(
'open'
);
});
});
state
.
videoVolumeControl
.
buttonEl
.
on
(
'blur'
,
function
()
{
state
.
videoVolumeControl
.
volumeSliderEl
.
find
(
'a'
).
focus
();
});
state
.
videoVolumeControl
.
volumeSliderEl
.
find
(
'a'
).
on
(
'blur'
,
function
()
{
state
.
videoVolumeControl
.
el
.
removeClass
(
'open'
);
});
}
}
// ***************************************************************
// ***************************************************************
...
...
common/lib/xmodule/xmodule/js/src/videoalpha/08_video_speed_control.js
View file @
0b58c22b
...
@@ -21,34 +21,41 @@ function () {
...
@@ -21,34 +21,41 @@ function () {
// function _makeFunctionsPublic(state)
// function _makeFunctionsPublic(state)
//
//
// Functions which will be accessible via 'state' object. When called,
these functions will
// Functions which will be accessible via 'state' object. When called,
// get the 'state' object as a context.
//
these functions will
get the 'state' object as a context.
function
_makeFunctionsPublic
(
state
)
{
function
_makeFunctionsPublic
(
state
)
{
state
.
videoSpeedControl
.
changeVideoSpeed
=
_
.
bind
(
changeVideoSpeed
,
state
);
state
.
videoSpeedControl
.
changeVideoSpeed
=
_
.
bind
(
changeVideoSpeed
,
state
);
state
.
videoSpeedControl
.
setSpeed
=
_
.
bind
(
setSpeed
,
state
);
state
.
videoSpeedControl
.
setSpeed
=
_
.
bind
(
setSpeed
,
state
);
state
.
videoSpeedControl
.
reRender
=
_
.
bind
(
reRender
,
state
);
state
.
videoSpeedControl
.
reRender
=
_
.
bind
(
reRender
,
state
);
}
}
// function _renderElements(state)
// function _renderElements(state)
//
//
// Create any necessary DOM elements, attach them, and set their initial configuration. Also
// Create any necessary DOM elements, attach them, and set their
// make the created DOM elements available via the 'state' object. Much easier to work this
// initial configuration. Also make the created DOM elements available
// way - you don't have to do repeated jQuery element selects.
// via the 'state' object. Much easier to work this way - you don't
// have to do repeated jQuery element selects.
function
_renderElements
(
state
)
{
function
_renderElements
(
state
)
{
state
.
videoSpeedControl
.
speeds
=
state
.
speeds
;
state
.
videoSpeedControl
.
speeds
=
state
.
speeds
;
state
.
videoSpeedControl
.
el
=
state
.
el
.
find
(
'div.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
)
{
$
.
each
(
state
.
videoSpeedControl
.
speeds
,
function
(
index
,
speed
)
{
var
link
=
'<a class="speed_link" href="#">'
+
speed
+
'x</a>'
;
//var link = $('<a href="#">' + speed + 'x</a>');
state
.
videoSpeedControl
.
videoSpeedsEl
var
link
=
'<a href="#">'
+
speed
+
'x</a>'
;
.
prepend
(
$
(
'<li data-speed="'
+
speed
+
'">'
+
link
+
'</li>'
)
state
.
videoSpeedControl
.
videoSpeedsEl
.
prepend
(
$
(
'<li data-speed="'
+
speed
+
'">'
+
link
+
'</li>'
)
);
);
});
});
state
.
videoSpeedControl
.
setSpeed
(
state
.
speed
);
state
.
videoSpeedControl
.
setSpeed
(
state
.
speed
);
...
@@ -56,9 +63,11 @@ function () {
...
@@ -56,9 +63,11 @@ function () {
// function _bindHandlers(state)
// 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
)
{
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
())
{
if
(
onTouchBasedDevice
())
{
state
.
videoSpeedControl
.
el
.
on
(
'click'
,
function
(
event
)
{
state
.
videoSpeedControl
.
el
.
on
(
'click'
,
function
(
event
)
{
...
@@ -77,18 +86,36 @@ function () {
...
@@ -77,18 +86,36 @@ function () {
event
.
preventDefault
();
event
.
preventDefault
();
$
(
this
).
removeClass
(
'open'
);
$
(
this
).
removeClass
(
'open'
);
});
});
state
.
videoSpeedControl
.
el
.
children
(
'a'
)
.
on
(
'focus'
,
function
()
{
$
(
this
).
parent
().
addClass
(
'open'
);
})
.
on
(
'blur'
,
function
()
{
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.
// Public functions start here.
// These are available via the 'state' object. Their context ('this' keyword) is the 'state' object.
// These are available via the 'state' object. Their context ('this'
// The magic private function that makes them available and sets up their context is makeFunctionsPublic().
// keyword) is the 'state' object. The magic private function that makes
// them available and sets up their context is makeFunctionsPublic().
// ***************************************************************
// ***************************************************************
function
setSpeed
(
speed
)
{
function
setSpeed
(
speed
)
{
this
.
videoSpeedControl
.
videoSpeedsEl
.
find
(
'li'
).
removeClass
(
'active'
);
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'
);
this
.
videoSpeedControl
.
el
.
find
(
'p.active'
).
html
(
''
+
speed
+
'x'
);
}
}
...
@@ -102,10 +129,15 @@ function () {
...
@@ -102,10 +129,15 @@ function () {
this
.
videoSpeedControl
.
setSpeed
(
this
.
videoSpeedControl
.
setSpeed
(
// To meet the API expected format.
// 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
);
}
}
}
}
...
@@ -119,7 +151,6 @@ function () {
...
@@ -119,7 +151,6 @@ 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 href="#">'
+
speed
+
'x</a>'
;
link
=
'<a href="#">'
+
speed
+
'x</a>'
;
listItem
=
$
(
'<li data-speed="'
+
speed
+
'">'
+
link
+
'</li>'
);
listItem
=
$
(
'<li data-speed="'
+
speed
+
'">'
+
link
+
'</li>'
);
...
@@ -131,7 +162,11 @@ function () {
...
@@ -131,7 +162,11 @@ function () {
_this
.
videoSpeedControl
.
videoSpeedsEl
.
prepend
(
listItem
);
_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.
}
}
});
});
...
...
common/lib/xmodule/xmodule/js/src/videoalpha/09_video_caption.js
View file @
0b58c22b
...
@@ -109,6 +109,7 @@ function () {
...
@@ -109,6 +109,7 @@ function () {
if
(
this
.
videoType
===
'html5'
)
{
if
(
this
.
videoType
===
'html5'
)
{
this
.
el
.
on
(
'mousemove'
,
this
.
videoCaption
.
autoShowCaptions
);
this
.
el
.
on
(
'mousemove'
,
this
.
videoCaption
.
autoShowCaptions
);
this
.
el
.
on
(
'keydown'
,
this
.
videoCaption
.
autoShowCaptions
);
// Moving slider on subtitles is not a mouse move,
// Moving slider on subtitles is not a mouse move,
// but captions and controls should be showed.
// but captions and controls should be showed.
...
@@ -122,6 +123,10 @@ function () {
...
@@ -122,6 +123,10 @@ function () {
this
.
videoCaption
.
hideCaptions
(
this
.
hide_captions
);
this
.
videoCaption
.
hideCaptions
(
this
.
hide_captions
);
if
(
!
this
.
youtubeId
(
'1.0'
))
{
return
;
}
$
.
ajaxWithPrefix
({
$
.
ajaxWithPrefix
({
url
:
_this
.
videoCaption
.
captionURL
(),
url
:
_this
.
videoCaption
.
captionURL
(),
notifyOnError
:
false
,
notifyOnError
:
false
,
...
...
lms/templates/videoalpha.html
View file @
0b58c22b
<
%!
from
django
.
utils
.
translation
import
ugettext
as
_
%
>
<
%!
from
django
.
utils
.
translation
import
ugettext
as
_
%
>
% if display_name is not UNDEFINED and display_name is not None:
% if display_name is not UNDEFINED and display_name is not None:
<h2>
${display_name}
</h2>
<h2>
${display_name}
</h2>
% endif
% endif
<div
<div
id=
"video_${id}"
id=
"video_${id}"
class=
"videoalpha"
class=
"videoalpha"
%
if
not
settings
.
MITX_FEATURES
['
STUB_VIDEO_FOR_TESTING
']
:
%
if
not
settings
.
MITX_FEATURES
['
STUB_VIDEO_FOR_TESTING
']
:
data-streams=
"${youtube_streams}"
data-streams=
"${youtube_streams}"
%
endif
%
endif
${'
data-sub=
"{}"
'.
format
(
sub
)
if
sub
else
''}
${'
data-sub=
"{}"
'.
format
(
sub
)
if
sub
else
''}
${'
data-autoplay=
"{}"
'.
format
(
autoplay
)
if
autoplay
else
''}
${'
data-autoplay=
"{}"
'.
format
(
autoplay
)
if
autoplay
else
''}
%
if
not
settings
.
MITX_FEATURES
['
STUB_VIDEO_FOR_TESTING
']
:
${'
data-mp4-source=
"{}"
'.
format
(
sources
.
get
('
mp4
'))
if
sources
.
get
('
mp4
')
else
''}
${'
data-webm-source=
"{}"
'.
format
(
sources
.
get
('
webm
'))
if
sources
.
get
('
webm
')
else
''}
${'
data-ogg-source=
"{}"
'.
format
(
sources
.
get
('
ogv
'))
if
sources
.
get
('
ogv
')
else
''}
%
endif
data-caption-data-dir=
"${data_dir}"
%
if
not
settings
.
MITX_FEATURES
['
STUB_VIDEO_FOR_TESTING
']
:
data-show-captions=
"${show_captions}"
${'
data-mp4-source=
"{}"
'.
format
(
sources
.
get
('
mp4
'))
if
sources
.
get
('
mp4
')
else
''}
data-start=
"${start}"
${'
data-webm-source=
"{}"
'.
format
(
sources
.
get
('
webm
'))
if
sources
.
get
('
webm
')
else
''}
data-end=
"${end}"
${'
data-ogg-source=
"{}"
'.
format
(
sources
.
get
('
ogv
'))
if
sources
.
get
('
ogv
')
else
''}
data-caption-asset-path=
"${caption_asset_path}"
%
endif
data-autoplay=
"${autoplay}"
data-caption-data-dir=
"${data_dir}"
data-show-captions=
"${show_captions}"
data-start=
"${start}"
data-end=
"${end}"
data-caption-asset-path=
"${caption_asset_path}"
data-autoplay=
"${autoplay}"
>
>
<div
class=
"tc-wrapper"
>
<div
class=
"tc-wrapper"
>
<article
class=
"video-wrapper"
>
<article
class=
"video-wrapper"
>
<div
class=
"video-player-pre"
></div>
<div
class=
"video-player-pre"
></div>
<section
class=
"video-player"
>
<div
id=
"${id}"
></div>
<section
class=
"video-player"
>
</section>
<div
id=
"${id}"
></div>
<div
class=
"video-player-post"
></div>
</section>
<section
class=
"video-controls"
>
<div
class=
"slider"
></div>
<div
class=
"video-player-post"
></div>
<div>
<ul
class=
"vcr"
>
<section
class=
"video-controls"
>
<li><a
class=
"video_control"
href=
"#"
title=
"${_('Play')}"
></a></li>
<div
class=
"slider"
tabindex=
"0"
title=
"Video position"
></div>
<li><div
class=
"vidtime"
>
0:00 / 0:00
</div></li>
</ul>
<div>
<div
class=
"secondary-controls"
>
<ul
class=
"vcr"
>
<div
class=
"speeds"
>
<li><a
class=
"video_control"
href=
"#"
tabindex=
"0"
title=
"${_('Play')}"
></a></li>
<a
href=
"#"
>
<li><div
class=
"vidtime"
>
0:00 / 0:00
</div></li>
<h3>
${_('Speed')}
</h3>
</ul>
<p
class=
"active"
></p>
<div
class=
"secondary-controls"
>
</a>
<div
class=
"speeds"
>
<ol
class=
"video_speeds"
></ol>
<a
href=
"#"
tabindex=
"0"
title=
"Speeds"
>
</div>
<h3
tabindex=
"-1"
>
${_('Speed')}
</h3>
<div
class=
"volume"
>
<p
tabindex=
"-1"
class=
"active"
></p>
<a
href=
"#"
></a>
</a>
<div
class=
"volume-slider-container"
>
<ol
tabindex=
"-1"
class=
"video_speeds"
></ol>
<div
class=
"volume-slider"
></div>
</div>
</div>
</div>
<div
class=
"volume"
>
<a
href=
"#"
class=
"add-fullscreen"
title=
"${_('Fill browser')}"
>
${_('Fill browser')}
</a>
<a
href=
"#"
tabindex=
"0"
title=
"Volume"
></a>
<a
href=
"#"
class=
"quality_control"
title=
"${_('HD')}"
>
${_('HD')}
</a>
<div
tabindex=
"-1"
class=
"volume-slider-container"
>
<div
tabindex=
"-1"
class=
"volume-slider"
></div>
</div>
</div>
<a
href=
"#"
class=
"add-fullscreen"
tabindex=
"0"
title=
"${_('Fill browser')}"
>
${_('Fill browser')}
</a>
<a
href=
"#"
class=
"quality_control"
tabindex=
"0"
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>
</div>
</div>
</section>
</section>
</article>
</article>
<ol
class=
"subtitles"
><li></li></ol>
</div>
<ol
class=
"subtitles"
tabindex=
"0"
title=
"Captions"
><li></li></ol>
</div>
</div>
</div>
% if sources.get('main'):
% if sources.get('main'):
<div
class=
"video-sources"
>
<div
class=
"video-sources"
>
<p>
${_('Download video
<a
href=
"%s"
>
here
</a>
.') % sources.get('main')}
</p>
<p>
${(_('Download video') + '
<a
href=
"%s"
>
' + _('here') + '
</a>
.') % sources.get('main')}
</p>
</div>
</div>
% endif
% endif
% if track:
% if track:
<div
class=
"video-tracks"
>
<div
class=
"video-tracks"
>
<p>
${_('Download subtitles
<a
href=
"%s"
>
here
</a>
.') % track}
</p>
<p>
${(_('Download subtitles') + '
<a
href=
"%s"
>
' + _('here') + '
</a>
.') % track}
</p>
</div>
</div>
% endif
% endif
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