wai-website-theme 1.3.1 → 1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/_includes/different.html +2 -1
  3. data/_includes/external.html +2 -1
  4. data/_includes/header.html +2 -1
  5. data/_includes/menuitem.html +6 -2
  6. data/_includes/peoplelist.html +21 -0
  7. data/_includes/prevnext-navigation.html +56 -0
  8. data/_includes/{prevnext.html → prevnext-order.html} +9 -0
  9. data/_includes/translation-note-msg.html +5 -3
  10. data/_includes/video-player.html +2 -2
  11. data/_layouts/default.html +8 -1
  12. data/_layouts/news.html +7 -1
  13. data/_layouts/policy.html +7 -1
  14. data/_layouts/sidenav.html +8 -1
  15. data/_layouts/sidenavsidebar.html +8 -1
  16. data/assets/ableplayer/Gruntfile.js +2 -1
  17. data/assets/ableplayer/README.md +158 -85
  18. data/assets/ableplayer/build/ableplayer.dist.js +15445 -13823
  19. data/assets/ableplayer/build/ableplayer.js +15445 -13823
  20. data/assets/ableplayer/build/ableplayer.min.css +1 -2
  21. data/assets/ableplayer/build/ableplayer.min.js +3 -10
  22. data/assets/ableplayer/package-lock.json +944 -346
  23. data/assets/ableplayer/package.json +8 -8
  24. data/assets/ableplayer/scripts/ableplayer-base.js +515 -524
  25. data/assets/ableplayer/scripts/browser.js +158 -158
  26. data/assets/ableplayer/scripts/buildplayer.js +1750 -1682
  27. data/assets/ableplayer/scripts/caption.js +424 -401
  28. data/assets/ableplayer/scripts/chapters.js +259 -259
  29. data/assets/ableplayer/scripts/control.js +1831 -1594
  30. data/assets/ableplayer/scripts/description.js +333 -256
  31. data/assets/ableplayer/scripts/dialog.js +145 -145
  32. data/assets/ableplayer/scripts/dragdrop.js +746 -749
  33. data/assets/ableplayer/scripts/event.js +875 -696
  34. data/assets/ableplayer/scripts/initialize.js +819 -912
  35. data/assets/ableplayer/scripts/langs.js +979 -743
  36. data/assets/ableplayer/scripts/metadata.js +124 -124
  37. data/assets/ableplayer/scripts/misc.js +170 -137
  38. data/assets/ableplayer/scripts/preference.js +904 -904
  39. data/assets/ableplayer/scripts/search.js +172 -172
  40. data/assets/ableplayer/scripts/sign.js +82 -78
  41. data/assets/ableplayer/scripts/slider.js +449 -448
  42. data/assets/ableplayer/scripts/track.js +409 -309
  43. data/assets/ableplayer/scripts/transcript.js +684 -595
  44. data/assets/ableplayer/scripts/translation.js +63 -67
  45. data/assets/ableplayer/scripts/ttml2webvtt.js +85 -85
  46. data/assets/ableplayer/scripts/vimeo.js +448 -0
  47. data/assets/ableplayer/scripts/volume.js +395 -380
  48. data/assets/ableplayer/scripts/vts.js +1077 -1077
  49. data/assets/ableplayer/scripts/webvtt.js +766 -763
  50. data/assets/ableplayer/scripts/youtube.js +695 -478
  51. data/assets/ableplayer/styles/ableplayer.css +54 -46
  52. data/assets/ableplayer/translations/nl.js +54 -54
  53. data/assets/ableplayer/translations/pt-br.js +311 -0
  54. data/assets/ableplayer/translations/tr.js +311 -0
  55. data/assets/ableplayer/translations/zh-tw.js +1 -1
  56. data/assets/css/style.css +1 -1
  57. data/assets/css/style.css.map +1 -1
  58. data/assets/images/icons.svg +5 -5
  59. data/assets/scripts/main.js +7 -0
  60. data/assets/search/tipuesearch.js +3 -3
  61. metadata +8 -3
