wai-website-theme 1.3.1 → 1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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);