wai-website-theme 1.7 → 1.9.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/_data/navigation.yml +24 -1
- data/_includes/body-class.html +1 -1
- data/_includes/ednote.html +32 -0
- data/_includes/footer.html +28 -2
- data/_includes/icon.html +2 -2
- data/_includes/link.html +1 -1
- data/_includes/prevnext-navigation.html +0 -8
- data/_includes/secondarynav.html +13 -83
- data/_includes/subpages.html +35 -0
- data/_layouts/default.html +4 -4
- data/_layouts/home.html +1 -1
- data/_layouts/languagefile.js +7 -0
- data/_layouts/news.html +2 -2
- data/_layouts/policy.html +2 -2
- data/_layouts/sidenav.html +2 -2
- data/_layouts/sidenavsidebar.html +2 -2
- data/assets/ableplayer/build/ableplayer.dist.js +419 -220
- data/assets/ableplayer/build/ableplayer.js +391 -192
- data/assets/ableplayer/build/ableplayer.min.js +2 -2
- 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/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/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/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/css/style.css +1 -1
- data/assets/css/style.css.map +1 -1
- data/assets/fonts/notosansmono/notosansmono-bold.woff +0 -0
- data/assets/fonts/notosansmono/notosansmono-bold.woff2 +0 -0
- data/assets/fonts/notosansmono/notosansmono-regular.woff +0 -0
- data/assets/fonts/notosansmono/notosansmono-regular.woff2 +0 -0
- data/assets/images/icons.svg +3 -0
- data/assets/images/inline.png +0 -0
- data/assets/images/social-sharing-default.jpg +0 -0
- data/assets/scripts/lang/ar.js +4 -0
- data/assets/scripts/lang/de.js +4 -0
- data/assets/scripts/lang/el.js +4 -0
- data/assets/scripts/lang/es.js +4 -0
- data/assets/scripts/lang/fr.js +4 -0
- data/assets/scripts/lang/ja.js +4 -0
- data/assets/scripts/lang/ko.js +4 -0
- data/assets/scripts/lang/nl.js +4 -0
- data/assets/scripts/lang/pt-BR.js +4 -0
- data/assets/scripts/lang/ru.js +4 -0
- data/assets/scripts/lang/zh-hans.js +4 -0
- data/assets/scripts/main.js +20 -7
- metadata +23 -9
- data/assets/fonts/notosansmono/notosansmono-semicondensed.woff +0 -0
- data/assets/fonts/notosansmono/notosansmono-semicondensed.woff2 +0 -0
- data/assets/fonts/notosansmono/notosansmono-semicondensedbold.woff +0 -0
- data/assets/fonts/notosansmono/notosansmono-semicondensedbold.woff2 +0 -0
@@ -34,11 +34,15 @@
|
|
34
34
|
/*global $, jQuery */
|
35
35
|
"use strict";
|
36
36
|
|
37
|
+
// maintain an array of Able Player instances for use globally (e.g., for keeping prefs in sync)
|
38
|
+
var AblePlayerInstances = [];
|
39
|
+
|
37
40
|
(function ($) {
|
38
41
|
$(document).ready(function () {
|
42
|
+
|
39
43
|
$('video, audio').each(function (index, element) {
|
40
44
|
if ($(element).data('able-player') !== undefined) {
|
41
|
-
new AblePlayer($(this),$(element));
|
45
|
+
AblePlayerInstances.push(new AblePlayer($(this),$(element)));
|
42
46
|
}
|
43
47
|
});
|
44
48
|
});
|
@@ -61,10 +65,8 @@
|
|
61
65
|
// Parameters are:
|
62
66
|
// media - jQuery selector or element identifying the media.
|
63
67
|
window.AblePlayer = function(media) {
|
64
|
-
|
65
68
|
// Keep track of the last player created for use with global events.
|
66
69
|
AblePlayer.lastCreated = this;
|
67
|
-
|
68
70
|
this.media = media;
|
69
71
|
if ($(media).length === 0) {
|
70
72
|
this.provideFallback();
|
@@ -845,7 +847,6 @@
|
|
845
847
|
// Bootstrap from this.media possibly being an ID or other selector.
|
846
848
|
this.$media = $(this.media).first();
|
847
849
|
this.media = this.$media[0];
|
848
|
-
|
849
850
|
// Set media type to 'audio' or 'video'; this determines some of the behavior of player creation.
|
850
851
|
if (this.$media.is('audio')) {
|
851
852
|
this.mediaType = 'audio';
|
@@ -1395,7 +1396,7 @@
|
|
1395
1396
|
AblePlayer.prototype.updateCookie = function( setting ) {
|
1396
1397
|
|
1397
1398
|
// called when a particular setting had been updated
|
1398
|
-
// useful for settings updated
|
1399
|
+
// useful for settings updated indepedently of Preferences dialog
|
1399
1400
|
// e.g., prefAutoScrollTranscript, which is updated in control.js > handleTranscriptLockToggle()
|
1400
1401
|
// setting is any supported preference name (e.g., "prefCaptions")
|
1401
1402
|
// OR 'transcript' or 'sign' (not user-defined preferences, used to save position of draggable windows)
|
@@ -1608,8 +1609,10 @@
|
|
1608
1609
|
return prefs;
|
1609
1610
|
};
|
1610
1611
|
|
1611
|
-
// Loads current/default preferences from cookie into the AblePlayer object.
|
1612
1612
|
AblePlayer.prototype.loadCurrentPreferences = function () {
|
1613
|
+
|
1614
|
+
// Load current/default preferences from cookie into the AblePlayer object.
|
1615
|
+
|
1613
1616
|
var available = this.getAvailablePreferences();
|
1614
1617
|
var cookie = this.getCookie();
|
1615
1618
|
|
@@ -1991,7 +1994,7 @@
|
|
1991
1994
|
cancelButton = $('<button class="modal-button">' + this.tt.cancel + '</button>');
|
1992
1995
|
saveButton.click(function () {
|
1993
1996
|
dialog.hide();
|
1994
|
-
|
1997
|
+
thisObj.savePrefsFromForm();
|
1995
1998
|
});
|
1996
1999
|
cancelButton.click(function () {
|
1997
2000
|
dialog.hide();
|
@@ -2028,19 +2031,22 @@
|
|
2028
2031
|
});
|
2029
2032
|
};
|
2030
2033
|
|
2031
|
-
// Reset preferences form with default values from cookie
|
2032
|
-
// Called when user clicks cancel or close button in Prefs Dialog
|
2033
|
-
// also called when user presses Escape
|
2034
|
-
|
2035
2034
|
AblePlayer.prototype.resetPrefsForm = function () {
|
2036
2035
|
|
2037
|
-
|
2036
|
+
// Reset preferences form with default values from cookie
|
2037
|
+
// Called when:
|
2038
|
+
// User clicks cancel or close button in Prefs Dialog
|
2039
|
+
// User presses Escape to close Prefs dialog
|
2040
|
+
// User clicks Save in Prefs dialog, & there's more than one player on page
|
2041
|
+
|
2042
|
+
var thisObj, cookie, available, i, prefName, prefId, thisDiv, thisId;
|
2038
2043
|
|
2039
2044
|
thisObj = this;
|
2040
2045
|
cookie = this.getCookie();
|
2041
2046
|
available = this.getAvailablePreferences();
|
2042
2047
|
for (i=0; i<available.length; i++) {
|
2043
2048
|
prefName = available[i]['name'];
|
2049
|
+
prefId = this.mediaId + '_' + prefName;
|
2044
2050
|
if ((prefName.indexOf('Captions') !== -1) && (prefName !== 'prefCaptions')) {
|
2045
2051
|
// this is a caption-related select box
|
2046
2052
|
$('select[name="' + prefName + '"]').val(cookie.preferences[prefName]);
|
@@ -2058,21 +2064,24 @@
|
|
2058
2064
|
this.stylizeCaptions(this.$sampleCapsDiv);
|
2059
2065
|
};
|
2060
2066
|
|
2061
|
-
// Return a prefs object constructed from the form.
|
2062
2067
|
AblePlayer.prototype.savePrefsFromForm = function () {
|
2068
|
+
|
2069
|
+
// Return a prefs object constructed from the form.
|
2063
2070
|
// called when user saves the Preferences form
|
2064
2071
|
// update cookie with new value
|
2065
|
-
var
|
2072
|
+
var cookie, available, prefName, prefId, numChanges,
|
2073
|
+
numCapChanges, capSizeChanged, capSizeValue, newValue;
|
2066
2074
|
|
2067
2075
|
numChanges = 0;
|
2068
2076
|
numCapChanges = 0; // changes to caption-style-related preferences
|
2069
2077
|
capSizeChanged = false;
|
2070
|
-
|
2071
|
-
|
2078
|
+
cookie = this.getCookie();
|
2079
|
+
available = this.getAvailablePreferences();
|
2072
2080
|
for (var i=0; i < available.length; i++) {
|
2073
2081
|
// only prefs with labels are used in the Prefs form
|
2074
2082
|
if (available[i]['label']) {
|
2075
|
-
|
2083
|
+
prefName = available[i]['name'];
|
2084
|
+
prefId = this.mediaId + '_' + prefName;
|
2076
2085
|
if (prefName == 'prefDescFormat') {
|
2077
2086
|
// As of v4.0.10, prefDescFormat is no longer a choice
|
2078
2087
|
// this.prefDescFormat = $('input[name="' + prefName + '"]:checked').val();
|
@@ -2084,7 +2093,7 @@
|
|
2084
2093
|
}
|
2085
2094
|
else if ((prefName.indexOf('Captions') !== -1) && (prefName !== 'prefCaptions')) {
|
2086
2095
|
// this is one of the caption-related select fields
|
2087
|
-
newValue = $('select[
|
2096
|
+
newValue = $('select[id="' + prefId + '"]').val();
|
2088
2097
|
if (cookie.preferences[prefName] !== newValue) { // user changed setting
|
2089
2098
|
cookie.preferences[prefName] = newValue;
|
2090
2099
|
// also update global var for this pref (for caption fields, not done elsewhere)
|
@@ -2098,7 +2107,7 @@
|
|
2098
2107
|
}
|
2099
2108
|
}
|
2100
2109
|
else { // all other fields are checkboxes
|
2101
|
-
if ($('input[
|
2110
|
+
if ($('input[id="' + prefId + '"]').is(':checked')) {
|
2102
2111
|
cookie.preferences[prefName] = 1;
|
2103
2112
|
if (this[prefName] === 1) {
|
2104
2113
|
// nothing has changed
|
@@ -2136,35 +2145,38 @@
|
|
2136
2145
|
// update font size of YouTube captions
|
2137
2146
|
this.youTubePlayer.setOption(this.ytCaptionModule,'fontSize',this.translatePrefs('size',capSizeValue,'youtube'));
|
2138
2147
|
}
|
2139
|
-
|
2140
|
-
|
2141
|
-
|
2142
|
-
|
2143
|
-
|
2144
|
-
|
2145
|
-
|
2146
|
-
|
2148
|
+
if (AblePlayerInstances.length > 1) {
|
2149
|
+
// there are multiple players on this page.
|
2150
|
+
// update prefs for ALL of them
|
2151
|
+
for (var i=0; i<AblePlayerInstances.length; i++) {
|
2152
|
+
AblePlayerInstances[i].updatePrefs();
|
2153
|
+
AblePlayerInstances[i].loadCurrentPreferences();
|
2154
|
+
AblePlayerInstances[i].resetPrefsForm();
|
2155
|
+
if (numCapChanges > 0) {
|
2156
|
+
AblePlayerInstances[i].stylizeCaptions(AblePlayerInstances[i].$captionsDiv);
|
2157
|
+
// also apply same changes to descriptions, if present
|
2158
|
+
if (typeof AblePlayerInstances[i].$descDiv !== 'undefined') {
|
2159
|
+
AblePlayerInstances[i].stylizeCaptions(AblePlayerInstances[i].$descDiv);
|
2160
|
+
}
|
2161
|
+
}
|
2162
|
+
}
|
2163
|
+
}
|
2164
|
+
else {
|
2165
|
+
// there is only one player
|
2166
|
+
this.updatePrefs();
|
2167
|
+
if (numCapChanges > 0) {
|
2168
|
+
this.stylizeCaptions(this.$captionsDiv);
|
2169
|
+
// also apply same changes to descriptions, if present
|
2170
|
+
if (typeof this.$descDiv !== 'undefined') {
|
2171
|
+
this.stylizeCaptions(this.$descDiv);
|
2172
|
+
}
|
2173
|
+
}
|
2174
|
+
}
|
2147
2175
|
}
|
2148
2176
|
|
2149
|
-
// Updates player based on current prefs. Safe to call multiple times.
|
2150
2177
|
AblePlayer.prototype.updatePrefs = function () {
|
2151
2178
|
|
2152
|
-
|
2153
|
-
|
2154
|
-
// modifier keys (update help text)
|
2155
|
-
if (this.prefAltKey === 1) {
|
2156
|
-
modHelp = 'Alt + ';
|
2157
|
-
}
|
2158
|
-
else {
|
2159
|
-
modHelp = '';
|
2160
|
-
}
|
2161
|
-
if (this.prefCtrlKey === 1) {
|
2162
|
-
modHelp += 'Control + ';
|
2163
|
-
}
|
2164
|
-
if (this.prefShiftKey === 1) {
|
2165
|
-
modHelp += 'Shift + ';
|
2166
|
-
}
|
2167
|
-
$('.able-help-modifiers').text(modHelp);
|
2179
|
+
// Update player based on current prefs. Safe to call multiple times.
|
2168
2180
|
|
2169
2181
|
// tabbable transcript
|
2170
2182
|
if (this.prefTabbable === 1) {
|
@@ -2187,6 +2199,7 @@
|
|
2187
2199
|
};
|
2188
2200
|
|
2189
2201
|
AblePlayer.prototype.usingModifierKeys = function(e) {
|
2202
|
+
|
2190
2203
|
// return true if user is holding down required modifier keys
|
2191
2204
|
if ((this.prefAltKey === 1) && !e.altKey) {
|
2192
2205
|
return false;
|
@@ -3374,44 +3387,51 @@
|
|
3374
3387
|
|
3375
3388
|
// Populate menu with menu items
|
3376
3389
|
if (which === 'prefs') {
|
3377
|
-
|
3378
|
-
|
3379
|
-
|
3380
|
-
|
3381
|
-
|
3382
|
-
|
3383
|
-
|
3384
|
-
|
3385
|
-
|
3386
|
-
|
3387
|
-
|
3388
|
-
|
3389
|
-
|
3390
|
-
|
3391
|
-
|
3392
|
-
|
3393
|
-
|
3394
|
-
|
3395
|
-
|
3396
|
-
|
3397
|
-
|
3398
|
-
|
3399
|
-
|
3400
|
-
|
3401
|
-
|
3402
|
-
|
3403
|
-
|
3404
|
-
|
3405
|
-
|
3406
|
-
|
3407
|
-
|
3408
|
-
|
3409
|
-
|
3410
|
-
|
3411
|
-
|
3412
|
-
|
3413
|
-
|
3414
|
-
|
3390
|
+
if (this.prefCats.length > 1) {
|
3391
|
+
for (i = 0; i < this.prefCats.length; i++) {
|
3392
|
+
$menuItem = $('<li></li>',{
|
3393
|
+
'role': 'menuitem',
|
3394
|
+
'tabindex': '-1'
|
3395
|
+
});
|
3396
|
+
prefCat = this.prefCats[i];
|
3397
|
+
if (prefCat === 'captions') {
|
3398
|
+
$menuItem.text(this.tt.prefMenuCaptions);
|
3399
|
+
}
|
3400
|
+
else if (prefCat === 'descriptions') {
|
3401
|
+
$menuItem.text(this.tt.prefMenuDescriptions);
|
3402
|
+
}
|
3403
|
+
else if (prefCat === 'keyboard') {
|
3404
|
+
$menuItem.text(this.tt.prefMenuKeyboard);
|
3405
|
+
}
|
3406
|
+
else if (prefCat === 'transcript') {
|
3407
|
+
$menuItem.text(this.tt.prefMenuTranscript);
|
3408
|
+
}
|
3409
|
+
$menuItem.on('click',function() {
|
3410
|
+
whichPref = $(this).text();
|
3411
|
+
thisObj.setFullscreen(false);
|
3412
|
+
if (whichPref === thisObj.tt.prefMenuCaptions) {
|
3413
|
+
thisObj.captionPrefsDialog.show();
|
3414
|
+
}
|
3415
|
+
else if (whichPref === thisObj.tt.prefMenuDescriptions) {
|
3416
|
+
thisObj.descPrefsDialog.show();
|
3417
|
+
}
|
3418
|
+
else if (whichPref === thisObj.tt.prefMenuKeyboard) {
|
3419
|
+
thisObj.keyboardPrefsDialog.show();
|
3420
|
+
}
|
3421
|
+
else if (whichPref === thisObj.tt.prefMenuTranscript) {
|
3422
|
+
thisObj.transcriptPrefsDialog.show();
|
3423
|
+
}
|
3424
|
+
thisObj.closePopups();
|
3425
|
+
});
|
3426
|
+
$menu.append($menuItem);
|
3427
|
+
}
|
3428
|
+
this.$prefsButton.attr('data-prefs-popup','menu');
|
3429
|
+
}
|
3430
|
+
else if (this.prefCats.length == 1) {
|
3431
|
+
// only 1 category, so don't create a popup menu.
|
3432
|
+
// Instead, open dialog directly when user clicks Prefs button
|
3433
|
+
this.$prefsButton.attr('data-prefs-popup',this.prefCats[0]);
|
3434
|
+
}
|
3415
3435
|
}
|
3416
3436
|
else if (which === 'captions' || which === 'chapters') {
|
3417
3437
|
hasDefault = false;
|
@@ -3562,34 +3582,34 @@
|
|
3562
3582
|
|
3563
3583
|
if (this.chaptersPopup && this.chaptersPopup.is(':visible')) {
|
3564
3584
|
this.chaptersPopup.hide();
|
3565
|
-
this.$chaptersButton.
|
3585
|
+
this.$chaptersButton.removeAttr('aria-expanded').focus();
|
3566
3586
|
}
|
3567
3587
|
if (this.captionsPopup && this.captionsPopup.is(':visible')) {
|
3568
3588
|
this.captionsPopup.hide();
|
3569
|
-
this.$ccButton.
|
3589
|
+
this.$ccButton.removeAttr('aria-expanded').focus();
|
3570
3590
|
}
|
3571
3591
|
if (this.prefsPopup && this.prefsPopup.is(':visible')) {
|
3572
3592
|
this.prefsPopup.hide();
|
3573
3593
|
// restore menu items to their original state
|
3574
3594
|
this.prefsPopup.find('li').removeClass('able-focus').attr('tabindex','-1');
|
3575
|
-
this.$prefsButton.
|
3595
|
+
this.$prefsButton.removeAttr('aria-expanded').focus();
|
3576
3596
|
}
|
3577
3597
|
if (this.$volumeSlider && this.$volumeSlider.is(':visible')) {
|
3578
3598
|
this.$volumeSlider.hide().attr('aria-hidden','true');
|
3579
3599
|
this.$volumeAlert.text(this.tt.volumeSliderClosed);
|
3580
|
-
this.$volumeButton.
|
3600
|
+
this.$volumeButton.removeAttr('aria-expanded').focus();
|
3581
3601
|
}
|
3582
3602
|
if (this.$transcriptPopup && this.$transcriptPopup.is(':visible')) {
|
3583
3603
|
this.$transcriptPopup.hide();
|
3584
3604
|
// restore menu items to their original state
|
3585
3605
|
this.$transcriptPopup.find('li').removeClass('able-focus').attr('tabindex','-1');
|
3586
|
-
this.$transcriptPopupButton.
|
3606
|
+
this.$transcriptPopupButton.removeAttr('aria-expanded').focus();
|
3587
3607
|
}
|
3588
3608
|
if (this.$signPopup && this.$signPopup.is(':visible')) {
|
3589
3609
|
this.$signPopup.hide();
|
3590
3610
|
// restore menu items to their original state
|
3591
3611
|
this.$signPopup.find('li').removeClass('able-focus').attr('tabindex','-1');
|
3592
|
-
this.$signPopupButton.
|
3612
|
+
this.$signPopupButton.removeAttr('aria-expanded').focus();
|
3593
3613
|
}
|
3594
3614
|
};
|
3595
3615
|
|
@@ -3973,15 +3993,31 @@
|
|
3973
3993
|
});
|
3974
3994
|
if (control === 'volume' || control === 'preferences') {
|
3975
3995
|
if (control == 'preferences') {
|
3976
|
-
|
3996
|
+
this.prefCats = this.getPreferencesGroups();
|
3997
|
+
if (this.prefCats.length > 1) {
|
3998
|
+
// Prefs button will trigger a menu
|
3999
|
+
popupMenuId = this.mediaId + '-prefs-menu';
|
4000
|
+
$newButton.attr({
|
4001
|
+
'aria-controls': popupMenuId,
|
4002
|
+
'aria-haspopup': 'menu'
|
4003
|
+
});
|
4004
|
+
}
|
4005
|
+
else if (this.prefCats.length === 1) {
|
4006
|
+
// Prefs button will trigger a dialog
|
4007
|
+
$newButton.attr({
|
4008
|
+
'aria-haspopup': 'dialog'
|
4009
|
+
});
|
4010
|
+
}
|
3977
4011
|
}
|
3978
4012
|
else if (control === 'volume') {
|
3979
4013
|
popupMenuId = this.mediaId + '-volume-slider';
|
4014
|
+
// volume slider popup is not a menu or a dialog
|
4015
|
+
// therefore, using aria-expanded rather than aria-haspopup to communicate properties/state
|
4016
|
+
$newButton.attr({
|
4017
|
+
'aria-controls': popupMenuId,
|
4018
|
+
'aria-expanded': 'false'
|
4019
|
+
});
|
3980
4020
|
}
|
3981
|
-
$newButton.attr({
|
3982
|
-
'aria-controls': popupMenuId,
|
3983
|
-
'aria-expanded': 'false'
|
3984
|
-
});
|
3985
4021
|
}
|
3986
4022
|
if (this.iconType === 'font') {
|
3987
4023
|
if (control === 'volume') {
|
@@ -5955,6 +5991,121 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
5955
5991
|
this.setDuration(max);
|
5956
5992
|
}
|
5957
5993
|
|
5994
|
+
// handle seekHead events
|
5995
|
+
this.seekHead.on('mouseenter mouseleave mousemove mousedown mouseup focus blur touchstart touchmove touchend', function (e) {
|
5996
|
+
|
5997
|
+
if (e.type === 'mouseenter' || e.type === 'focus') {
|
5998
|
+
thisObj.overHead = true;
|
5999
|
+
}
|
6000
|
+
else if (e.type === 'mouseleave' || e.type === 'blur') {
|
6001
|
+
thisObj.overHead = false;
|
6002
|
+
if (!thisObj.overBody && thisObj.tracking && thisObj.trackDevice === 'mouse') {
|
6003
|
+
thisObj.stopTracking(thisObj.pageXToPosition(e.pageX));
|
6004
|
+
}
|
6005
|
+
}
|
6006
|
+
else if (e.type === 'mousemove' || e.type === 'touchmove') {
|
6007
|
+
if (thisObj.tracking && thisObj.trackDevice === 'mouse') {
|
6008
|
+
thisObj.trackHeadAtPageX(e.pageX);
|
6009
|
+
}
|
6010
|
+
}
|
6011
|
+
else if (e.type === 'mousedown' || e.type === 'touchstart') {
|
6012
|
+
thisObj.startTracking('mouse', thisObj.pageXToPosition(thisObj.seekHead.offset() + (thisObj.seekHead.width() / 2)));
|
6013
|
+
if (!thisObj.bodyDiv.is(':focus')) {
|
6014
|
+
thisObj.bodyDiv.focus();
|
6015
|
+
}
|
6016
|
+
e.preventDefault();
|
6017
|
+
}
|
6018
|
+
else if (e.type === 'mouseup' || e.type === 'touchend') {
|
6019
|
+
if (thisObj.tracking && thisObj.trackDevice === 'mouse') {
|
6020
|
+
thisObj.stopTracking(thisObj.pageXToPosition(e.pageX));
|
6021
|
+
}
|
6022
|
+
}
|
6023
|
+
if (e.type !== 'mousemove' && e.type !== 'mousedown' && e.type !== 'mouseup' && e.type !== 'touchstart' && e.type !== 'touchend') {
|
6024
|
+
thisObj.refreshTooltip();
|
6025
|
+
}
|
6026
|
+
});
|
6027
|
+
|
6028
|
+
// handle bodyDiv events
|
6029
|
+
this.bodyDiv.on(
|
6030
|
+
'mouseenter mouseleave mousemove mousedown mouseup keydown keyup touchstart touchmove touchend', function (e) {
|
6031
|
+
|
6032
|
+
if (e.type === 'mouseenter') {
|
6033
|
+
thisObj.overBody = true;
|
6034
|
+
}
|
6035
|
+
else if (e.type === 'mouseleave') {
|
6036
|
+
thisObj.overBody = false;
|
6037
|
+
thisObj.overBodyMousePos = null;
|
6038
|
+
if (!thisObj.overHead && thisObj.tracking && thisObj.trackDevice === 'mouse') {
|
6039
|
+
thisObj.stopTracking(thisObj.pageXToPosition(e.pageX));
|
6040
|
+
}
|
6041
|
+
}
|
6042
|
+
else if (e.type === 'mousemove' || e.type === 'touchmove') {
|
6043
|
+
thisObj.overBodyMousePos = {
|
6044
|
+
x: e.pageX,
|
6045
|
+
y: e.pageY
|
6046
|
+
};
|
6047
|
+
if (thisObj.tracking && thisObj.trackDevice === 'mouse') {
|
6048
|
+
thisObj.trackHeadAtPageX(e.pageX);
|
6049
|
+
}
|
6050
|
+
}
|
6051
|
+
else if (e.type === 'mousedown' || e.type === 'touchstart') {
|
6052
|
+
thisObj.startTracking('mouse', thisObj.pageXToPosition(e.pageX));
|
6053
|
+
thisObj.trackHeadAtPageX(e.pageX);
|
6054
|
+
if (!thisObj.seekHead.is(':focus')) {
|
6055
|
+
thisObj.seekHead.focus();
|
6056
|
+
}
|
6057
|
+
e.preventDefault();
|
6058
|
+
}
|
6059
|
+
else if (e.type === 'mouseup' || e.type === 'touchend') {
|
6060
|
+
if (thisObj.tracking && thisObj.trackDevice === 'mouse') {
|
6061
|
+
thisObj.stopTracking(thisObj.pageXToPosition(e.pageX));
|
6062
|
+
}
|
6063
|
+
}
|
6064
|
+
else if (e.type === 'keydown') {
|
6065
|
+
// Home
|
6066
|
+
if (e.which === 36) {
|
6067
|
+
thisObj.trackImmediatelyTo(0);
|
6068
|
+
}
|
6069
|
+
// End
|
6070
|
+
else if (e.which === 35) {
|
6071
|
+
thisObj.trackImmediatelyTo(thisObj.duration);
|
6072
|
+
}
|
6073
|
+
// Left arrow or down arrow
|
6074
|
+
else if (e.which === 37 || e.which === 40) {
|
6075
|
+
thisObj.arrowKeyDown(-1);
|
6076
|
+
}
|
6077
|
+
// Right arrow or up arrow
|
6078
|
+
else if (e.which === 39 || e.which === 38) {
|
6079
|
+
thisObj.arrowKeyDown(1);
|
6080
|
+
}
|
6081
|
+
// Page up
|
6082
|
+
else if (e.which === 33 && bigInterval > 0) {
|
6083
|
+
thisObj.arrowKeyDown(bigInterval);
|
6084
|
+
}
|
6085
|
+
// Page down
|
6086
|
+
else if (e.which === 34 && bigInterval > 0) {
|
6087
|
+
thisObj.arrowKeyDown(-bigInterval);
|
6088
|
+
}
|
6089
|
+
else {
|
6090
|
+
return;
|
6091
|
+
}
|
6092
|
+
e.preventDefault();
|
6093
|
+
}
|
6094
|
+
else if (e.type === 'keyup') {
|
6095
|
+
if (e.which >= 33 && e.which <= 40) {
|
6096
|
+
if (thisObj.tracking && thisObj.trackDevice === 'keyboard') {
|
6097
|
+
thisObj.stopTracking(thisObj.keyTrackPosition);
|
6098
|
+
}
|
6099
|
+
e.preventDefault();
|
6100
|
+
}
|
6101
|
+
}
|
6102
|
+
if (e.type !== 'mouseup' && e.type !== 'keydown' && e.type !== 'keydown') {
|
6103
|
+
thisObj.refreshTooltip();
|
6104
|
+
}
|
6105
|
+
});
|
6106
|
+
|
6107
|
+
/* Old event listeners on seekHead and bodyDiv...
|
6108
|
+
|
5958
6109
|
this.seekHead.hover(function (e) {
|
5959
6110
|
thisObj.overHead = true;
|
5960
6111
|
thisObj.refreshTooltip();
|
@@ -6076,6 +6227,7 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
6076
6227
|
e.preventDefault();
|
6077
6228
|
}
|
6078
6229
|
});
|
6230
|
+
*/
|
6079
6231
|
}
|
6080
6232
|
|
6081
6233
|
AccessibleSlider.prototype.arrowKeyDown = function (multiplier) {
|
@@ -6818,7 +6970,7 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
6818
6970
|
e.stopPropagation();
|
6819
6971
|
});
|
6820
6972
|
|
6821
|
-
$('body > *').not('.able-modal-overlay').not('.able-modal-dialog').
|
6973
|
+
$('body > *').not('.able-modal-overlay').not('.able-modal-dialog').removeAttr('aria-hidden');
|
6822
6974
|
};
|
6823
6975
|
|
6824
6976
|
AccessibleDialog.prototype.show = function () {
|
@@ -6865,7 +7017,7 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
6865
7017
|
}
|
6866
7018
|
this.modal.css('display', 'none');
|
6867
7019
|
this.modal.attr('aria-hidden', 'true');
|
6868
|
-
$('body > *').not('.able-modal-overlay').not('.able-modal-dialog').
|
7020
|
+
$('body > *').not('.able-modal-overlay').not('.able-modal-dialog').removeAttr('aria-hidden');
|
6869
7021
|
|
6870
7022
|
this.focusedElementBeforeModal.focus();
|
6871
7023
|
};
|
@@ -7638,7 +7790,6 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
7638
7790
|
deferred = new $.Deferred();
|
7639
7791
|
promise = deferred.promise();
|
7640
7792
|
thisObj = this;
|
7641
|
-
|
7642
7793
|
if (typeof duration !== 'undefined' && typeof elapsed !== 'undefined') {
|
7643
7794
|
mediaTimes['duration'] = duration;
|
7644
7795
|
mediaTimes['elapsed'] = elapsed;
|
@@ -7771,7 +7922,6 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
7771
7922
|
return;
|
7772
7923
|
}
|
7773
7924
|
*/
|
7774
|
-
|
7775
7925
|
var deferred, promise, thisObj, duration, elapsed;
|
7776
7926
|
deferred = new $.Deferred();
|
7777
7927
|
promise = deferred.promise();
|
@@ -7782,7 +7932,7 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
7782
7932
|
deferred.resolve('ended');
|
7783
7933
|
}
|
7784
7934
|
else if (this.media.paused) {
|
7785
|
-
|
7935
|
+
deferred.resolve('paused');
|
7786
7936
|
}
|
7787
7937
|
else if (this.media.readyState !== 4) {
|
7788
7938
|
deferred.resolve('buffering');
|
@@ -8227,8 +8377,7 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
8227
8377
|
this.$ccButton.attr({
|
8228
8378
|
'aria-label': this.tt.captions,
|
8229
8379
|
'aria-haspopup': 'true',
|
8230
|
-
'aria-controls': this.mediaId + '-captions-menu'
|
8231
|
-
'aria-expanded': 'false'
|
8380
|
+
'aria-controls': this.mediaId + '-captions-menu'
|
8232
8381
|
});
|
8233
8382
|
this.$ccButton.find('span.able-clipped').text(this.tt.captions);
|
8234
8383
|
}
|
@@ -8270,7 +8419,6 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
8270
8419
|
}
|
8271
8420
|
}
|
8272
8421
|
}
|
8273
|
-
|
8274
8422
|
if (context === 'playpause' || context == 'init'){
|
8275
8423
|
if (typeof this.$bigPlayButton !== 'undefined' && typeof this.seekBar !== 'undefined') {
|
8276
8424
|
// Choose show/hide for big play button and adjust position.
|
@@ -8316,7 +8464,11 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
8316
8464
|
// Set a flag to ignore the coming scroll event.
|
8317
8465
|
// there's no other way I know of to differentiate programmatic and user-initiated scroll events.
|
8318
8466
|
this.scrollingTranscript = true;
|
8319
|
-
|
8467
|
+
// only scroll once after moving a highlight
|
8468
|
+
if (this.movingHighlight) {
|
8469
|
+
$('.able-transcript').scrollTop(newTop);
|
8470
|
+
this.movingHighlight = false;
|
8471
|
+
}
|
8320
8472
|
}
|
8321
8473
|
}
|
8322
8474
|
}
|
@@ -8328,8 +8480,7 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
8328
8480
|
this.$chaptersButton.attr({
|
8329
8481
|
'aria-label': this.tt.chapters,
|
8330
8482
|
'aria-haspopup': 'true',
|
8331
|
-
'aria-controls': this.mediaId + '-chapters-menu'
|
8332
|
-
'aria-expanded': 'false'
|
8483
|
+
'aria-controls': this.mediaId + '-chapters-menu'
|
8333
8484
|
});
|
8334
8485
|
}
|
8335
8486
|
}
|
@@ -8373,28 +8524,45 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
8373
8524
|
// also don't update while tracking, since this may Pause/Play the player but we don't want to send a Pause/Play update.
|
8374
8525
|
this.getPlayerState().then(function(currentState) {
|
8375
8526
|
if (thisObj.$status.text() !== textByState[currentState] && !thisObj.seekBar.tracking) {
|
8376
|
-
// Debounce updates; only update after status has stayed steadily different for
|
8377
|
-
|
8527
|
+
// Debounce updates; only update after status has stayed steadily different for a while
|
8528
|
+
// "A while" is defined differently depending on context
|
8529
|
+
if (thisObj.swappingSrc) {
|
8530
|
+
// this is where most of the chatter occurs (e.g., playing, paused, buffering, playing),
|
8531
|
+
// so set a longer wait time before writing a status message
|
8532
|
+
if (!thisObj.debouncingStatus) {
|
8533
|
+
thisObj.statusMessageThreshold = 2000; // in ms (2 seconds)
|
8534
|
+
}
|
8535
|
+
}
|
8536
|
+
else {
|
8537
|
+
// for all other contexts (e.g., users clicks Play/Pause)
|
8538
|
+
// user should receive more rapid feedback
|
8539
|
+
if (!thisObj.debouncingStatus) {
|
8540
|
+
thisObj.statusMessageThreshold = 250; // in ms
|
8541
|
+
}
|
8542
|
+
}
|
8543
|
+
timestamp = (new Date()).getTime();
|
8378
8544
|
if (!thisObj.statusDebounceStart) {
|
8379
8545
|
thisObj.statusDebounceStart = timestamp;
|
8380
|
-
//
|
8546
|
+
// Call refreshControls() again after allotted time has passed
|
8547
|
+
thisObj.debouncingStatus = true;
|
8381
8548
|
thisObj.statusTimeout = setTimeout(function () {
|
8549
|
+
thisObj.debouncingStatus = false;
|
8382
8550
|
thisObj.refreshControls(context);
|
8383
|
-
},
|
8384
|
-
}
|
8385
|
-
else if ((timestamp - thisObj.statusDebounceStart) > 250) {
|
8386
|
-
thisObj.$status.text(textByState[currentState]);
|
8387
|
-
thisObj.statusDebounceStart = null;
|
8388
|
-
clearTimeout(thisObj.statusTimeout);
|
8389
|
-
thisObj.statusTimeout = null;
|
8551
|
+
}, thisObj.statusMessageThreshold);
|
8390
8552
|
}
|
8553
|
+
else if ((timestamp - thisObj.statusDebounceStart) > thisObj.statusMessageThreshold) {
|
8554
|
+
thisObj.$status.text(textByState[currentState]);
|
8555
|
+
thisObj.statusDebounceStart = null;
|
8556
|
+
clearTimeout(thisObj.statusTimeout);
|
8557
|
+
thisObj.statusTimeout = null;
|
8558
|
+
}
|
8391
8559
|
}
|
8392
8560
|
else {
|
8393
8561
|
thisObj.statusDebounceStart = null;
|
8562
|
+
thisObj.debouncingStatus = false;
|
8394
8563
|
clearTimeout(thisObj.statusTimeout);
|
8395
8564
|
thisObj.statusTimeout = null;
|
8396
8565
|
}
|
8397
|
-
|
8398
8566
|
// Don't change play/pause button display while using the seek bar (or if YouTube stopped)
|
8399
8567
|
if (!thisObj.seekBar.tracking && !thisObj.stoppingYouTube) {
|
8400
8568
|
if (currentState === 'paused' || currentState === 'stopped' || currentState === 'ended') {
|
@@ -8699,7 +8867,7 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
8699
8867
|
if (this.captionsPopup && this.captionsPopup.is(':visible')) {
|
8700
8868
|
this.captionsPopup.hide();
|
8701
8869
|
this.hidingPopup = false;
|
8702
|
-
this.$ccButton.
|
8870
|
+
this.$ccButton.removeAttr('aria-expanded').focus();
|
8703
8871
|
}
|
8704
8872
|
else {
|
8705
8873
|
this.closePopups();
|
@@ -8726,7 +8894,7 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
8726
8894
|
if (this.chaptersPopup.is(':visible')) {
|
8727
8895
|
this.chaptersPopup.hide();
|
8728
8896
|
this.hidingPopup = false;
|
8729
|
-
this.$chaptersButton.
|
8897
|
+
this.$chaptersButton.removeAttr('aria-expanded').focus();
|
8730
8898
|
}
|
8731
8899
|
else {
|
8732
8900
|
this.closePopups();
|
@@ -8760,6 +8928,7 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
8760
8928
|
};
|
8761
8929
|
|
8762
8930
|
AblePlayer.prototype.handlePrefsClick = function(pref) {
|
8931
|
+
|
8763
8932
|
// NOTE: the prefs menu is positioned near the right edge of the player
|
8764
8933
|
// This assumes the Prefs button is also positioned in that vicinity
|
8765
8934
|
// (last or second-last button the right)
|
@@ -8775,7 +8944,7 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
8775
8944
|
if (this.prefsPopup.is(':visible')) {
|
8776
8945
|
this.prefsPopup.hide();
|
8777
8946
|
this.hidingPopup = false;
|
8778
|
-
this.$prefsButton.
|
8947
|
+
this.$prefsButton.removeAttr('aria-expanded').focus();
|
8779
8948
|
// restore each menu item to original hidden state
|
8780
8949
|
this.prefsPopup.find('li').removeClass('able-focus').attr('tabindex','-1');
|
8781
8950
|
}
|
@@ -9759,6 +9928,7 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
9759
9928
|
}
|
9760
9929
|
|
9761
9930
|
AblePlayer.prototype.stylizeCaptions = function($element, pref) {
|
9931
|
+
|
9762
9932
|
// $element is the jQuery element containing the captions
|
9763
9933
|
// this function handles stylizing of the sample caption text in the Prefs dialog
|
9764
9934
|
// plus the actual production captions
|
@@ -10573,10 +10743,15 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
10573
10743
|
}
|
10574
10744
|
|
10575
10745
|
if (currentTime >= start && currentTime <= end && !isChapterHeading) {
|
10576
|
-
|
10577
|
-
|
10578
|
-
|
10579
|
-
|
10746
|
+
|
10747
|
+
// If this item isn't already highlighted, it should be
|
10748
|
+
if (!($(this).hasClass('able-highlight'))) {
|
10749
|
+
// remove all previous highlights before adding one to current span
|
10750
|
+
thisObj.$transcriptArea.find('.able-highlight').removeClass('able-highlight');
|
10751
|
+
$(this).addClass('able-highlight');
|
10752
|
+
thisObj.movingHighlight = true;
|
10753
|
+
}
|
10754
|
+
return false;
|
10580
10755
|
}
|
10581
10756
|
});
|
10582
10757
|
thisObj.currentHighlight = $('.able-highlight');
|
@@ -11128,11 +11303,11 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
11128
11303
|
(function ($) {
|
11129
11304
|
// Media events
|
11130
11305
|
AblePlayer.prototype.onMediaUpdateTime = function (duration, elapsed) {
|
11306
|
+
|
11131
11307
|
// duration and elapsed are passed from callback functions of Vimeo API events
|
11132
11308
|
// duration is expressed as sss.xxx
|
11133
11309
|
// elapsed is expressed as sss.xxx
|
11134
11310
|
var thisObj = this;
|
11135
|
-
|
11136
11311
|
this.getMediaTimes(duration,elapsed).then(function(mediaTimes) {
|
11137
11312
|
thisObj.duration = mediaTimes['duration'];
|
11138
11313
|
thisObj.elapsed = mediaTimes['elapsed'];
|
@@ -11313,7 +11488,9 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
11313
11488
|
AblePlayer.prototype.onClickPlayerButton = function (el) {
|
11314
11489
|
|
11315
11490
|
// 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?
|
11316
|
-
|
11491
|
+
|
11492
|
+
var whichButton, prefsPopup;
|
11493
|
+
whichButton = $(el).attr('class').split(' ')[0].substr(20);
|
11317
11494
|
if (whichButton === 'play') {
|
11318
11495
|
this.clickedPlay = true;
|
11319
11496
|
this.handlePlay();
|
@@ -11363,7 +11540,25 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
11363
11540
|
this.handleSignToggle();
|
11364
11541
|
}
|
11365
11542
|
else if (whichButton === 'preferences') {
|
11366
|
-
|
11543
|
+
if ($(el).attr('data-prefs-popup') === 'menu') {
|
11544
|
+
this.handlePrefsClick();
|
11545
|
+
}
|
11546
|
+
else {
|
11547
|
+
this.closePopups();
|
11548
|
+
prefsPopup = $(el).attr('data-prefs-popup');
|
11549
|
+
if (prefsPopup === 'keyboard') {
|
11550
|
+
this.keyboardPrefsDialog.show();
|
11551
|
+
}
|
11552
|
+
else if (prefsPopup === 'captions') {
|
11553
|
+
this.captionPrefsDialog.show();
|
11554
|
+
}
|
11555
|
+
else if (prefsPopup === 'descriptions') {
|
11556
|
+
this.descPrefsDialog.show();
|
11557
|
+
}
|
11558
|
+
else if (prefsPopup === 'transcript') {
|
11559
|
+
this.transcriptPrefsDialog.show();
|
11560
|
+
}
|
11561
|
+
}
|
11367
11562
|
}
|
11368
11563
|
else if (whichButton === 'help') {
|
11369
11564
|
this.handleHelpClick();
|
@@ -11414,7 +11609,6 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
11414
11609
|
if (which >= 65 && which <= 90) {
|
11415
11610
|
which += 32;
|
11416
11611
|
}
|
11417
|
-
|
11418
11612
|
// Only use keypress to control player if focus is NOT on a form field or contenteditable element
|
11419
11613
|
if (!(
|
11420
11614
|
$(':focus').is('[contenteditable]') ||
|
@@ -11538,7 +11732,7 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
11538
11732
|
if (!thisObj.startedPlaying) {
|
11539
11733
|
// start playing; no further user action is required
|
11540
11734
|
thisObj.playMedia();
|
11541
|
-
|
11735
|
+
}
|
11542
11736
|
thisObj.userClickedPlaylist = false; // reset
|
11543
11737
|
}
|
11544
11738
|
if (thisObj.seekTrigger == 'restart' || thisObj.seekTrigger == 'chapter' || thisObj.seekTrigger == 'transcript') {
|
@@ -11582,11 +11776,7 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
11582
11776
|
// already started playing
|
11583
11777
|
// we're here because a new media source has been loaded and is ready to resume playback
|
11584
11778
|
thisObj.getPlayerState().then(function(currentState) {
|
11585
|
-
if (thisObj.swappingSrc && currentState === 'stopped') {
|
11586
|
-
// Safari is the only browser that returns value of 'stopped' (observed in 12.0.1 on MacOS)
|
11587
|
-
// This prevents 'timeupdate' events from triggering, which prevents the new media src
|
11588
|
-
// from resuming playback at swapTime
|
11589
|
-
// This is a hack to jump start Safari
|
11779
|
+
if (thisObj.swappingSrc && (currentState === 'stopped' || currentState === 'paused')) {
|
11590
11780
|
thisObj.startedPlaying = false;
|
11591
11781
|
if (thisObj.swapTime > 0) {
|
11592
11782
|
thisObj.seekTo(thisObj.swapTime);
|
@@ -11630,8 +11820,8 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
11630
11820
|
.on('pause',function() {
|
11631
11821
|
if (!thisObj.clickedPlay) {
|
11632
11822
|
// 'pause' was triggered automatically, not initiated by user
|
11633
|
-
// this happens in some browsers
|
11634
|
-
//
|
11823
|
+
// this happens in some browsers when swapping source
|
11824
|
+
// (e.g., between tracks in a playlist or swapping description)
|
11635
11825
|
if (thisObj.hasPlaylist || thisObj.swappingSrc) {
|
11636
11826
|
// do NOT set playing to false.
|
11637
11827
|
// doing so prevents continual playback after new track is loaded
|
@@ -12067,44 +12257,42 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
12067
12257
|
|
12068
12258
|
// add event listener to toolbar to start and end drag
|
12069
12259
|
// other event listeners will be added when drag starts
|
12070
|
-
$toolbar.on('mousedown', function(e) {
|
12071
|
-
e.stopPropagation();
|
12072
|
-
if (!thisObj.windowMenuClickRegistered) {
|
12073
|
-
thisObj.windowMenuClickRegistered = true;
|
12074
|
-
thisObj.startMouseX = e.pageX;
|
12075
|
-
thisObj.startMouseY = e.pageY;
|
12076
|
-
thisObj.dragDevice = 'mouse';
|
12077
|
-
thisObj.startDrag(which, $window);
|
12078
|
-
}
|
12079
|
-
return false;
|
12080
|
-
});
|
12081
|
-
$toolbar.on('mouseup', function(e) {
|
12260
|
+
$toolbar.on('mousedown mouseup touchstart touchend', function(e) {
|
12082
12261
|
e.stopPropagation();
|
12083
|
-
if (
|
12084
|
-
|
12085
|
-
|
12086
|
-
|
12262
|
+
if (e.type === 'mousedown' || e.type === 'touchstart') {
|
12263
|
+
if (!thisObj.windowMenuClickRegistered) {
|
12264
|
+
thisObj.windowMenuClickRegistered = true;
|
12265
|
+
thisObj.startMouseX = e.pageX;
|
12266
|
+
thisObj.startMouseY = e.pageY;
|
12267
|
+
thisObj.dragDevice = 'mouse'; // ok to use this even if device is a touchpad
|
12268
|
+
thisObj.startDrag(which, $window);
|
12269
|
+
}
|
12270
|
+
}
|
12271
|
+
else if (e.type === 'mouseup' || e.type === 'touchend') {
|
12272
|
+
if (thisObj.dragging && thisObj.dragDevice === 'mouse') {
|
12273
|
+
thisObj.endDrag(which);
|
12274
|
+
}
|
12275
|
+
}
|
12276
|
+
return false;
|
12087
12277
|
});
|
12088
12278
|
|
12089
12279
|
// add event listeners for resizing
|
12090
|
-
$resizeHandle.on('mousedown', function(e) {
|
12091
|
-
|
12092
|
-
e.stopPropagation();
|
12093
|
-
if (!thisObj.windowMenuClickRegistered) {
|
12094
|
-
thisObj.windowMenuClickRegistered = true;
|
12095
|
-
thisObj.startMouseX = e.pageX;
|
12096
|
-
thisObj.startMouseY = e.pageY;
|
12097
|
-
thisObj.startResize(which, $window);
|
12098
|
-
return false;
|
12099
|
-
}
|
12100
|
-
});
|
12101
|
-
|
12102
|
-
$resizeHandle.on('mouseup', function(e) {
|
12280
|
+
$resizeHandle.on('mousedown mouseup touchstart touchend', function(e) {
|
12103
12281
|
e.stopPropagation();
|
12104
|
-
if (
|
12105
|
-
|
12106
|
-
|
12107
|
-
|
12282
|
+
if (e.type === 'mousedown' || e.type === 'touchstart') {
|
12283
|
+
if (!thisObj.windowMenuClickRegistered) {
|
12284
|
+
thisObj.windowMenuClickRegistered = true;
|
12285
|
+
thisObj.startMouseX = e.pageX;
|
12286
|
+
thisObj.startMouseY = e.pageY;
|
12287
|
+
thisObj.startResize(which, $window);
|
12288
|
+
}
|
12289
|
+
}
|
12290
|
+
else if (e.type === 'mouseup' || e.type === 'touchend') {
|
12291
|
+
if (thisObj.resizing) {
|
12292
|
+
thisObj.endResize(which);
|
12293
|
+
}
|
12294
|
+
}
|
12295
|
+
return false;
|
12108
12296
|
});
|
12109
12297
|
|
12110
12298
|
// whenever a window is clicked, bring it to the foreground
|
@@ -12549,8 +12737,8 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
12549
12737
|
}).focus();
|
12550
12738
|
|
12551
12739
|
// add device-specific event listeners
|
12552
|
-
if (this.dragDevice === 'mouse') {
|
12553
|
-
$(document).on('mousemove',function(e) {
|
12740
|
+
if (this.dragDevice === 'mouse') { // might also be a touchpad
|
12741
|
+
$(document).on('mousemove touchmove',function(e) {
|
12554
12742
|
if (thisObj.dragging) {
|
12555
12743
|
// calculate new top left based on current mouse position - offset
|
12556
12744
|
newX = e.pageX - thisObj.dragOffsetX;
|
@@ -12654,7 +12842,7 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
12654
12842
|
$windowButton = this.$signPopupButton;
|
12655
12843
|
}
|
12656
12844
|
|
12657
|
-
$(document).off('mousemove mouseup');
|
12845
|
+
$(document).off('mousemove mouseup touchmove touchup');
|
12658
12846
|
this.$activeWindow.off('keydown').removeClass('able-drag');
|
12659
12847
|
|
12660
12848
|
if (this.dragDevice === 'keyboard') {
|
@@ -12731,7 +12919,7 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
12731
12919
|
this.dragStartHeight = this.$activeWindow.height();
|
12732
12920
|
|
12733
12921
|
// add event listeners
|
12734
|
-
$(document).on('mousemove',function(e) {
|
12922
|
+
$(document).on('mousemove touchmove',function(e) {
|
12735
12923
|
if (thisObj.resizing) {
|
12736
12924
|
// calculate new width and height based on changes to mouse position
|
12737
12925
|
newWidth = thisObj.dragStartWidth + (e.pageX - thisObj.startMouseX);
|
@@ -12755,7 +12943,7 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
12755
12943
|
$windowButton = this.$signPopupButton;
|
12756
12944
|
}
|
12757
12945
|
|
12758
|
-
$(document).off('mousemove mouseup');
|
12946
|
+
$(document).off('mousemove mouseup touchmove touchup');
|
12759
12947
|
this.$activeWindow.off('keydown');
|
12760
12948
|
|
12761
12949
|
$windowButton.show().focus();
|
@@ -12790,11 +12978,21 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
12790
12978
|
// If sign language is provided, it must be provided for all sources
|
12791
12979
|
this.signFile = this.$sources.first().attr('data-sign-src');
|
12792
12980
|
if (this.signFile) {
|
12793
|
-
|
12794
|
-
|
12795
|
-
|
12796
|
-
|
12797
|
-
|
12981
|
+
if (this.isIOS()) {
|
12982
|
+
// IOS does not allow multiple videos to play simultaneously
|
12983
|
+
// Therefore, sign language as rendered by Able Player unfortunately won't work
|
12984
|
+
this.hasSignLanguage = false;
|
12985
|
+
if (this.debug) {
|
12986
|
+
console.log('Sign language has been disabled due to IOS restrictions');
|
12987
|
+
}
|
12988
|
+
}
|
12989
|
+
else {
|
12990
|
+
if (this.debug) {
|
12991
|
+
console.log('This video has an accompanying sign language video: ' + this.signFile);
|
12992
|
+
}
|
12993
|
+
this.hasSignLanguage = true;
|
12994
|
+
this.injectSignPlayerCode();
|
12995
|
+
}
|
12798
12996
|
}
|
12799
12997
|
else {
|
12800
12998
|
this.hasSignLanguage = false;
|
@@ -12808,17 +13006,6 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
12808
13006
|
AblePlayer.prototype.injectSignPlayerCode = function() {
|
12809
13007
|
|
12810
13008
|
// create and inject surrounding HTML structure
|
12811
|
-
// If IOS:
|
12812
|
-
// If video:
|
12813
|
-
// IOS does not support any of the player's functionality
|
12814
|
-
// - everything plays in its own player
|
12815
|
-
// Therefore, AblePlayer is not loaded & all functionality is disabled
|
12816
|
-
// (this all determined. If this is IOS && video, this function is never called)
|
12817
|
-
// If audio:
|
12818
|
-
// HTML cannot be injected as a *parent* of the <audio> element
|
12819
|
-
// It is therefore injected *after* the <audio> element
|
12820
|
-
// This is only a problem in IOS 6 and earlier,
|
12821
|
-
// & is a known bug, fixed in IOS 7
|
12822
13009
|
|
12823
13010
|
var thisObj, signVideoId, signVideoWidth, i, signSrc, srcType, $signSource;
|
12824
13011
|
|
@@ -13882,10 +14069,10 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
13882
14069
|
thisObj = this;
|
13883
14070
|
// get language of the web page, if specified
|
13884
14071
|
if ($('body').attr('lang')) {
|
13885
|
-
lang = $('body').attr('lang');
|
14072
|
+
lang = $('body').attr('lang').toLowerCase();
|
13886
14073
|
}
|
13887
14074
|
else if ($('html').attr('lang')) {
|
13888
|
-
lang = $('html').attr('lang');
|
14075
|
+
lang = $('html').attr('lang').toLowerCase();
|
13889
14076
|
}
|
13890
14077
|
else {
|
13891
14078
|
lang = null;
|
@@ -15389,7 +15576,7 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
15389
15576
|
|
15390
15577
|
AblePlayer.prototype.getVimeoDimensions = function (vimeoContainerId) {
|
15391
15578
|
|
15392
|
-
// get dimensions of
|
15579
|
+
// get dimensions of Vimeo video, return array with width & height
|
15393
15580
|
// Sources, in order of priority:
|
15394
15581
|
// 1. The width and height attributes on <video>
|
15395
15582
|
// 2. YouTube (not yet supported; can't seem to get this data via YouTube Data API without OAuth!)
|
@@ -15423,6 +15610,9 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
15423
15610
|
|
15424
15611
|
AblePlayer.prototype.resizeVimeoPlayer = function(youTubeId, youTubeContainerId) {
|
15425
15612
|
|
15613
|
+
// NOTE: This function is modeled after same function in youtube.js
|
15614
|
+
// in case useful for Vimeo, but is not currently used
|
15615
|
+
|
15426
15616
|
// called after player is ready, if youTube dimensions were previously unknown
|
15427
15617
|
// Now need to get them from the iframe element that YouTube injected
|
15428
15618
|
// and resize Able Player to match
|
@@ -15479,6 +15669,7 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
15479
15669
|
|
15480
15670
|
AblePlayer.prototype.setupVimeoCaptions = function () {
|
15481
15671
|
|
15672
|
+
console.log('setupVimeoCaptions');
|
15482
15673
|
// called from setupAltCaptions if player is YouTube and there are no <track> captions
|
15483
15674
|
|
15484
15675
|
// use YouTube Data API to get caption data from YouTube
|
@@ -15591,6 +15782,11 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
15591
15782
|
};
|
15592
15783
|
|
15593
15784
|
AblePlayer.prototype.initVimeoCaptionModule = function () {
|
15785
|
+
|
15786
|
+
// NOTE: This function is modeled after same function in youtube.js
|
15787
|
+
// in case useful for Vimeo, but is not currently used
|
15788
|
+
|
15789
|
+
|
15594
15790
|
// This function is called when YouTube onApiChange event fires
|
15595
15791
|
// to indicate that the player has loaded (or unloaded) a module with exposed API methods
|
15596
15792
|
// it isn't fired until the video starts playing
|
@@ -15658,6 +15854,9 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
15658
15854
|
|
15659
15855
|
AblePlayer.prototype.getVimeoPosterUrl = function (youTubeId, width) {
|
15660
15856
|
|
15857
|
+
// NOTE: This function is modeled after same function in youtube.js
|
15858
|
+
// in case useful for Vimeo, but is not currently used
|
15859
|
+
|
15661
15860
|
// return a URL for retrieving a YouTube poster image
|
15662
15861
|
// supported values of width: 120, 320, 480, 640
|
15663
15862
|
|
@@ -15681,4 +15880,4 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith('<?xml
|
|
15681
15880
|
return false;
|
15682
15881
|
};
|
15683
15882
|
|
15684
|
-
})(jQuery);
|
15883
|
+
})(jQuery);
|