webshims-rails 0.3 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. data/lib/webshims-rails.rb +1 -1
  2. data/lib/webshims-rails/version.rb +2 -2
  3. data/readme.textile +5 -3
  4. data/vendor/assets/javascripts/webshims/dev/extras/custom-validity.js +261 -0
  5. data/vendor/assets/javascripts/webshims/dev/extras/modernizr-custom.js +535 -0
  6. data/vendor/assets/javascripts/webshims/dev/extras/mousepress.js +60 -0
  7. data/vendor/assets/javascripts/webshims/dev/polyfiller.js +1171 -0
  8. data/vendor/assets/javascripts/webshims/dev/shims/FlashCanvas/README +62 -0
  9. data/vendor/assets/javascripts/webshims/dev/shims/FlashCanvas/canvas2png.js +42 -0
  10. data/vendor/assets/javascripts/webshims/dev/shims/FlashCanvas/flashcanvas.js +28 -0
  11. data/vendor/assets/javascripts/webshims/dev/shims/FlashCanvas/flashcanvas.swf +0 -0
  12. data/vendor/assets/javascripts/webshims/dev/shims/FlashCanvas/proxy.php +73 -0
  13. data/vendor/assets/javascripts/webshims/dev/shims/FlashCanvas/save.php +49 -0
  14. data/vendor/assets/javascripts/webshims/dev/shims/FlashCanvasPro/README +82 -0
  15. data/vendor/assets/javascripts/webshims/dev/shims/FlashCanvasPro/canvas2png.js +42 -0
  16. data/vendor/assets/javascripts/webshims/dev/shims/FlashCanvasPro/flash10canvas.swf +0 -0
  17. data/vendor/assets/javascripts/webshims/dev/shims/FlashCanvasPro/flash9canvas.swf +0 -0
  18. data/vendor/assets/javascripts/webshims/dev/shims/FlashCanvasPro/flashcanvas.js +31 -0
  19. data/vendor/assets/javascripts/webshims/dev/shims/FlashCanvasPro/proxy.php +73 -0
  20. data/vendor/assets/javascripts/webshims/dev/shims/FlashCanvasPro/save.php +49 -0
  21. data/vendor/assets/javascripts/webshims/dev/shims/combos/1.js +1710 -0
  22. data/vendor/assets/javascripts/webshims/dev/shims/combos/10.js +3317 -0
  23. data/vendor/assets/javascripts/webshims/dev/shims/combos/11.js +1585 -0
  24. data/vendor/assets/javascripts/webshims/dev/shims/combos/12.js +1587 -0
  25. data/vendor/assets/javascripts/webshims/dev/shims/combos/13.js +1054 -0
  26. data/vendor/assets/javascripts/webshims/dev/shims/combos/14.js +476 -0
  27. data/vendor/assets/javascripts/webshims/dev/shims/combos/15.js +314 -0
  28. data/vendor/assets/javascripts/webshims/dev/shims/combos/16.js +2101 -0
  29. data/vendor/assets/javascripts/webshims/dev/shims/combos/17.js +2264 -0
  30. data/vendor/assets/javascripts/webshims/dev/shims/combos/18.js +2161 -0
  31. data/vendor/assets/javascripts/webshims/dev/shims/combos/19.js +2244 -0
  32. data/vendor/assets/javascripts/webshims/dev/shims/combos/2.js +2294 -0
  33. data/vendor/assets/javascripts/webshims/dev/shims/combos/20.js +1607 -0
  34. data/vendor/assets/javascripts/webshims/dev/shims/combos/21.js +1635 -0
  35. data/vendor/assets/javascripts/webshims/dev/shims/combos/22.js +2409 -0
  36. data/vendor/assets/javascripts/webshims/dev/shims/combos/23.js +2168 -0
  37. data/vendor/assets/javascripts/webshims/dev/shims/combos/24.js +2777 -0
  38. data/vendor/assets/javascripts/webshims/dev/shims/combos/25.js +2204 -0
  39. data/vendor/assets/javascripts/webshims/dev/shims/combos/26.js +2863 -0
  40. data/vendor/assets/javascripts/webshims/dev/shims/combos/27.js +4079 -0
  41. data/vendor/assets/javascripts/webshims/dev/shims/combos/3.js +2971 -0
  42. data/vendor/assets/javascripts/webshims/dev/shims/combos/4.js +823 -0
  43. data/vendor/assets/javascripts/webshims/dev/shims/combos/5.js +1078 -0
  44. data/vendor/assets/javascripts/webshims/dev/shims/combos/59.js +1754 -0
  45. data/vendor/assets/javascripts/webshims/dev/shims/combos/6.js +1230 -0
  46. data/vendor/assets/javascripts/webshims/dev/shims/combos/7.js +1485 -0
  47. data/vendor/assets/javascripts/webshims/dev/shims/combos/8.js +1442 -0
  48. data/vendor/assets/javascripts/webshims/dev/shims/combos/9.js +2515 -0
  49. data/vendor/assets/javascripts/webshims/dev/shims/details.js +146 -0
  50. data/vendor/assets/javascripts/webshims/dev/shims/dom-extend.js +908 -0
  51. data/vendor/assets/javascripts/webshims/dev/shims/es5.js +802 -0
  52. data/vendor/assets/javascripts/webshims/dev/shims/excanvas.js +924 -0
  53. data/vendor/assets/javascripts/webshims/dev/shims/form-core.js +660 -0
  54. data/vendor/assets/javascripts/webshims/dev/shims/form-datalist.js +677 -0
  55. data/vendor/assets/javascripts/webshims/dev/shims/form-message.js +164 -0
  56. data/vendor/assets/javascripts/webshims/dev/shims/form-native-extend.js +256 -0
  57. data/vendor/assets/javascripts/webshims/dev/shims/form-native-fix.js +261 -0
  58. data/vendor/assets/javascripts/webshims/dev/shims/form-number-date-api.js +384 -0
  59. data/vendor/assets/javascripts/webshims/dev/shims/form-number-date-ui.js +847 -0
  60. data/vendor/assets/javascripts/webshims/dev/shims/form-shim-extend.js +1472 -0
  61. data/vendor/assets/javascripts/webshims/dev/shims/geolocation.js +168 -0
  62. data/vendor/assets/javascripts/webshims/dev/shims/i18n/errormessages-ar.js +32 -0
  63. data/vendor/assets/javascripts/webshims/dev/shims/i18n/errormessages-ch-ZN.js +32 -0
  64. data/vendor/assets/javascripts/webshims/dev/shims/i18n/errormessages-de.txt +33 -0
  65. data/vendor/assets/javascripts/webshims/dev/shims/i18n/errormessages-el.js +32 -0
  66. data/vendor/assets/javascripts/webshims/dev/shims/i18n/errormessages-en.txt +34 -0
  67. data/vendor/assets/javascripts/webshims/dev/shims/i18n/errormessages-es.js +32 -0
  68. data/vendor/assets/javascripts/webshims/dev/shims/i18n/errormessages-fr.js +32 -0
  69. data/vendor/assets/javascripts/webshims/dev/shims/i18n/errormessages-he.js +32 -0
  70. data/vendor/assets/javascripts/webshims/dev/shims/i18n/errormessages-hi.js +32 -0
  71. data/vendor/assets/javascripts/webshims/dev/shims/i18n/errormessages-hu.js +32 -0
  72. data/vendor/assets/javascripts/webshims/dev/shims/i18n/errormessages-it.js +32 -0
  73. data/vendor/assets/javascripts/webshims/dev/shims/i18n/errormessages-ja.js +32 -0
  74. data/vendor/assets/javascripts/webshims/dev/shims/i18n/errormessages-nl.js +32 -0
  75. data/vendor/assets/javascripts/webshims/dev/shims/i18n/errormessages-pt-PT.js +32 -0
  76. data/vendor/assets/javascripts/webshims/dev/shims/i18n/errormessages-ru.js +32 -0
  77. data/vendor/assets/javascripts/webshims/dev/shims/i18n/errormessages-sv.js +32 -0
  78. data/vendor/assets/javascripts/webshims/dev/shims/json-storage.js +308 -0
  79. data/vendor/assets/javascripts/webshims/dev/shims/jwplayer/license.txt +1 -0
  80. data/vendor/assets/javascripts/webshims/dev/shims/jwplayer/player.swf +0 -0
  81. data/vendor/assets/javascripts/webshims/dev/shims/jwplayer/readme.html +87 -0
  82. data/vendor/assets/javascripts/webshims/dev/shims/mediaelement-core.js +534 -0
  83. data/vendor/assets/javascripts/webshims/dev/shims/mediaelement-native-fix.js +99 -0
  84. data/vendor/assets/javascripts/webshims/dev/shims/mediaelement-swf.js +1074 -0
  85. data/vendor/assets/javascripts/webshims/dev/shims/mediaelement-yt.js +543 -0
  86. data/vendor/assets/javascripts/webshims/dev/shims/styles/details-arrows.png +0 -0
  87. data/vendor/assets/javascripts/webshims/dev/shims/styles/forms.png +0 -0
  88. data/vendor/assets/javascripts/webshims/dev/shims/styles/polyfill-loader.gif +0 -0
  89. data/vendor/assets/javascripts/webshims/dev/shims/styles/shim.css +677 -0
  90. data/vendor/assets/javascripts/webshims/dev/shims/swf/jwwebshims.swf +0 -0
  91. data/vendor/assets/javascripts/webshims/dev/shims/swf/localStorage.swf +0 -0
  92. data/vendor/assets/javascripts/webshims/dev/shims/track-ui.js +292 -0
  93. data/vendor/assets/javascripts/webshims/dev/shims/track.js +763 -0
  94. data/vendor/assets/javascripts/webshims/minified/extras/modernizr-custom.js +20 -20
  95. data/vendor/assets/javascripts/webshims/minified/polyfiller.js +29 -29
  96. data/vendor/assets/javascripts/webshims/minified/shims/combos/1.js +37 -33
  97. data/vendor/assets/javascripts/webshims/minified/shims/combos/10.js +83 -76
  98. data/vendor/assets/javascripts/webshims/minified/shims/combos/11.js +44 -42
  99. data/vendor/assets/javascripts/webshims/minified/shims/combos/12.js +43 -38
  100. data/vendor/assets/javascripts/webshims/minified/shims/combos/13.js +27 -25
  101. data/vendor/assets/javascripts/webshims/minified/shims/combos/16.js +60 -55
  102. data/vendor/assets/javascripts/webshims/minified/shims/combos/17.js +68 -64
  103. data/vendor/assets/javascripts/webshims/minified/shims/combos/18.js +60 -59
  104. data/vendor/assets/javascripts/webshims/minified/shims/combos/19.js +66 -64
  105. data/vendor/assets/javascripts/webshims/minified/shims/combos/2.js +74 -69
  106. data/vendor/assets/javascripts/webshims/minified/shims/combos/20.js +46 -43
  107. data/vendor/assets/javascripts/webshims/minified/shims/combos/21.js +52 -47
  108. data/vendor/assets/javascripts/webshims/minified/shims/combos/22.js +61 -57
  109. data/vendor/assets/javascripts/webshims/minified/shims/combos/23.js +68 -60
  110. data/vendor/assets/javascripts/webshims/minified/shims/combos/24.js +82 -77
  111. data/vendor/assets/javascripts/webshims/minified/shims/combos/25.js +58 -0
  112. data/vendor/assets/javascripts/webshims/minified/shims/combos/26.js +80 -0
  113. data/vendor/assets/javascripts/webshims/minified/shims/combos/27.js +103 -0
  114. data/vendor/assets/javascripts/webshims/minified/shims/combos/3.js +96 -91
  115. data/vendor/assets/javascripts/webshims/minified/shims/combos/4.js +30 -31
  116. data/vendor/assets/javascripts/webshims/minified/shims/combos/5.js +37 -39
  117. data/vendor/assets/javascripts/webshims/minified/shims/combos/59.js +59 -61
  118. data/vendor/assets/javascripts/webshims/minified/shims/combos/6.js +31 -29
  119. data/vendor/assets/javascripts/webshims/minified/shims/combos/7.js +38 -37
  120. data/vendor/assets/javascripts/webshims/minified/shims/combos/8.js +38 -33
  121. data/vendor/assets/javascripts/webshims/minified/shims/combos/9.js +68 -63
  122. data/vendor/assets/javascripts/webshims/minified/shims/dom-extend.js +22 -20
  123. data/vendor/assets/javascripts/webshims/minified/shims/es5.js +15 -14
  124. data/vendor/assets/javascripts/webshims/minified/shims/form-core.js +22 -22
  125. data/vendor/assets/javascripts/webshims/minified/shims/form-datalist.js +22 -22
  126. data/vendor/assets/javascripts/webshims/minified/shims/form-message.js +8 -9
  127. data/vendor/assets/javascripts/webshims/minified/shims/form-native-extend.js +7 -8
  128. data/vendor/assets/javascripts/webshims/minified/shims/form-number-date-ui.js +23 -21
  129. data/vendor/assets/javascripts/webshims/minified/shims/form-shim-extend.js +44 -33
  130. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-sv.js +3 -0
  131. data/vendor/assets/javascripts/webshims/minified/shims/jwplayer/player.swf +0 -0
  132. data/vendor/assets/javascripts/webshims/minified/shims/jwplayer/readme.html +86 -86
  133. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-core.js +16 -13
  134. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-swf.js +30 -30
  135. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-yt.js +14 -0
  136. data/vendor/assets/javascripts/webshims/minified/shims/styles/shim.css +71 -10
  137. data/vendor/assets/javascripts/webshims/minified/shims/track-ui.js +9 -0
  138. data/vendor/assets/javascripts/webshims/minified/shims/track.js +20 -0
  139. metadata +101 -5
  140. data/vendor/assets/javascripts/webshims/minified/shims/form-output.js +0 -5
