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,454 @@
1
+ (function ($) {
2
+
3
+
4
+ // Events:
5
+ // startTracking(event, position)
6
+ // tracking(event, position)
7
+ // stopTracking(event, position)
8
+
9
+ window. AccessibleSlider = function(mediaType, div, orientation, length, min, max, bigInterval, label, className, trackingMedia, initialState) {
10
+
11
+ // mediaType is either 'audio' or 'video'
12
+ // div is the host element around which the slider will be built
13
+ // orientation is either 'horizontal' or 'vertical'
14
+ // length is the width or height of the slider, depending on orientation
15
+ // min is the low end of the slider scale
16
+ // max is the high end of the slider scale
17
+ // bigInterval is the number of steps supported by page up/page down (set to 0 if not supported)
18
+ // (smallInterval, defined as nextStep below, is always set to 1) - this is the interval supported by arrow keys
19
+ // label is used within an aria-label attribute to identify the slider to screen reader users
20
+ // className is used as the root within class names (e.g., 'able-' + classname + '-head')
21
+ // trackingMedia is true if this is a media timeline; otherwise false
22
+ // initialState is either 'visible' or 'hidden'
23
+
24
+ var thisObj;
25
+
26
+ thisObj = this;
27
+
28
+ // Initialize some variables.
29
+ this.position = 0; // Note: position does not change while tracking.
30
+ this.tracking = false;
31
+ this.trackDevice = null; // 'mouse' or 'keyboard'
32
+ this.keyTrackPosition = 0;
33
+ this.lastTrackPosition = 0;
34
+ this.nextStep = 1;
35
+ this.inertiaCount = 0;
36
+
37
+ this.bodyDiv = $(div);
38
+
39
+ // Add divs for tracking amount of media loaded and played
40
+ if (trackingMedia) {
41
+ this.loadedDiv = $('<div></div>');
42
+ this.playedDiv = $('<div></div>');
43
+ }
44
+
45
+ // Add a seekhead
46
+ this.seekHead = $('<div>',{
47
+ 'orientation': orientation,
48
+ 'class': 'able-' + className + '-head'
49
+ });
50
+
51
+ if (initialState === 'visible') {
52
+ this.seekHead.attr('tabindex', '0');
53
+ }
54
+ else {
55
+ this.seekHead.attr('tabindex', '-1');
56
+ }
57
+ // Since head is focusable, it gets the aria roles/titles.
58
+ this.seekHead.attr({
59
+ 'role': 'slider',
60
+ 'aria-label': label,
61
+ 'aria-valuemin': min,
62
+ 'aria-valuemax': max
63
+ });
64
+
65
+ this.timeTooltip = $('<div>');
66
+ this.bodyDiv.append(this.timeTooltip);
67
+
68
+ this.timeTooltip.attr('role', 'tooltip');
69
+ this.timeTooltip.addClass('able-tooltip');
70
+
71
+ this.bodyDiv.append(this.loadedDiv);
72
+ this.bodyDiv.append(this.playedDiv);
73
+ this.bodyDiv.append(this.seekHead);
74
+
75
+ this.bodyDiv.wrap('<div></div>');
76
+ this.wrapperDiv = this.bodyDiv.parent();
77
+
78
+ if (orientation === 'horizontal') {
79
+ this.wrapperDiv.width(length);
80
+ this.loadedDiv.width(0);
81
+ }
82
+ else {
83
+ this.wrapperDiv.height(length);
84
+ this.loadedDiv.height(0);
85
+ }
86
+ this.wrapperDiv.addClass('able-' + className + '-wrapper');
87
+
88
+ if (trackingMedia) {
89
+ this.loadedDiv.addClass('able-' + className + '-loaded');
90
+
91
+ this.playedDiv.width(0);
92
+ this.playedDiv.addClass('able-' + className + '-played');
93
+
94
+ // Set a default duration. User can call this dynamically if duration changes.
95
+ this.setDuration(max);
96
+ }
97
+
98
+ this.seekHead.hover(function (event) {
99
+ thisObj.overHead = true;
100
+ thisObj.refreshTooltip();
101
+ }, function (event) {
102
+ thisObj.overHead = false;
103
+
104
+ if (!thisObj.overBody && thisObj.tracking && thisObj.trackDevice === 'mouse') {
105
+ thisObj.stopTracking(thisObj.pageXToPosition(event.pageX));
106
+ }
107
+ thisObj.refreshTooltip();
108
+ });
109
+
110
+ this.seekHead.mousemove(function (event) {
111
+ if (thisObj.tracking && thisObj.trackDevice === 'mouse') {
112
+ thisObj.trackHeadAtPageX(event.pageX);
113
+ }
114
+ });
115
+
116
+ this.seekHead.focus(function (event) {
117
+ thisObj.overHead = true;
118
+ thisObj.refreshTooltip();
119
+ });
120
+
121
+ this.seekHead.blur(function (event) {
122
+ thisObj.overHead = false;
123
+ thisObj.refreshTooltip();
124
+ });
125
+
126
+ this.bodyDiv.hover(function () {
127
+ thisObj.overBody = true;
128
+ thisObj.refreshTooltip();
129
+ }, function (event) {
130
+ thisObj.overBody = false;
131
+ thisObj.overBodyMousePos = null;
132
+ thisObj.refreshTooltip();
133
+
134
+ if (!thisObj.overHead && thisObj.tracking && thisObj.trackDevice === 'mouse') {
135
+ thisObj.stopTracking(thisObj.pageXToPosition(event.pageX));
136
+ }
137
+ });
138
+
139
+ this.bodyDiv.mousemove(function (event) {
140
+ thisObj.overBodyMousePos = {
141
+ x: event.pageX,
142
+ y: event.pageY
143
+ };
144
+ if (thisObj.tracking && thisObj.trackDevice === 'mouse') {
145
+ thisObj.trackHeadAtPageX(event.pageX);
146
+ }
147
+ thisObj.refreshTooltip();
148
+ });
149
+
150
+ this.bodyDiv.mousedown(function (event) {
151
+ thisObj.startTracking('mouse', thisObj.pageXToPosition(event.pageX));
152
+ thisObj.trackHeadAtPageX(event.pageX);
153
+ if (!thisObj.seekHead.is(':focus')) {
154
+ thisObj.seekHead.focus();
155
+ }
156
+ event.preventDefault();
157
+ });
158
+
159
+ this.seekHead.mousedown(function (event) {
160
+ thisObj.startTracking('mouse', thisObj.pageXToPosition(thisObj.seekHead.offset() + (thisObj.seekHead.width() / 2)));
161
+ if (!thisObj.bodyDiv.is(':focus')) {
162
+ thisObj.bodyDiv.focus();
163
+ }
164
+ event.preventDefault();
165
+ });
166
+
167
+ this.bodyDiv.mouseup(function (event) {
168
+ if (thisObj.tracking && thisObj.trackDevice === 'mouse') {
169
+ thisObj.stopTracking(thisObj.pageXToPosition(event.pageX));
170
+ }
171
+ })
172
+
173
+ this.seekHead.mouseup(function (event) {
174
+ if (thisObj.tracking && thisObj.trackDevice === 'mouse') {
175
+ thisObj.stopTracking(thisObj.pageXToPosition(event.pageX));
176
+ }
177
+ });
178
+
179
+ this.bodyDiv.keydown(function (event) {
180
+ // Home
181
+ if (event.which === 36) {
182
+ thisObj.trackImmediatelyTo(0);
183
+ }
184
+ // End
185
+ else if (event.which === 35) {
186
+ thisObj.trackImmediatelyTo(thisObj.duration);
187
+ }
188
+ // Left arrow or down arrow
189
+ else if (event.which === 37 || event.which === 40) {
190
+ thisObj.arrowKeyDown(-1);
191
+ }
192
+ // Right arrow or up arrow
193
+ else if (event.which === 39 || event.which === 38) {
194
+ thisObj.arrowKeyDown(1);
195
+ }
196
+ // Page up
197
+ else if (event.which === 33 && bigInterval > 0) {
198
+ thisObj.arrowKeyDown(bigInterval);
199
+ }
200
+ // Page down
201
+ else if (event.which === 34 && bigInterval > 0) {
202
+ thisObj.arrowKeyDown(-bigInterval);
203
+ }
204
+
205
+ else {
206
+ return;
207
+ }
208
+ event.preventDefault();
209
+ });
210
+
211
+ this.bodyDiv.keyup(function (event) {
212
+ if (event.which >= 33 && event.which <= 40) {
213
+ if (thisObj.tracking && thisObj.trackDevice === 'keyboard') {
214
+ thisObj.stopTracking(thisObj.keyTrackPosition);
215
+ }
216
+ event.preventDefault();
217
+ }
218
+ });
219
+ }
220
+
221
+ AccessibleSlider.prototype.arrowKeyDown = function (multiplier) {
222
+ if (this.tracking && this.trackDevice === 'keyboard') {
223
+ this.keyTrackPosition = this.boundPos(this.keyTrackPosition + (this.nextStep * multiplier));
224
+ this.inertiaCount += 1;
225
+ if (this.inertiaCount === 20) {
226
+ this.inertiaCount = 0;
227
+ this.nextStep *= 2;
228
+ }
229
+ this.trackHeadAtPosition(this.keyTrackPosition);
230
+ }
231
+ else {
232
+ this.nextStep = 1;
233
+ this.inertiaCount = 0;
234
+ this.keyTrackPosition = this.boundPos(this.position + (this.nextStep * multiplier));
235
+ this.startTracking('keyboard', this.keyTrackPosition);
236
+ this.trackHeadAtPosition(this.keyTrackPosition);
237
+ }
238
+ };
239
+ /*
240
+ AccessibleSlider.prototype.pageUp = function (multiplier) {
241
+ if (this.tracking && this.trackDevice === 'keyboard') {
242
+ this.keyTrackPosition = this.boundPos(this.keyTrackPosition + (this.nextStep * multiplier));
243
+ this.inertiaCount += 1;
244
+ if (this.inertiaCount === 20) {
245
+ this.inertiaCount = 0;
246
+ this.nextStep *= 2;
247
+ }
248
+ this.trackHeadAtPosition(this.keyTrackPosition);
249
+ }
250
+ else {
251
+ this.nextStep = 1;
252
+ this.inertiaCount = 0;
253
+ this.keyTrackPosition = this.boundPos(this.position + (this.nextStep * multiplier));
254
+ this.startTracking('keyboard', this.keyTrackPosition);
255
+ this.trackHeadAtPosition(this.keyTrackPosition);
256
+ }
257
+ };
258
+ */
259
+ AccessibleSlider.prototype.pageXToPosition = function (pageX) {
260
+ var offset = pageX - this.bodyDiv.offset().left;
261
+ var position = this.duration * (offset / this.bodyDiv.width());
262
+ return this.boundPos(position);
263
+ };
264
+
265
+ AccessibleSlider.prototype.boundPos = function (position) {
266
+ return Math.max(0, Math.min(position, this.duration));
267
+ }
268
+
269
+ AccessibleSlider.prototype.setDuration = function (duration) {
270
+ if (duration !== this.duration) {
271
+ this.duration = duration;
272
+ this.resetHeadLocation();
273
+ this.seekHead.attr('aria-valuemax', duration);
274
+ }
275
+ };
276
+
277
+ AccessibleSlider.prototype.setWidth = function (width) {
278
+ this.wrapperDiv.width(width);
279
+ this.resizeDivs();
280
+ this.resetHeadLocation();
281
+ };
282
+
283
+ AccessibleSlider.prototype.getWidth = function () {
284
+ return this.wrapperDiv.width();
285
+ };
286
+
287
+ AccessibleSlider.prototype.resizeDivs = function () {
288
+ this.playedDiv.width(this.bodyDiv.width() * (this.position / this.duration));
289
+ this.loadedDiv.width(this.bodyDiv.width() * this.buffered);
290
+ };
291
+
292
+ // Stops tracking, sets the head location to the current position.
293
+ AccessibleSlider.prototype.resetHeadLocation = function () {
294
+ var ratio = this.position / this.duration;
295
+ var center = this.bodyDiv.width() * ratio;
296
+ this.seekHead.css('left', center - (this.seekHead.width() / 2));
297
+
298
+ if (this.tracking) {
299
+ this.stopTracking(this.position);
300
+ }
301
+ };
302
+
303
+ AccessibleSlider.prototype.setPosition = function (position, updateLive) {
304
+ this.position = position;
305
+ this.resetHeadLocation();
306
+ this.refreshTooltip();
307
+ this.resizeDivs();
308
+ this.updateAriaValues(position, updateLive);
309
+ }
310
+
311
+ // TODO: Native HTML5 can have several buffered segments, and this actually happens quite often. Change this to display them all.
312
+ AccessibleSlider.prototype.setBuffered = function (ratio) {
313
+ this.buffered = ratio;
314
+ this.redrawDivs;
315
+ }
316
+
317
+ AccessibleSlider.prototype.startTracking = function (device, position) {
318
+ if (!this.tracking) {
319
+ this.trackDevice = device;
320
+ this.tracking = true;
321
+ this.bodyDiv.trigger('startTracking', [position]);
322
+ }
323
+ };
324
+
325
+ AccessibleSlider.prototype.stopTracking = function (position) {
326
+ this.trackDevice = null;
327
+ this.tracking = false;
328
+ this.bodyDiv.trigger('stopTracking', [position]);
329
+ this.setPosition(position, true);
330
+ };
331
+
332
+ AccessibleSlider.prototype.trackHeadAtPageX = function (pageX) {
333
+ var position = this.pageXToPosition(pageX);
334
+ var newLeft = pageX - this.bodyDiv.offset().left - (this.seekHead.width() / 2);
335
+ newLeft = Math.max(0, Math.min(newLeft, this.bodyDiv.width() - this.seekHead.width()));
336
+ this.lastTrackPosition = position;
337
+ this.seekHead.css('left', newLeft);
338
+ this.reportTrackAtPosition(position);
339
+ };
340
+
341
+ AccessibleSlider.prototype.trackHeadAtPosition = function (position) {
342
+ var ratio = position / this.duration;
343
+ var center = this.bodyDiv.width() * ratio;
344
+ this.lastTrackPosition = position;
345
+ this.seekHead.css('left', center - (this.seekHead.width() / 2));
346
+ this.reportTrackAtPosition(position);
347
+ };
348
+
349
+ AccessibleSlider.prototype.reportTrackAtPosition = function (position) {
350
+ this.bodyDiv.trigger('tracking', [position]);
351
+ this.updateAriaValues(position, true);
352
+ };
353
+
354
+ AccessibleSlider.prototype.updateAriaValues = function (position, updateLive) {
355
+ // TODO: Localize, move to another function.
356
+ var pHours = Math.floor(position / 3600);
357
+ var pMinutes = Math.floor((position % 3600) / 60);
358
+ var pSeconds = Math.floor(position % 60);
359
+
360
+ var pHourWord = pHours === 1 ? 'hour' : 'hours';
361
+ var pMinuteWord = pMinutes === 1 ? 'minute' : 'minutes';
362
+ var pSecondWord = pSeconds === 1 ? 'second' : 'seconds';
363
+
364
+ var descriptionText;
365
+ if (pHours > 0) {
366
+ descriptionText = pHours +
367
+ ' ' + pHourWord +
368
+ ', ' + pMinutes +
369
+ ' ' + pMinuteWord +
370
+ ', ' + pSeconds +
371
+ ' ' + pSecondWord;
372
+ }
373
+ else if (pMinutes > 0) {
374
+ descriptionText = pMinutes +
375
+ ' ' + pMinuteWord +
376
+ ', ' + pSeconds +
377
+ ' ' + pSecondWord;
378
+ }
379
+ else {
380
+ descriptionText = pSeconds + ' ' + pSecondWord;
381
+ }
382
+
383
+ /* Comment to stop live region from generating or being used. */
384
+ if (!this.liveAriaRegion) {
385
+ this.liveAriaRegion = $('<span>', {
386
+ 'class': 'able-offscreen',
387
+ 'aria-live': 'polite'
388
+ });
389
+ this.wrapperDiv.append(this.liveAriaRegion);
390
+ }
391
+ if (updateLive && (this.liveAriaRegion.text() !== descriptionText)) {
392
+ this.liveAriaRegion.text(descriptionText);
393
+ }
394
+
395
+ // Uncomment the following lines to use aria values instead of separate live region.
396
+ this.seekHead.attr('aria-valuetext', descriptionText);
397
+ this.seekHead.attr('aria-valuenow', Math.floor(position).toString());
398
+ };
399
+
400
+ AccessibleSlider.prototype.trackImmediatelyTo = function (position) {
401
+ this.startTracking('keyboard', position);
402
+ this.trackHeadAtPosition(position);
403
+ this.keyTrackPosition = position;
404
+ };
405
+
406
+ AccessibleSlider.prototype.refreshTooltip = function () {
407
+ if (this.overHead) {
408
+ this.timeTooltip.show();
409
+ if (this.tracking) {
410
+ this.timeTooltip.text(this.positionToStr(this.lastTrackPosition));
411
+ }
412
+ else {
413
+ this.timeTooltip.text(this.positionToStr(this.position));
414
+ }
415
+ this.setTooltipPosition(this.seekHead.position().left + (this.seekHead.width() / 2));
416
+ }
417
+ else if (this.overBody && this.overBodyMousePos) {
418
+ this.timeTooltip.show();
419
+ this.timeTooltip.text(this.positionToStr(this.pageXToPosition(this.overBodyMousePos.x)));
420
+ this.setTooltipPosition(this.overBodyMousePos.x - this.bodyDiv.offset().left);
421
+ }
422
+ else {
423
+ this.timeTooltip.hide();
424
+ }
425
+ };
426
+
427
+ AccessibleSlider.prototype.setTooltipPosition = function (x) {
428
+ this.timeTooltip.css({
429
+ left: x - (this.timeTooltip.width() / 2) - 10,
430
+ bottom: this.seekHead.height() + 10
431
+ });
432
+ };
433
+
434
+ AccessibleSlider.prototype.positionToStr = function (seconds) {
435
+
436
+ // same logic as misc.js > formatSecondsAsColonTime()
437
+ var dHours = Math.floor(seconds / 3600);
438
+ var dMinutes = Math.floor(seconds / 60) % 60;
439
+ var dSeconds = Math.floor(seconds % 60);
440
+ if (dSeconds < 10) {
441
+ dSeconds = '0' + dSeconds;
442
+ }
443
+ if (dHours > 0) {
444
+ if (dMinutes < 10) {
445
+ dMinutes = '0' + dMinutes;
446
+ }
447
+ return dHours + ':' + dMinutes + ':' + dSeconds;
448
+ }
449
+ else {
450
+ return dMinutes + ':' + dSeconds;
451
+ }
452
+ };
453
+
454
+ })(jQuery);