@@ -1,909 +1,909 @@
1
1
  (function ($) {
2
- AblePlayer.prototype.setCookie = function(cookieValue) {
3
- Cookies.set('Able-Player', cookieValue, { expires:90 });
4
- // set the cookie lifetime for 90 days
5
- };
6
-
7
- AblePlayer.prototype.getCookie = function() {
8
-
9
- var defaultCookie = {
10
- preferences: {},
11
- sign: {},
12
- transcript: {}
13
- };
14
-
15
- var cookie;
16
- try {
17
- cookie = Cookies.getJSON('Able-Player');
18
- }
19
- catch (err) {
20
- // Original cookie can't be parsed; update to default
21
- Cookies.getJSON(defaultCookie);
22
- cookie = defaultCookie;
23
- }
24
- if (cookie) {
25
- return cookie;
26
- }
27
- else {
28
- return defaultCookie;
29
- }
30
- };
31
-
32
- AblePlayer.prototype.updateCookie = function( setting ) {
33
-
34
- // called when a particular setting had been updated
35
- // useful for settings updated indpedently of Preferences dialog
36
- // e.g., prefAutoScrollTranscript, which is updated in control.js > handleTranscriptLockToggle()
37
- // setting is any supported preference name (e.g., "prefCaptions")
38
- // OR 'transcript' or 'sign' (not user-defined preferences, used to save position of draggable windows)
39
- var cookie, $window, windowPos, available, i, prefName;
40
- cookie = this.getCookie();
41
-
42
- if (setting === 'transcript' || setting === 'sign') {
43
- if (setting === 'transcript') {
44
- $window = this.$transcriptArea;
45
- windowPos = $window.position();
46
- if (typeof cookie.transcript === 'undefined') {
47
- cookie.transcript = {};
48
- }
49
- cookie.transcript['position'] = $window.css('position'); // either 'relative' or 'absolute'
50
- cookie.transcript['zindex'] = $window.css('z-index');
51
- cookie.transcript['top'] = windowPos.top;
52
- cookie.transcript['left'] = windowPos.left;
53
- cookie.transcript['width'] = $window.width();
54
- cookie.transcript['height'] = $window.height();
55
- }
56
- else if (setting === 'sign') {
57
- $window = this.$signWindow;
58
- windowPos = $window.position();
59
- if (typeof cookie.sign === 'undefined') {
60
- cookie.sign = {};
61
- }
62
- cookie.sign['position'] = $window.css('position'); // either 'relative' or 'absolute'
63
- cookie.sign['zindex'] = $window.css('z-index');
64
- cookie.sign['top'] = windowPos.top;
65
- cookie.sign['left'] = windowPos.left;
66
- cookie.sign['width'] = $window.width();
67
- cookie.sign['height'] = $window.height();
68
- }
69
- }
70
- else {
71
- available = this.getAvailablePreferences();
72
- // Rebuild cookie with current cookie values,
73
- // replacing the one value that's been changed
74
- for (i = 0; i < available.length; i++) {
75
- prefName = available[i]['name'];
76
- if (prefName == setting) {
77
- // this is the one that requires an update
78
- cookie.preferences[prefName] = this[prefName];
79
- }
80
- }
81
- }
82
- // Save updated cookie
83
- this.setCookie(cookie);
84
- };
85
-
86
- AblePlayer.prototype.getPreferencesGroups = function() {
87
-
88
- // return array of groups in the order in which they will appear
89
- // in the Preferences popup menu
90
- // Human-readable label for each group is defined in translation table
91
- if (this.mediaType === 'video') {
92
- return ['captions','descriptions','keyboard','transcript'];
93
- }
94
- else if (this.mediaType === 'audio') {
95
- var groups = [];
96
- groups.push('keyboard');
97
- if (this.lyricsMode) {
98
- groups.push('transcript');
99
- }
100
- return groups;
101
- }
102
- }
103
-
104
- AblePlayer.prototype.getAvailablePreferences = function() {
105
-
106
- // Return the list of currently available preferences.
107
- // Preferences with no 'label' are set within player, not shown in Prefs dialog
108
- var prefs = [];
109
-
110
- // Modifier keys preferences
111
- prefs.push({
112
- 'name': 'prefAltKey', // use alt key with shortcuts
113
- 'label': this.tt.prefAltKey,
114
- 'group': 'keyboard',
115
- 'default': 1
116
- });
117
- prefs.push({
118
- 'name': 'prefCtrlKey', // use ctrl key with shortcuts
119
- 'label': this.tt.prefCtrlKey,
120
- 'group': 'keyboard',
121
- 'default': 1
122
- });
123
- prefs.push({
124
- 'name': 'prefShiftKey',
125
- 'label': this.tt.prefShiftKey,
126
- 'group': 'keyboard',
127
- 'default': 0
128
- });
129
-
130
- // Transcript preferences
131
- prefs.push({
132
- 'name': 'prefTranscript', // transcript default state
133
- 'label': null,
134
- 'group': 'transcript',
135
- 'default': 0 // off because turning it on has a certain WOW factor
136
- });
137
- prefs.push({
138
- 'name': 'prefHighlight', // highlight transcript as media plays
139
- 'label': this.tt.prefHighlight,
140
- 'group': 'transcript',
141
- 'default': 1 // on because many users can benefit
142
- });
143
- prefs.push({
144
- 'name': 'prefAutoScrollTranscript',
145
- 'label': null,
146
- 'group': 'transcript',
147
- 'default': 1
148
- });
149
- prefs.push({
150
- 'name': 'prefTabbable', // tab-enable transcript
151
- 'label': this.tt.prefTabbable,
152
- 'group': 'transcript',
153
- 'default': 0 // off because if users don't need it, it impedes tabbing elsewhere on the page
154
- });
155
-
156
- if (this.mediaType === 'video') {
157
-
158
- // Caption preferences
159
- prefs.push({
160
- 'name': 'prefCaptions', // closed captions default state
161
- 'label': null,
162
- 'group': 'captions',
163
- 'default': 1
164
- });
2
+ AblePlayer.prototype.setCookie = function(cookieValue) {
3
+ Cookies.set('Able-Player', cookieValue, { expires:90 });
4
+ // set the cookie lifetime for 90 days
5
+ };
6
+
7
+ AblePlayer.prototype.getCookie = function() {
8
+
9
+ var defaultCookie = {
10
+ preferences: {},
11
+ sign: {},
12
+ transcript: {}
13
+ };
14
+
15
+ var cookie;
16
+ try {
17
+ cookie = Cookies.getJSON('Able-Player');
18
+ }
19
+ catch (err) {
20
+ // Original cookie can't be parsed; update to default
21
+ Cookies.getJSON(defaultCookie);
22
+ cookie = defaultCookie;
23
+ }
24
+ if (cookie) {
25
+ return cookie;
26
+ }
27
+ else {
28
+ return defaultCookie;
29
+ }
30
+ };
31
+
32
+ AblePlayer.prototype.updateCookie = function( setting ) {
33
+
34
+ // called when a particular setting had been updated
35
+ // useful for settings updated indpedently of Preferences dialog
36
+ // e.g., prefAutoScrollTranscript, which is updated in control.js > handleTranscriptLockToggle()
37
+ // setting is any supported preference name (e.g., "prefCaptions")
38
+ // OR 'transcript' or 'sign' (not user-defined preferences, used to save position of draggable windows)
39
+ var cookie, $window, windowPos, available, i, prefName;
40
+ cookie = this.getCookie();
41
+
42
+ if (setting === 'transcript' || setting === 'sign') {
43
+ if (setting === 'transcript') {
44
+ $window = this.$transcriptArea;
45
+ windowPos = $window.position();
46
+ if (typeof cookie.transcript === 'undefined') {
47
+ cookie.transcript = {};
48
+ }
49
+ cookie.transcript['position'] = $window.css('position'); // either 'relative' or 'absolute'
50
+ cookie.transcript['zindex'] = $window.css('z-index');
51
+ cookie.transcript['top'] = windowPos.top;
52
+ cookie.transcript['left'] = windowPos.left;
53
+ cookie.transcript['width'] = $window.width();
54
+ cookie.transcript['height'] = $window.height();
55
+ }
56
+ else if (setting === 'sign') {
57
+ $window = this.$signWindow;
58
+ windowPos = $window.position();
59
+ if (typeof cookie.sign === 'undefined') {
60
+ cookie.sign = {};
61
+ }
62
+ cookie.sign['position'] = $window.css('position'); // either 'relative' or 'absolute'
63
+ cookie.sign['zindex'] = $window.css('z-index');
64
+ cookie.sign['top'] = windowPos.top;
65
+ cookie.sign['left'] = windowPos.left;
66
+ cookie.sign['width'] = $window.width();
67
+ cookie.sign['height'] = $window.height();
68
+ }
69
+ }
70
+ else {
71
+ available = this.getAvailablePreferences();
72
+ // Rebuild cookie with current cookie values,
73
+ // replacing the one value that's been changed
74
+ for (i = 0; i < available.length; i++) {
75
+ prefName = available[i]['name'];
76
+ if (prefName == setting) {
77
+ // this is the one that requires an update
78
+ cookie.preferences[prefName] = this[prefName];
79
+ }
80
+ }
81
+ }
82
+ // Save updated cookie
83
+ this.setCookie(cookie);
84
+ };
85
+
86
+ AblePlayer.prototype.getPreferencesGroups = function() {
87
+
88
+ // return array of groups in the order in which they will appear
89
+ // in the Preferences popup menu
90
+ // Human-readable label for each group is defined in translation table
91
+ if (this.mediaType === 'video') {
92
+ return ['captions','descriptions','keyboard','transcript'];
93
+ }
94
+ else if (this.mediaType === 'audio') {
95
+ var groups = [];
96
+ groups.push('keyboard');
97
+ if (this.lyricsMode) {
98
+ groups.push('transcript');
99
+ }
100
+ return groups;
101
+ }
102
+ }
103
+
104
+ AblePlayer.prototype.getAvailablePreferences = function() {
105
+
106
+ // Return the list of currently available preferences.
107
+ // Preferences with no 'label' are set within player, not shown in Prefs dialog
108
+ var prefs = [];
109
+
110
+ // Modifier keys preferences
111
+ prefs.push({
112
+ 'name': 'prefAltKey', // use alt key with shortcuts
113
+ 'label': this.tt.prefAltKey,
114
+ 'group': 'keyboard',
115
+ 'default': 1
116
+ });
117
+ prefs.push({
118
+ 'name': 'prefCtrlKey', // use ctrl key with shortcuts
119
+ 'label': this.tt.prefCtrlKey,
120
+ 'group': 'keyboard',
121
+ 'default': 1
122
+ });
123
+ prefs.push({
124
+ 'name': 'prefShiftKey',
125
+ 'label': this.tt.prefShiftKey,
126
+ 'group': 'keyboard',
127
+ 'default': 0
128
+ });
129
+
130
+ // Transcript preferences
131
+ prefs.push({
132
+ 'name': 'prefTranscript', // transcript default state
133
+ 'label': null,
134
+ 'group': 'transcript',
135
+ 'default': 0 // off because turning it on has a certain WOW factor
136
+ });
137
+ prefs.push({
138
+ 'name': 'prefHighlight', // highlight transcript as media plays
139
+ 'label': this.tt.prefHighlight,
140
+ 'group': 'transcript',
141
+ 'default': 1 // on because many users can benefit
142
+ });
143
+ prefs.push({
144
+ 'name': 'prefAutoScrollTranscript',
145
+ 'label': null,
146
+ 'group': 'transcript',
147
+ 'default': 1
148
+ });
149
+ prefs.push({
150
+ 'name': 'prefTabbable', // tab-enable transcript
151
+ 'label': this.tt.prefTabbable,
152
+ 'group': 'transcript',
153
+ 'default': 0 // off because if users don't need it, it impedes tabbing elsewhere on the page
154
+ });
155
+
156
+ if (this.mediaType === 'video') {
157
+
158
+ // Caption preferences
159
+ prefs.push({
160
+ 'name': 'prefCaptions', // closed captions default state
161
+ 'label': null,
162
+ 'group': 'captions',
163
+ 'default': 1
164
+ });
165
165
  /* // not supported yet
166
- prefs.push({
167
- 'name': 'prefCaptionsStyle',
168
- 'label': this.tt.prefCaptionsStyle,
169
- 'group': 'captions',
170
- 'default': this.tt.captionsStylePopOn
171
- });
166
+ prefs.push({
167
+ 'name': 'prefCaptionsStyle',
168
+ 'label': this.tt.prefCaptionsStyle,
169
+ 'group': 'captions',
170
+ 'default': this.tt.captionsStylePopOn
171
+ });
172
172
  */
173
- prefs.push({
174
- 'name': 'prefCaptionsPosition',
175
- 'label': this.tt.prefCaptionsPosition,
176
- 'group': 'captions',
177
- 'default': this.defaultCaptionsPosition
178
- });
179
- prefs.push({
180
- 'name': 'prefCaptionsFont',
181
- 'label': this.tt.prefCaptionsFont,
182
- 'group': 'captions',
183
- 'default': this.tt.sans
184
- });
185
- prefs.push({
186
- 'name': 'prefCaptionsSize',
187
- 'label': this.tt.prefCaptionsSize,
188
- 'group': 'captions',
189
- 'default': '100%'
190
- });
191
- prefs.push({
192
- 'name': 'prefCaptionsColor',
193
- 'label': this.tt.prefCaptionsColor,
194
- 'group': 'captions',
195
- 'default': 'white'
196
- });
197
- prefs.push({
198
- 'name': 'prefCaptionsBGColor',
199
- 'label': this.tt.prefCaptionsBGColor,
200
- 'group': 'captions',
201
- 'default': 'black'
202
- });
203
- prefs.push({
204
- 'name': 'prefCaptionsOpacity',
205
- 'label': this.tt.prefCaptionsOpacity,
206
- 'group': 'captions',
207
- 'default': '100%'
208
- });
209
-
210
- // Description preferences
211
- prefs.push({
212
- 'name': 'prefDesc', // audio description default state
213
- 'label': null,
214
- 'group': 'descriptions',
215
- 'default': 0 // off because users who don't need it might find it distracting
216
- });
217
- prefs.push({
218
- 'name': 'prefDescFormat', // audio description default state
219
- 'label': this.tt.prefDescFormat,
220
- 'group': 'descriptions',
221
- 'default': 'video'
222
- });
223
- prefs.push({
224
- 'name': 'prefDescPause', // automatically pause when closed description starts
225
- 'label': this.tt.prefDescPause,
226
- 'group': 'descriptions',
227
- 'default': 0 // off because it burdens user with restarting after every pause
228
- });
229
- prefs.push({
230
- 'name': 'prefVisibleDesc', // visibly show closed description (if avilable and used)
231
- 'label': this.tt.prefVisibleDesc,
232
- 'group': 'descriptions',
233
- 'default': 1 // on because sighted users probably want to see this cool feature in action
234
- });
235
-
236
- // Video preferences without a category (not shown in Preferences dialogs)
237
- prefs.push({
238
- 'name': 'prefSign', // open sign language window by default if avilable
239
- 'label': null,
240
- 'group': null,
241
- 'default': 0 // off because clicking an icon to see the sign window has a powerful impact
242
- });
243
-
244
- }
245
- return prefs;
246
- };
247
-
248
- // Loads current/default preferences from cookie into the AblePlayer object.
249
- AblePlayer.prototype.loadCurrentPreferences = function () {
250
- var available = this.getAvailablePreferences();
251
- var cookie = this.getCookie();
252
-
253
- // Copy current cookie values into this object, and fill in any default values.
254
- for (var ii = 0; ii < available.length; ii++) {
255
- var prefName = available[ii]['name'];
256
- var defaultValue = available[ii]['default'];
257
- if (cookie.preferences[prefName] !== undefined) {
258
- this[prefName] = cookie.preferences[prefName];
259
- }
260
- else {
261
- cookie.preferences[prefName] = defaultValue;
262
- this[prefName] = defaultValue;
263
- }
264
- }
265
-
266
- // Save since we may have added default values.
267
- this.setCookie(cookie);
268
- };
269
-
270
- AblePlayer.prototype.injectPrefsForm = function (form) {
271
-
272
- // Creates a preferences form and injects it.
273
- // form is one of the supported forms (groups) defined in getPreferencesGroups()
274
-
275
- var available, thisObj, $prefsDiv, formTitle, introText,
276
- $prefsIntro,$prefsIntroP2,p3Text,$prefsIntroP3,i, j,
277
- $fieldset, fieldsetClass, fieldsetId,
278
- $descFieldset1, $descLegend1, $descFieldset2, $descLegend2, $legend,
279
- thisPref, $thisDiv, thisClass, thisId, $thisLabel, $thisField,
280
- $div1,id1,$radio1,$label1,
281
- $div2,id2,$radio2,$label2,
282
- options,$thisOption,optionValue,optionText,sampleCapsDiv,
283
- changedPref,changedSpan,changedText,
284
- currentDescState,
285
- $kbHeading,$kbList,kbLabels,keys,kbListText,$kbListItem,
286
- dialog,saveButton,cancelButton;
287
-
288
- thisObj = this;
289
- available = this.getAvailablePreferences();
290
-
291
- // outer container, will be assigned role="dialog"
292
- $prefsDiv = $('<div>',{
293
- 'class': 'able-prefs-form '
294
- });
295
- var customClass = 'able-prefs-form-' + form;
296
- $prefsDiv.addClass(customClass);
297
-
298
- // add intro
299
- if (form == 'captions') {
300
- formTitle = this.tt.prefTitleCaptions;
301
- introText = this.tt.prefIntroCaptions;
302
- // Uncomment the following line to include a cookie warning
303
- // Not included for now in order to cut down on unnecessary verbiage
304
- // introText += ' ' + this.tt.prefCookieWarning;
305
- $prefsIntro = $('<p>',{
306
- text: introText
307
- });
308
- $prefsDiv.append($prefsIntro);
309
- }
310
- else if (form == 'descriptions') {
311
- formTitle = this.tt.prefTitleDescriptions;
312
- var $prefsIntro = $('<p>',{
313
- text: this.tt.prefIntroDescription1
314
- });
315
- var $prefsIntroUL = $('<ul>');
316
- var $prefsIntroLI1 = $('<li>',{
317
- text: this.tt.prefDescFormatOption1
318
- });
319
- var $prefsIntroLI2 = $('<li>',{
320
- text: this.tt.prefDescFormatOption2
321
- });
322
-
323
- $prefsIntroUL.append($prefsIntroLI1,$prefsIntroLI2);
324
- if (this.hasOpenDesc && this.hasClosedDesc) {
325
- currentDescState = this.tt.prefIntroDescription2 + ' ';
326
- currentDescState += '<strong>' + this.tt.prefDescFormatOption1b + '</strong>';
327
- currentDescState += ' <em>' + this.tt.and + '</em> <strong>' + this.tt.prefDescFormatOption2b + '</strong>.';
328
- }
329
- else if (this.hasOpenDesc) {
330
- currentDescState = this.tt.prefIntroDescription2;
331
- currentDescState += ' <strong>' + this.tt.prefDescFormatOption1b + '</strong>.';
332
- }
333
- else if (this.hasClosedDesc) {
334
- currentDescState = this.tt.prefIntroDescription2;
335
- currentDescState += ' <strong>' + this.tt.prefDescFormatOption2b + '</strong>.';
336
- }
337
- else {
338
- currentDescState = this.tt.prefIntroDescriptionNone;
339
- }
340
- $prefsIntroP2 = $('<p>',{
341
- html: currentDescState
342
- });
343
-
344
- p3Text = this.tt.prefIntroDescription3;
345
- if (this.hasOpenDesc || this.hasClosedDesc) {
346
- p3Text += ' ' + this.tt.prefIntroDescription4;
347
- }
348
- $prefsIntroP3 = $('<p>',{
349
- text: p3Text
350
- });
351
-
352
- $prefsDiv.append($prefsIntro,$prefsIntroUL,$prefsIntroP2,$prefsIntroP3);
353
- }
354
- else if (form == 'keyboard') {
355
- formTitle = this.tt.prefTitleKeyboard;
356
- introText = this.tt.prefIntroKeyboard1;
357
- introText += ' ' + this.tt.prefIntroKeyboard2;
358
- introText += ' ' + this.tt.prefIntroKeyboard3;
359
- $prefsIntro = $('<p>',{
360
- text: introText
361
- });
362
- $prefsDiv.append($prefsIntro);
363
- }
364
- else if (form == 'transcript') {
365
- formTitle = this.tt.prefTitleTranscript;
366
- introText = this.tt.prefIntroTranscript;
367
- // Uncomment the following line to include a cookie warning
368
- // Not included for now in order to cut down on unnecessary verbiage
369
- // introText += ' ' + this.tt.prefCookieWarning;
370
- $prefsIntro = $('<p>',{
371
- text: introText
372
- });
373
- $prefsDiv.append($prefsIntro);
374
- }
375
-
376
- if (form === 'descriptions') {
377
- // descriptions form has two field sets
378
-
379
- // Fieldset 1
380
- $descFieldset1 = $('<fieldset>');
381
- fieldsetClass = 'able-prefs-' + form + '1';
382
- fieldsetId = this.mediaId + '-prefs-' + form + '1';
383
- $descFieldset1.addClass(fieldsetClass).attr('id',fieldsetId);
384
- $descLegend1 = $('<legend>' + this.tt.prefDescFormat + '</legend>');
385
- $descFieldset1.append($descLegend1);
386
-
387
- // Fieldset 2
388
- $descFieldset2 = $('<fieldset>');
389
- fieldsetClass = 'able-prefs-' + form + '2';
390
- fieldsetId = this.mediaId + '-prefs-' + form + '2';
391
- $descFieldset2.addClass(fieldsetClass).attr('id',fieldsetId);
392
- $descLegend2 = $('<legend>' + this.tt.prefHeadingTextDescription + '</legend>');
393
- $descFieldset2.append($descLegend2);
394
- }
395
- else {
396
- // all other forms just have one fieldset
397
- $fieldset = $('<fieldset>');
398
- fieldsetClass = 'able-prefs-' + form;
399
- fieldsetId = this.mediaId + '-prefs-' + form;
400
- $fieldset.addClass(fieldsetClass).attr('id',fieldsetId);
401
- if (form === 'keyboard') {
402
- $legend = $('<legend>' + this.tt.prefHeadingKeyboard1 + '</legend>');
403
- $fieldset.append($legend);
404
- }
405
- }
406
- for (i=0; i<available.length; i++) {
407
-
408
- // only include prefs on the current form if they have a label
409
- if ((available[i]['group'] == form) && available[i]['label']) {
410
-
411
- thisPref = available[i]['name'];
412
- thisClass = 'able-' + thisPref;
413
- thisId = this.mediaId + '_' + thisPref;
414
- if (thisPref !== 'prefDescFormat') {
415
- $thisDiv = $('<div>').addClass(thisClass);
416
- }
417
-
418
- // Audio Description preferred format radio buttons
419
- if (thisPref == 'prefDescFormat') {
420
-
421
- // option 1 radio button
422
- $div1 = $('<div>');
423
- id1 = thisId + '_1';
424
- $label1 = $('<label>')
425
- .attr('for',id1)
426
- .text(this.capitalizeFirstLetter(this.tt.prefDescFormatOption1))
427
- $radio1 = $('<input>',{
428
- type: 'radio',
429
- name: thisPref,
430
- id: id1,
431
- value: 'video'
432
- });
433
- if (this.prefDescFormat === 'video') {
434
- $radio1.prop('checked',true);
435
- };
436
- $div1.append($radio1,$label1);
437
-
438
- // option 2 radio button
439
- $div2 = $('<div>');
440
- id2 = thisId + '_2';
441
- $label2 = $('<label>')
442
- .attr('for',id2)
443
- .text(this.capitalizeFirstLetter(this.tt.prefDescFormatOption2));
444
- $radio2 = $('<input>',{
445
- type: 'radio',
446
- name: thisPref,
447
- id: id2,
448
- value: 'text'
449
- });
450
- if (this.prefDescFormat === 'text') {
451
- $radio2.prop('checked',true);
452
- };
453
- $div2.append($radio2,$label2);
454
- }
455
- else if (form === 'captions') {
456
- $thisLabel = $('<label for="' + thisId + '"> ' + available[i]['label'] + '</label>');
457
- $thisField = $('<select>',{
458
- name: thisPref,
459
- id: thisId,
460
- });
461
- if (thisPref !== 'prefCaptions' && thisPref !== 'prefCaptionsStyle') {
462
- // add a change handler that updates the style of the sample caption text
463
- $thisField.change(function() {
464
- changedPref = $(this).attr('name');
465
- thisObj.stylizeCaptions(thisObj.$sampleCapsDiv,changedPref);
466
- });
467
- }
468
- options = this.getCaptionsOptions(thisPref);
469
- for (j=0; j < options.length; j++) {
470
- if (thisPref === 'prefCaptionsPosition') {
471
- optionValue = options[j];
472
- if (optionValue === 'overlay') {
473
- optionText = this.tt.captionsPositionOverlay;
474
- }
475
- else if (optionValue === 'below') {
476
- optionValue = options[j];
477
- optionText = this.tt.captionsPositionBelow;
478
- }
479
- }
480
- else if (thisPref === 'prefCaptionsColor' || thisPref === 'prefCaptionsBGColor') {
481
- optionValue = options[j][0];
482
- optionText = options[j][1];
483
- }
484
- else if (thisPref === 'prefCaptionsOpacity') {
485
- optionValue = options[j];
486
- optionText = options[j];
487
- if (optionValue === '0%') {
488
- optionText += ' (' + this.tt.transparent + ')';
489
- }
490
- else if (optionValue === '100%') {
491
- optionText += ' (' + this.tt.solid + ')';
492
- }
493
- }
494
- else {
495
- optionValue = options[j];
496
- optionText = options[j];
497
- }
498
- $thisOption = $('<option>',{
499
- value: optionValue,
500
- text: optionText
501
- });
502
- if (this[thisPref] === optionValue) {
503
- $thisOption.prop('selected',true);
504
- }
505
- $thisField.append($thisOption);
506
- }
507
- $thisDiv.append($thisLabel,$thisField);
508
- }
509
- else { // all other fields are checkboxes
510
- $thisLabel = $('<label for="' + thisId + '"> ' + available[i]['label'] + '</label>');
511
- $thisField = $('<input>',{
512
- type: 'checkbox',
513
- name: thisPref,
514
- id: thisId,
515
- value: 'true'
516
- });
517
- // check current active value for this preference
518
- if (this[thisPref] === 1) {
519
- $thisField.prop('checked',true);
520
- }
521
- if (form === 'keyboard') {
522
- // add a change handler that updates the list of current keyboard shortcuts
523
- $thisField.change(function() {
524
- changedPref = $(this).attr('name');
525
- if (changedPref === 'prefAltKey') {
526
- changedSpan = '.able-modkey-alt';
527
- changedText = thisObj.tt.prefAltKey + ' + ';
528
- }
529
- else if (changedPref === 'prefCtrlKey') {
530
- changedSpan = '.able-modkey-ctrl';
531
- changedText = thisObj.tt.prefCtrlKey + ' + ';
532
- }
533
- else if (changedPref === 'prefShiftKey') {
534
- changedSpan = '.able-modkey-shift';
535
- changedText = thisObj.tt.prefShiftKey + ' + ';
536
- }
537
- if ($(this).is(':checked')) {
538
- $(changedSpan).text(changedText);
539
- }
540
- else {
541
- $(changedSpan).text('');
542
- }
543
- });
544
- }
545
- $thisDiv.append($thisField,$thisLabel);
546
- }
547
- if (form === 'descriptions') {
548
- if (thisPref === 'prefDescFormat') {
549
- $descFieldset1.append($div1,$div2);
550
- }
551
- else {
552
- $descFieldset2.append($thisDiv);
553
- }
554
- }
555
- else {
556
- $fieldset.append($thisDiv);
557
- }
558
- }
559
- }
560
- if (form === 'descriptions') {
561
- $prefsDiv.append($descFieldset1,$descFieldset2);
562
- }
563
- else {
564
- $prefsDiv.append($fieldset);
565
- }
566
- if (form === 'captions') {
567
- // add a sample closed caption div to prefs dialog
568
- if (this.mediaType === 'video') {
569
- this.$sampleCapsDiv = $('<div>',{
570
- 'class': 'able-captions-sample'
571
- }).text(this.tt.sampleCaptionText);
572
- $prefsDiv.append(this.$sampleCapsDiv);
573
- this.stylizeCaptions(this.$sampleCapsDiv);
574
- }
575
- }
576
- else if (form === 'keyboard') {
577
- // add a current list of keyboard shortcuts
578
- $kbHeading = $('<h2>',{
579
- text: this.tt.prefHeadingKeyboard2
580
- });
581
- $kbList = $('<ul>');
582
- // create arrays of kbLabels and keys
583
- kbLabels = [];
584
- keys = [];
585
- for (i=0; i<this.controls.length; i++) {
586
- if (this.controls[i] === 'play') {
587
- kbLabels.push(this.tt.play + '/' + this.tt.pause);
588
- keys.push('p</span> <em>' + this.tt.or + '</em> <span class="able-help-modifiers"> ' + this.tt.spacebar);
589
- }
590
- else if (this.controls[i] === 'restart') {
591
- kbLabels.push(this.tt.restart);
592
- keys.push('s');
593
- }
594
- else if (this.controls[i] === 'rewind') {
595
- kbLabels.push(this.tt.rewind);
596
- keys.push('r');
597
- }
598
- else if (this.controls[i] === 'forward') {
599
- kbLabels.push(this.tt.forward);
600
- keys.push('f');
601
- }
602
- else if (this.controls[i] === 'volume') {
603
- kbLabels.push(this.tt.volume);
604
- keys.push('v</span> <em>' + this.tt.or + '</em> <span class="able-modkey">1-9');
605
- // mute toggle
606
- kbLabels.push(this.tt.mute + '/' + this.tt.unmute);
607
- keys.push('m');
608
- }
609
- else if (this.controls[i] === 'captions') {
610
- if (this.captions.length > 1) {
611
- // caption button launches a Captions popup menu
612
- kbLabels.push(this.tt.captions);
613
- }
614
- else {
615
- // there is only one caption track
616
- // therefore caption button is a toggle
617
- if (this.captionsOn) {
618
- kbLabels.push(this.tt.hideCaptions);
619
- }
620
- else {
621
- kbLabels.push(this.tt.showCaptions);
622
- }
623
- }
624
- keys.push('c');
625
- }
626
- else if (this.controls[i] === 'descriptions') {
627
- if (this.descOn) {
628
- kbLabels.push(this.tt.turnOffDescriptions);
629
- }
630
- else {
631
- kbLabels.push(this.tt.turnOnDescriptions);
632
- }
633
- keys.push('d');
634
- }
635
- else if (this.controls[i] === 'prefs') {
636
- kbLabels.push(this.tt.preferences);
637
- keys.push('e');
638
- }
639
- else if (this.controls[i] === 'help') {
640
- kbLabels.push(this.tt.help);
641
- keys.push('h');
642
- }
643
- }
644
- for (i=0; i<keys.length; i++) {
645
- // alt
646
- kbListText = '<span class="able-modkey-alt">';
647
- if (this.prefAltKey === 1) {
648
- kbListText += this.tt.prefAltKey + ' + ';
649
- }
650
- kbListText += '</span>';
651
- // ctrl
652
- kbListText += '<span class="able-modkey-ctrl">';
653
- if (this.prefCtrlKey === 1) {
654
- kbListText += this.tt.prefCtrlKey + ' + ';
655
- }
656
- kbListText += '</span>';
657
- // shift
658
- kbListText += '<span class="able-modkey-shift">';
659
- if (this.prefShiftKey === 1) {
660
- kbListText += this.tt.prefShiftKey + ' + ';
661
- }
662
- kbListText += '</span>';
663
- kbListText += '<span class="able-modkey">' + keys[i] + '</span>';
664
- kbListText += ' = ' + kbLabels[i];
665
- $kbListItem = $('<li>',{
666
- html: kbListText
667
- });
668
- $kbList.append($kbListItem);
669
- }
670
- // add Escape key
671
- kbListText = '<span class="able-modkey">' + this.tt.escapeKey + '</span>';
672
- kbListText += ' = ' + this.tt.escapeKeyFunction;
673
- $kbListItem = $('<li>',{
674
- html: kbListText
675
- });
676
- $kbList.append($kbListItem);
677
- // put it all together
678
- $prefsDiv.append($kbHeading,$kbList);
679
- }
680
-
681
- // $prefsDiv (dialog) must be appended to the BODY!
682
- // otherwise when aria-hidden="true" is applied to all background content
683
- // that will include an ancestor of the dialog,
684
- // which will render the dialog unreadable by screen readers
685
- $('body').append($prefsDiv);
686
- dialog = new AccessibleDialog($prefsDiv, this.$prefsButton, 'dialog', formTitle, $prefsIntro, thisObj.tt.closeButtonLabel, '32em');
687
-
688
- // Add save and cancel buttons.
689
- $prefsDiv.append('<hr>');
690
- saveButton = $('<button class="modal-button">' + this.tt.save + '</button>');
691
- cancelButton = $('<button class="modal-button">' + this.tt.cancel + '</button>');
692
- saveButton.click(function () {
693
- dialog.hide();
694
- thisObj.savePrefsFromForm();
695
- });
696
- cancelButton.click(function () {
697
- dialog.hide();
698
- thisObj.resetPrefsForm();
699
- });
700
-
701
- $prefsDiv.append(saveButton);
702
- $prefsDiv.append(cancelButton);
703
-
704
- // add global reference for future control
705
- if (form === 'captions') {
706
- this.captionPrefsDialog = dialog;
707
- }
708
- else if (form === 'descriptions') {
709
- this.descPrefsDialog = dialog;
710
- }
711
- else if (form === 'keyboard') {
712
- this.keyboardPrefsDialog = dialog;
713
- }
714
- else if (form === 'transcript') {
715
- this.transcriptPrefsDialog = dialog;
716
- }
717
-
718
- // Add click handler for dialog close button
719
- // (button is added in dialog.js)
720
- $('div.able-prefs-form button.modalCloseButton').click(function() {
721
- thisObj.resetPrefsForm();
722
- })
723
- // Add handler for escape key
724
- $('div.able-prefs-form').keydown(function(e) {
725
- if (e.which === 27) { // escape
726
- thisObj.resetPrefsForm();
727
- }
728
- });
729
- };
730
-
731
- // Reset preferences form with default values from cookie
732
- // Called when user clicks cancel or close button in Prefs Dialog
733
- // also called when user presses Escape
734
-
735
- AblePlayer.prototype.resetPrefsForm = function () {
736
-
737
- var thisObj, cookie, available, i, prefName, thisDiv, thisId;
738
-
739
- thisObj = this;
740
- cookie = this.getCookie();
741
- available = this.getAvailablePreferences();
742
- for (i=0; i<available.length; i++) {
743
- prefName = available[i]['name'];
744
- if (prefName === 'prefDescFormat') {
745
- if (this[prefName] === 'text') {
746
- $('input[value="text"]').prop('checked',true);
747
- }
748
- else {
749
- $('input[value="video"]').prop('checked',true);
750
- }
751
- }
752
- else if ((prefName.indexOf('Captions') !== -1) && (prefName !== 'prefCaptions')) {
753
- // this is a caption-related select box
754
- $('select[name="' + prefName + '"]').val(cookie.preferences[prefName]);
755
- }
756
- else { // all others are checkboxes
757
- if (this[prefName] === 1) {
758
- $('input[name="' + prefName + '"]').prop('checked',true);
759
- }
760
- else {
761
- $('input[name="' + prefName + '"]').prop('checked',false);
762
- }
763
- }
764
- }
765
- // also restore style of sample caption div
766
- this.stylizeCaptions(this.$sampleCapsDiv);
767
- };
768
-
769
- // Return a prefs object constructed from the form.
770
- AblePlayer.prototype.savePrefsFromForm = function () {
771
- // called when user saves the Preferences form
772
- // update cookie with new value
773
- var numChanges, numCapChanges, capSizeChanged, capSizeValue, newValue;
774
-
775
- numChanges = 0;
776
- numCapChanges = 0; // changes to caption-style-related preferences
777
- capSizeChanged = false;
778
- var cookie = this.getCookie();
779
- var available = this.getAvailablePreferences();
780
- for (var i=0; i < available.length; i++) {
781
- // only prefs with labels are used in the Prefs form
782
- if (available[i]['label']) {
783
- var prefName = available[i]['name'];
784
- if (prefName == 'prefDescFormat') {
785
- this.prefDescFormat = $('input[name="' + prefName + '"]:checked').val();
786
- if (this.prefDescFormat !== cookie.preferences['prefDescFormat']) { // user changed setting
787
- cookie.preferences['prefDescFormat'] = this.prefDescFormat;
788
- numChanges++;
789
- }
790
- }
791
- else if ((prefName.indexOf('Captions') !== -1) && (prefName !== 'prefCaptions')) {
792
- // this is one of the caption-related select fields
793
- newValue = $('select[name="' + prefName + '"]').val();
794
- if (cookie.preferences[prefName] !== newValue) { // user changed setting
795
- cookie.preferences[prefName] = newValue;
796
- // also update global var for this pref (for caption fields, not done elsewhere)
797
- this[prefName] = newValue;
798
- numChanges++;
799
- numCapChanges++;
800
- }
801
- if (prefName === 'prefCaptionsSize') {
802
- capSizeChanged = true;
803
- capSizeValue = newValue;
804
- }
805
- }
806
- else { // all other fields are checkboxes
807
- if ($('input[name="' + prefName + '"]').is(':checked')) {
808
- cookie.preferences[prefName] = 1;
809
- if (this[prefName] === 1) {
810
- // nothing has changed
811
- }
812
- else {
813
- // user has just turned this pref on
814
- this[prefName] = 1;
815
- numChanges++;
816
- }
817
- }
818
- else { // thisPref is not checked
819
- cookie.preferences[prefName] = 0;
820
- if (this[prefName] === 1) {
821
- // user has just turned this pref off
822
- this[prefName] = 0;
823
- numChanges++;
824
- }
825
- else {
826
- // nothing has chaged
827
- }
828
- }
829
- }
830
- }
831
- }
832
- if (numChanges > 0) {
833
- this.setCookie(cookie);
834
- this.showAlert(this.tt.prefSuccess);
835
- }
836
- else {
837
- this.showAlert(this.tt.prefNoChange);
838
- }
839
- if (this.player === 'youtube' &&
840
- (typeof this.usingYouTubeCaptions !== 'undefined' && this.usingYouTubeCaptions) &&
841
- capSizeChanged) {
842
- // update font size of YouTube captions
843
- this.youTubePlayer.setOption(this.ytCaptionModule,'fontSize',this.translatePrefs('size',capSizeValue,'youtube'));
844
- }
845
- this.updatePrefs();
846
- if (numCapChanges > 0) {
847
- this.stylizeCaptions(this.$captionsDiv);
848
- // also apply same changes to descriptions, if present
849
- if (typeof this.$descDiv !== 'undefined') {
850
- this.stylizeCaptions(this.$descDiv);
851
- }
852
- }
853
- }
854
-
855
- // Updates player based on current prefs. Safe to call multiple times.
856
- AblePlayer.prototype.updatePrefs = function () {
857
-
858
- var modHelp;
859
-
860
- // modifier keys (update help text)
861
- if (this.prefAltKey === 1) {
862
- modHelp = 'Alt + ';
863
- }
864
- else {
865
- modHelp = '';
866
- }
867
- if (this.prefCtrlKey === 1) {
868
- modHelp += 'Control + ';
869
- }
870
- if (this.prefShiftKey === 1) {
871
- modHelp += 'Shift + ';
872
- }
873
- $('.able-help-modifiers').text(modHelp);
874
-
875
- // tabbable transcript
876
- if (this.prefTabbable === 1) {
877
- $('.able-transcript span.able-transcript-seekpoint').attr('tabindex','0');
878
- }
879
- else {
880
- $('.able-transcript span.able-transcript-seekpoint').removeAttr('tabindex');
881
- }
882
-
883
- // transcript highlights
884
- if (this.prefHighlight === 0) {
885
- // user doesn't want highlights; remove any existing highlights
886
- $('.able-transcript span').removeClass('able-highlight');
887
- }
888
-
889
- // Re-initialize caption and description in case relevant settings have changed
890
- this.updateCaption();
891
- this.refreshingDesc = true;
892
- this.initDescription();
893
- };
894
-
895
- AblePlayer.prototype.usingModifierKeys = function(e) {
896
- // return true if user is holding down required modifier keys
897
- if ((this.prefAltKey === 1) && !e.altKey) {
898
- return false;
899
- }
900
- if ((this.prefCtrlKey === 1) && !e.ctrlKey) {
901
- return false;
902
- }
903
- if ((this.prefShiftKey === 1) && !e.shiftKey) {
904
- return false;
905
- }
906
- return true;
907
- };
173
+ prefs.push({
174
+ 'name': 'prefCaptionsPosition',
175
+ 'label': this.tt.prefCaptionsPosition,
176
+ 'group': 'captions',
177
+ 'default': this.defaultCaptionsPosition
178
+ });
179
+ prefs.push({
180
+ 'name': 'prefCaptionsFont',
181
+ 'label': this.tt.prefCaptionsFont,
182
+ 'group': 'captions',
183
+ 'default': this.tt.sans
184
+ });
185
+ prefs.push({
186
+ 'name': 'prefCaptionsSize',
187
+ 'label': this.tt.prefCaptionsSize,
188
+ 'group': 'captions',
189
+ 'default': '100%'
190
+ });
191
+ prefs.push({
192
+ 'name': 'prefCaptionsColor',
193
+ 'label': this.tt.prefCaptionsColor,
194
+ 'group': 'captions',
195
+ 'default': 'white'
196
+ });
197
+ prefs.push({
198
+ 'name': 'prefCaptionsBGColor',
199
+ 'label': this.tt.prefCaptionsBGColor,
200
+ 'group': 'captions',
201
+ 'default': 'black'
202
+ });
203
+ prefs.push({
204
+ 'name': 'prefCaptionsOpacity',
205
+ 'label': this.tt.prefCaptionsOpacity,
206
+ 'group': 'captions',
207
+ 'default': '100%'
208
+ });
209
+
210
+ // Description preferences
211
+ prefs.push({
212
+ 'name': 'prefDesc', // audio description default state
213
+ 'label': null,
214
+ 'group': 'descriptions',
215
+ 'default': 0 // off because users who don't need it might find it distracting
216
+ });
217
+ prefs.push({
218
+ 'name': 'prefDescFormat', // audio description default state
219
+ 'label': this.tt.prefDescFormat,
220
+ 'group': 'descriptions',
221
+ 'default': 'video'
222
+ });
223
+ prefs.push({
224
+ 'name': 'prefDescPause', // automatically pause when closed description starts
225
+ 'label': this.tt.prefDescPause,
226
+ 'group': 'descriptions',
227
+ 'default': 0 // off because it burdens user with restarting after every pause
228
+ });
229
+ prefs.push({
230
+ 'name': 'prefVisibleDesc', // visibly show closed description (if avilable and used)
231
+ 'label': this.tt.prefVisibleDesc,
232
+ 'group': 'descriptions',
233
+ 'default': 1 // on because sighted users probably want to see this cool feature in action
234
+ });
235
+
236
+ // Video preferences without a category (not shown in Preferences dialogs)
237
+ prefs.push({
238
+ 'name': 'prefSign', // open sign language window by default if avilable
239
+ 'label': null,
240
+ 'group': null,
241
+ 'default': 0 // off because clicking an icon to see the sign window has a powerful impact
242
+ });
243
+
244
+ }
245
+ return prefs;
246
+ };
247
+
248
+ // Loads current/default preferences from cookie into the AblePlayer object.
249
+ AblePlayer.prototype.loadCurrentPreferences = function () {
250
+ var available = this.getAvailablePreferences();
251
+ var cookie = this.getCookie();
252
+
253
+ // Copy current cookie values into this object, and fill in any default values.
254
+ for (var ii = 0; ii < available.length; ii++) {
255
+ var prefName = available[ii]['name'];
256
+ var defaultValue = available[ii]['default'];
257
+ if (cookie.preferences[prefName] !== undefined) {
258
+ this[prefName] = cookie.preferences[prefName];
259
+ }
260
+ else {
261
+ cookie.preferences[prefName] = defaultValue;
262
+ this[prefName] = defaultValue;
263
+ }
264
+ }
265
+
266
+ // Save since we may have added default values.
267
+ this.setCookie(cookie);
268
+ };
269
+
270
+ AblePlayer.prototype.injectPrefsForm = function (form) {
271
+
272
+ // Creates a preferences form and injects it.
273
+ // form is one of the supported forms (groups) defined in getPreferencesGroups()
274
+
275
+ var available, thisObj, $prefsDiv, formTitle, introText,
276
+ $prefsIntro,$prefsIntroP2,p3Text,$prefsIntroP3,i, j,
277
+ $fieldset, fieldsetClass, fieldsetId,
278
+ $descFieldset1, $descLegend1, $descFieldset2, $descLegend2, $legend,
279
+ thisPref, $thisDiv, thisClass, thisId, $thisLabel, $thisField,
280
+ $div1,id1,$radio1,$label1,
281
+ $div2,id2,$radio2,$label2,
282
+ options,$thisOption,optionValue,optionText,sampleCapsDiv,
283
+ changedPref,changedSpan,changedText,
284
+ currentDescState,
285
+ $kbHeading,$kbList,kbLabels,keys,kbListText,$kbListItem,
286
+ dialog,saveButton,cancelButton;
287
+
288
+ thisObj = this;
289
+ available = this.getAvailablePreferences();
290
+
291
+ // outer container, will be assigned role="dialog"
292
+ $prefsDiv = $('<div>',{
293
+ 'class': 'able-prefs-form '
294
+ });
295
+ var customClass = 'able-prefs-form-' + form;
296
+ $prefsDiv.addClass(customClass);
297
+
298
+ // add intro
299
+ if (form == 'captions') {
300
+ formTitle = this.tt.prefTitleCaptions;
301
+ introText = this.tt.prefIntroCaptions;
302
+ // Uncomment the following line to include a cookie warning
303
+ // Not included for now in order to cut down on unnecessary verbiage
304
+ // introText += ' ' + this.tt.prefCookieWarning;
305
+ $prefsIntro = $('<p>',{
306
+ text: introText
307
+ });
308
+ $prefsDiv.append($prefsIntro);
309
+ }
310
+ else if (form == 'descriptions') {
311
+ formTitle = this.tt.prefTitleDescriptions;
312
+ var $prefsIntro = $('<p>',{
313
+ text: this.tt.prefIntroDescription1
314
+ });
315
+ var $prefsIntroUL = $('<ul>');
316
+ var $prefsIntroLI1 = $('<li>',{
317
+ text: this.tt.prefDescFormatOption1
318
+ });
319
+ var $prefsIntroLI2 = $('<li>',{
320
+ text: this.tt.prefDescFormatOption2
321
+ });
322
+
323
+ $prefsIntroUL.append($prefsIntroLI1,$prefsIntroLI2);
324
+ if (this.hasOpenDesc && this.hasClosedDesc) {
325
+ currentDescState = this.tt.prefIntroDescription2 + ' ';
326
+ currentDescState += '<strong>' + this.tt.prefDescFormatOption1b + '</strong>';
327
+ currentDescState += ' <em>' + this.tt.and + '</em> <strong>' + this.tt.prefDescFormatOption2b + '</strong>.';
328
+ }
329
+ else if (this.hasOpenDesc) {
330
+ currentDescState = this.tt.prefIntroDescription2;
331
+ currentDescState += ' <strong>' + this.tt.prefDescFormatOption1b + '</strong>.';
332
+ }
333
+ else if (this.hasClosedDesc) {
334
+ currentDescState = this.tt.prefIntroDescription2;
335
+ currentDescState += ' <strong>' + this.tt.prefDescFormatOption2b + '</strong>.';
336
+ }
337
+ else {
338
+ currentDescState = this.tt.prefIntroDescriptionNone;
339
+ }
340
+ $prefsIntroP2 = $('<p>',{
341
+ html: currentDescState
342
+ });
343
+
344
+ p3Text = this.tt.prefIntroDescription3;
345
+ if (this.hasOpenDesc || this.hasClosedDesc) {
346
+ p3Text += ' ' + this.tt.prefIntroDescription4;
347
+ }
348
+ $prefsIntroP3 = $('<p>',{
349
+ text: p3Text
350
+ });
351
+
352
+ $prefsDiv.append($prefsIntro,$prefsIntroUL,$prefsIntroP2,$prefsIntroP3);
353
+ }
354
+ else if (form == 'keyboard') {
355
+ formTitle = this.tt.prefTitleKeyboard;
356
+ introText = this.tt.prefIntroKeyboard1;
357
+ introText += ' ' + this.tt.prefIntroKeyboard2;
358
+ introText += ' ' + this.tt.prefIntroKeyboard3;
359
+ $prefsIntro = $('<p>',{
360
+ text: introText
361
+ });
362
+ $prefsDiv.append($prefsIntro);
363
+ }
364
+ else if (form == 'transcript') {
365
+ formTitle = this.tt.prefTitleTranscript;
366
+ introText = this.tt.prefIntroTranscript;
367
+ // Uncomment the following line to include a cookie warning
368
+ // Not included for now in order to cut down on unnecessary verbiage
369
+ // introText += ' ' + this.tt.prefCookieWarning;
370
+ $prefsIntro = $('<p>',{
371
+ text: introText
372
+ });
373
+ $prefsDiv.append($prefsIntro);
374
+ }
375
+
376
+ if (form === 'descriptions') {
377
+ // descriptions form has two field sets
378
+
379
+ // Fieldset 1
380
+ $descFieldset1 = $('<fieldset>');
381
+ fieldsetClass = 'able-prefs-' + form + '1';
382
+ fieldsetId = this.mediaId + '-prefs-' + form + '1';
383
+ $descFieldset1.addClass(fieldsetClass).attr('id',fieldsetId);
384
+ $descLegend1 = $('<legend>' + this.tt.prefDescFormat + '</legend>');
385
+ $descFieldset1.append($descLegend1);
386
+
387
+ // Fieldset 2
388
+ $descFieldset2 = $('<fieldset>');
389
+ fieldsetClass = 'able-prefs-' + form + '2';
390
+ fieldsetId = this.mediaId + '-prefs-' + form + '2';
391
+ $descFieldset2.addClass(fieldsetClass).attr('id',fieldsetId);
392
+ $descLegend2 = $('<legend>' + this.tt.prefHeadingTextDescription + '</legend>');
393
+ $descFieldset2.append($descLegend2);
394
+ }
395
+ else {
396
+ // all other forms just have one fieldset
397
+ $fieldset = $('<fieldset>');
398
+ fieldsetClass = 'able-prefs-' + form;
399
+ fieldsetId = this.mediaId + '-prefs-' + form;
400
+ $fieldset.addClass(fieldsetClass).attr('id',fieldsetId);
401
+ if (form === 'keyboard') {
402
+ $legend = $('<legend>' + this.tt.prefHeadingKeyboard1 + '</legend>');
403
+ $fieldset.append($legend);
404
+ }
405
+ }
406
+ for (i=0; i<available.length; i++) {
407
+
408
+ // only include prefs on the current form if they have a label
409
+ if ((available[i]['group'] == form) && available[i]['label']) {
410
+
411
+ thisPref = available[i]['name'];
412
+ thisClass = 'able-' + thisPref;
413
+ thisId = this.mediaId + '_' + thisPref;
414
+ if (thisPref !== 'prefDescFormat') {
415
+ $thisDiv = $('<div>').addClass(thisClass);
416
+ }
417
+
418
+ // Audio Description preferred format radio buttons
419
+ if (thisPref == 'prefDescFormat') {
420
+
421
+ // option 1 radio button
422
+ $div1 = $('<div>');
423
+ id1 = thisId + '_1';
424
+ $label1 = $('<label>')
425
+ .attr('for',id1)
426
+ .text(this.capitalizeFirstLetter(this.tt.prefDescFormatOption1))
427
+ $radio1 = $('<input>',{
428
+ type: 'radio',
429
+ name: thisPref,
430
+ id: id1,
431
+ value: 'video'
432
+ });
433
+ if (this.prefDescFormat === 'video') {
434
+ $radio1.prop('checked',true);
435
+ };
436
+ $div1.append($radio1,$label1);
437
+
438
+ // option 2 radio button
439
+ $div2 = $('<div>');
440
+ id2 = thisId + '_2';
441
+ $label2 = $('<label>')
442
+ .attr('for',id2)
443
+ .text(this.capitalizeFirstLetter(this.tt.prefDescFormatOption2));
444
+ $radio2 = $('<input>',{
445
+ type: 'radio',
446
+ name: thisPref,
447
+ id: id2,
448
+ value: 'text'
449
+ });
450
+ if (this.prefDescFormat === 'text') {
451
+ $radio2.prop('checked',true);
452
+ };
453
+ $div2.append($radio2,$label2);
454
+ }
455
+ else if (form === 'captions') {
456
+ $thisLabel = $('<label for="' + thisId + '"> ' + available[i]['label'] + '</label>');
457
+ $thisField = $('<select>',{
458
+ name: thisPref,
459
+ id: thisId,
460
+ });
461
+ if (thisPref !== 'prefCaptions' && thisPref !== 'prefCaptionsStyle') {
462
+ // add a change handler that updates the style of the sample caption text
463
+ $thisField.change(function() {
464
+ changedPref = $(this).attr('name');
465
+ thisObj.stylizeCaptions(thisObj.$sampleCapsDiv,changedPref);
466
+ });
467
+ }
468
+ options = this.getCaptionsOptions(thisPref);
469
+ for (j=0; j < options.length; j++) {
470
+ if (thisPref === 'prefCaptionsPosition') {
471
+ optionValue = options[j];
472
+ if (optionValue === 'overlay') {
473
+ optionText = this.tt.captionsPositionOverlay;
474
+ }
475
+ else if (optionValue === 'below') {
476
+ optionValue = options[j];
477
+ optionText = this.tt.captionsPositionBelow;
478
+ }
479
+ }
480
+ else if (thisPref === 'prefCaptionsColor' || thisPref === 'prefCaptionsBGColor') {
481
+ optionValue = options[j][0];
482
+ optionText = options[j][1];
483
+ }
484
+ else if (thisPref === 'prefCaptionsOpacity') {
485
+ optionValue = options[j];
486
+ optionText = options[j];
487
+ if (optionValue === '0%') {
488
+ optionText += ' (' + this.tt.transparent + ')';
489
+ }
490
+ else if (optionValue === '100%') {
491
+ optionText += ' (' + this.tt.solid + ')';
492
+ }
493
+ }
494
+ else {
495
+ optionValue = options[j];
496
+ optionText = options[j];
497
+ }
498
+ $thisOption = $('<option>',{
499
+ value: optionValue,
500
+ text: optionText
501
+ });
502
+ if (this[thisPref] === optionValue) {
503
+ $thisOption.prop('selected',true);
504
+ }
505
+ $thisField.append($thisOption);
506
+ }
507
+ $thisDiv.append($thisLabel,$thisField);
508
+ }
509
+ else { // all other fields are checkboxes
510
+ $thisLabel = $('<label for="' + thisId + '"> ' + available[i]['label'] + '</label>');
511
+ $thisField = $('<input>',{
512
+ type: 'checkbox',
513
+ name: thisPref,
514
+ id: thisId,
515
+ value: 'true'
516
+ });
517
+ // check current active value for this preference
518
+ if (this[thisPref] === 1) {
519
+ $thisField.prop('checked',true);
520
+ }
521
+ if (form === 'keyboard') {
522
+ // add a change handler that updates the list of current keyboard shortcuts
523
+ $thisField.change(function() {
524
+ changedPref = $(this).attr('name');
525
+ if (changedPref === 'prefAltKey') {
526
+ changedSpan = '.able-modkey-alt';
527
+ changedText = thisObj.tt.prefAltKey + ' + ';
528
+ }
529
+ else if (changedPref === 'prefCtrlKey') {
530
+ changedSpan = '.able-modkey-ctrl';
531
+ changedText = thisObj.tt.prefCtrlKey + ' + ';
532
+ }
533
+ else if (changedPref === 'prefShiftKey') {
534
+ changedSpan = '.able-modkey-shift';
535
+ changedText = thisObj.tt.prefShiftKey + ' + ';
536
+ }
537
+ if ($(this).is(':checked')) {
538
+ $(changedSpan).text(changedText);
539
+ }
540
+ else {
541
+ $(changedSpan).text('');
542
+ }
543
+ });
544
+ }
545
+ $thisDiv.append($thisField,$thisLabel);
546
+ }
547
+ if (form === 'descriptions') {
548
+ if (thisPref === 'prefDescFormat') {
549
+ $descFieldset1.append($div1,$div2);
550
+ }
551
+ else {
552
+ $descFieldset2.append($thisDiv);
553
+ }
554
+ }
555
+ else {
556
+ $fieldset.append($thisDiv);
557
+ }
558
+ }
559
+ }
560
+ if (form === 'descriptions') {
561
+ $prefsDiv.append($descFieldset1,$descFieldset2);
562
+ }
563
+ else {
564
+ $prefsDiv.append($fieldset);
565
+ }
566
+ if (form === 'captions') {
567
+ // add a sample closed caption div to prefs dialog
568
+ if (this.mediaType === 'video') {
569
+ this.$sampleCapsDiv = $('<div>',{
570
+ 'class': 'able-captions-sample'
571
+ }).text(this.tt.sampleCaptionText);
572
+ $prefsDiv.append(this.$sampleCapsDiv);
573
+ this.stylizeCaptions(this.$sampleCapsDiv);
574
+ }
575
+ }
576
+ else if (form === 'keyboard') {
577
+ // add a current list of keyboard shortcuts
578
+ $kbHeading = $('<h2>',{
579
+ text: this.tt.prefHeadingKeyboard2
580
+ });
581
+ $kbList = $('<ul>');
582
+ // create arrays of kbLabels and keys
583
+ kbLabels = [];
584
+ keys = [];
585
+ for (i=0; i<this.controls.length; i++) {
586
+ if (this.controls[i] === 'play') {
587
+ kbLabels.push(this.tt.play + '/' + this.tt.pause);
588
+ keys.push('p</span> <em>' + this.tt.or + '</em> <span class="able-help-modifiers"> ' + this.tt.spacebar);
589
+ }
590
+ else if (this.controls[i] === 'restart') {
591
+ kbLabels.push(this.tt.restart);
592
+ keys.push('s');
593
+ }
594
+ else if (this.controls[i] === 'rewind') {
595
+ kbLabels.push(this.tt.rewind);
596
+ keys.push('r');
597
+ }
598
+ else if (this.controls[i] === 'forward') {
599
+ kbLabels.push(this.tt.forward);
600
+ keys.push('f');
601
+ }
602
+ else if (this.controls[i] === 'volume') {
603
+ kbLabels.push(this.tt.volume);
604
+ keys.push('v</span> <em>' + this.tt.or + '</em> <span class="able-modkey">1-9');
605
+ // mute toggle
606
+ kbLabels.push(this.tt.mute + '/' + this.tt.unmute);
607
+ keys.push('m');
608
+ }
609
+ else if (this.controls[i] === 'captions') {
610
+ if (this.captions.length > 1) {
611
+ // caption button launches a Captions popup menu
612
+ kbLabels.push(this.tt.captions);
613
+ }
614
+ else {
615
+ // there is only one caption track
616
+ // therefore caption button is a toggle
617
+ if (this.captionsOn) {
618
+ kbLabels.push(this.tt.hideCaptions);
619
+ }
620
+ else {
621
+ kbLabels.push(this.tt.showCaptions);
622
+ }
623
+ }
624
+ keys.push('c');
625
+ }
626
+ else if (this.controls[i] === 'descriptions') {
627
+ if (this.descOn) {
628
+ kbLabels.push(this.tt.turnOffDescriptions);
629
+ }
630
+ else {
631
+ kbLabels.push(this.tt.turnOnDescriptions);
632
+ }
633
+ keys.push('d');
634
+ }
635
+ else if (this.controls[i] === 'prefs') {
636
+ kbLabels.push(this.tt.preferences);
637
+ keys.push('e');
638
+ }
639
+ else if (this.controls[i] === 'help') {
640
+ kbLabels.push(this.tt.help);
641
+ keys.push('h');
642
+ }
643
+ }
644
+ for (i=0; i<keys.length; i++) {
645
+ // alt
646
+ kbListText = '<span class="able-modkey-alt">';
647
+ if (this.prefAltKey === 1) {
648
+ kbListText += this.tt.prefAltKey + ' + ';
649
+ }
650
+ kbListText += '</span>';
651
+ // ctrl
652
+ kbListText += '<span class="able-modkey-ctrl">';
653
+ if (this.prefCtrlKey === 1) {
654
+ kbListText += this.tt.prefCtrlKey + ' + ';
655
+ }
656
+ kbListText += '</span>';
657
+ // shift
658
+ kbListText += '<span class="able-modkey-shift">';
659
+ if (this.prefShiftKey === 1) {
660
+ kbListText += this.tt.prefShiftKey + ' + ';
661
+ }
662
+ kbListText += '</span>';
663
+ kbListText += '<span class="able-modkey">' + keys[i] + '</span>';
664
+ kbListText += ' = ' + kbLabels[i];
665
+ $kbListItem = $('<li>',{
666
+ html: kbListText
667
+ });
668
+ $kbList.append($kbListItem);
669
+ }
670
+ // add Escape key
671
+ kbListText = '<span class="able-modkey">' + this.tt.escapeKey + '</span>';
672
+ kbListText += ' = ' + this.tt.escapeKeyFunction;
673
+ $kbListItem = $('<li>',{
674
+ html: kbListText
675
+ });
676
+ $kbList.append($kbListItem);
677
+ // put it all together
678
+ $prefsDiv.append($kbHeading,$kbList);
679
+ }
680
+
681
+ // $prefsDiv (dialog) must be appended to the BODY!
682
+ // otherwise when aria-hidden="true" is applied to all background content
683
+ // that will include an ancestor of the dialog,
684
+ // which will render the dialog unreadable by screen readers
685
+ $('body').append($prefsDiv);
686
+ dialog = new AccessibleDialog($prefsDiv, this.$prefsButton, 'dialog', formTitle, $prefsIntro, thisObj.tt.closeButtonLabel, '32em');
687
+
688
+ // Add save and cancel buttons.
689
+ $prefsDiv.append('<hr>');
690
+ saveButton = $('<button class="modal-button">' + this.tt.save + '</button>');
691
+ cancelButton = $('<button class="modal-button">' + this.tt.cancel + '</button>');
692
+ saveButton.click(function () {
693
+ dialog.hide();
694
+ thisObj.savePrefsFromForm();
695
+ });
696
+ cancelButton.click(function () {
697
+ dialog.hide();
698
+ thisObj.resetPrefsForm();
699
+ });
700
+
701
+ $prefsDiv.append(saveButton);
702
+ $prefsDiv.append(cancelButton);
703
+
704
+ // add global reference for future control
705
+ if (form === 'captions') {
706
+ this.captionPrefsDialog = dialog;
707
+ }
708
+ else if (form === 'descriptions') {
709
+ this.descPrefsDialog = dialog;
710
+ }
711
+ else if (form === 'keyboard') {
712
+ this.keyboardPrefsDialog = dialog;
713
+ }
714
+ else if (form === 'transcript') {
715
+ this.transcriptPrefsDialog = dialog;
716
+ }
717
+
718
+ // Add click handler for dialog close button
719
+ // (button is added in dialog.js)
720
+ $('div.able-prefs-form button.modalCloseButton').click(function() {
721
+ thisObj.resetPrefsForm();
722
+ })
723
+ // Add handler for escape key
724
+ $('div.able-prefs-form').keydown(function(e) {
725
+ if (e.which === 27) { // escape
726
+ thisObj.resetPrefsForm();
727
+ }
728
+ });
729
+ };
730
+
731
+ // Reset preferences form with default values from cookie
732
+ // Called when user clicks cancel or close button in Prefs Dialog
733
+ // also called when user presses Escape
734
+
735
+ AblePlayer.prototype.resetPrefsForm = function () {
736
+
737
+ var thisObj, cookie, available, i, prefName, thisDiv, thisId;
738
+
739
+ thisObj = this;
740
+ cookie = this.getCookie();
741
+ available = this.getAvailablePreferences();
742
+ for (i=0; i<available.length; i++) {
743
+ prefName = available[i]['name'];
744
+ if (prefName === 'prefDescFormat') {
745
+ if (this[prefName] === 'text') {
746
+ $('input[value="text"]').prop('checked',true);
747
+ }
748
+ else {
749
+ $('input[value="video"]').prop('checked',true);
750
+ }
751
+ }
752
+ else if ((prefName.indexOf('Captions') !== -1) && (prefName !== 'prefCaptions')) {
753
+ // this is a caption-related select box
754
+ $('select[name="' + prefName + '"]').val(cookie.preferences[prefName]);
755
+ }
756
+ else { // all others are checkboxes
757
+ if (this[prefName] === 1) {
758
+ $('input[name="' + prefName + '"]').prop('checked',true);
759
+ }
760
+ else {
761
+ $('input[name="' + prefName + '"]').prop('checked',false);
762
+ }
763
+ }
764
+ }
765
+ // also restore style of sample caption div
766
+ this.stylizeCaptions(this.$sampleCapsDiv);
767
+ };
768
+
769
+ // Return a prefs object constructed from the form.
770
+ AblePlayer.prototype.savePrefsFromForm = function () {
771
+ // called when user saves the Preferences form
772
+ // update cookie with new value
773
+ var numChanges, numCapChanges, capSizeChanged, capSizeValue, newValue;
774
+
775
+ numChanges = 0;
776
+ numCapChanges = 0; // changes to caption-style-related preferences
777
+ capSizeChanged = false;
778
+ var cookie = this.getCookie();
779
+ var available = this.getAvailablePreferences();
780
+ for (var i=0; i < available.length; i++) {
781
+ // only prefs with labels are used in the Prefs form
782
+ if (available[i]['label']) {
783
+ var prefName = available[i]['name'];
784
+ if (prefName == 'prefDescFormat') {
785
+ this.prefDescFormat = $('input[name="' + prefName + '"]:checked').val();
786
+ if (this.prefDescFormat !== cookie.preferences['prefDescFormat']) { // user changed setting
787
+ cookie.preferences['prefDescFormat'] = this.prefDescFormat;
788
+ numChanges++;
789
+ }
790
+ }
791
+ else if ((prefName.indexOf('Captions') !== -1) && (prefName !== 'prefCaptions')) {
792
+ // this is one of the caption-related select fields
793
+ newValue = $('select[name="' + prefName + '"]').val();
794
+ if (cookie.preferences[prefName] !== newValue) { // user changed setting
795
+ cookie.preferences[prefName] = newValue;
796
+ // also update global var for this pref (for caption fields, not done elsewhere)
797
+ this[prefName] = newValue;
798
+ numChanges++;
799
+ numCapChanges++;
800
+ }
801
+ if (prefName === 'prefCaptionsSize') {
802
+ capSizeChanged = true;
803
+ capSizeValue = newValue;
804
+ }
805
+ }
806
+ else { // all other fields are checkboxes
807
+ if ($('input[name="' + prefName + '"]').is(':checked')) {
808
+ cookie.preferences[prefName] = 1;
809
+ if (this[prefName] === 1) {
810
+ // nothing has changed
811
+ }
812
+ else {
813
+ // user has just turned this pref on
814
+ this[prefName] = 1;
815
+ numChanges++;
816
+ }
817
+ }
818
+ else { // thisPref is not checked
819
+ cookie.preferences[prefName] = 0;
820
+ if (this[prefName] === 1) {
821
+ // user has just turned this pref off
822
+ this[prefName] = 0;
823
+ numChanges++;
824
+ }
825
+ else {
826
+ // nothing has chaged
827
+ }
828
+ }
829
+ }
830
+ }
831
+ }
832
+ if (numChanges > 0) {
833
+ this.setCookie(cookie);
834
+ this.showAlert(this.tt.prefSuccess);
835
+ }
836
+ else {
837
+ this.showAlert(this.tt.prefNoChange);
838
+ }
839
+ if (this.player === 'youtube' &&
840
+ (typeof this.usingYouTubeCaptions !== 'undefined' && this.usingYouTubeCaptions) &&
841
+ capSizeChanged) {
842
+ // update font size of YouTube captions
843
+ this.youTubePlayer.setOption(this.ytCaptionModule,'fontSize',this.translatePrefs('size',capSizeValue,'youtube'));
844
+ }
845
+ this.updatePrefs();
846
+ if (numCapChanges > 0) {
847
+ this.stylizeCaptions(this.$captionsDiv);
848
+ // also apply same changes to descriptions, if present
849
+ if (typeof this.$descDiv !== 'undefined') {
850
+ this.stylizeCaptions(this.$descDiv);
851
+ }
852
+ }
853
+ }
854
+
855
+ // Updates player based on current prefs. Safe to call multiple times.
856
+ AblePlayer.prototype.updatePrefs = function () {
857
+
858
+ var modHelp;
859
+
860
+ // modifier keys (update help text)
861
+ if (this.prefAltKey === 1) {
862
+ modHelp = 'Alt + ';
863
+ }
864
+ else {
865
+ modHelp = '';
866
+ }
867
+ if (this.prefCtrlKey === 1) {
868
+ modHelp += 'Control + ';
869
+ }
870
+ if (this.prefShiftKey === 1) {
871
+ modHelp += 'Shift + ';
872
+ }
873
+ $('.able-help-modifiers').text(modHelp);
874
+
875
+ // tabbable transcript
876
+ if (this.prefTabbable === 1) {
877
+ $('.able-transcript span.able-transcript-seekpoint').attr('tabindex','0');
878
+ }
879
+ else {
880
+ $('.able-transcript span.able-transcript-seekpoint').removeAttr('tabindex');
881
+ }
882
+
883
+ // transcript highlights
884
+ if (this.prefHighlight === 0) {
885
+ // user doesn't want highlights; remove any existing highlights
886
+ $('.able-transcript span').removeClass('able-highlight');
887
+ }
888
+
889
+ // Re-initialize caption and description in case relevant settings have changed
890
+ this.updateCaption();
891
+ this.refreshingDesc = true;
892
+ this.initDescription();
893
+ };
894
+
895
+ AblePlayer.prototype.usingModifierKeys = function(e) {
896
+ // return true if user is holding down required modifier keys
897
+ if ((this.prefAltKey === 1) && !e.altKey) {
898
+ return false;
899
+ }
900
+ if ((this.prefCtrlKey === 1) && !e.ctrlKey) {
901
+ return false;
902
+ }
903
+ if ((this.prefShiftKey === 1) && !e.shiftKey) {
904
+ return false;
905
+ }
906
+ return true;
907
+ };
908
908
 
909
909
  })(jQuery);