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,404 +1,427 @@
1
1
  (function ($) {
2
- AblePlayer.prototype.updateCaption = function (time) {
3
- if (!this.usingYouTubeCaptions && (typeof this.$captionsWrapper !== 'undefined')) {
4
- if (this.captionsOn) {
5
- this.$captionsWrapper.show();
6
- this.showCaptions(time || this.getElapsed());
7
- }
8
- else if (this.$captionsWrapper) {
9
- this.$captionsWrapper.hide();
10
- this.prefCaptions = 0;
11
- }
12
- }
13
- };
14
-
15
- AblePlayer.prototype.updateCaptionsMenu = function (lang) {
16
-
17
- // uncheck all previous menu items
18
- this.captionsPopup.find('li').attr('aria-checked','false');
19
- if (typeof lang === 'undefined') {
20
- // check the last menu item (captions off)
21
- this.captionsPopup.find('li').last().attr('aria-checked','true');
22
- }
23
- else {
24
- // check the newly selected lang
25
- this.captionsPopup.find('li[lang=' + lang + ']').attr('aria-checked','true');
26
- }
27
- };
28
-
29
- // Returns the function used when a caption is clicked in the captions menu.
30
- // Not called if user clicks "Captions off". Instead, that triggers getCaptionOffFunction()
31
- AblePlayer.prototype.getCaptionClickFunction = function (track) {
32
-
33
- var thisObj = this;
34
- return function () {
35
- thisObj.selectedCaptions = track;
36
- thisObj.captionLang = track.language;
37
- thisObj.currentCaption = -1;
38
-
39
- if (thisObj.usingYouTubeCaptions) {
40
- if (thisObj.captionsOn) {
41
- if (typeof thisObj.ytCaptionModule !== 'undefined') {
42
- // captions are already on. Just need to change the language
43
- thisObj.youTubePlayer.setOption(thisObj.ytCaptionModule, 'track', {'languageCode': thisObj.captionLang});
44
- }
45
- else {
46
- // need to wait for caption module to be loaded to change the language
47
- // caption module will be loaded after video starts playing, triggered by onApiChange event
48
- // at that point, thosObj.captionLang will be passed to the module as the default language
49
- }
50
- }
51
- else {
52
- // captions are off (i.e., captions module has been unloaded; need to reload it)
53
- // user's selected language will be reset after module has successfully loaded
54
- // (the onApiChange event will be fired -- see initialize.js > initYouTubePlayer())
55
- thisObj.resettingYouTubeCaptions = true;
56
- thisObj.youTubePlayer.loadModule(thisObj.ytCaptionModule);
57
- }
58
- }
59
- else {
60
- thisObj.syncTrackLanguages('captions',thisObj.captionLang);
61
- if (!this.swappingSrc) {
62
- thisObj.updateCaption();
63
- thisObj.showDescription(thisObj.getElapsed());
64
- }
65
- }
66
- thisObj.captionsOn = true;
67
- // stopgap to prevent spacebar in Firefox from reopening popup
68
- // immediately after closing it (used in handleCaptionToggle())
69
- thisObj.hidingPopup = true;
70
- thisObj.captionsPopup.hide();
71
- // Ensure stopgap gets cancelled if handleCaptionToggle() isn't called
72
- // e.g., if user triggered button with Enter or mouse click, not spacebar
73
- setTimeout(function() {
74
- thisObj.hidingPopup = false;
75
- }, 100);
76
- thisObj.updateCaptionsMenu(thisObj.captionLang);
77
- thisObj.$ccButton.focus();
78
-
79
- // save preference to cookie
80
- thisObj.prefCaptions = 1;
81
- thisObj.updateCookie('prefCaptions');
82
-
83
- thisObj.refreshControls();
84
- }
85
- };
86
-
87
- // Returns the function used when the "Captions Off" button is clicked in the captions tooltip.
88
- AblePlayer.prototype.getCaptionOffFunction = function () {
89
-
90
- var thisObj = this;
91
- return function () {
92
- if (thisObj.player == 'youtube') {
93
- thisObj.youTubePlayer.unloadModule(thisObj.ytCaptionModule);
94
- }
95
- thisObj.captionsOn = false;
96
- thisObj.currentCaption = -1;
97
- // stopgap to prevent spacebar in Firefox from reopening popup
98
- // immediately after closing it (used in handleCaptionToggle())
99
- thisObj.hidingPopup = true;
100
- thisObj.captionsPopup.hide();
101
- // Ensure stopgap gets cancelled if handleCaptionToggle() isn't called
102
- // e.g., if user triggered button with Enter or mouse click, not spacebar
103
- setTimeout(function() {
104
- thisObj.hidingPopup = false;
105
- }, 100);
106
- thisObj.updateCaptionsMenu();
107
- thisObj.$ccButton.focus();
108
-
109
- // save preference to cookie
110
- thisObj.prefCaptions = 0;
111
- thisObj.updateCookie('prefCaptions');
112
- if (!this.swappingSrc) {
113
- thisObj.refreshControls();
114
- thisObj.updateCaption();
115
- }
116
- }
117
- };
118
-
119
- AblePlayer.prototype.showCaptions = function(now) {
120
-
121
- var c, thisCaption, captionText;
122
- var cues;
123
- if (this.selectedCaptions) {
124
- cues = this.selectedCaptions.cues;
125
- }
126
- else if (this.captions.length >= 1) {
127
- cues = this.captions[0].cues;
128
- }
129
- else {
130
- cues = [];
131
- }
132
- for (c = 0; c < cues.length; c++) {
133
- if ((cues[c].start <= now) && (cues[c].end > now)) {
134
- thisCaption = c;
135
- break;
136
- }
137
- }
138
- if (typeof thisCaption !== 'undefined') {
139
- if (this.currentCaption !== thisCaption) {
140
- // it's time to load the new caption into the container div
141
- captionText = this.flattenCueForCaption(cues[thisCaption]).replace('\n', '<br>');
142
- this.$captionsDiv.html(captionText);
143
- this.currentCaption = thisCaption;
144
- if (captionText.length === 0) {
145
- // hide captionsDiv; otherwise background-color is visible due to padding
146
- this.$captionsDiv.css('display','none');
147
- }
148
- else {
149
- this.$captionsDiv.css('display','inline-block');
150
- }
151
- }
152
- }
153
- else {
154
- this.$captionsDiv.html('');
155
- this.currentCaption = -1;
156
- }
157
- };
158
-
159
- AblePlayer.prototype.flattenCueForCaption = function (cue) {
160
-
161
- // Takes a cue and returns the caption text to display
162
- // Also used for chapters
163
-
164
- // Support for 'i' and 'b' tags added in 2.3.66
165
- // TODO: Add support for 'c' (class) and 'ruby'
166
-
167
- // c (class): <c.myClass1.myClass2>Some text</c>
168
- // Classes can be used to modify other tags too (e.g., <v.loud>)
169
- // If <c> tag, should be rendered as a <span>
170
-
171
- // ruby: http://www.w3schools.com/tags/tag_ruby.asp
172
-
173
- // WebVTT also supports 'u' (underline)
174
- // I see no reason to support that in Able Player.
175
- // If it's available authors are likely to use it incorrectly
176
- // where <i> or <b> should be used instead
177
- // Here are the rare use cases where an underline is appropriate on the web:
178
- // http://html5doctor.com/u-element/
179
-
180
- var result = [];
181
-
182
- var flattenComponent = function (component) {
183
- var result = [], ii;
184
- if (component.type === 'string') {
185
- result.push(component.value);
186
- }
187
- else if (component.type === 'v') {
188
- result.push('(' + component.value + ')');
189
- for (ii = 0; ii < component.children.length; ii++) {
190
- result.push(flattenComponent(component.children[ii]));
191
- }
192
- }
193
- else if (component.type === 'i') {
194
- result.push('<em>');
195
- for (ii = 0; ii < component.children.length; ii++) {
196
- result.push(flattenComponent(component.children[ii]));
197
- }
198
- result.push('</em>');
199
- }
200
- else if (component.type === 'b') {
201
- result.push('<strong>');
202
- for (ii = 0; ii < component.children.length; ii++) {
203
- result.push(flattenComponent(component.children[ii]));
204
- }
205
- result.push('</strong>');
206
- }
207
- else {
208
- for (ii = 0; ii < component.children.length; ii++) {
209
- result.push(flattenComponent(component.children[ii]));
210
- }
211
- }
212
- return result.join('');
213
- };
214
-
215
- if (typeof cue.components !== 'undefined') {
216
- for (var ii = 0; ii < cue.components.children.length; ii++) {
217
- result.push(flattenComponent(cue.components.children[ii]));
218
- }
219
- }
220
- return result.join('');
221
- };
222
-
223
- AblePlayer.prototype.getCaptionsOptions = function(pref) {
224
-
225
- var options = [];
226
-
227
- switch (pref) {
228
-
229
- case 'prefCaptionsFont':
230
- options[0] = this.tt.serif;
231
- options[1] = this.tt.sans;
232
- options[3] = this.tt.cursive;
233
- options[4] = this.tt.fantasy;
234
- options[2] = this.tt.monospace;
235
- break;
236
-
237
- case 'prefCaptionsColor':
238
- case 'prefCaptionsBGColor':
239
- // HTML color values must be in English
240
- options[0] = ['white',this.tt.white];
241
- options[1] = ['yellow',this.tt.yellow];
242
- options[2] = ['green',this.tt.green];
243
- options[3] = ['cyan',this.tt.cyan];
244
- options[4] = ['blue',this.tt.blue];
245
- options[5] = ['magenta',this.tt.magenta];
246
- options[6] = ['red',this.tt.red];
247
- options[7] = ['black',this.tt.black];
248
- break;
249
-
250
- case 'prefCaptionsSize':
251
- options[0] = '75%';
252
- options[1] = '100%';
253
- options[2] = '125%';
254
- options[3] = '150%';
255
- options[4] = '200%';
256
- break;
257
-
258
- case 'prefCaptionsOpacity':
259
- options[0] = '0%';
260
- options[1] = '25%';
261
- options[2] = '50%';
262
- options[3] = '75%';
263
- options[4] = '100%';
264
- break;
265
-
266
- case 'prefCaptionsStyle':
267
- options[0] = this.tt.captionsStylePopOn;
268
- options[1] = this.tt.captionsStyleRollUp;
269
- break;
270
-
271
- case 'prefCaptionsPosition':
272
- options[0] = 'overlay';
273
- options[1] = 'below';
274
- break;
275
-
276
- }
277
- return options;
278
- };
279
-
280
- AblePlayer.prototype.translatePrefs = function(pref, value, outputFormat) {
281
-
282
- // translate current value of pref to a value supported by outputformat
283
- if (outputFormat == 'youtube') {
284
- if (pref === 'size') {
285
- // YouTube font sizes are a range from -1 to 3 (0 = default)
286
- switch (value) {
287
- case '75%':
288
- return -1;
289
- case '100%':
290
- return 0;
291
- case '125%':
292
- return 1;
293
- case '150%':
294
- return 2;
295
- case '200%':
296
- return 3;
297
- }
298
- }
299
- }
300
- return false;
301
- }
302
-
303
- AblePlayer.prototype.stylizeCaptions = function($element, pref) {
304
- // $element is the jQuery element containing the captions
305
- // this function handles stylizing of the sample caption text in the Prefs dialog
306
- // plus the actual production captions
307
- // TODO: consider applying the same user prefs to visible text-based description
308
- var property, newValue, opacity, lineHeight;
309
-
310
- if (typeof $element !== 'undefined') {
311
- if (pref == 'prefCaptionsPosition') {
312
- this.positionCaptions();
313
- }
314
- else if (typeof pref !== 'undefined') {
315
- // just change the one property that user just changed
316
- if (pref === 'prefCaptionsFont') {
317
- property = 'font-family';
318
- }
319
- else if (pref === 'prefCaptionsSize') {
320
- property = 'font-size';
321
- }
322
- else if (pref === 'prefCaptionsColor') {
323
- property = 'color';
324
- }
325
- else if (pref === 'prefCaptionsBGColor') {
326
- property = 'background-color';
327
- }
328
- else if (pref === 'prefCaptionsOpacity') {
329
- property = 'opacity';
330
- }
331
- if (pref === 'prefCaptionsOpacity') {
332
- newValue = parseFloat($('#' + this.mediaId + '_' + pref).val()) / 100.0;
333
- }
334
- else {
335
- newValue = $('#' + this.mediaId + '_' + pref).val();
336
- }
337
- $element.css(property, newValue);
338
- }
339
- else { // no property was specified, update all styles with current saved prefs
340
- opacity = parseFloat(this.prefCaptionsOpacity) / 100.0;
341
- $element.css({
342
- 'font-family': this.prefCaptionsFont,
343
- 'font-size': this.prefCaptionsSize,
344
- 'color': this.prefCaptionsColor,
345
- 'background-color': this.prefCaptionsBGColor,
346
- 'opacity': opacity
347
- });
348
- if ($element === this.$captionsDiv) {
349
- if (typeof this.$captionsWrapper !== 'undefined') {
350
- lineHeight = parseInt(this.prefCaptionsSize,10) + 25;
351
- this.$captionsWrapper.css('line-height',lineHeight + '%');
352
- }
353
- }
354
- if (this.prefCaptionsPosition === 'below') {
355
- // also need to add the background color to the wrapper div
356
- if (typeof this.$captionsWrapper !== 'undefined') {
357
- this.$captionsWrapper.css({
358
- 'background-color': this.prefCaptionsBGColor,
359
- 'opacity': '1'
360
- });
361
- }
362
- }
363
- else if (this.prefCaptionsPosition === 'overlay') {
364
- // no background color for overlay wrapper, captions are displayed in-line
365
- if (typeof this.$captionsWrapper !== 'undefined') {
366
- this.$captionsWrapper.css({
367
- 'background-color': 'transparent',
368
- 'opacity': ''
369
- });
370
- }
371
- }
372
- this.positionCaptions();
373
- }
374
- }
375
- };
376
- AblePlayer.prototype.positionCaptions = function(position) {
377
-
378
- // set caption position to either 'overlay' or 'below'
379
- // if position parameter was passed to this function, use that
380
- // otherwise use user preference
381
- if (typeof position === 'undefined') {
382
- position = this.prefCaptionsPosition;
383
- }
384
- if (typeof this.$captionsWrapper !== 'undefined') {
385
-
386
- if (position == 'below') {
387
- this.$captionsWrapper.removeClass('able-captions-overlay').addClass('able-captions-below');
388
- // also need to update in-line styles
389
- this.$captionsWrapper.css({
390
- 'background-color': this.prefCaptionsBGColor,
391
- 'opacity': '1'
392
- });
393
- }
394
- else {
395
- this.$captionsWrapper.removeClass('able-captions-below').addClass('able-captions-overlay');
396
- this.$captionsWrapper.css({
397
- 'background-color': 'transparent',
398
- 'opacity': ''
399
- });
400
- }
401
- }
402
- };
2
+ AblePlayer.prototype.updateCaption = function (time) {
3
+
4
+ if (!this.usingYouTubeCaptions && (typeof this.$captionsWrapper !== 'undefined')) {
5
+ if (this.captionsOn) {
6
+ this.$captionsWrapper.show();
7
+ if (typeof time !== 'undefined') {
8
+ this.showCaptions(time);
9
+ }
10
+ }
11
+ else if (this.$captionsWrapper) {
12
+ this.$captionsWrapper.hide();
13
+ this.prefCaptions = 0;
14
+ }
15
+ }
16
+ };
17
+
18
+ AblePlayer.prototype.updateCaptionsMenu = function (lang) {
19
+
20
+ // uncheck all previous menu items
21
+ this.captionsPopup.find('li').attr('aria-checked','false');
22
+ if (typeof lang === 'undefined') {
23
+ // check the last menu item (captions off)
24
+ this.captionsPopup.find('li').last().attr('aria-checked','true');
25
+ }
26
+ else {
27
+ // check the newly selected lang
28
+ this.captionsPopup.find('li[lang=' + lang + ']').attr('aria-checked','true');
29
+ }
30
+ };
31
+
32
+ // Returns the function used when a caption is clicked in the captions menu.
33
+ // Not called if user clicks "Captions off". Instead, that triggers getCaptionOffFunction()
34
+ AblePlayer.prototype.getCaptionClickFunction = function (track) {
35
+
36
+ var thisObj = this;
37
+ return function () {
38
+ thisObj.selectedCaptions = track;
39
+ thisObj.captionLang = track.language;
40
+ thisObj.currentCaption = -1;
41
+ if (thisObj.usingYouTubeCaptions) {
42
+ if (thisObj.captionsOn) {
43
+ if (typeof thisObj.ytCaptionModule !== 'undefined') {
44
+ // captions are already on. Just need to change the language
45
+ thisObj.youTubePlayer.setOption(thisObj.ytCaptionModule, 'track', {'languageCode': thisObj.captionLang});
46
+ }
47
+ else {
48
+ // need to wait for caption module to be loaded to change the language
49
+ // caption module will be loaded after video starts playing, triggered by onApiChange event
50
+ // at that point, thosObj.captionLang will be passed to the module as the default language
51
+ }
52
+ }
53
+ else {
54
+ // captions are off (i.e., captions module has been unloaded; need to reload it)
55
+ // user's selected language will be reset after module has successfully loaded
56
+ // (the onApiChange event will be fired -- see initialize.js > initYouTubePlayer())
57
+ thisObj.resettingYouTubeCaptions = true;
58
+ thisObj.youTubePlayer.loadModule(thisObj.ytCaptionModule);
59
+ }
60
+ }
61
+ else if (thisObj.usingVimeoCaptions) {
62
+ thisObj.vimeoPlayer.enableTextTrack(thisObj.captionLang).then(function(track) {
63
+ // track.language = the iso code for the language
64
+ // track.kind = 'captions' or 'subtitles'
65
+ // track.label = the human-readable label
66
+ }).catch(function(error) {
67
+ switch (error.name) {
68
+ case 'InvalidTrackLanguageError':
69
+ // no track was available with the specified language
70
+ console.log('No ' + track.kind + ' track is available in the specified language (' + track.label + ')');
71
+ break;
72
+ case 'InvalidTrackError':
73
+ // no track was available with the specified language and kind
74
+ console.log('No ' + track.kind + ' track is available in the specified language (' + track.label + ')');
75
+ break;
76
+ default:
77
+ // some other error occurred
78
+ console.log('Error loading ' + track.label + ' ' + track.kind + ' track');
79
+ break;
80
+ }
81
+ });
82
+ }
83
+ else { // using local track elements for captions/subtitles
84
+ thisObj.syncTrackLanguages('captions',thisObj.captionLang);
85
+ if (!thisObj.swappingSrc) {
86
+ thisObj.updateCaption(thisObj.elapsed);
87
+ thisObj.showDescription(thisObj.elapsed);
88
+ }
89
+ }
90
+ thisObj.captionsOn = true;
91
+ // stopgap to prevent spacebar in Firefox from reopening popup
92
+ // immediately after closing it (used in handleCaptionToggle())
93
+ thisObj.hidingPopup = true;
94
+ thisObj.captionsPopup.hide();
95
+ // Ensure stopgap gets cancelled if handleCaptionToggle() isn't called
96
+ // e.g., if user triggered button with Enter or mouse click, not spacebar
97
+ setTimeout(function() {
98
+ thisObj.hidingPopup = false;
99
+ }, 100);
100
+ thisObj.updateCaptionsMenu(thisObj.captionLang);
101
+ thisObj.$ccButton.focus();
102
+
103
+ // save preference to cookie
104
+ thisObj.prefCaptions = 1;
105
+ thisObj.updateCookie('prefCaptions');
106
+ thisObj.refreshControls('captions');
107
+ }
108
+ };
109
+
110
+ // Returns the function used when the "Captions Off" button is clicked in the captions tooltip.
111
+ AblePlayer.prototype.getCaptionOffFunction = function () {
112
+
113
+ var thisObj = this;
114
+ return function () {
115
+ if (thisObj.player == 'youtube') {
116
+ thisObj.youTubePlayer.unloadModule(thisObj.ytCaptionModule);
117
+ }
118
+ thisObj.captionsOn = false;
119
+ thisObj.currentCaption = -1;
120
+ // stopgap to prevent spacebar in Firefox from reopening popup
121
+ // immediately after closing it (used in handleCaptionToggle())
122
+ thisObj.hidingPopup = true;
123
+ thisObj.captionsPopup.hide();
124
+ // Ensure stopgap gets cancelled if handleCaptionToggle() isn't called
125
+ // e.g., if user triggered button with Enter or mouse click, not spacebar
126
+ setTimeout(function() {
127
+ thisObj.hidingPopup = false;
128
+ }, 100);
129
+ thisObj.updateCaptionsMenu();
130
+ thisObj.$ccButton.focus();
131
+
132
+ // save preference to cookie
133
+ thisObj.prefCaptions = 0;
134
+ thisObj.updateCookie('prefCaptions');
135
+ if (!this.swappingSrc) {
136
+ thisObj.refreshControls('captions');
137
+ thisObj.updateCaption();
138
+ }
139
+ }
140
+ };
141
+
142
+ AblePlayer.prototype.showCaptions = function(now) {
143
+
144
+ var c, thisCaption, captionText;
145
+ var cues;
146
+ if (this.selectedCaptions) {
147
+ cues = this.selectedCaptions.cues;
148
+ }
149
+ else if (this.captions.length >= 1) {
150
+ cues = this.captions[0].cues;
151
+ }
152
+ else {
153
+ cues = [];
154
+ }
155
+ for (c = 0; c < cues.length; c++) {
156
+ if ((cues[c].start <= now) && (cues[c].end > now)) {
157
+ thisCaption = c;
158
+ break;
159
+ }
160
+ }
161
+ if (typeof thisCaption !== 'undefined') {
162
+ if (this.currentCaption !== thisCaption) {
163
+ // it's time to load the new caption into the container div
164
+ captionText = this.flattenCueForCaption(cues[thisCaption]).replace('\n', '<br>');
165
+ this.$captionsDiv.html(captionText);
166
+ this.currentCaption = thisCaption;
167
+ if (captionText.length === 0) {
168
+ // hide captionsDiv; otherwise background-color is visible due to padding
169
+ this.$captionsDiv.css('display','none');
170
+ }
171
+ else {
172
+ this.$captionsDiv.css('display','inline-block');
173
+ }
174
+ }
175
+ }
176
+ else {
177
+ this.$captionsDiv.html('');
178
+ this.currentCaption = -1;
179
+ }
180
+ };
181
+
182
+ AblePlayer.prototype.flattenCueForCaption = function (cue) {
183
+
184
+ // Takes a cue and returns the caption text to display
185
+ // Also used for chapters
186
+
187
+ // Support for 'i' and 'b' tags added in 2.3.66
188
+ // TODO: Add support for 'c' (class) and 'ruby'
189
+
190
+ // c (class): <c.myClass1.myClass2>Some text</c>
191
+ // Classes can be used to modify other tags too (e.g., <v.loud>)
192
+ // If <c> tag, should be rendered as a <span>
193
+
194
+ // ruby: http://www.w3schools.com/tags/tag_ruby.asp
195
+
196
+ // WebVTT also supports 'u' (underline)
197
+ // I see no reason to support that in Able Player.
198
+ // If it's available authors are likely to use it incorrectly
199
+ // where <i> or <b> should be used instead
200
+ // Here are the rare use cases where an underline is appropriate on the web:
201
+ // http://html5doctor.com/u-element/
202
+
203
+ var result = [];
204
+
205
+ var flattenComponent = function (component) {
206
+ var result = [], ii;
207
+ if (component.type === 'string') {
208
+ result.push(component.value);
209
+ }
210
+ else if (component.type === 'v') {
211
+ result.push('(' + component.value + ')');
212
+ for (ii = 0; ii < component.children.length; ii++) {
213
+ result.push(flattenComponent(component.children[ii]));
214
+ }
215
+ }
216
+ else if (component.type === 'i') {
217
+ result.push('<em>');
218
+ for (ii = 0; ii < component.children.length; ii++) {
219
+ result.push(flattenComponent(component.children[ii]));
220
+ }
221
+ result.push('</em>');
222
+ }
223
+ else if (component.type === 'b') {
224
+ result.push('<strong>');
225
+ for (ii = 0; ii < component.children.length; ii++) {
226
+ result.push(flattenComponent(component.children[ii]));
227
+ }
228
+ result.push('</strong>');
229
+ }
230
+ else {
231
+ for (ii = 0; ii < component.children.length; ii++) {
232
+ result.push(flattenComponent(component.children[ii]));
233
+ }
234
+ }
235
+ return result.join('');
236
+ };
237
+
238
+ if (typeof cue.components !== 'undefined') {
239
+ for (var ii = 0; ii < cue.components.children.length; ii++) {
240
+ result.push(flattenComponent(cue.components.children[ii]));
241
+ }
242
+ }
243
+ return result.join('');
244
+ };
245
+
246
+ AblePlayer.prototype.getCaptionsOptions = function(pref) {
247
+
248
+ var options = [];
249
+
250
+ switch (pref) {
251
+
252
+ case 'prefCaptionsFont':
253
+ options[0] = this.tt.serif;
254
+ options[1] = this.tt.sans;
255
+ options[3] = this.tt.cursive;
256
+ options[4] = this.tt.fantasy;
257
+ options[2] = this.tt.monospace;
258
+ break;
259
+
260
+ case 'prefCaptionsColor':
261
+ case 'prefCaptionsBGColor':
262
+ // HTML color values must be in English
263
+ options[0] = ['white',this.tt.white];
264
+ options[1] = ['yellow',this.tt.yellow];
265
+ options[2] = ['green',this.tt.green];
266
+ options[3] = ['cyan',this.tt.cyan];
267
+ options[4] = ['blue',this.tt.blue];
268
+ options[5] = ['magenta',this.tt.magenta];
269
+ options[6] = ['red',this.tt.red];
270
+ options[7] = ['black',this.tt.black];
271
+ break;
272
+
273
+ case 'prefCaptionsSize':
274
+ options[0] = '75%';
275
+ options[1] = '100%';
276
+ options[2] = '125%';
277
+ options[3] = '150%';
278
+ options[4] = '200%';
279
+ break;
280
+
281
+ case 'prefCaptionsOpacity':
282
+ options[0] = '0%';
283
+ options[1] = '25%';
284
+ options[2] = '50%';
285
+ options[3] = '75%';
286
+ options[4] = '100%';
287
+ break;
288
+
289
+ case 'prefCaptionsStyle':
290
+ options[0] = this.tt.captionsStylePopOn;
291
+ options[1] = this.tt.captionsStyleRollUp;
292
+ break;
293
+
294
+ case 'prefCaptionsPosition':
295
+ options[0] = 'overlay';
296
+ options[1] = 'below';
297
+ break;
298
+
299
+ }
300
+ return options;
301
+ };
302
+
303
+ AblePlayer.prototype.translatePrefs = function(pref, value, outputFormat) {
304
+
305
+ // translate current value of pref to a value supported by outputformat
306
+ if (outputFormat == 'youtube') {
307
+ if (pref === 'size') {
308
+ // YouTube font sizes are a range from -1 to 3 (0 = default)
309
+ switch (value) {
310
+ case '75%':
311
+ return -1;
312
+ case '100%':
313
+ return 0;
314
+ case '125%':
315
+ return 1;
316
+ case '150%':
317
+ return 2;
318
+ case '200%':
319
+ return 3;
320
+ }
321
+ }
322
+ }
323
+ return false;
324
+ }
325
+
326
+ AblePlayer.prototype.stylizeCaptions = function($element, pref) {
327
+ // $element is the jQuery element containing the captions
328
+ // this function handles stylizing of the sample caption text in the Prefs dialog
329
+ // plus the actual production captions
330
+ // TODO: consider applying the same user prefs to visible text-based description
331
+ var property, newValue, opacity, lineHeight;
332
+
333
+ if (typeof $element !== 'undefined') {
334
+ if (pref == 'prefCaptionsPosition') {
335
+ this.positionCaptions();
336
+ }
337
+ else if (typeof pref !== 'undefined') {
338
+ // just change the one property that user just changed
339
+ if (pref === 'prefCaptionsFont') {
340
+ property = 'font-family';
341
+ }
342
+ else if (pref === 'prefCaptionsSize') {
343
+ property = 'font-size';
344
+ }
345
+ else if (pref === 'prefCaptionsColor') {
346
+ property = 'color';
347
+ }
348
+ else if (pref === 'prefCaptionsBGColor') {
349
+ property = 'background-color';
350
+ }
351
+ else if (pref === 'prefCaptionsOpacity') {
352
+ property = 'opacity';
353
+ }
354
+ if (pref === 'prefCaptionsOpacity') {
355
+ newValue = parseFloat($('#' + this.mediaId + '_' + pref).val()) / 100.0;
356
+ }
357
+ else {
358
+ newValue = $('#' + this.mediaId + '_' + pref).val();
359
+ }
360
+ $element.css(property, newValue);
361
+ }
362
+ else { // no property was specified, update all styles with current saved prefs
363
+ opacity = parseFloat(this.prefCaptionsOpacity) / 100.0;
364
+ $element.css({
365
+ 'font-family': this.prefCaptionsFont,
366
+ 'font-size': this.prefCaptionsSize,
367
+ 'color': this.prefCaptionsColor,
368
+ 'background-color': this.prefCaptionsBGColor,
369
+ 'opacity': opacity
370
+ });
371
+ if ($element === this.$captionsDiv) {
372
+ if (typeof this.$captionsWrapper !== 'undefined') {
373
+ lineHeight = parseInt(this.prefCaptionsSize,10) + 25;
374
+ this.$captionsWrapper.css('line-height',lineHeight + '%');
375
+ }
376
+ }
377
+ if (this.prefCaptionsPosition === 'below') {
378
+ // also need to add the background color to the wrapper div
379
+ if (typeof this.$captionsWrapper !== 'undefined') {
380
+ this.$captionsWrapper.css({
381
+ 'background-color': this.prefCaptionsBGColor,
382
+ 'opacity': '1'
383
+ });
384
+ }
385
+ }
386
+ else if (this.prefCaptionsPosition === 'overlay') {
387
+ // no background color for overlay wrapper, captions are displayed in-line
388
+ if (typeof this.$captionsWrapper !== 'undefined') {
389
+ this.$captionsWrapper.css({
390
+ 'background-color': 'transparent',
391
+ 'opacity': ''
392
+ });
393
+ }
394
+ }
395
+ this.positionCaptions();
396
+ }
397
+ }
398
+ };
399
+ AblePlayer.prototype.positionCaptions = function(position) {
400
+
401
+ // set caption position to either 'overlay' or 'below'
402
+ // if position parameter was passed to this function, use that
403
+ // otherwise use user preference
404
+ if (typeof position === 'undefined') {
405
+ position = this.prefCaptionsPosition;
406
+ }
407
+ if (typeof this.$captionsWrapper !== 'undefined') {
408
+
409
+ if (position == 'below') {
410
+ this.$captionsWrapper.removeClass('able-captions-overlay').addClass('able-captions-below');
411
+ // also need to update in-line styles
412
+ this.$captionsWrapper.css({
413
+ 'background-color': this.prefCaptionsBGColor,
414
+ 'opacity': '1'
415
+ });
416
+ }
417
+ else {
418
+ this.$captionsWrapper.removeClass('able-captions-below').addClass('able-captions-overlay');
419
+ this.$captionsWrapper.css({
420
+ 'background-color': 'transparent',
421
+ 'opacity': ''
422
+ });
423
+ }
424
+ }
425
+ };
403
426
 
404
427
  })(jQuery);