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,765 @@
1
+ (function ($) {
2
+ // See section 4.1 of dev.w3.org/html5/webvtt for format details.
3
+ AblePlayer.prototype.parseWebVTT = function(srcFile,text) {
4
+
5
+ // Normalize line ends to \n.
6
+ text = text.replace(/(\r\n|\n|\r)/g,'\n');
7
+
8
+ var parserState = {
9
+ src: srcFile,
10
+ text: text,
11
+ error: null,
12
+ metadata: {},
13
+ cues: [],
14
+ line: 1,
15
+ column: 1
16
+ };
17
+
18
+ try {
19
+ act(parserState, parseFileBody);
20
+ }
21
+ catch (err) {
22
+ var errString = 'Invalid WebVTT file: ' + parserState.src + '\n';
23
+ errString += 'Line: ' + parserState.line + ', ';
24
+ errString += 'Column: ' + parserState.column + '\n';
25
+ errString += err;
26
+ if (console.warn) {
27
+ console.warn(errString);
28
+ }
29
+ else if (console.log) {
30
+ console.log(errString);
31
+ }
32
+ }
33
+ return parserState;
34
+ }
35
+
36
+ function actList(state, list) {
37
+ var results = [];
38
+ for (var ii = 0; ii < list.length; ii++) {
39
+ results.push(act(state, list[ii]));
40
+ }
41
+ return results;
42
+ }
43
+
44
+ // Applies the action and checks for errors.
45
+ function act(state, action) {
46
+ var val = action(state);
47
+ if (state.error !== null) {
48
+ throw state.error;
49
+ }
50
+ return val;
51
+ }
52
+
53
+ function updatePosition(state, cutText) {
54
+ for (var ii = 0; ii < cutText.length; ii++) {
55
+ if (cutText[ii] === '\n') {
56
+ state.column = 1;
57
+ state.line += 1;
58
+ }
59
+ else {
60
+ state.column += 1;
61
+ }
62
+ }
63
+ }
64
+
65
+ function cut(state, length) {
66
+ var returnText = state.text.substring(0, length);
67
+ updatePosition(state, returnText);
68
+ state.text = state.text.substring(length);
69
+ return returnText;
70
+ }
71
+
72
+ function cutLine(state, length) {
73
+ var nextEOL = state.text.indexOf('\n');
74
+ var returnText;
75
+ if (nextEOL === -1) {
76
+ returnText = state.text;
77
+ updatePosition(state, returnText);
78
+ state.text = '';
79
+ }
80
+ else {
81
+ returnText = state.text.substring(0, nextEOL);
82
+ updatePosition(state, returnText + '\n');
83
+ state.text = state.text.substring(nextEOL + 1);
84
+ }
85
+ return returnText;
86
+ }
87
+
88
+ function peekLine(state) {
89
+ var nextEOL = state.text.indexOf('\n');
90
+ if (nextEOL === -1) {
91
+ return state.text;
92
+ }
93
+ else {
94
+ return state.text.substring(0, nextEOL);
95
+ }
96
+ }
97
+
98
+ function parseFileBody(state) {
99
+ actList(state, [
100
+ eatOptionalBOM,
101
+ eatSignature]);
102
+ var c = state.text[0];
103
+ if (c === ' ' || c === '\t' || c === '\n') {
104
+ actList(state, [
105
+ eatUntilEOLInclusive,
106
+ parseMetadataHeaders,
107
+ eatAtLeast1EmptyLines,
108
+ parseCuesAndComments]);
109
+ }
110
+ else {
111
+ state.error = "WEBVTT signature not followed by whitespace.";
112
+ }
113
+ }
114
+
115
+ // Parses all metadata headers until a cue is discovered.
116
+ function parseMetadataHeaders(state) {
117
+ while (true) {
118
+ var nextLine = peekLine(state);
119
+ if (nextLine.indexOf('-->') !== -1) {
120
+ return;
121
+ }
122
+ else if (nextLine.length === 0) {
123
+ return;
124
+ }
125
+ else {
126
+ var keyValue = act(state, getMetadataKeyValue);
127
+ state.metadata[keyValue[0]] = keyValue[1];
128
+ act(state, eatUntilEOLInclusive);
129
+ }
130
+ }
131
+ }
132
+
133
+ function nextSpaceOrNewline(s) {
134
+ var possible = [];
135
+ var spaceIndex = s.indexOf(' ');
136
+ if (spaceIndex >= 0) {
137
+ possible.push(spaceIndex);
138
+ }
139
+ var tabIndex = s.indexOf('\t');
140
+ if (tabIndex >= 0) {
141
+ possible.push(tabIndex);
142
+ }
143
+ var lineIndex = s.indexOf('\n');
144
+ if (lineIndex >= 0) {
145
+ possible.push(lineIndex);
146
+ }
147
+
148
+ return Math.min.apply(null, possible);
149
+ }
150
+
151
+ function getMetadataKeyValue(state) {
152
+ var next = state.text.indexOf('\n');
153
+ var pair = cut(state, next);
154
+ var colon = pair.indexOf(':');
155
+ if (colon === -1) {
156
+ state.error = 'Missing colon.';
157
+ return;
158
+ }
159
+ else {
160
+ var pairName = pair.substring(0, colon);
161
+ var pairValue = pair.substring(colon + 1);
162
+ return [pairName, pairValue];
163
+ }
164
+ }
165
+
166
+ function getSettingsKeyValue(state) {
167
+ var next = nextSpaceOrNewline(state.text);
168
+ var pair = cut(state, next);
169
+ var colon = pair.indexOf(':');
170
+ if (colon === -1) {
171
+ state.error = 'Missing colon.';
172
+ return;
173
+ }
174
+ else {
175
+ var pairName = pair.substring(0, colon);
176
+ var pairValue = pair.substring(colon + 1);
177
+ return [pairName, pairValue];
178
+ }
179
+ }
180
+
181
+ function parseCuesAndComments(state) {
182
+ while (true) {
183
+ var nextLine = peekLine(state);
184
+ // If NOTE is not on a line all its own, it must be followed by a space or tab.
185
+ if (nextLine.indexOf('NOTE') === 0 && ((nextLine.length === 4) || (nextLine[4] === ' ') || (nextLine[4] === '\t'))) {
186
+ actList(state, [eatComment, eatEmptyLines]);
187
+ }
188
+ else if ($.trim(nextLine).length === 0 && state.text.length > 0) {
189
+ act(state, eatEmptyLines);
190
+ }
191
+ else if ($.trim(nextLine).length > 0) {
192
+ act(state, parseCue);
193
+ }
194
+ else {
195
+ // Everythings parsed!
196
+ return;
197
+ }
198
+ }
199
+ }
200
+
201
+ function parseCue(state) {
202
+
203
+ var nextLine = peekLine(state);
204
+ var cueId;
205
+ var errString;
206
+
207
+ if(nextLine.indexOf('-->') === -1) {
208
+ cueId = cutLine(state);
209
+ nextLine = peekLine(state);
210
+ if(nextLine.indexOf('-->') === -1) {
211
+ errString = 'Invalid WebVTT file: ' + state.src + '\n';
212
+ errString += 'Line: ' + state.line + ', ';
213
+ errString += 'Column: ' + state.column + '\n';
214
+ errString += 'Expected cue timing for cueId \''+cueId+'\' but found: ' + nextLine + '\n';
215
+ if (console.warn) {
216
+ console.warn(errString);
217
+ }
218
+ else if (console.log) {
219
+ console.log(errString);
220
+ }
221
+ return; // Return leaving line for parseCuesAndComments to handle
222
+ }
223
+ }
224
+
225
+ var cueTimings = actList(state, [getTiming,
226
+ eatAtLeast1SpacesOrTabs,
227
+ eatArrow,
228
+ eatAtLeast1SpacesOrTabs,
229
+ getTiming]);
230
+
231
+ var startTime = cueTimings[0];
232
+ var endTime = cueTimings[4];
233
+ if (startTime >= endTime) {
234
+ state.error = 'Start time is not sooner than end time.';
235
+ return;
236
+ }
237
+
238
+ act(state, eatSpacesOrTabs);
239
+ var cueSettings = act(state, getCueSettings);
240
+ // Cut the newline.
241
+ cut(state, 1);
242
+ var components = act(state, getCuePayload);
243
+
244
+ if (typeof cueId === 'undefined') {
245
+ cueId = state.cues.length + 1;
246
+ }
247
+ state.cues.push({
248
+ id: cueId,
249
+ start: startTime,
250
+ end: endTime,
251
+ settings: cueSettings,
252
+ components: components
253
+ });
254
+ }
255
+
256
+ function getCueSettings(state) {
257
+ var cueSettings = {};
258
+ while (state.text.length > 0 && state.text[0] !== '\n') {
259
+ var keyValue = act(state, getSettingsKeyValue);
260
+ cueSettings[keyValue[0]] = keyValue[1];
261
+ act(state, eatSpacesOrTabs);
262
+ }
263
+ return cueSettings;
264
+ }
265
+
266
+ function getCuePayload(state) {
267
+ // Parser based on instructions in draft.
268
+ var result = {type: 'internal', tagName: '', value: '', classes: [], annotation: '', parent: null, children: [], language: ''};
269
+ var current = result;
270
+ var languageStack = [];
271
+ while (state.text.length > 0) {
272
+ var nextLine = peekLine(state);
273
+ if (nextLine.indexOf('-->') !== -1 || /^\s*$/.test(nextLine)) {
274
+ break; // Handle empty cues
275
+ }
276
+ // Have to separately detect double-lines ending cue due to our non-standard parsing.
277
+ // TODO: Redo outer algorithm to conform to W3 spec?
278
+ if (state.text.length >= 2 && state.text[0] === '\n' && state.text[1] === '\n') {
279
+ cut(state, 2);
280
+ break;
281
+ }
282
+
283
+ var token = getCueToken(state);
284
+ // We'll use the tokens themselves as objects where possible.
285
+ if (token.type === 'string') {
286
+ current.children.push(token);
287
+ }
288
+ else if (token.type === 'startTag') {
289
+ token.type = token.tagName;
290
+ // Define token.parent; added by Terrill to fix bug end 'endTag' loop
291
+ token.parent = current;
292
+ if ($.inArray(token.tagName, ['i', 'b', 'u', 'ruby']) !== -1) {
293
+ if (languageStack.length > 0) {
294
+ current.language = languageStack[languageStack.length - 1];
295
+ }
296
+ current.children.push(token);
297
+ current = token;
298
+ }
299
+ else if (token.tagName === 'rt' && current.tagName === 'ruby') {
300
+ if (languageStack.length > 0) {
301
+ current.language = languageStack[languageStack.length - 1];
302
+ }
303
+ current.children.push(token);
304
+ current = token;
305
+ }
306
+ else if (token.tagName === 'c') {
307
+ token.value = token.annotation;
308
+ if (languageStack.length > 0) {
309
+ current.language = languageStack[languageStack.length - 1];
310
+ }
311
+ current.children.push(token);
312
+ current = token;
313
+ }
314
+ else if (token.tagName === 'v') {
315
+ token.value = token.annotation;
316
+ if (languageStack.length > 0) {
317
+ current.language = languageStack[languageStack.length - 1];
318
+ }
319
+ current.children.push(token);
320
+ current = token;
321
+ }
322
+ else if (token.tagName === 'lang') {
323
+ languageStack.push(token.annotation);
324
+ if (languageStack.length > 0) {
325
+ current.language = languageStack[languageStack.length - 1];
326
+ }
327
+ current.children.push(token);
328
+ current = token;
329
+ }
330
+ }
331
+ else if (token.type === 'endTag') {
332
+ if (token.tagName === current.type && $.inArray(token.tagName, ['c', 'i', 'b', 'u', 'ruby', 'rt', 'v']) !== -1) {
333
+ // NOTE from Terrill: This was resulting in an error because current.parent was undefined
334
+ // Fixed (I think) by assigning current token to token.parent in 'startTag' loop
335
+ current = current.parent;
336
+ }
337
+ else if (token.tagName === 'lang' && current.type === 'lang') {
338
+ current = current.parent;
339
+ languageStack.pop();
340
+ }
341
+ else if (token.tagName === 'ruby' && current.type === 'rt') {
342
+ current = current.parent.parent;
343
+ }
344
+ }
345
+ else if (token.type === 'timestampTag') {
346
+ var tempState = {
347
+ text: token.value,
348
+ error: null,
349
+ metadata: {},
350
+ cues: [],
351
+ line: 1,
352
+ column: 1
353
+ };
354
+ try {
355
+ var timing = act(tempState, getTiming);
356
+ if (tempState.text.length === 0) {
357
+ token.value = timing;
358
+ current.push(token);
359
+ }
360
+ }
361
+ catch (err) {
362
+ }
363
+ }
364
+ }
365
+ return result;
366
+ }
367
+
368
+ // Gets a single cue token; uses the method in the w3 specification.
369
+ function getCueToken(state) {
370
+ var tokenState = 'data';
371
+ var result = [];
372
+ var buffer = '';
373
+ var token = {type: '', tagName: '', value: '', classes: [], annotation: '', children: []}
374
+
375
+ while (true) {
376
+ var c;
377
+ // Double newlines indicate end of token.
378
+ if (state.text.length >= 2 && state.text[0] === '\n' && state.text[1] === '\n') {
379
+ c = '\u0004';
380
+ }
381
+ else if (state.text.length > 0) {
382
+ c = state.text[0];
383
+ }
384
+ else {
385
+ // End of file.
386
+ c = '\u0004';
387
+ }
388
+ if (tokenState === 'data') {
389
+ if (c === '&') {
390
+ buffer = '&';
391
+ tokenState = 'escape';
392
+ }
393
+ else if (c === '<') {
394
+ if (result.length === 0) {
395
+ tokenState = 'tag';
396
+ }
397
+ else {
398
+ token.type = 'string';
399
+ token.value = result.join('');
400
+ return token;
401
+ }
402
+ }
403
+ else if (c === '\u0004') {
404
+ return {type: 'string', value: result.join('')};
405
+ }
406
+ else {
407
+ result.push(c);
408
+ }
409
+ }
410
+ else if (tokenState === 'escape') {
411
+ if (c === '&') {
412
+ result.push(buffer);
413
+ buffer = '&';
414
+ }
415
+ else if (c.match(/[0-9a-z]/)) {
416
+ buffer += c;
417
+ }
418
+ else if (c === ';') {
419
+ if (buffer === '&amp') {
420
+ result.push('&');
421
+ }
422
+ else if (buffer === '&lt') {
423
+ result.push('<');
424
+ }
425
+ else if (buffer === '&gt') {
426
+ result.push('>');
427
+ }
428
+ else if (buffer === '&lrm') {
429
+ result.push('\u200e');
430
+ }
431
+ else if (buffer === '&rlm') {
432
+ result.push('\u200f');
433
+ }
434
+ else if (buffer === '&nbsp') {
435
+ result.push('\u00a0');
436
+ }
437
+ else {
438
+ result.push(buffer);
439
+ result.push(';');
440
+ }
441
+ tokenState = 'data';
442
+ }
443
+ else if (c === '<' || c === '\u0004') {
444
+ result.push(buffer);
445
+ token.type = 'string';
446
+ token.value = result.join('');
447
+ return token;
448
+ }
449
+ else if (c === '\t' || c === '\n' || c === '\u000c' || c === ' ') { // Handle unescaped & chars as strings
450
+ result.push(buffer);
451
+ token.type = 'string';
452
+ token.value = result.join('');
453
+ return token;
454
+ }
455
+ else {
456
+ result.push(buffer);
457
+ tokenState = 'data';
458
+ }
459
+ }
460
+ else if (tokenState === 'tag') {
461
+ if (c === '\t' || c === '\n' || c === '\u000c' || c === ' ') {
462
+ tokenState = 'startTagAnnotation';
463
+ }
464
+ else if (c === '.') {
465
+ tokenState = 'startTagClass';
466
+ }
467
+ else if (c === '/') {
468
+ tokenState = 'endTag';
469
+ }
470
+ else if (c.match('[0-9]')) {
471
+ tokenState = 'timestampTag';
472
+ result.push(c);
473
+ }
474
+ else if (c === '>') {
475
+ cut(state, 1);
476
+ break;
477
+ }
478
+ else if (c === '\u0004') {
479
+ token.tagName = '';
480
+ token.type = 'startTag';
481
+ return token;
482
+ }
483
+ else {
484
+ result.push(c);
485
+ tokenState = 'startTag';
486
+ }
487
+ }
488
+ else if (tokenState === 'startTag') {
489
+ if (c === '\t' || c === '\u000c' || c === ' ') {
490
+ tokenState = 'startTagAnnotation';
491
+ }
492
+ else if (c === '\n') {
493
+ buffer = c;
494
+ tokenState = 'startTagAnnotation';
495
+ }
496
+ else if (c === '.') {
497
+ tokenState = 'startTagClass';
498
+ }
499
+ else if (c === '>') {
500
+ cut(state, 1);
501
+ token.tagName = result.join('');
502
+ token.type = 'startTag';
503
+ return token;
504
+ }
505
+ else if (c === '\u0004') {
506
+ token.tagName = result.join('');
507
+ token.type = 'startTag';
508
+ return token;
509
+ }
510
+ else {
511
+ result.push(c);
512
+ }
513
+ }
514
+ else if (tokenState === 'startTagClass') {
515
+ if (c === '\t' || c === '\u000c' || c === ' ') {
516
+ token.classes.push(buffer);
517
+ buffer = '';
518
+ tokenState = 'startTagAnnotation';
519
+ }
520
+ else if (c === '\n') {
521
+ token.classes.push(buffer);
522
+ buffer = c;
523
+ tokenState = 'startTagAnnotation';
524
+ }
525
+ else if (c === '.') {
526
+ token.classes.push(buffer);
527
+ buffer = "";
528
+ }
529
+ else if (c === '>') {
530
+ cut(state, 1);
531
+ token.classes.push(buffer);
532
+ token.type = 'startTag';
533
+ token.tagName = result.join('');
534
+ return token;
535
+ }
536
+ else if (c === '\u0004') {
537
+ token.classes.push(buffer);
538
+ token.type = 'startTag';
539
+ token.tagName = result.join('');
540
+ return token;
541
+ }
542
+ else {
543
+ buffer += 'c';
544
+ }
545
+ }
546
+ else if (tokenState === 'startTagAnnotation') {
547
+ if (c === '>') {
548
+ cut(state, 1);
549
+ buffer = $.trim(buffer).replace(/ +/, ' ');
550
+ token.type = 'startTag';
551
+ token.tagName = result.join('');
552
+ token.annotation = buffer;
553
+ return token;
554
+ }
555
+ else if (c === '\u0004') {
556
+ buffer = $.trim(buffer).replace(/ +/, ' ');
557
+ token.type = 'startTag';
558
+ token.tagName = result.join('');
559
+ token.annotation = buffer;
560
+ return token;
561
+ }
562
+ else {
563
+ buffer += c;
564
+ }
565
+ }
566
+ else if (tokenState === 'endTag') {
567
+ if (c === '>') {
568
+ cut(state, 1);
569
+ token.type = 'endTag';
570
+ token.tagName = result.join('');
571
+ return token;
572
+ }
573
+ else if (c === '\u0004') {
574
+ token.type = 'endTag';
575
+ token.tagName = result.join('');
576
+ return token;
577
+ }
578
+ else {
579
+ result.push(c);
580
+ }
581
+ }
582
+ else if (tokenState === 'timestampTag') {
583
+ if (c === '>') {
584
+ cut(state, 1);
585
+ token.type = 'timestampTag';
586
+ token.name = result.join('');
587
+ return token;
588
+ }
589
+ else if (c === '\u0004') {
590
+ token.type = 'timestampTag';
591
+ token.name = result.join('');
592
+ return token;
593
+ }
594
+ else {
595
+ result.push(c);
596
+ }
597
+ }
598
+ else {
599
+ throw 'Unknown tokenState ' + tokenState;
600
+ }
601
+
602
+ cut(state, 1);
603
+ }
604
+ }
605
+
606
+ function eatComment(state) {
607
+ // Cut the NOTE line.
608
+ var noteLine = cutLine(state);
609
+ if (noteLine.indexOf('-->') !== -1) {
610
+ state.error = 'Invalid syntax: --> in NOTE line.';
611
+ return;
612
+ }
613
+ while (true) {
614
+ var nextLine = peekLine(state);
615
+ if ($.trim(nextLine).length === 0) {
616
+ // End of comment.
617
+ return;
618
+ }
619
+ else if (nextLine.indexOf('-->') !== -1) {
620
+ state.error = 'Invalid syntax: --> in comment.';
621
+ return;
622
+ }
623
+ else {
624
+ cutLine(state);
625
+ }
626
+ }
627
+ }
628
+
629
+ // Initial byte order mark.
630
+ function eatOptionalBOM(state) {
631
+ if (state.text[0] === '\ufeff') {
632
+ cut(state, 1);
633
+ }
634
+
635
+ }
636
+
637
+ // "WEBVTT" string.
638
+ function eatSignature(state) {
639
+ if (state.text.substring(0,6) === 'WEBVTT') {
640
+ cut(state, 6);
641
+ }
642
+ else {
643
+ state.error = 'Invalid signature.';
644
+ }
645
+ }
646
+
647
+ function eatArrow(state) {
648
+ if (state.text.length < 3 || state.text.substring(0,3) !== '-->') {
649
+ state.error = 'Missing -->';
650
+ }
651
+ else {
652
+ cut(state, 3);
653
+ }
654
+ }
655
+
656
+ function eatSingleSpaceOrTab(state) {
657
+ if (state.text[0] === '\t' || state.text[0] === ' ') {
658
+ cut(state, 1);
659
+ }
660
+ else {
661
+ state.error = 'Missing space.';
662
+ }
663
+ }
664
+
665
+ function eatSpacesOrTabs(state) {
666
+ while (state.text[0] === '\t' || state.text[0] === ' ') {
667
+ cut(state, 1);
668
+ }
669
+ }
670
+
671
+ function eatAtLeast1SpacesOrTabs(state) {
672
+ var numEaten = 0;
673
+ while (state.text[0] === '\t' || state.text[0] === ' ') {
674
+ cut(state, 1);
675
+ numEaten += 1;
676
+ }
677
+ if (numEaten === 0) {
678
+ state.error = 'Missing space.';
679
+ }
680
+ }
681
+
682
+ function eatUntilEOLInclusive(state) {
683
+ var nextEOL = state.text.indexOf('\n');
684
+ if (nextEOL === -1) {
685
+ state.error = 'Missing EOL.';
686
+ }
687
+ else {
688
+ cut(state, nextEOL + 1);
689
+ }
690
+ }
691
+
692
+ function eatEmptyLines(state) {
693
+ while (state.text.length > 0) {
694
+ var nextLine = peekLine(state);
695
+ if ($.trim(nextLine).length === 0) {
696
+ cutLine(state);
697
+ }
698
+ else {
699
+ break;
700
+ }
701
+ }
702
+ }
703
+
704
+ // Eats empty lines, but throws an error if there's not at least one.
705
+ function eatAtLeast1EmptyLines(state) {
706
+ var linesEaten = 0;
707
+ while (state.text.length > 0) {
708
+ var nextLine = peekLine(state);
709
+ if ($.trim(nextLine).length === 0) {
710
+ cutLine(state);
711
+ linesEaten += 1;
712
+ }
713
+ else {
714
+ break;
715
+ }
716
+ }
717
+ if (linesEaten === 0) {
718
+ state.error = 'Missing empty line.';
719
+ }
720
+ }
721
+
722
+ function getTiming(state) {
723
+ var nextSpace = nextSpaceOrNewline(state.text);
724
+ if (nextSpace === -1) {
725
+ state.error('Missing timing.');
726
+ return;
727
+ }
728
+ var timestamp = cut(state, nextSpace);
729
+
730
+ var results = /((\d\d):)?((\d\d):)(\d\d).(\d\d\d)|(\d+).(\d\d\d)/.exec(timestamp);
731
+
732
+ if (!results) {
733
+ state.error = 'Unable to parse timestamp';
734
+ return;
735
+ }
736
+ var time = 0;
737
+ var hours = results[2];
738
+ var minutes = results[4];
739
+
740
+ if (minutes) {
741
+ if (parseInt(minutes, 10) > 59) {
742
+ state.error = 'Invalid minute range';
743
+ return;
744
+ }
745
+ if (hours) {
746
+ time += 3600 * parseInt(hours, 10);
747
+ }
748
+ time += 60 * parseInt(minutes, 10);
749
+ var seconds = results[5];
750
+ if (parseInt(seconds, 10) > 59) {
751
+ state.error = 'Invalid second range';
752
+ return;
753
+ }
754
+
755
+ time += parseInt(seconds, 10);
756
+ time += parseInt(results[6], 10) / 1000;
757
+ }
758
+ else {
759
+ time += parseInt(results[7], 10);
760
+ time += parseInt(results[8], 10) / 1000;
761
+ }
762
+
763
+ return time;
764
+ }
765
+ })(jQuery);