wai-website-theme 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +52 -0
  4. data/_data/lang.json +730 -0
  5. data/_data/techniques.yml +180 -0
  6. data/_data/wcag.yml +125 -0
  7. data/_includes/.DS_Store +0 -0
  8. data/_includes/body-class.html +1 -0
  9. data/_includes/box.html +10 -0
  10. data/_includes/excol.html +13 -0
  11. data/_includes/footer.html +40 -0
  12. data/_includes/head.html +23 -0
  13. data/_includes/header.html +59 -0
  14. data/_includes/icon.html +6 -0
  15. data/_includes/img.html +17 -0
  16. data/_includes/multilang-list-policy-links.html +29 -0
  17. data/_includes/multilang-list.html +35 -0
  18. data/_includes/multilang-policy-title.html +5 -0
  19. data/_includes/multilang-title-full.html +1 -0
  20. data/_includes/multilang-title.html +1 -0
  21. data/_includes/navlist.html +22 -0
  22. data/_includes/notes.html +2 -0
  23. data/_includes/prevnext.html +34 -0
  24. data/_includes/resources.html +19 -0
  25. data/_includes/sidenav.html +65 -0
  26. data/_includes/sidenote.html +14 -0
  27. data/_includes/toc.html +10 -0
  28. data/_includes/video-player.html +99 -0
  29. data/_layouts/default.html +26 -0
  30. data/_layouts/home.html +14 -0
  31. data/_layouts/news.html +21 -0
  32. data/_layouts/none.html +1 -0
  33. data/_layouts/policy.html +72 -0
  34. data/_layouts/sidenav.html +27 -0
  35. data/_layouts/sidenavsidebar.html +22 -0
  36. data/assets/ableplayer/.gitattributes +14 -0
  37. data/assets/ableplayer/.gitignore +7 -0
  38. data/assets/ableplayer/Gruntfile.js +105 -0
  39. data/assets/ableplayer/LICENSE +26 -0
  40. data/assets/ableplayer/README.md +656 -0
  41. data/assets/ableplayer/build/ableplayer.dist.js +12157 -0
  42. data/assets/ableplayer/build/ableplayer.js +12157 -0
  43. data/assets/ableplayer/build/ableplayer.min.css +2 -0
  44. data/assets/ableplayer/build/ableplayer.min.js +8 -0
  45. data/assets/ableplayer/button-icons/able-icons.svg +116 -0
  46. data/assets/ableplayer/button-icons/black/captions.png +0 -0
  47. data/assets/ableplayer/button-icons/black/chapters.png +0 -0
  48. data/assets/ableplayer/button-icons/black/close.png +0 -0
  49. data/assets/ableplayer/button-icons/black/descriptions.png +0 -0
  50. data/assets/ableplayer/button-icons/black/ellipsis.png +0 -0
  51. data/assets/ableplayer/button-icons/black/faster.png +0 -0
  52. data/assets/ableplayer/button-icons/black/forward.png +0 -0
  53. data/assets/ableplayer/button-icons/black/fullscreen-collapse.png +0 -0
  54. data/assets/ableplayer/button-icons/black/fullscreen-expand.png +0 -0
  55. data/assets/ableplayer/button-icons/black/help.png +0 -0
  56. data/assets/ableplayer/button-icons/black/next.png +0 -0
  57. data/assets/ableplayer/button-icons/black/pause.png +0 -0
  58. data/assets/ableplayer/button-icons/black/pipe.png +0 -0
  59. data/assets/ableplayer/button-icons/black/play.png +0 -0
  60. data/assets/ableplayer/button-icons/black/preferences.png +0 -0
  61. data/assets/ableplayer/button-icons/black/previous.png +0 -0
  62. data/assets/ableplayer/button-icons/black/rabbit.png +0 -0
  63. data/assets/ableplayer/button-icons/black/restart.png +0 -0
  64. data/assets/ableplayer/button-icons/black/rewind.png +0 -0
  65. data/assets/ableplayer/button-icons/black/sign.png +0 -0
  66. data/assets/ableplayer/button-icons/black/slower.png +0 -0
  67. data/assets/ableplayer/button-icons/black/stop.png +0 -0
  68. data/assets/ableplayer/button-icons/black/transcript.png +0 -0
  69. data/assets/ableplayer/button-icons/black/turtle.png +0 -0
  70. data/assets/ableplayer/button-icons/black/volume-loud.png +0 -0
  71. data/assets/ableplayer/button-icons/black/volume-medium.png +0 -0
  72. data/assets/ableplayer/button-icons/black/volume-mute.png +0 -0
  73. data/assets/ableplayer/button-icons/black/volume-soft.png +0 -0
  74. data/assets/ableplayer/button-icons/fonts/able.eot +0 -0
  75. data/assets/ableplayer/button-icons/fonts/able.svg +40 -0
  76. data/assets/ableplayer/button-icons/fonts/able.ttf +0 -0
  77. data/assets/ableplayer/button-icons/fonts/able.woff +0 -0
  78. data/assets/ableplayer/button-icons/white/captions.png +0 -0
  79. data/assets/ableplayer/button-icons/white/chapters.png +0 -0
  80. data/assets/ableplayer/button-icons/white/close.png +0 -0
  81. data/assets/ableplayer/button-icons/white/descriptions.png +0 -0
  82. data/assets/ableplayer/button-icons/white/ellipsis.png +0 -0
  83. data/assets/ableplayer/button-icons/white/faster.png +0 -0
  84. data/assets/ableplayer/button-icons/white/forward.png +0 -0
  85. data/assets/ableplayer/button-icons/white/fullscreen-collapse.png +0 -0
  86. data/assets/ableplayer/button-icons/white/fullscreen-expand.png +0 -0
  87. data/assets/ableplayer/button-icons/white/help.png +0 -0
  88. data/assets/ableplayer/button-icons/white/next.png +0 -0
  89. data/assets/ableplayer/button-icons/white/pause.png +0 -0
  90. data/assets/ableplayer/button-icons/white/pipe.png +0 -0
  91. data/assets/ableplayer/button-icons/white/play.png +0 -0
  92. data/assets/ableplayer/button-icons/white/preferences.png +0 -0
  93. data/assets/ableplayer/button-icons/white/previous.png +0 -0
  94. data/assets/ableplayer/button-icons/white/rabbit.png +0 -0
  95. data/assets/ableplayer/button-icons/white/restart.png +0 -0
  96. data/assets/ableplayer/button-icons/white/rewind.png +0 -0
  97. data/assets/ableplayer/button-icons/white/sign.png +0 -0
  98. data/assets/ableplayer/button-icons/white/slower.png +0 -0
  99. data/assets/ableplayer/button-icons/white/stop.png +0 -0
  100. data/assets/ableplayer/button-icons/white/transcript.png +0 -0
  101. data/assets/ableplayer/button-icons/white/turtle.png +0 -0
  102. data/assets/ableplayer/button-icons/white/volume-loud.png +0 -0
  103. data/assets/ableplayer/button-icons/white/volume-medium.png +0 -0
  104. data/assets/ableplayer/button-icons/white/volume-mute.png +0 -0
  105. data/assets/ableplayer/button-icons/white/volume-soft.png +0 -0
  106. data/assets/ableplayer/images/wingrip.png +0 -0
  107. data/assets/ableplayer/package.json +22 -0
  108. data/assets/ableplayer/scripts/JQuery.doWhen.js +113 -0
  109. data/assets/ableplayer/scripts/ableplayer-base.js +440 -0
  110. data/assets/ableplayer/scripts/browser.js +162 -0
  111. data/assets/ableplayer/scripts/buildplayer.js +1609 -0
  112. data/assets/ableplayer/scripts/caption.js +385 -0
  113. data/assets/ableplayer/scripts/chapters.js +242 -0
  114. data/assets/ableplayer/scripts/control.js +1514 -0
  115. data/assets/ableplayer/scripts/description.js +283 -0
  116. data/assets/ableplayer/scripts/dialog.js +147 -0
  117. data/assets/ableplayer/scripts/dragdrop.js +766 -0
  118. data/assets/ableplayer/scripts/event.js +595 -0
  119. data/assets/ableplayer/scripts/initialize.js +725 -0
  120. data/assets/ableplayer/scripts/langs.js +750 -0
  121. data/assets/ableplayer/scripts/metadata.js +134 -0
  122. data/assets/ableplayer/scripts/misc.js +72 -0
  123. data/assets/ableplayer/scripts/preference.js +909 -0
  124. data/assets/ableplayer/scripts/search.js +171 -0
  125. data/assets/ableplayer/scripts/sign.js +92 -0
  126. data/assets/ableplayer/scripts/slider.js +454 -0
  127. data/assets/ableplayer/scripts/track.js +296 -0
  128. data/assets/ableplayer/scripts/transcript.js +590 -0
  129. data/assets/ableplayer/scripts/translation.js +66 -0
  130. data/assets/ableplayer/scripts/volume.js +383 -0
  131. data/assets/ableplayer/scripts/webvtt.js +765 -0
  132. data/assets/ableplayer/scripts/youtube.js +471 -0
  133. data/assets/ableplayer/styles/ableplayer.css +1241 -0
  134. data/assets/ableplayer/thirdparty/js.cookie.js +145 -0
  135. data/assets/ableplayer/thirdparty/modernizr.custom.js +4 -0
  136. data/assets/ableplayer/translations/ca.js +1 -0
  137. data/assets/ableplayer/translations/de.js +1 -0
  138. data/assets/ableplayer/translations/en.js +305 -0
  139. data/assets/ableplayer/translations/es.js +305 -0
  140. data/assets/ableplayer/translations/fr.js +305 -0
  141. data/assets/ableplayer/translations/it.js +303 -0
  142. data/assets/ableplayer/translations/ja.js +305 -0
  143. data/assets/ableplayer/translations/nl.js +305 -0
  144. data/assets/css/style.css +4360 -0
  145. data/assets/css/style.css.map +1 -0
  146. data/assets/fonts/anonymouspro-bold.woff +0 -0
  147. data/assets/fonts/anonymouspro-bold.woff2 +0 -0
  148. data/assets/fonts/anonymouspro-bolditalic.woff +0 -0
  149. data/assets/fonts/anonymouspro-bolditalic.woff2 +0 -0
  150. data/assets/fonts/anonymouspro-italic.woff +0 -0
  151. data/assets/fonts/anonymouspro-italic.woff2 +0 -0
  152. data/assets/fonts/anonymouspro-regular.woff +0 -0
  153. data/assets/fonts/anonymouspro-regular.woff2 +0 -0
  154. data/assets/fonts/notosans-bold.woff +0 -0
  155. data/assets/fonts/notosans-bold.woff2 +0 -0
  156. data/assets/fonts/notosans-bolditalic.woff +0 -0
  157. data/assets/fonts/notosans-bolditalic.woff2 +0 -0
  158. data/assets/fonts/notosans-italic.woff +0 -0
  159. data/assets/fonts/notosans-italic.woff2 +0 -0
  160. data/assets/fonts/notosans-regular.woff +0 -0
  161. data/assets/fonts/notosans-regular.woff2 +0 -0
  162. data/assets/images/.DS_Store +0 -0
  163. data/assets/images/Shape.svg +10 -0
  164. data/assets/images/icon-related-content.svg +14 -0
  165. data/assets/images/icons.svg +126 -0
  166. data/assets/images/teaser-image@1x.jpg +0 -0
  167. data/assets/images/teaser-image@2x.jpg +0 -0
  168. data/assets/images/w3c.sketch +0 -0
  169. data/assets/images/w3c.svg +10 -0
  170. data/assets/scripts/jquery.min.js +4 -0
  171. data/assets/scripts/main.js +208 -0
  172. data/assets/scripts/svg4everybody.js +1 -0
  173. metadata +257 -0
@@ -0,0 +1,909 @@
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
+ });
165
+ /* // not supported yet
166
+ prefs.push({
167
+ 'name': 'prefCaptionsStyle',
168
+ 'label': this.tt.prefCaptionsStyle,
169
+ 'group': 'captions',
170
+ 'default': this.tt.captionsStylePopOn
171
+ });
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(event) {
725
+ if (event.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
+
909
+ })(jQuery);