wai-website-theme 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +52 -0
- data/_data/lang.json +730 -0
- data/_data/techniques.yml +180 -0
- data/_data/wcag.yml +125 -0
- data/_includes/.DS_Store +0 -0
- data/_includes/body-class.html +1 -0
- data/_includes/box.html +10 -0
- data/_includes/excol.html +13 -0
- data/_includes/footer.html +40 -0
- data/_includes/head.html +23 -0
- data/_includes/header.html +59 -0
- data/_includes/icon.html +6 -0
- data/_includes/img.html +17 -0
- data/_includes/multilang-list-policy-links.html +29 -0
- data/_includes/multilang-list.html +35 -0
- data/_includes/multilang-policy-title.html +5 -0
- data/_includes/multilang-title-full.html +1 -0
- data/_includes/multilang-title.html +1 -0
- data/_includes/navlist.html +22 -0
- data/_includes/notes.html +2 -0
- data/_includes/prevnext.html +34 -0
- data/_includes/resources.html +19 -0
- data/_includes/sidenav.html +65 -0
- data/_includes/sidenote.html +14 -0
- data/_includes/toc.html +10 -0
- data/_includes/video-player.html +99 -0
- data/_layouts/default.html +26 -0
- data/_layouts/home.html +14 -0
- data/_layouts/news.html +21 -0
- data/_layouts/none.html +1 -0
- data/_layouts/policy.html +72 -0
- data/_layouts/sidenav.html +27 -0
- data/_layouts/sidenavsidebar.html +22 -0
- data/assets/ableplayer/.gitattributes +14 -0
- data/assets/ableplayer/.gitignore +7 -0
- data/assets/ableplayer/Gruntfile.js +105 -0
- data/assets/ableplayer/LICENSE +26 -0
- data/assets/ableplayer/README.md +656 -0
- data/assets/ableplayer/build/ableplayer.dist.js +12157 -0
- data/assets/ableplayer/build/ableplayer.js +12157 -0
- data/assets/ableplayer/build/ableplayer.min.css +2 -0
- data/assets/ableplayer/build/ableplayer.min.js +8 -0
- data/assets/ableplayer/button-icons/able-icons.svg +116 -0
- data/assets/ableplayer/button-icons/black/captions.png +0 -0
- data/assets/ableplayer/button-icons/black/chapters.png +0 -0
- data/assets/ableplayer/button-icons/black/close.png +0 -0
- data/assets/ableplayer/button-icons/black/descriptions.png +0 -0
- data/assets/ableplayer/button-icons/black/ellipsis.png +0 -0
- data/assets/ableplayer/button-icons/black/faster.png +0 -0
- data/assets/ableplayer/button-icons/black/forward.png +0 -0
- data/assets/ableplayer/button-icons/black/fullscreen-collapse.png +0 -0
- data/assets/ableplayer/button-icons/black/fullscreen-expand.png +0 -0
- data/assets/ableplayer/button-icons/black/help.png +0 -0
- data/assets/ableplayer/button-icons/black/next.png +0 -0
- data/assets/ableplayer/button-icons/black/pause.png +0 -0
- data/assets/ableplayer/button-icons/black/pipe.png +0 -0
- data/assets/ableplayer/button-icons/black/play.png +0 -0
- data/assets/ableplayer/button-icons/black/preferences.png +0 -0
- data/assets/ableplayer/button-icons/black/previous.png +0 -0
- data/assets/ableplayer/button-icons/black/rabbit.png +0 -0
- data/assets/ableplayer/button-icons/black/restart.png +0 -0
- data/assets/ableplayer/button-icons/black/rewind.png +0 -0
- data/assets/ableplayer/button-icons/black/sign.png +0 -0
- data/assets/ableplayer/button-icons/black/slower.png +0 -0
- data/assets/ableplayer/button-icons/black/stop.png +0 -0
- data/assets/ableplayer/button-icons/black/transcript.png +0 -0
- data/assets/ableplayer/button-icons/black/turtle.png +0 -0
- data/assets/ableplayer/button-icons/black/volume-loud.png +0 -0
- data/assets/ableplayer/button-icons/black/volume-medium.png +0 -0
- data/assets/ableplayer/button-icons/black/volume-mute.png +0 -0
- data/assets/ableplayer/button-icons/black/volume-soft.png +0 -0
- data/assets/ableplayer/button-icons/fonts/able.eot +0 -0
- data/assets/ableplayer/button-icons/fonts/able.svg +40 -0
- data/assets/ableplayer/button-icons/fonts/able.ttf +0 -0
- data/assets/ableplayer/button-icons/fonts/able.woff +0 -0
- data/assets/ableplayer/button-icons/white/captions.png +0 -0
- data/assets/ableplayer/button-icons/white/chapters.png +0 -0
- data/assets/ableplayer/button-icons/white/close.png +0 -0
- data/assets/ableplayer/button-icons/white/descriptions.png +0 -0
- data/assets/ableplayer/button-icons/white/ellipsis.png +0 -0
- data/assets/ableplayer/button-icons/white/faster.png +0 -0
- data/assets/ableplayer/button-icons/white/forward.png +0 -0
- data/assets/ableplayer/button-icons/white/fullscreen-collapse.png +0 -0
- data/assets/ableplayer/button-icons/white/fullscreen-expand.png +0 -0
- data/assets/ableplayer/button-icons/white/help.png +0 -0
- data/assets/ableplayer/button-icons/white/next.png +0 -0
- data/assets/ableplayer/button-icons/white/pause.png +0 -0
- data/assets/ableplayer/button-icons/white/pipe.png +0 -0
- data/assets/ableplayer/button-icons/white/play.png +0 -0
- data/assets/ableplayer/button-icons/white/preferences.png +0 -0
- data/assets/ableplayer/button-icons/white/previous.png +0 -0
- data/assets/ableplayer/button-icons/white/rabbit.png +0 -0
- data/assets/ableplayer/button-icons/white/restart.png +0 -0
- data/assets/ableplayer/button-icons/white/rewind.png +0 -0
- data/assets/ableplayer/button-icons/white/sign.png +0 -0
- data/assets/ableplayer/button-icons/white/slower.png +0 -0
- data/assets/ableplayer/button-icons/white/stop.png +0 -0
- data/assets/ableplayer/button-icons/white/transcript.png +0 -0
- data/assets/ableplayer/button-icons/white/turtle.png +0 -0
- data/assets/ableplayer/button-icons/white/volume-loud.png +0 -0
- data/assets/ableplayer/button-icons/white/volume-medium.png +0 -0
- data/assets/ableplayer/button-icons/white/volume-mute.png +0 -0
- data/assets/ableplayer/button-icons/white/volume-soft.png +0 -0
- data/assets/ableplayer/images/wingrip.png +0 -0
- data/assets/ableplayer/package.json +22 -0
- data/assets/ableplayer/scripts/JQuery.doWhen.js +113 -0
- data/assets/ableplayer/scripts/ableplayer-base.js +440 -0
- data/assets/ableplayer/scripts/browser.js +162 -0
- data/assets/ableplayer/scripts/buildplayer.js +1609 -0
- data/assets/ableplayer/scripts/caption.js +385 -0
- data/assets/ableplayer/scripts/chapters.js +242 -0
- data/assets/ableplayer/scripts/control.js +1514 -0
- data/assets/ableplayer/scripts/description.js +283 -0
- data/assets/ableplayer/scripts/dialog.js +147 -0
- data/assets/ableplayer/scripts/dragdrop.js +766 -0
- data/assets/ableplayer/scripts/event.js +595 -0
- data/assets/ableplayer/scripts/initialize.js +725 -0
- data/assets/ableplayer/scripts/langs.js +750 -0
- data/assets/ableplayer/scripts/metadata.js +134 -0
- data/assets/ableplayer/scripts/misc.js +72 -0
- data/assets/ableplayer/scripts/preference.js +909 -0
- data/assets/ableplayer/scripts/search.js +171 -0
- data/assets/ableplayer/scripts/sign.js +92 -0
- data/assets/ableplayer/scripts/slider.js +454 -0
- data/assets/ableplayer/scripts/track.js +296 -0
- data/assets/ableplayer/scripts/transcript.js +590 -0
- data/assets/ableplayer/scripts/translation.js +66 -0
- data/assets/ableplayer/scripts/volume.js +383 -0
- data/assets/ableplayer/scripts/webvtt.js +765 -0
- data/assets/ableplayer/scripts/youtube.js +471 -0
- data/assets/ableplayer/styles/ableplayer.css +1241 -0
- data/assets/ableplayer/thirdparty/js.cookie.js +145 -0
- data/assets/ableplayer/thirdparty/modernizr.custom.js +4 -0
- data/assets/ableplayer/translations/ca.js +1 -0
- data/assets/ableplayer/translations/de.js +1 -0
- data/assets/ableplayer/translations/en.js +305 -0
- data/assets/ableplayer/translations/es.js +305 -0
- data/assets/ableplayer/translations/fr.js +305 -0
- data/assets/ableplayer/translations/it.js +303 -0
- data/assets/ableplayer/translations/ja.js +305 -0
- data/assets/ableplayer/translations/nl.js +305 -0
- data/assets/css/style.css +4360 -0
- data/assets/css/style.css.map +1 -0
- data/assets/fonts/anonymouspro-bold.woff +0 -0
- data/assets/fonts/anonymouspro-bold.woff2 +0 -0
- data/assets/fonts/anonymouspro-bolditalic.woff +0 -0
- data/assets/fonts/anonymouspro-bolditalic.woff2 +0 -0
- data/assets/fonts/anonymouspro-italic.woff +0 -0
- data/assets/fonts/anonymouspro-italic.woff2 +0 -0
- data/assets/fonts/anonymouspro-regular.woff +0 -0
- data/assets/fonts/anonymouspro-regular.woff2 +0 -0
- data/assets/fonts/notosans-bold.woff +0 -0
- data/assets/fonts/notosans-bold.woff2 +0 -0
- data/assets/fonts/notosans-bolditalic.woff +0 -0
- data/assets/fonts/notosans-bolditalic.woff2 +0 -0
- data/assets/fonts/notosans-italic.woff +0 -0
- data/assets/fonts/notosans-italic.woff2 +0 -0
- data/assets/fonts/notosans-regular.woff +0 -0
- data/assets/fonts/notosans-regular.woff2 +0 -0
- data/assets/images/.DS_Store +0 -0
- data/assets/images/Shape.svg +10 -0
- data/assets/images/icon-related-content.svg +14 -0
- data/assets/images/icons.svg +126 -0
- data/assets/images/teaser-image@1x.jpg +0 -0
- data/assets/images/teaser-image@2x.jpg +0 -0
- data/assets/images/w3c.sketch +0 -0
- data/assets/images/w3c.svg +10 -0
- data/assets/scripts/jquery.min.js +4 -0
- data/assets/scripts/main.js +208 -0
- data/assets/scripts/svg4everybody.js +1 -0
- metadata +257 -0
|
@@ -0,0 +1,595 @@
|
|
|
1
|
+
(function ($) {
|
|
2
|
+
// Media events
|
|
3
|
+
AblePlayer.prototype.onMediaUpdateTime = function () {
|
|
4
|
+
|
|
5
|
+
var currentTime = this.getElapsed();
|
|
6
|
+
if (this.swappingSrc && (typeof this.swapTime !== 'undefined')) {
|
|
7
|
+
if (this.swapTime === currentTime) {
|
|
8
|
+
// described version been swapped and media has scrubbed to time of previous version
|
|
9
|
+
if (this.playing) {
|
|
10
|
+
// resume playback
|
|
11
|
+
this.playMedia();
|
|
12
|
+
// reset vars
|
|
13
|
+
this.swappingSrc = false;
|
|
14
|
+
this.swapTime = null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
else if (this.startedPlaying) {
|
|
19
|
+
// do all the usual time-sync stuff during playback
|
|
20
|
+
if (this.prefHighlight === 1) {
|
|
21
|
+
this.highlightTranscript(currentTime);
|
|
22
|
+
}
|
|
23
|
+
this.updateCaption();
|
|
24
|
+
this.showDescription(currentTime);
|
|
25
|
+
this.updateChapter(currentTime);
|
|
26
|
+
this.updateMeta();
|
|
27
|
+
this.refreshControls();
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
AblePlayer.prototype.onMediaPause = function () {
|
|
32
|
+
// do something
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
AblePlayer.prototype.onMediaComplete = function () {
|
|
36
|
+
// if there's a playlist, advance to next item and start playing
|
|
37
|
+
if (this.hasPlaylist) {
|
|
38
|
+
if (this.playlistIndex === (this.$playlist.length - 1)) {
|
|
39
|
+
// this is the last track in the playlist
|
|
40
|
+
if (this.loop) {
|
|
41
|
+
this.playlistIndex = 0;
|
|
42
|
+
this.swapSource(0);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// this is not the last track. Play the next one.
|
|
47
|
+
this.playlistIndex++;
|
|
48
|
+
this.swapSource(this.playlistIndex)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
this.refreshControls();
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
AblePlayer.prototype.onMediaNewSourceLoad = function () {
|
|
55
|
+
|
|
56
|
+
if (this.swappingSrc === true) {
|
|
57
|
+
// new source file has just been loaded
|
|
58
|
+
if (this.swapTime > 0) {
|
|
59
|
+
// this.swappingSrc will be set to false after seek is complete
|
|
60
|
+
// see onMediaUpdateTime()
|
|
61
|
+
this.seekTo(this.swapTime);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
if (this.playing) {
|
|
65
|
+
// should be able to resume playback
|
|
66
|
+
if (this.player === 'jw') {
|
|
67
|
+
var player = this.jwPlayer;
|
|
68
|
+
// Seems to be a bug in JW player, where this doesn't work when fired immediately.
|
|
69
|
+
// Thus have to use a setTimeout
|
|
70
|
+
setTimeout(function () {
|
|
71
|
+
player.play(true);
|
|
72
|
+
}, 500);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
this.playMedia();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
this.swappingSrc = false; // swapping is finished
|
|
79
|
+
this.refreshControls();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// End Media events
|
|
85
|
+
|
|
86
|
+
AblePlayer.prototype.onWindowResize = function () {
|
|
87
|
+
|
|
88
|
+
if (this.isFullscreen()) {
|
|
89
|
+
|
|
90
|
+
var newWidth, newHeight;
|
|
91
|
+
|
|
92
|
+
newWidth = $(window).width();
|
|
93
|
+
|
|
94
|
+
// haven't isolated why, but some browsers return an innerHeight that's 20px too tall in fullscreen mode
|
|
95
|
+
// Test results:
|
|
96
|
+
// Browsers that require a 20px adjustment: Firefox, IE11 (Trident), Edge
|
|
97
|
+
if (this.isUserAgent('Firefox') || this.isUserAgent('Trident') || this.isUserAgent('Edge')) {
|
|
98
|
+
newHeight = window.innerHeight - this.$playerDiv.outerHeight() - 20;
|
|
99
|
+
}
|
|
100
|
+
else if (window.outerHeight >= window.innerHeight) {
|
|
101
|
+
// Browsers that do NOT require adjustment: Chrome, Safari, Opera, MSIE 10
|
|
102
|
+
newHeight = window.innerHeight - this.$playerDiv.outerHeight();
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
// Observed in Safari 9.0.1 on Mac OS X: outerHeight is actually less than innerHeight
|
|
106
|
+
// Maybe a bug, or maybe window.outerHeight is already adjusted for controller height(?)
|
|
107
|
+
// No longer observed in Safari 9.0.2
|
|
108
|
+
newHeight = window.outerHeight;
|
|
109
|
+
}
|
|
110
|
+
if (!this.$descDiv.is(':hidden')) {
|
|
111
|
+
newHeight -= this.$descDiv.height();
|
|
112
|
+
}
|
|
113
|
+
this.positionCaptions('overlay');
|
|
114
|
+
}
|
|
115
|
+
else { // not fullscreen
|
|
116
|
+
if (this.restoringAfterFullScreen) {
|
|
117
|
+
newWidth = this.preFullScreenWidth;
|
|
118
|
+
newHeight = this.preFullScreenHeight;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// not restoring after full screen
|
|
122
|
+
newWidth = this.$ableWrapper.width();
|
|
123
|
+
if (typeof this.aspectRatio !== 'undefined') {
|
|
124
|
+
newHeight = Math.round(newWidth / this.aspectRatio);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
// not likely, since this.aspectRatio is defined during intialization
|
|
128
|
+
// however, this is a fallback scenario just in case
|
|
129
|
+
newHeight = this.$ableWrapper.height();
|
|
130
|
+
}
|
|
131
|
+
this.positionCaptions(); // reset with this.prefCaptionsPosition
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
this.resizePlayer(newWidth, newHeight);
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
AblePlayer.prototype.addSeekbarListeners = function () {
|
|
138
|
+
var thisObj = this;
|
|
139
|
+
|
|
140
|
+
// Handle seek bar events.
|
|
141
|
+
this.seekBar.bodyDiv.on('startTracking', function (event) {
|
|
142
|
+
thisObj.pausedBeforeTracking = thisObj.isPaused();
|
|
143
|
+
thisObj.pauseMedia();
|
|
144
|
+
}).on('tracking', function (event, position) {
|
|
145
|
+
// Scrub transcript, captions, and metadata.
|
|
146
|
+
thisObj.highlightTranscript(position);
|
|
147
|
+
thisObj.updateCaption(position);
|
|
148
|
+
thisObj.showDescription(position);
|
|
149
|
+
thisObj.updateChapter(thisObj.convertChapterTimeToVideoTime(position));
|
|
150
|
+
thisObj.updateMeta(position);
|
|
151
|
+
thisObj.refreshControls();
|
|
152
|
+
}).on('stopTracking', function (event, position) {
|
|
153
|
+
if (thisObj.useChapterTimes) {
|
|
154
|
+
thisObj.seekTo(thisObj.convertChapterTimeToVideoTime(position));
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
thisObj.seekTo(position);
|
|
158
|
+
}
|
|
159
|
+
if (!thisObj.pausedBeforeTracking) {
|
|
160
|
+
setTimeout(function () {
|
|
161
|
+
thisObj.playMedia();
|
|
162
|
+
}, 200);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
AblePlayer.prototype.onClickPlayerButton = function (el) {
|
|
168
|
+
// TODO: This is super-fragile since we need to know the length of the class name to split off; update this to other way of dispatching?
|
|
169
|
+
var whichButton = $(el).attr('class').split(' ')[0].substr(20);
|
|
170
|
+
if (whichButton === 'play') {
|
|
171
|
+
this.handlePlay();
|
|
172
|
+
}
|
|
173
|
+
else if (whichButton === 'restart') {
|
|
174
|
+
this.handleRestart();
|
|
175
|
+
}
|
|
176
|
+
else if (whichButton === 'rewind') {
|
|
177
|
+
this.handleRewind();
|
|
178
|
+
}
|
|
179
|
+
else if (whichButton === 'forward') {
|
|
180
|
+
this.handleFastForward();
|
|
181
|
+
}
|
|
182
|
+
else if (whichButton === 'mute') {
|
|
183
|
+
this.handleMute();
|
|
184
|
+
}
|
|
185
|
+
else if (whichButton === 'volume') {
|
|
186
|
+
this.handleVolume();
|
|
187
|
+
}
|
|
188
|
+
else if (whichButton === 'faster') {
|
|
189
|
+
this.handleRateIncrease();
|
|
190
|
+
}
|
|
191
|
+
else if (whichButton === 'slower') {
|
|
192
|
+
this.handleRateDecrease();
|
|
193
|
+
}
|
|
194
|
+
else if (whichButton === 'captions') {
|
|
195
|
+
this.handleCaptionToggle();
|
|
196
|
+
}
|
|
197
|
+
else if (whichButton === 'chapters') {
|
|
198
|
+
this.handleChapters();
|
|
199
|
+
}
|
|
200
|
+
else if (whichButton === 'descriptions') {
|
|
201
|
+
this.handleDescriptionToggle();
|
|
202
|
+
}
|
|
203
|
+
else if (whichButton === 'sign') {
|
|
204
|
+
this.handleSignToggle();
|
|
205
|
+
}
|
|
206
|
+
else if (whichButton === 'preferences') {
|
|
207
|
+
this.handlePrefsClick();
|
|
208
|
+
}
|
|
209
|
+
else if (whichButton === 'help') {
|
|
210
|
+
this.handleHelpClick();
|
|
211
|
+
}
|
|
212
|
+
else if (whichButton === 'transcript') {
|
|
213
|
+
this.handleTranscriptToggle();
|
|
214
|
+
}
|
|
215
|
+
else if (whichButton === 'fullscreen') {
|
|
216
|
+
this.handleFullscreenToggle();
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
AblePlayer.prototype.okToHandleKeyPress = function () {
|
|
221
|
+
|
|
222
|
+
// returns true unless user's focus is on a UI element
|
|
223
|
+
// that is likely to need supported keystrokes, including space
|
|
224
|
+
var activeElement = $(document.activeElement).prop('tagName');
|
|
225
|
+
if (activeElement === 'INPUT') {
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
AblePlayer.prototype.onPlayerKeyPress = function (e) {
|
|
234
|
+
// handle keystrokes (using DHTML Style Guide recommended key combinations)
|
|
235
|
+
// http://dev.aol.com/dhtml_style_guide/#mediaplayer
|
|
236
|
+
// Modifier keys Alt + Ctrl are on by default, but can be changed within Preferences
|
|
237
|
+
// NOTE #1: Style guide only supports Play/Pause, Stop, Mute, Captions, & Volume Up & Down
|
|
238
|
+
// The rest are reasonable best choices
|
|
239
|
+
// NOTE #2: If there are multiple players on a single page, keystroke handlers
|
|
240
|
+
// are only bound to the FIRST player
|
|
241
|
+
if (!this.okToHandleKeyPress()) {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
// Convert to lower case.
|
|
245
|
+
var which = e.which;
|
|
246
|
+
|
|
247
|
+
if (which >= 65 && which <= 90) {
|
|
248
|
+
which += 32;
|
|
249
|
+
}
|
|
250
|
+
if (which === 27) {
|
|
251
|
+
this.closePopups();
|
|
252
|
+
}
|
|
253
|
+
else if (which === 32) { // spacebar = play/pause
|
|
254
|
+
if (!($('.able-controller button').is(':focus'))) {
|
|
255
|
+
// only toggle play if a button does not have focus
|
|
256
|
+
// if a button has focus, space should activate that button
|
|
257
|
+
this.handlePlay();
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
else if (which === 112) { // p = play/pause
|
|
261
|
+
if (this.usingModifierKeys(e)) {
|
|
262
|
+
this.handlePlay();
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
else if (which === 115) { // s = stop (now restart)
|
|
266
|
+
if (this.usingModifierKeys(e)) {
|
|
267
|
+
this.handleRestart();
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
else if (which === 109) { // m = mute
|
|
271
|
+
if (this.usingModifierKeys(e)) {
|
|
272
|
+
this.handleMute();
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
else if (which === 118) { // v = volume
|
|
276
|
+
if (this.usingModifierKeys(e)) {
|
|
277
|
+
this.handleVolume();
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
else if (which >= 49 && which <= 57) { // set volume 1-9
|
|
281
|
+
if (this.usingModifierKeys(e)) {
|
|
282
|
+
this.handleVolume(which);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
else if (which === 99) { // c = caption toggle
|
|
286
|
+
if (this.usingModifierKeys(e)) {
|
|
287
|
+
this.handleCaptionToggle();
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
else if (which === 100) { // d = description
|
|
291
|
+
if (this.usingModifierKeys(e)) {
|
|
292
|
+
this.handleDescriptionToggle();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
else if (which === 102) { // f = forward
|
|
296
|
+
if (this.usingModifierKeys(e)) {
|
|
297
|
+
this.handleFastForward();
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
else if (which === 114) { // r = rewind
|
|
301
|
+
if (this.usingModifierKeys(e)) {
|
|
302
|
+
this.handleRewind();
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
else if (which === 101) { // e = preferences
|
|
306
|
+
if (this.usingModifierKeys(e)) {
|
|
307
|
+
this.handlePrefsClick();
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
else if (which === 13) { // Enter
|
|
311
|
+
var thisElement = $(document.activeElement);
|
|
312
|
+
if (thisElement.prop('tagName') === 'SPAN') {
|
|
313
|
+
// register a click on this SPAN
|
|
314
|
+
// if it's a transcript span the transcript span click handler will take over
|
|
315
|
+
thisElement.click();
|
|
316
|
+
}
|
|
317
|
+
else if (thisElement.prop('tagName') === 'LI') {
|
|
318
|
+
thisElement.click();
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
AblePlayer.prototype.addHtml5MediaListeners = function () {
|
|
324
|
+
|
|
325
|
+
var thisObj = this;
|
|
326
|
+
|
|
327
|
+
// NOTE: iOS does not support autoplay,
|
|
328
|
+
// and no events are triggered until media begins to play
|
|
329
|
+
this.$media
|
|
330
|
+
.on('emptied',function() {
|
|
331
|
+
// do something
|
|
332
|
+
})
|
|
333
|
+
.on('loadedmetadata',function() {
|
|
334
|
+
thisObj.onMediaNewSourceLoad();
|
|
335
|
+
})
|
|
336
|
+
.on('canplay',function() {
|
|
337
|
+
// previously handled seeking to startTime here
|
|
338
|
+
// but it's probably safer to wait for canplaythrough
|
|
339
|
+
// so we know player can seek ahead to anything
|
|
340
|
+
})
|
|
341
|
+
.on('canplaythrough',function() {
|
|
342
|
+
if (!thisObj.startedPlaying) {
|
|
343
|
+
if (thisObj.startTime) {
|
|
344
|
+
if (thisObj.seeking) {
|
|
345
|
+
// a seek has already been initiated
|
|
346
|
+
// since canplaythrough has been triggered, the seek is complete
|
|
347
|
+
thisObj.seeking = false;
|
|
348
|
+
if (thisObj.autoplay) {
|
|
349
|
+
thisObj.playMedia();
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
// haven't started seeking yet
|
|
354
|
+
thisObj.seekTo(thisObj.startTime);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
else if (thisObj.defaultChapter && typeof thisObj.selectedChapters !== 'undefined') {
|
|
358
|
+
thisObj.seekToChapter(thisObj.defaultChapter);
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
// there is now startTime, therefore no seeking required
|
|
362
|
+
if (thisObj.autoplay) {
|
|
363
|
+
thisObj.playMedia();
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
// already started playing
|
|
369
|
+
}
|
|
370
|
+
})
|
|
371
|
+
.on('playing',function() {
|
|
372
|
+
thisObj.playing = true;
|
|
373
|
+
thisObj.refreshControls();
|
|
374
|
+
})
|
|
375
|
+
.on('ended',function() {
|
|
376
|
+
thisObj.onMediaComplete();
|
|
377
|
+
})
|
|
378
|
+
.on('progress', function() {
|
|
379
|
+
thisObj.refreshControls();
|
|
380
|
+
})
|
|
381
|
+
.on('waiting',function() {
|
|
382
|
+
thisObj.refreshControls();
|
|
383
|
+
})
|
|
384
|
+
.on('durationchange',function() {
|
|
385
|
+
// Display new duration.
|
|
386
|
+
thisObj.refreshControls();
|
|
387
|
+
})
|
|
388
|
+
.on('timeupdate',function() {
|
|
389
|
+
thisObj.onMediaUpdateTime();
|
|
390
|
+
})
|
|
391
|
+
.on('play',function() {
|
|
392
|
+
if (thisObj.debug) {
|
|
393
|
+
console.log('media play event');
|
|
394
|
+
}
|
|
395
|
+
})
|
|
396
|
+
.on('pause',function() {
|
|
397
|
+
thisObj.onMediaPause();
|
|
398
|
+
})
|
|
399
|
+
.on('ratechange',function() {
|
|
400
|
+
// do something
|
|
401
|
+
})
|
|
402
|
+
.on('volumechange',function() {
|
|
403
|
+
thisObj.volume = thisObj.getVolume();
|
|
404
|
+
if (thisObj.debug) {
|
|
405
|
+
console.log('media volume change to ' + thisObj.volume + ' (' + thisObj.volumeButton + ')');
|
|
406
|
+
}
|
|
407
|
+
})
|
|
408
|
+
.on('error',function() {
|
|
409
|
+
if (thisObj.debug) {
|
|
410
|
+
switch (thisObj.media.error.code) {
|
|
411
|
+
case 1:
|
|
412
|
+
console.log('HTML5 Media Error: MEDIA_ERR_ABORTED');
|
|
413
|
+
break;
|
|
414
|
+
case 2:
|
|
415
|
+
console.log('HTML5 Media Error: MEDIA_ERR_NETWORK ');
|
|
416
|
+
break;
|
|
417
|
+
case 3:
|
|
418
|
+
console.log('HTML5 Media Error: MEDIA_ERR_DECODE ');
|
|
419
|
+
break;
|
|
420
|
+
case 4:
|
|
421
|
+
console.log('HTML5 Media Error: MEDIA_ERR_SRC_NOT_SUPPORTED ');
|
|
422
|
+
break;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
AblePlayer.prototype.addJwMediaListeners = function () {
|
|
429
|
+
var thisObj = this;
|
|
430
|
+
// add listeners for JW Player events
|
|
431
|
+
this.jwPlayer
|
|
432
|
+
.onTime(function() {
|
|
433
|
+
thisObj.onMediaUpdateTime();
|
|
434
|
+
})
|
|
435
|
+
.onComplete(function() {
|
|
436
|
+
thisObj.onMediaComplete();
|
|
437
|
+
})
|
|
438
|
+
.onReady(function() {
|
|
439
|
+
if (thisObj.debug) {
|
|
440
|
+
console.log('JW Player onReady event fired');
|
|
441
|
+
}
|
|
442
|
+
// remove JW Player from tab order.
|
|
443
|
+
// We don't want users tabbing into the Flash object and getting trapped
|
|
444
|
+
$('#' + thisObj.jwId).removeAttr('tabindex');
|
|
445
|
+
|
|
446
|
+
// JW Player was initialized with no explicit width or height; get them now
|
|
447
|
+
thisObj.$fallbackWrapper = $('#' + thisObj.mediaId + '_fallback_wrapper');
|
|
448
|
+
thisObj.fallbackDefaultWidth = thisObj.$fallbackWrapper.width();
|
|
449
|
+
thisObj.fallbackDefaultHeight = thisObj.$fallbackWrapper.height();
|
|
450
|
+
thisObj.fallbackRatio = thisObj.fallbackDefaultWidth / thisObj.fallbackDefaultHeight;
|
|
451
|
+
|
|
452
|
+
if (thisObj.startTime > 0 && !thisObj.startedPlaying) {
|
|
453
|
+
thisObj.seekTo(thisObj.startTime);
|
|
454
|
+
thisObj.startedPlaying = true;
|
|
455
|
+
}
|
|
456
|
+
thisObj.refreshControls();
|
|
457
|
+
})
|
|
458
|
+
.onSeek(function(event) {
|
|
459
|
+
// this is called when user scrubs ahead or back,
|
|
460
|
+
// after the target offset is reached
|
|
461
|
+
if (thisObj.debug) {
|
|
462
|
+
console.log('Seeking to ' + event.position + '; target: ' + event.offset);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
if (thisObj.jwSeekPause) {
|
|
466
|
+
// media was temporarily paused
|
|
467
|
+
thisObj.jwSeekPause = false;
|
|
468
|
+
thisObj.playMedia();
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
setTimeout(function () {
|
|
472
|
+
thisObj.refreshControls();
|
|
473
|
+
}, 300);
|
|
474
|
+
})
|
|
475
|
+
.onPlay(function() {
|
|
476
|
+
if (thisObj.debug) {
|
|
477
|
+
console.log('JW Player onPlay event fired');
|
|
478
|
+
}
|
|
479
|
+
thisObj.refreshControls();
|
|
480
|
+
})
|
|
481
|
+
.onPause(function() {
|
|
482
|
+
thisObj.onMediaPause();
|
|
483
|
+
})
|
|
484
|
+
.onBuffer(function() {
|
|
485
|
+
if (thisObj.debug) {
|
|
486
|
+
console.log('JW Player onBuffer event fired');
|
|
487
|
+
}
|
|
488
|
+
thisObj.refreshControls();
|
|
489
|
+
})
|
|
490
|
+
.onBufferChange(function() {
|
|
491
|
+
thisObj.refreshControls();
|
|
492
|
+
})
|
|
493
|
+
.onIdle(function(e) {
|
|
494
|
+
if (thisObj.debug) {
|
|
495
|
+
console.log('JW Player onIdle event fired');
|
|
496
|
+
}
|
|
497
|
+
thisObj.refreshControls();
|
|
498
|
+
})
|
|
499
|
+
.onMeta(function() {
|
|
500
|
+
if (thisObj.debug) {
|
|
501
|
+
console.log('JW Player onMeta event fired');
|
|
502
|
+
}
|
|
503
|
+
})
|
|
504
|
+
.onPlaylist(function() {
|
|
505
|
+
if (thisObj.debug) {
|
|
506
|
+
console.log('JW Player onPlaylist event fired');
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
// Playlist change includes new media source.
|
|
510
|
+
thisObj.onMediaNewSourceLoad();
|
|
511
|
+
});
|
|
512
|
+
};
|
|
513
|
+
|
|
514
|
+
AblePlayer.prototype.addEventListeners = function () {
|
|
515
|
+
var thisObj, whichButton, thisElement;
|
|
516
|
+
|
|
517
|
+
// Save the current object context in thisObj for use with inner functions.
|
|
518
|
+
thisObj = this;
|
|
519
|
+
|
|
520
|
+
// Appropriately resize media player for full screen.
|
|
521
|
+
$(window).resize(function () {
|
|
522
|
+
thisObj.onWindowResize();
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
// Refresh player if it changes from hidden to visible
|
|
526
|
+
// There is no event triggered by a change in visibility
|
|
527
|
+
// but MutationObserver works in most browsers:
|
|
528
|
+
// http://caniuse.com/#feat=mutationobserver
|
|
529
|
+
var target = this.$ableDiv[0];
|
|
530
|
+
var observer = new MutationObserver(function(mutations) {
|
|
531
|
+
mutations.forEach(function(mutation) {
|
|
532
|
+
if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
|
|
533
|
+
// the player's style attribute has changed. Check to see if it's visible
|
|
534
|
+
if (thisObj.$ableDiv.is(':visible')) {
|
|
535
|
+
thisObj.refreshControls();
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
});
|
|
540
|
+
var config = { attributes: true, childList: true, characterData: true };
|
|
541
|
+
observer.observe(target, config);
|
|
542
|
+
|
|
543
|
+
this.addSeekbarListeners();
|
|
544
|
+
|
|
545
|
+
// handle clicks on player buttons
|
|
546
|
+
this.$controllerDiv.find('button').on('click',function(){
|
|
547
|
+
thisObj.onClickPlayerButton(this);
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
// handle local keydown events if this isn't the only player on the page;
|
|
551
|
+
// otherwise these are dispatched by global handler (see ableplayer-base,js)
|
|
552
|
+
this.$ableDiv.keydown(function (e) {
|
|
553
|
+
if (AblePlayer.nextIndex > 1) {
|
|
554
|
+
thisObj.onPlayerKeyPress(e);
|
|
555
|
+
}
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
// transcript is not a child of this.$ableDiv
|
|
559
|
+
// therefore, must be added separately
|
|
560
|
+
if (this.$transcriptArea) {
|
|
561
|
+
this.$transcriptArea.keydown(function (e) {
|
|
562
|
+
if (AblePlayer.nextIndex > 1) {
|
|
563
|
+
thisObj.onPlayerKeyPress(e);
|
|
564
|
+
}
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// handle clicks on playlist items
|
|
569
|
+
if (this.$playlist) {
|
|
570
|
+
this.$playlist.click(function() {
|
|
571
|
+
thisObj.playlistIndex = $(this).index();
|
|
572
|
+
thisObj.swapSource(thisObj.playlistIndex);
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// Also play/pause when clicking on the media.
|
|
577
|
+
this.$media.click(function () {
|
|
578
|
+
thisObj.handlePlay();
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
// add listeners for media events
|
|
582
|
+
if (this.player === 'html5') {
|
|
583
|
+
this.addHtml5MediaListeners();
|
|
584
|
+
}
|
|
585
|
+
else if (this.player === 'jw') {
|
|
586
|
+
this.addJwMediaListeners();
|
|
587
|
+
}
|
|
588
|
+
else if (this.player === 'youtube') {
|
|
589
|
+
// Youtube doesn't give us time update events, so we just periodically generate them ourselves
|
|
590
|
+
setInterval(function () {
|
|
591
|
+
thisObj.onMediaUpdateTime();
|
|
592
|
+
}, 300);
|
|
593
|
+
}
|
|
594
|
+
};
|
|
595
|
+
})(jQuery);
|