@@ -0,0 +1,292 @@
1
+ jQuery.webshims.register('track-ui', function($, webshims, window, document, undefined){
2
+ var options = webshims.cfg.track;
3
+ var enterE = {type: 'enter'};
4
+ var exitE = {type: 'exit'};
5
+ var showTracks = {subtitles: 1, captions: 1};
6
+ var mediaelement = webshims.mediaelement;
7
+ var usesNativeTrack = function(){
8
+ return !options.override && Modernizr.track;
9
+ };
10
+
11
+ var trackDisplay = {
12
+ update: function(baseData, media){
13
+ if(!baseData.activeCues.length){
14
+ this.hide(baseData);
15
+ } else {
16
+ if(!this.compareArray(baseData.displayedActiveCues, baseData.activeCues)){
17
+ baseData.displayedActiveCues = baseData.activeCues;
18
+ if(!baseData.trackDisplay){
19
+ baseData.trackDisplay = $('<div class="cue-display"></div>').insertAfter(media);
20
+ this.addEvents(baseData, media);
21
+ }
22
+
23
+ if(baseData.hasDirtyTrackDisplay){
24
+ media.triggerHandler('forceupdatetrackdisplay');
25
+ }
26
+ this.showCues(baseData);
27
+ }
28
+ }
29
+ },
30
+ showCues: function(baseData){
31
+ var element = $('<span class="cue-wrapper" />');
32
+ $.each(baseData.displayedActiveCues, function(i, cue){
33
+ var id = (cue.id) ? 'id="cue-id-'+cue.id +'"' : '';
34
+ element.append(
35
+ $('<span '+ id+ ' class="cue" />').html(cue.getCueAsHTML())
36
+ );
37
+ });
38
+ baseData.trackDisplay.html(element);
39
+ },
40
+ compareArray: function(a1, a2){
41
+ var ret = true;
42
+ var i = 0;
43
+ var len = a1.length;
44
+ if(len != a2.length){
45
+ ret = false;
46
+ } else {
47
+ for(; i < len; i++){
48
+ if(a1[i] != a2[i]){
49
+ ret = false;
50
+ break;
51
+ }
52
+ }
53
+ }
54
+ return ret;
55
+ },
56
+ addEvents: function(baseData, media){
57
+ if(options.positionDisplay){
58
+ var timer;
59
+ var positionDisplay = function(_force){
60
+ if(baseData.displayedActiveCues.length || _force === true){
61
+ baseData.trackDisplay.css({display: 'none'});
62
+ var uiElement = media.getShadowElement();
63
+ var offsetElement = uiElement.offsetParent();
64
+ var uiHeight = uiElement.innerHeight();
65
+ var uiWidth = uiElement.innerWidth();
66
+ var position = uiElement.position();
67
+ var displaySize = uiHeight * uiWidth;
68
+ baseData.trackDisplay.css({
69
+ left: position.left,
70
+ width: uiWidth,
71
+ height: uiHeight - 45,
72
+ top: position.top,
73
+ display: 'block'
74
+ });
75
+
76
+ baseData.trackDisplay.css('fontSize', Math.max(Math.round(uiHeight / 30), 7));
77
+ baseData.hasDirtyTrackDisplay = false;
78
+ } else {
79
+ baseData.hasDirtyTrackDisplay = true;
80
+ }
81
+ };
82
+ var delayed = function(e){
83
+ clearTimeout(timer);
84
+ timer = setTimeout(positionDisplay, 0);
85
+ };
86
+ var forceUpdate = function(){
87
+ positionDisplay(true);
88
+ };
89
+ media.bind('updateshadowdom playerdimensionchange mediaelementapichange updatetrackdisplay updatemediaelementdimensions swfstageresize', delayed);
90
+ media.bind('forceupdatetrackdisplay', forceUpdate);
91
+ forceUpdate();
92
+ }
93
+ },
94
+ hide: function(baseData){
95
+ if(baseData.trackDisplay && baseData.displayedActiveCues.length){
96
+ baseData.displayedActiveCues = [];
97
+ baseData.trackDisplay.empty();
98
+ }
99
+ }
100
+ };
101
+
102
+ $.extend($.event.customEvent, {
103
+ updatetrackdisplay: true,
104
+ forceupdatetrackdisplay: true
105
+ });
106
+
107
+ mediaelement.trackDisplay = trackDisplay;
108
+
109
+ if(!mediaelement.createCueList){
110
+
111
+ var cueListProto = {
112
+ getCueById: function(id){
113
+ var cue = null;
114
+ for(var i = 0, len = this.length; i < len; i++){
115
+ if(this[i].id === id){
116
+ cue = this[i];
117
+ break;
118
+ }
119
+ }
120
+ return cue;
121
+ }
122
+ };
123
+
124
+ mediaelement.createCueList = function(){
125
+ return $.extend([], cueListProto);
126
+ };
127
+ }
128
+
129
+ mediaelement.getActiveCue = function(track, media, time, baseData){
130
+ if(!track._lastFoundCue){
131
+ track._lastFoundCue = {index: 0, time: 0};
132
+ }
133
+
134
+ if(Modernizr.track && !options.override && !track._shimActiveCues){
135
+ track._shimActiveCues = mediaelement.createCueList();
136
+ }
137
+
138
+ var i = 0;
139
+ var len;
140
+ var cue;
141
+
142
+ for(; i < track.shimActiveCues.length; i++){
143
+ cue = track.shimActiveCues[i];
144
+ if(cue.startTime > time || cue.endTime < time){
145
+ track.shimActiveCues.splice(i, 1);
146
+ i--;
147
+ if(cue.pauseOnExit){
148
+ $(media).pause();
149
+ }
150
+ $(track).triggerHandler('cuechange');
151
+ $(cue).triggerHandler('exit');
152
+ } else if(track.mode == 'showing' && showTracks[track.kind] && $.inArray(cue, baseData.activeCues) == -1){
153
+ baseData.activeCues.push(cue);
154
+ }
155
+ }
156
+
157
+
158
+ len = track.cues.length;
159
+ i = track._lastFoundCue.time < time ? track._lastFoundCue.index : 0;
160
+
161
+ for(; i < len; i++){
162
+ cue = track.cues[i];
163
+
164
+ if(cue.startTime <= time && cue.endTime >= time && $.inArray(cue, track.shimActiveCues) == -1){
165
+ track.shimActiveCues.push(cue);
166
+ if(track.mode == 'showing' && showTracks[track.kind]){
167
+ baseData.activeCues.push(cue);
168
+ }
169
+ $(track).triggerHandler('cuechange');
170
+ $(cue).triggerHandler('enter');
171
+
172
+ track._lastFoundCue.time = time;
173
+ track._lastFoundCue.index = i;
174
+
175
+
176
+ }
177
+ if(cue.startTime > time){
178
+ break;
179
+ }
180
+ }
181
+ };
182
+
183
+ if(usesNativeTrack()){
184
+ (function(){
185
+ var block;
186
+ var triggerDisplayUpdate = function(elem){
187
+ if(!block){
188
+ setTimeout(function(){
189
+ block = true;
190
+ $(elem).triggerHandler('updatetrackdisplay');
191
+ block = false;
192
+ }, 9);
193
+ }
194
+ };
195
+ var trackDesc = webshims.defineNodeNameProperty('track', 'track', {
196
+ prop: {
197
+ get: function(){
198
+ triggerDisplayUpdate($(this).parent('audio, video'));
199
+ return trackDesc.prop._supget.apply(this, arguments);
200
+ }
201
+ }
202
+
203
+ });
204
+ ['audio', 'video'].forEach(function(nodeName){
205
+ var addTrack, textTracks;
206
+ textTracks = webshims.defineNodeNameProperty(nodeName, 'textTracks', {
207
+ prop: {
208
+ get: function(){
209
+ triggerDisplayUpdate(this);
210
+ return textTracks.prop._supget.apply(this, arguments);
211
+ }
212
+ }
213
+ });
214
+
215
+ addTrack = webshims.defineNodeNameProperty(nodeName, 'addTextTrack', {
216
+ prop: {
217
+ value: function(){
218
+ triggerDisplayUpdate(this);
219
+ return addTrack.prop._supvalue.apply(this, arguments);
220
+ }
221
+ }
222
+ });
223
+ });
224
+ })();
225
+ }
226
+
227
+ webshims.addReady(function(context, insertedElement){
228
+ $('video, audio', context)
229
+ .add(insertedElement.filter('video, audio'))
230
+ .each(function(){
231
+ var trackList;
232
+ var elem = $(this);
233
+ var baseData;
234
+ var addTrackView = function(){
235
+
236
+ elem
237
+ .unbind('.trackview')
238
+ .bind('play.trackview timeupdate.trackview updatetrackdisplay.trackview', function(e){
239
+ var track;
240
+ var time;
241
+
242
+ if(!trackList || !baseData){
243
+ trackList = elem.prop('textTracks');
244
+ baseData = webshims.data(elem[0], 'mediaelementBase') || webshims.data(elem[0], 'mediaelementBase', {});
245
+ if(!baseData.displayedActiveCues){
246
+ baseData.displayedActiveCues = [];
247
+ }
248
+ }
249
+
250
+ if (!trackList){return;}
251
+ time = elem.prop('currentTime');
252
+
253
+ if(!time && time !== 0){return;}
254
+ baseData.activeCues = [];
255
+ for(var i = 0, len = trackList.length; i < len; i++){
256
+ track = trackList[i];
257
+ if(track.mode != 'disabled' && track.cues && track.cues.length){
258
+ mediaelement.getActiveCue(track, elem, time, baseData);
259
+
260
+ }
261
+ }
262
+
263
+ trackDisplay.update(baseData, elem);
264
+
265
+ })
266
+ ;
267
+ };
268
+ if(!usesNativeTrack()){
269
+ addTrackView();
270
+ } else {
271
+ elem.bind('mediaelementapichange trackapichange', function(){
272
+ if(!usesNativeTrack() || elem.is('.nonnative-api-active')){
273
+ addTrackView();
274
+ } else {
275
+ trackList = elem.prop('textTracks');
276
+ baseData = webshims.data(elem[0], 'mediaelementBase') || webshims.data(elem[0], 'mediaelementBase', {});
277
+
278
+ $.each(trackList, function(i, track){
279
+
280
+ if(track._shimActiveCues){
281
+ delete track._shimActiveCues;
282
+ }
283
+ });
284
+ trackDisplay.hide(baseData);
285
+ elem.unbind('.trackview');
286
+ }
287
+ });
288
+ }
289
+ })
290
+ ;
291
+ });
292
+ });
@@ -0,0 +1,763 @@
1
+ jQuery.webshims.register('track', function($, webshims, window, document, undefined){
2
+ var mediaelement = webshims.mediaelement;
3
+ var id = new Date().getTime();
4
+ var showTracks = {subtitles: 1, captions: 1};
5
+ var notImplemented = function(){
6
+ webshims.error('not implemented yet');
7
+ };
8
+
9
+ var createEventTarget = function(obj){
10
+ var eventList = {};
11
+ obj.addEventListener = function(name, fn){
12
+ if(eventList[name]){
13
+ webshims.error('always use $.bind to the shimed event: '+ name +' already bound fn was: '+ eventList[name] +' your fn was: '+ fn);
14
+ }
15
+ eventList[name] = fn;
16
+
17
+ };
18
+ obj.removeEventListener = function(name, fn){
19
+ if(eventList[name] && eventList[name] != fn){
20
+ webshims.error('always use $.bind/$.unbind to the shimed event: '+ name +' already bound fn was: '+ eventList[name] +' your fn was: '+ fn);
21
+ }
22
+ if(eventList[name]){
23
+ delete eventList[name];
24
+ }
25
+ };
26
+ return obj;
27
+ };
28
+
29
+
30
+ var cueListProto = {
31
+ getCueById: function(id){
32
+ var cue = null;
33
+ for(var i = 0, len = this.length; i < len; i++){
34
+ if(this[i].id === id){
35
+ cue = this[i];
36
+ break;
37
+ }
38
+ }
39
+ return cue;
40
+ }
41
+ };
42
+ var textTrackProto = {
43
+ shimActiveCues: null,
44
+ _shimActiveCues: null,
45
+ activeCues: null,
46
+ cues: null,
47
+ kind: 'subtitles',
48
+ label: '',
49
+ language: '',
50
+ mode: 'disabled',
51
+ readyState: 0,
52
+ oncuechange: null,
53
+ toString: function() {
54
+ return "[object TextTrack]";
55
+ },
56
+ addCue: function(cue){
57
+ if(!this.cues){
58
+ this.cues = mediaelement.createCueList();
59
+ } else {
60
+ var lastCue = this.cues[this.cues.length-1];
61
+ if(lastCue && lastCue.startTime > cue.startTime){
62
+ webshims.error("cue startTime higher than previous cue's startTime");
63
+ }
64
+ }
65
+ if(cue.track){
66
+ webshims.error("cue already part of a track element");
67
+ }
68
+ cue.track = this;
69
+ this.cues.push(cue);
70
+ },
71
+ removeCue: notImplemented,
72
+ DISABLED: 'disabled',
73
+ OFF: 'disabled',
74
+ HIDDEN: 'hidden',
75
+ SHOWING: 'showing',
76
+ ERROR: 3,
77
+ LOADED: 2,
78
+ LOADING: 1,
79
+ NONE: 0
80
+ };
81
+ var copyProps = ['kind', 'label', 'srclang'];
82
+
83
+ var owns = Function.prototype.call.bind(Object.prototype.hasOwnProperty);
84
+
85
+ //ToDo: add/remove event
86
+ var updateMediaTrackList = function(baseData, trackList){
87
+ var removed = [];
88
+ var added = [];
89
+ var newTracks = [];
90
+ var i, len;
91
+ if(!baseData){
92
+ baseData = webshims.data(this, 'mediaelementBase') || webshims.data(this, 'mediaelementBase', {});
93
+ }
94
+
95
+ if(!trackList){
96
+ baseData.blockTrackListUpdate = true;
97
+ trackList = $.prop(this, 'textTracks');
98
+ baseData.blockTrackListUpdate = false;
99
+ }
100
+
101
+ clearTimeout(baseData.updateTrackListTimer);
102
+
103
+ $('track', this).each(function(){
104
+ var track = $.prop(this, 'track');
105
+ newTracks.push(track);
106
+ if(trackList.indexOf(track) == -1){
107
+ added.push(track);
108
+ }
109
+ });
110
+
111
+ if(baseData.scriptedTextTracks){
112
+ for(i = 0, len = baseData.scriptedTextTracks.length; i < len; i++){
113
+ newTracks.push(baseData.scriptedTextTracks[i]);
114
+ if(trackList.indexOf(baseData.scriptedTextTracks[i]) == -1){
115
+ added.push(baseData.scriptedTextTracks[i]);
116
+ }
117
+ }
118
+ }
119
+
120
+ for(i = 0, len = trackList.length; i < len; i++){
121
+ if(newTracks.indexOf(trackList[i]) == -1){
122
+ removed.push(trackList[i]);
123
+ }
124
+ }
125
+
126
+ if(removed.length || added.length){
127
+ trackList.splice(0);
128
+
129
+ for(i = 0, len = newTracks.length; i < len; i++){
130
+ trackList.push(newTracks[i]);
131
+ }
132
+ for(i = 0, len = removed.length; i < len; i++){
133
+ $([trackList]).triggerHandler($.Event({type: 'removetrack', track: trackList, track: removed[i]}));
134
+ }
135
+ for(i = 0, len = added.length; i < len; i++){
136
+ $([trackList]).triggerHandler($.Event({type: 'addtrack', track: trackList, track: added[i]}));
137
+ }
138
+ if(baseData.scriptedTextTracks || removed.length){
139
+ $(this).triggerHandler('updatetrackdisplay');
140
+ }
141
+ }
142
+ };
143
+
144
+ var refreshTrack = function(track, trackData){
145
+ var mode, kind;
146
+ if(!trackData){
147
+ trackData = webshims.data(track, 'trackData');
148
+ }
149
+ if(trackData && !trackData.isTriggering){
150
+ trackData.isTriggering = true;
151
+ mode = (trackData.track || {}).mode;
152
+ kind = (trackData.track || {}).kind;
153
+ setTimeout(function(){
154
+ if(mode !== (trackData.track || {}).mode || kind != (trackData.track || {}).kind){
155
+ if(!(trackData.track || {}).readyState){
156
+ $(track).triggerHandler('checktrackmode');
157
+ } else {
158
+ $(track).parent().triggerHandler('updatetrackdisplay');
159
+ }
160
+ }
161
+ trackData.isTriggering = false;
162
+
163
+ }, 9);
164
+ }
165
+ };
166
+
167
+ var emptyDiv = $('<div />')[0];
168
+ window.TextTrackCue = function(startTime, endTime, text){
169
+ if(arguments.length != 3){
170
+ webshims.error("wrong arguments.length for TextTrackCue.constructor");
171
+ }
172
+
173
+ this.startTime = startTime;
174
+ this.endTime = endTime;
175
+ this.text = text;
176
+
177
+ this.id = "";
178
+ this.pauseOnExit = false;
179
+
180
+ createEventTarget(this);
181
+ };
182
+
183
+ window.TextTrackCue.prototype = {
184
+
185
+ onenter: null,
186
+ onexit: null,
187
+ pauseOnExit: false,
188
+ getCueAsHTML: function(){
189
+ var lastText = "";
190
+ var parsedText = "";
191
+ var fragment = document.createDocumentFragment();
192
+ var fn;
193
+ if(!owns(this, 'getCueAsHTML')){
194
+ fn = this.getCueAsHTML = function(){
195
+ var i, len;
196
+ if(lastText != this.text){
197
+ lastText = this.text;
198
+ parsedText = mediaelement.parseCueTextToHTML(lastText);
199
+ emptyDiv.innerHTML = parsedText;
200
+
201
+ for(i = 0, len = emptyDiv.childNodes.length; i < len; i++){
202
+ fragment.appendChild(emptyDiv.childNodes[i].cloneNode(true));
203
+ }
204
+ }
205
+ return fragment.cloneNode(true);
206
+ };
207
+
208
+ }
209
+ return fn ? fn.apply(this, arguments) : fragment.cloneNode(true);
210
+ },
211
+ track: null,
212
+
213
+
214
+ id: ''
215
+ //todo-->
216
+ // ,
217
+ // snapToLines: true,
218
+ // line: 'auto',
219
+ // size: 100,
220
+ // position: 50,
221
+ // vertical: '',
222
+ // align: 'middle'
223
+ };
224
+
225
+
226
+
227
+
228
+
229
+ mediaelement.createCueList = function(){
230
+ return $.extend([], cueListProto);
231
+ };
232
+
233
+ mediaelement.parseCueTextToHTML = (function(){
234
+ var tagSplits = /(<\/?[^>]+>)/ig;
235
+ var allowedTags = /^(?:c|v|ruby|rt|b|i|u)/;
236
+ var regEnd = /\<\s*\//;
237
+ var addToTemplate = function(localName, attribute, tag, html){
238
+ var ret;
239
+ if(regEnd.test(html)){
240
+ ret = '</'+ localName +'>';
241
+ } else {
242
+ tag.splice(0, 1);
243
+ ret = '<'+ localName +' '+ attribute +'="'+ (tag.join(' ').replace(/\"/g, '&#34;')) +'">';
244
+ }
245
+ return ret;
246
+ };
247
+ var replacer = function(html){
248
+ var tag = html.replace(/[<\/>]+/ig,"").split(/[\s\.]+/);
249
+ if(tag[0]){
250
+ tag[0] = tag[0].toLowerCase();
251
+ if(allowedTags.test(tag[0])){
252
+ if(tag[0] == 'c'){
253
+ html = addToTemplate('span', 'class', tag, html);
254
+ } else if(tag[0] == 'v'){
255
+ html = addToTemplate('q', 'title', tag, html);
256
+ }
257
+ } else {
258
+ html = "";
259
+ }
260
+ }
261
+ return html;
262
+ };
263
+
264
+ return function(cueText){
265
+ return cueText.replace(tagSplits, replacer);
266
+ };
267
+ })();
268
+
269
+ mediaelement.loadTextTrack = function(mediaelem, track, trackData, _default){
270
+ var loadEvents = 'play playing timeupdate updatetrackdisplay';
271
+ var obj = trackData.track;
272
+ var load = function(){
273
+ var src = $.prop(track, 'src');
274
+ var error;
275
+ var ajax;
276
+ if(obj.mode != 'disabled' && src && $.attr(track, 'src')){
277
+ $(mediaelem).unbind(loadEvents, load);
278
+ $(track).unbind('checktrackmode', load);
279
+ if(!obj.readyState){
280
+ error = function(){
281
+ obj.readyState = 3;
282
+ obj.cues = null;
283
+ obj.activeCues = obj.shimActiveCues = obj._shimActiveCues = null;
284
+ $(track).triggerHandler('error');
285
+ };
286
+ obj.readyState = 1;
287
+ try {
288
+ obj.cues = mediaelement.createCueList();
289
+ obj.activeCues = obj.shimActiveCues = obj._shimActiveCues = mediaelement.createCueList();
290
+ ajax = $.ajax({
291
+ dataType: 'text',
292
+ url: src,
293
+ success: function(text){
294
+ if(ajax.getResponseHeader('content-type') != 'text/vtt'){
295
+ webshims.error('set the mime-type of your WebVTT files to text/vtt. see: http://dev.w3.org/html5/webvtt/#text/vtt');
296
+ }
297
+ mediaelement.parseCaptions(text, obj, function(cues){
298
+ if(cues && 'length' in cues){
299
+ obj.readyState = 2;
300
+ $(track).triggerHandler('load');
301
+ $(mediaelem).triggerHandler('updatetrackdisplay');
302
+ } else {
303
+ error();
304
+ }
305
+ });
306
+
307
+ },
308
+ error: error
309
+ });
310
+ } catch(er){
311
+ error();
312
+ webshims.warn(er);
313
+ }
314
+ }
315
+ }
316
+ };
317
+ obj.readyState = 0;
318
+ obj.shimActiveCues = null;
319
+ obj._shimActiveCues = null;
320
+ obj.activeCues = null;
321
+ obj.cues = null;
322
+ $(mediaelem).unbind(loadEvents, load);
323
+ $(track).unbind('checktrackmode', load);
324
+ $(mediaelem).bind(loadEvents, load);
325
+ $(track).bind('checktrackmode', load);
326
+ if(_default){
327
+ obj.mode = showTracks[obj.kind] ? 'showing' : 'hidden';
328
+ load();
329
+ }
330
+ };
331
+
332
+ mediaelement.createTextTrack = function(mediaelem, track){
333
+ var obj, trackData;
334
+ if(track.nodeName){
335
+ trackData = webshims.data(track, 'trackData');
336
+
337
+ if(trackData){
338
+ refreshTrack(track, trackData);
339
+ obj = trackData.track;
340
+ }
341
+ }
342
+
343
+ if(!obj){
344
+ obj = createEventTarget(webshims.objectCreate(textTrackProto));
345
+ copyProps.forEach(function(copyProp){
346
+ var prop = $.prop(track, copyProp);
347
+ if(prop){
348
+ if(copyProp == 'srclang'){
349
+ copyProp = 'language';
350
+ }
351
+ obj[copyProp] = prop;
352
+ }
353
+ });
354
+
355
+
356
+ if(track.nodeName){
357
+ trackData = webshims.data(track, 'trackData', {track: obj});
358
+ mediaelement.loadTextTrack(mediaelem, track, trackData, $.prop(track, 'default'));
359
+ } else {
360
+ obj.cues = mediaelement.createCueList();
361
+ obj.activeCues = obj._shimActiveCues = obj.shimActiveCues = mediaelement.createCueList();
362
+ obj.mode = 'hidden';
363
+ obj.readyState = 2;
364
+ }
365
+ }
366
+ return obj;
367
+ };
368
+
369
+
370
+ /*
371
+ taken from:
372
+ Captionator 0.5.1 [CaptionCrunch]
373
+ Christopher Giffard, 2011
374
+ Share and enjoy
375
+
376
+ https://github.com/cgiffard/Captionator
377
+
378
+ modified for webshims
379
+ */
380
+ mediaelement.parseCaptionChunk = (function(){
381
+ // Set up timestamp parsers
382
+ var WebVTTTimestampParser = /^(\d{2})?:?(\d{2}):(\d{2})\.(\d+)\s+\-\-\>\s+(\d{2})?:?(\d{2}):(\d{2})\.(\d+)\s*(.*)/;
383
+ var GoogleTimestampParser = /^([\d\.]+)\s+\+([\d\.]+)\s*(.*)/;
384
+ var WebVTTDEFAULTSCueParser = /^(DEFAULTS|DEFAULT)\s+\-\-\>\s+(.*)/g;
385
+ var WebVTTSTYLECueParser = /^(STYLE|STYLES)\s+\-\-\>\s*\n([\s\S]*)/g;
386
+ var WebVTTCOMMENTCueParser = /^(COMMENT|COMMENTS)\s+\-\-\>\s+(.*)/g;
387
+
388
+ return function(subtitleElement,objectCount){
389
+ var cueDefaults = [];
390
+
391
+ var subtitleParts, timeIn, timeOut, html, timeData, subtitlePartIndex, cueSettings = "", id, specialCueData;
392
+ var timestampMatch, tmpCue;
393
+
394
+ // WebVTT Special Cue Logic
395
+ if ((specialCueData = WebVTTDEFAULTSCueParser.exec(subtitleElement))) {
396
+ // cueDefaults = specialCueData.slice(2).join("");
397
+ // cueDefaults = cueDefaults.split(/\s+/g).filter(function(def) { return def && !!def.length; });
398
+ return null;
399
+ } else if ((specialCueData = WebVTTSTYLECueParser.exec(subtitleElement))) {
400
+ return null;
401
+ } else if ((specialCueData = WebVTTCOMMENTCueParser.exec(subtitleElement))) {
402
+ return null; // At this stage, we don't want to do anything with these.
403
+ }
404
+
405
+ subtitleParts = subtitleElement.split(/\n/g);
406
+
407
+ // Trim off any blank lines (logically, should only be max. one, but loop to be sure)
408
+ while (!subtitleParts[0].replace(/\s+/ig,"").length && subtitleParts.length > 0) {
409
+ subtitleParts.shift();
410
+ }
411
+
412
+ if (subtitleParts[0].match(/^\s*[a-z0-9]+\s*$/ig)) {
413
+ // The identifier becomes the cue ID (when *we* load the cues from file. Programatically created cues can have an ID of whatever.)
414
+ id = String(subtitleParts.shift().replace(/\s*/ig,""));
415
+ }
416
+
417
+ for (subtitlePartIndex = 0; subtitlePartIndex < subtitleParts.length; subtitlePartIndex ++) {
418
+ var timestamp = subtitleParts[subtitlePartIndex];
419
+
420
+ if ((timestampMatch = WebVTTTimestampParser.exec(timestamp))) {
421
+
422
+ // WebVTT
423
+
424
+ timeData = timestampMatch.slice(1);
425
+
426
+ timeIn = parseInt((timeData[0]||0) * 60 * 60,10) + // Hours
427
+ parseInt((timeData[1]||0) * 60,10) + // Minutes
428
+ parseInt((timeData[2]||0),10) + // Seconds
429
+ parseFloat("0." + (timeData[3]||0)); // MS
430
+
431
+ timeOut = parseInt((timeData[4]||0) * 60 * 60,10) + // Hours
432
+ parseInt((timeData[5]||0) * 60,10) + // Minutes
433
+ parseInt((timeData[6]||0),10) + // Seconds
434
+ parseFloat("0." + (timeData[7]||0)); // MS
435
+ /*
436
+ if (timeData[8]) {
437
+ cueSettings = timeData[8];
438
+ }
439
+ */
440
+ }
441
+
442
+ // We've got the timestamp - return all the other unmatched lines as the raw subtitle data
443
+ subtitleParts = subtitleParts.slice(0,subtitlePartIndex).concat(subtitleParts.slice(subtitlePartIndex+1));
444
+ break;
445
+ }
446
+
447
+ if (!timeIn && !timeOut) {
448
+ // We didn't extract any time information. Assume the cue is invalid!
449
+ return null;
450
+ }
451
+ /*
452
+ // Consolidate cue settings, convert defaults to object
453
+ var compositeCueSettings =
454
+ cueDefaults
455
+ .reduce(function(previous,current,index,array){
456
+ previous[current.split(":")[0]] = current.split(":")[1];
457
+ return previous;
458
+ },{});
459
+
460
+ // Loop through cue settings, replace defaults with cue specific settings if they exist
461
+ compositeCueSettings =
462
+ cueSettings
463
+ .split(/\s+/g)
464
+ .filter(function(set) { return set && !!set.length; })
465
+ // Convert array to a key/val object
466
+ .reduce(function(previous,current,index,array){
467
+ previous[current.split(":")[0]] = current.split(":")[1];
468
+ return previous;
469
+ },compositeCueSettings);
470
+
471
+ // Turn back into string like the TextTrackCue constructor expects
472
+ cueSettings = "";
473
+ for (var key in compositeCueSettings) {
474
+ if (compositeCueSettings.hasOwnProperty(key)) {
475
+ cueSettings += !!cueSettings.length ? " " : "";
476
+ cueSettings += key + ":" + compositeCueSettings[key];
477
+ }
478
+ }
479
+ */
480
+ // The remaining lines are the subtitle payload itself (after removing an ID if present, and the time);
481
+ html = subtitleParts.join("\n");
482
+ tmpCue = new TextTrackCue(timeIn, timeOut, html);
483
+ if(id){
484
+ tmpCue.id = id;
485
+ }
486
+ return tmpCue;
487
+ };
488
+ })();
489
+
490
+ mediaelement.parseCaptions = function(captionData, track, complete) {
491
+ var subtitles = mediaelement.createCueList();
492
+ var cue, lazyProcess, regWevVTT;
493
+ var startDate;
494
+ var isWEBVTT;
495
+ if (captionData) {
496
+
497
+ regWevVTT = /^WEBVTT(\s*FILE)?/ig;
498
+
499
+ lazyProcess = function(i, len){
500
+
501
+ for(; i < len; i++){
502
+ cue = captionData[i];
503
+ if(regWevVTT.test(cue)){
504
+ isWEBVTT = true;
505
+ } else if(cue.replace(/\s*/ig,"").length){
506
+ if(!isWEBVTT){
507
+ webshims.error('please use WebVTT format. This is the standard');
508
+ complete(null);
509
+ break;
510
+ }
511
+ cue = mediaelement.parseCaptionChunk(cue, i);
512
+ if(cue){
513
+ track.addCue(cue);
514
+ }
515
+ }
516
+ if(startDate < (new Date().getTime()) - 9){
517
+ i++;
518
+ setTimeout(function(){
519
+ startDate = new Date().getTime();
520
+ lazyProcess(i, len);
521
+ }, 90);
522
+
523
+ break;
524
+ }
525
+ }
526
+ if(i >= len){
527
+ if(!isWEBVTT){
528
+ webshims.error('please use WebVTT format. This is the standard');
529
+ }
530
+ complete(track.cues);
531
+ }
532
+ };
533
+
534
+ captionData = captionData.replace(/\r\n/g,"\n");
535
+
536
+ setTimeout(function(){
537
+ captionData = captionData.replace(/\r/g,"\n");
538
+ setTimeout(function(){
539
+ startDate = new Date().getTime();
540
+ captionData = captionData.split(/\n\n+/g);
541
+ lazyProcess(0, captionData.length);
542
+ }, 9);
543
+ }, 9);
544
+
545
+ } else {
546
+ webshims.error("Required parameter captionData not supplied.");
547
+ }
548
+ };
549
+
550
+
551
+ mediaelement.createTrackList = function(mediaelem, baseData){
552
+ baseData = baseData || webshims.data(mediaelem, 'mediaelementBase') || webshims.data(mediaelem, 'mediaelementBase', {});
553
+ if(!baseData.textTracks){
554
+ baseData.textTracks = [];
555
+ webshims.defineProperties(baseData.textTracks, {
556
+ onaddtrack: {value: null},
557
+ onremovetrack: {value: null}
558
+ });
559
+ createEventTarget(baseData.textTracks);
560
+ }
561
+ return baseData.textTracks;
562
+ };
563
+
564
+ if(!Modernizr.track){
565
+ webshims.defineNodeNamesBooleanProperty(['track'], 'default');
566
+ webshims.reflectProperties(['track'], ['srclang', 'label']);
567
+
568
+ webshims.defineNodeNameProperties('track', {
569
+ src: {
570
+ //attr: {},
571
+ reflect: true,
572
+ propType: 'src'
573
+ }
574
+ });
575
+ }
576
+
577
+ webshims.defineNodeNameProperties('track', {
578
+ kind: {
579
+ attr: Modernizr.track ? {
580
+ set: function(value){
581
+ var trackData = webshims.data(this, 'trackData');
582
+ this.setAttribute('data-kind', value);
583
+ if(trackData){
584
+ trackData.attrKind = value;
585
+ }
586
+ },
587
+ get: function(){
588
+ var trackData = webshims.data(this, 'trackData');
589
+ if(trackData && ('attrKind' in trackData)){
590
+ return trackData.attrKind;
591
+ }
592
+ return this.getAttribute('kind');
593
+ }
594
+ } : {},
595
+ reflect: true,
596
+ propType: 'enumarated',
597
+ defaultValue: 'subtitles',
598
+ limitedTo: ['subtitles', 'captions', 'descriptions', 'chapters', 'metadata']
599
+ }
600
+ });
601
+
602
+ webshims.onNodeNamesPropertyModify('track', 'kind', function(){
603
+ var trackData = webshims.data(this, 'trackData');
604
+ if(trackData){
605
+ trackData.track.kind = $.prop(this, 'kind');
606
+ refreshTrack(this, trackData);
607
+ }
608
+ });
609
+
610
+ webshims.onNodeNamesPropertyModify('track', 'src', function(val){
611
+ if(val){
612
+ var data = webshims.data(this, 'trackData');
613
+ var media;
614
+ if(data){
615
+ media = $(this).closest('video, audio');
616
+ if(media[0]){
617
+ mediaelement.loadTextTrack(media, this, data);
618
+ }
619
+ }
620
+ }
621
+
622
+ });
623
+
624
+ //
625
+
626
+ webshims.defineNodeNamesProperties(['track'], {
627
+ ERROR: {
628
+ value: 3
629
+ },
630
+ LOADED: {
631
+ value: 2
632
+ },
633
+ LOADING: {
634
+ value: 1
635
+ },
636
+ NONE: {
637
+ value: 0
638
+ },
639
+ readyState: {
640
+ get: function(){
641
+ return ($.prop(this, 'track') || {readyState: 0}).readyState;
642
+ },
643
+ writeable: false
644
+ },
645
+ track: {
646
+ get: function(){
647
+ return mediaelement.createTextTrack($(this).closest('audio, video')[0], this);
648
+ },
649
+ writeable: false
650
+ }
651
+ }, 'prop');
652
+
653
+ webshims.defineNodeNamesProperties(['audio', 'video'], {
654
+ textTracks: {
655
+ get: function(){
656
+
657
+ var media = this;
658
+ var baseData = webshims.data(media, 'mediaelementBase') || webshims.data(media, 'mediaelementBase', {});
659
+ var tracks = mediaelement.createTrackList(media, baseData);
660
+ if(!baseData.blockTrackListUpdate){
661
+ updateMediaTrackList.call(media, baseData, tracks);
662
+ }
663
+ return tracks;
664
+ },
665
+ writeable: false
666
+ },
667
+ addTextTrack: {
668
+ value: function(kind, label, lang){
669
+ var textTrack = mediaelement.createTextTrack(this, {
670
+ kind: kind || '',
671
+ label: label || '',
672
+ srclang: lang || ''
673
+ });
674
+ var baseData = webshims.data(this, 'mediaelementBase') || webshims.data(this, 'mediaelementBase', {});
675
+ if (!baseData.scriptedTextTracks) {
676
+ baseData.scriptedTextTracks = [];
677
+ }
678
+ baseData.scriptedTextTracks.push(textTrack);
679
+ updateMediaTrackList.call(this);
680
+ return textTrack;
681
+ }
682
+ }
683
+ }, 'prop');
684
+
685
+
686
+ $(document).bind('emptied ended updatetracklist', function(e){
687
+ if($(e.target).is('audio, video')){
688
+ var baseData = webshims.data(e.target, 'mediaelementBase');
689
+ if(baseData){
690
+ clearTimeout(baseData.updateTrackListTimer);
691
+ baseData.updateTrackListTimer = setTimeout(function(){
692
+ updateMediaTrackList.call(e.target, baseData);
693
+ }, 0);
694
+ }
695
+ }
696
+ });
697
+
698
+ var getNativeReadyState = function(trackElem, textTrack){
699
+ return textTrack.readyState || trackElem.readyState;
700
+ };
701
+
702
+ webshims.addReady(function(context, insertedElement){
703
+ var insertedMedia = insertedElement.filter('video, audio, track').closest('audio, video');
704
+ $('video, audio', context)
705
+ .add(insertedMedia)
706
+ .each(function(){
707
+ updateMediaTrackList.call(this);
708
+ })
709
+ .each(function(){
710
+ if(Modernizr.track){
711
+ var shimedTextTracks = $.prop(this, 'textTracks');
712
+ var origTextTracks = this.textTracks;
713
+ if(shimedTextTracks.length != origTextTracks.length){
714
+ webshims.error("textTracks couldn't be copied");
715
+ }
716
+
717
+ $('track', this)
718
+ .each(function(){
719
+ var shimedTrack = $.prop(this, 'track');
720
+ var origTrack = this.track;
721
+ var kind;
722
+ var readyState;
723
+ if(origTrack){
724
+ kind = $.prop(this, 'kind');
725
+ readyState = getNativeReadyState(this, origTrack);
726
+ if (origTrack.mode || readyState) {
727
+ shimedTrack.mode = origTrack.mode;
728
+ }
729
+ //disable track from showing + remove UI
730
+ if(kind != 'descriptions'){
731
+ origTrack.mode = (typeof origTrack.mode == 'string') ? 'disabled' : 0;
732
+ this.kind = 'metadata';
733
+ $(this).attr({kind: kind});
734
+ }
735
+
736
+ }
737
+ })
738
+ .bind('load error', function(e){
739
+ if(e.originalEvent){
740
+ e.stopImmediatePropagation();
741
+ }
742
+ })
743
+ ;
744
+ }
745
+ })
746
+ ;
747
+ insertedMedia.each(function(){
748
+ var media = this;
749
+ var baseData = webshims.data(media, 'mediaelementBase');
750
+ if(baseData){
751
+ clearTimeout(baseData.updateTrackListTimer);
752
+ baseData.updateTrackListTimer = setTimeout(function(){
753
+ updateMediaTrackList.call(media, baseData);
754
+ }, 9);
755
+ }
756
+ });
757
+ });
758
+
759
+ if(Modernizr.track){
760
+ $('video, audio').trigger('trackapichange');
761
+ }
762
+
763
+ });