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,1607 @@
1
+ (function($, Modernizr, webshims){
2
+ "use strict";
3
+ var hasNative = Modernizr.audio && Modernizr.video;
4
+ var supportsLoop = false;
5
+ var options = webshims.cfg.mediaelement;
6
+ var bugs = webshims.bugs;
7
+ var loadSwf = function(){
8
+ webshims.ready('mediaelement-swf', function(){
9
+ if(!webshims.mediaelement.createSWF){
10
+ webshims.modules["mediaelement-swf"].test = $.noop;
11
+ webshims.reTest(["mediaelement-swf"], hasNative);
12
+ }
13
+ });
14
+ };
15
+ var hasSwf;
16
+ if(hasNative){
17
+ var videoElem = document.createElement('video');
18
+ Modernizr.videoBuffered = ('buffered' in videoElem);
19
+ supportsLoop = ('loop' in videoElem);
20
+
21
+ webshims.capturingEvents(['play', 'playing', 'waiting', 'paused', 'ended', 'durationchange', 'loadedmetadata', 'canplay', 'volumechange']);
22
+
23
+ if(!Modernizr.videoBuffered){
24
+ webshims.addPolyfill('mediaelement-native-fix', {
25
+ f: 'mediaelement',
26
+ test: Modernizr.videoBuffered,
27
+ d: ['dom-support']
28
+ });
29
+
30
+ webshims.reTest('mediaelement-native-fix');
31
+ }
32
+ }
33
+
34
+ if(hasNative && !options.preferFlash){
35
+ var switchOptions = function(e){
36
+ var parent = e.target.parentNode;
37
+ if(!options.preferFlash && ($(e.target).is('audio, video') || (parent && $('source:last', parent)[0] == e.target)) ){
38
+ webshims.ready('DOM mediaelement', function(){
39
+ if(hasSwf){
40
+ loadSwf();
41
+ }
42
+ webshims.ready('WINDOWLOAD mediaelement-swf', function(){
43
+ setTimeout(function(){
44
+ if(hasSwf && !options.preferFlash && webshims.mediaelement.createSWF && !$(e.target).closest('audio, video').is('.nonnative-api-active')){
45
+ options.preferFlash = true;
46
+ document.removeEventListener('error', switchOptions, true);
47
+ $('audio, video').mediaLoad();
48
+ webshims.info("switching mediaelements option to 'preferFlash', due to an error with native player: "+e.target.src);
49
+ } else if(!hasSwf){
50
+ document.removeEventListener('error', switchOptions, true);
51
+ }
52
+ }, 20);
53
+ });
54
+ });
55
+ }
56
+ };
57
+ document.addEventListener('error', switchOptions, true);
58
+ $('audio, video').each(function(){
59
+ if(this.error){
60
+ switchOptions({target: this});
61
+ }
62
+ });
63
+ }
64
+
65
+ bugs.track = false;
66
+
67
+ if(Modernizr.track){
68
+ (function(){
69
+
70
+ if(!bugs.track){
71
+ bugs.track = typeof $('<track />')[0].readyState != 'number';
72
+ }
73
+
74
+ if(!bugs.track){
75
+ try {
76
+ new TextTrackCue(2, 3, '');
77
+ } catch(e){
78
+ bugs.track = true;
79
+ }
80
+ }
81
+
82
+ var trackOptions = webshims.cfg.track;
83
+ var trackListener = function(e){
84
+ $(e.target).filter('track').each(changeApi);
85
+ };
86
+ var changeApi = function(){
87
+ if(bugs.track || (!trackOptions.override && $.prop(this, 'readyState') == 3)){
88
+ trackOptions.override = true;
89
+ webshims.reTest('track');
90
+ document.removeEventListener('error', trackListener, true);
91
+ if(this && $.nodeName(this, 'track')){
92
+ webshims.error("track support was overwritten. Please check your vtt including your vtt mime-type");
93
+ } else {
94
+ webshims.info("track support was overwritten. due to bad browser support");
95
+ }
96
+ }
97
+ };
98
+ var detectTrackError = function(){
99
+ document.addEventListener('error', trackListener, true);
100
+
101
+ if(bugs.track){
102
+ changeApi();
103
+ } else {
104
+ $('track').each(changeApi);
105
+ }
106
+ };
107
+ if(!trackOptions.override){
108
+ if(webshims.isReady('track')){
109
+ detectTrackError();
110
+ } else {
111
+ $(detectTrackError);
112
+ }
113
+ }
114
+ })();
115
+
116
+ }
117
+
118
+ webshims.register('mediaelement-core', function($, webshims, window, document, undefined){
119
+ hasSwf = swfobject.hasFlashPlayerVersion('9.0.115');
120
+
121
+ var mediaelement = webshims.mediaelement;
122
+
123
+ var getSrcObj = function(elem, nodeName){
124
+ elem = $(elem);
125
+ var src = {src: elem.attr('src') || '', elem: elem, srcProp: elem.prop('src')};
126
+ if(!src.src){return src;}
127
+ var tmp = elem.attr('type');
128
+ if(tmp){
129
+ src.type = tmp;
130
+ src.container = $.trim(tmp.split(';')[0]);
131
+ } else {
132
+ if(!nodeName){
133
+ nodeName = elem[0].nodeName.toLowerCase();
134
+ if(nodeName == 'source'){
135
+ nodeName = (elem.closest('video, audio')[0] || {nodeName: 'video'}).nodeName.toLowerCase();
136
+ }
137
+ }
138
+ tmp = mediaelement.getTypeForSrc(src.src, nodeName );
139
+
140
+ if(tmp){
141
+ src.type = tmp;
142
+ src.container = tmp;
143
+ }
144
+ }
145
+ tmp = elem.attr('media');
146
+ if(tmp){
147
+ src.media = tmp;
148
+ }
149
+ return src;
150
+ };
151
+
152
+
153
+
154
+ var hasYt = !hasSwf && ('postMessage' in window) && hasNative;
155
+
156
+ var loadYt = (function(){
157
+ var loaded;
158
+ return function(){
159
+ if(loaded || !hasYt){return;}
160
+ loaded = true;
161
+ webshims.loader.loadScript("https://www.youtube.com/player_api");
162
+ $(function(){
163
+ webshims.polyfill("mediaelement-yt");
164
+ });
165
+ };
166
+ })();
167
+ var loadThird = function(){
168
+ if(hasSwf){
169
+ loadSwf();
170
+ } else {
171
+ loadYt();
172
+ }
173
+ };
174
+
175
+ webshims.addPolyfill('mediaelement-yt', {
176
+ test: !hasYt,
177
+ d: ['dom-support']
178
+ });
179
+
180
+ mediaelement.mimeTypes = {
181
+ audio: {
182
+ //ogm shouldn´t be used!
183
+ 'audio/ogg': ['ogg','oga', 'ogm'],
184
+ 'audio/ogg;codecs="opus"': 'opus',
185
+ 'audio/mpeg': ['mp2','mp3','mpga','mpega'],
186
+ 'audio/mp4': ['mp4','mpg4', 'm4r', 'm4a', 'm4p', 'm4b', 'aac'],
187
+ 'audio/wav': ['wav'],
188
+ 'audio/3gpp': ['3gp','3gpp'],
189
+ 'audio/webm': ['webm'],
190
+ 'audio/fla': ['flv', 'f4a', 'fla'],
191
+ 'application/x-mpegURL': ['m3u8', 'm3u']
192
+ },
193
+ video: {
194
+ //ogm shouldn´t be used!
195
+ 'video/ogg': ['ogg','ogv', 'ogm'],
196
+ 'video/mpeg': ['mpg','mpeg','mpe'],
197
+ 'video/mp4': ['mp4','mpg4', 'm4v'],
198
+ 'video/quicktime': ['mov','qt'],
199
+ 'video/x-msvideo': ['avi'],
200
+ 'video/x-ms-asf': ['asf', 'asx'],
201
+ 'video/flv': ['flv', 'f4v'],
202
+ 'video/3gpp': ['3gp','3gpp'],
203
+ 'video/webm': ['webm'],
204
+ 'application/x-mpegURL': ['m3u8', 'm3u'],
205
+ 'video/MP2T': ['ts']
206
+ }
207
+ }
208
+ ;
209
+
210
+ mediaelement.mimeTypes.source = $.extend({}, mediaelement.mimeTypes.audio, mediaelement.mimeTypes.video);
211
+
212
+ mediaelement.getTypeForSrc = function(src, nodeName){
213
+ if(src.indexOf('youtube.com/watch?') != -1 || src.indexOf('youtube.com/v/') != -1){
214
+ return 'video/youtube';
215
+ }
216
+ src = src.split('?')[0].split('.');
217
+ src = src[src.length - 1];
218
+ var mt;
219
+
220
+ $.each(mediaelement.mimeTypes[nodeName], function(mimeType, exts){
221
+ if(exts.indexOf(src) !== -1){
222
+ mt = mimeType;
223
+ return false;
224
+ }
225
+ });
226
+ return mt;
227
+ };
228
+
229
+
230
+ mediaelement.srces = function(mediaElem, srces){
231
+ mediaElem = $(mediaElem);
232
+ if(!srces){
233
+ srces = [];
234
+ var nodeName = mediaElem[0].nodeName.toLowerCase();
235
+ var src = getSrcObj(mediaElem, nodeName);
236
+
237
+ if(!src.src){
238
+
239
+ $('source', mediaElem).each(function(){
240
+ src = getSrcObj(this, nodeName);
241
+ if(src.src){srces.push(src);}
242
+ });
243
+ } else {
244
+ srces.push(src);
245
+ }
246
+ return srces;
247
+ } else {
248
+ mediaElem.removeAttr('src').removeAttr('type').find('source').remove();
249
+ if(!$.isArray(srces)){
250
+ srces = [srces];
251
+ }
252
+ srces.forEach(function(src){
253
+ var source = document.createElement('source');
254
+ if(typeof src == 'string'){
255
+ src = {src: src};
256
+ }
257
+ source.setAttribute('src', src.src);
258
+ if(src.type){
259
+ source.setAttribute('type', src.type);
260
+ }
261
+ if(src.media){
262
+ source.setAttribute('media', src.media);
263
+ }
264
+ mediaElem.append(source);
265
+ });
266
+
267
+ }
268
+ };
269
+
270
+
271
+ $.fn.loadMediaSrc = function(srces, poster){
272
+ return this.each(function(){
273
+ if(poster !== undefined){
274
+ $(this).removeAttr('poster');
275
+ if(poster){
276
+ $.attr(this, 'poster', poster);
277
+ }
278
+ }
279
+ mediaelement.srces(this, srces);
280
+ $(this).mediaLoad();
281
+ });
282
+ };
283
+
284
+ mediaelement.swfMimeTypes = ['video/3gpp', 'video/x-msvideo', 'video/quicktime', 'video/x-m4v', 'video/mp4', 'video/m4p', 'video/x-flv', 'video/flv', 'audio/mpeg', 'audio/aac', 'audio/mp4', 'audio/x-m4a', 'audio/m4a', 'audio/mp3', 'audio/x-fla', 'audio/fla', 'youtube/flv', 'jwplayer/jwplayer', 'video/youtube'];
285
+
286
+ mediaelement.canThirdPlaySrces = function(mediaElem, srces){
287
+ var ret = '';
288
+ if(hasSwf || hasYt){
289
+ mediaElem = $(mediaElem);
290
+ srces = srces || mediaelement.srces(mediaElem);
291
+ $.each(srces, function(i, src){
292
+ if(src.container && src.src && ((hasSwf && mediaelement.swfMimeTypes.indexOf(src.container) != -1) || (hasYt && src.container == 'video/youtube'))){
293
+ ret = src;
294
+ return false;
295
+ }
296
+ });
297
+
298
+ }
299
+
300
+ return ret;
301
+ };
302
+
303
+ var nativeCanPlayType = {};
304
+ mediaelement.canNativePlaySrces = function(mediaElem, srces){
305
+ var ret = '';
306
+ if(hasNative){
307
+ mediaElem = $(mediaElem);
308
+ var nodeName = (mediaElem[0].nodeName || '').toLowerCase();
309
+ if(!nativeCanPlayType[nodeName]){return ret;}
310
+ srces = srces || mediaelement.srces(mediaElem);
311
+
312
+ $.each(srces, function(i, src){
313
+ if(src.type && nativeCanPlayType[nodeName].prop._supvalue.call(mediaElem[0], src.type) ){
314
+ ret = src;
315
+ return false;
316
+ }
317
+ });
318
+ }
319
+ return ret;
320
+ };
321
+
322
+ mediaelement.setError = function(elem, message){
323
+ if(!message){
324
+ message = "can't play sources";
325
+ }
326
+
327
+ $(elem).pause().data('mediaerror', message);
328
+ webshims.warn('mediaelementError: '+ message);
329
+ setTimeout(function(){
330
+ if($(elem).data('mediaerror')){
331
+ $(elem).trigger('mediaerror');
332
+ }
333
+ }, 1);
334
+ };
335
+
336
+ var handleThird = (function(){
337
+ var requested;
338
+ return function( mediaElem, ret, data ){
339
+ webshims.ready(hasSwf ? 'mediaelement-swf' : 'mediaelement-yt', function(){
340
+ if(mediaelement.createSWF){
341
+ mediaelement.createSWF( mediaElem, ret, data );
342
+ } else if(!requested) {
343
+ requested = true;
344
+ loadThird();
345
+ //readd to ready
346
+ handleThird( mediaElem, ret, data );
347
+ }
348
+ });
349
+ if(!requested && hasYt && !mediaelement.createSWF){
350
+ loadYt();
351
+ }
352
+ };
353
+ })();
354
+
355
+ var stepSources = function(elem, data, useSwf, _srces, _noLoop){
356
+ var ret;
357
+ if(useSwf || (useSwf !== false && data && data.isActive == 'third')){
358
+ ret = mediaelement.canThirdPlaySrces(elem, _srces);
359
+ if(!ret){
360
+ if(_noLoop){
361
+ mediaelement.setError(elem, false);
362
+ } else {
363
+ stepSources(elem, data, false, _srces, true);
364
+ }
365
+ } else {
366
+ handleThird(elem, ret, data);
367
+ }
368
+ } else {
369
+ ret = mediaelement.canNativePlaySrces(elem, _srces);
370
+ if(!ret){
371
+ if(_noLoop){
372
+ mediaelement.setError(elem, false);
373
+ if(data && data.isActive == 'third') {
374
+ mediaelement.setActive(elem, 'html5', data);
375
+ }
376
+ } else {
377
+ stepSources(elem, data, true, _srces, true);
378
+ }
379
+ } else if(data && data.isActive == 'third') {
380
+ mediaelement.setActive(elem, 'html5', data);
381
+ }
382
+ }
383
+ };
384
+ var stopParent = /^(?:embed|object|datalist)$/i;
385
+ var selectSource = function(elem, data){
386
+ var baseData = webshims.data(elem, 'mediaelementBase') || webshims.data(elem, 'mediaelementBase', {});
387
+ var _srces = mediaelement.srces(elem);
388
+ var parent = elem.parentNode;
389
+
390
+ clearTimeout(baseData.loadTimer);
391
+ $.data(elem, 'mediaerror', false);
392
+
393
+ if(!_srces.length || !parent || parent.nodeType != 1 || stopParent.test(parent.nodeName || '')){return;}
394
+ data = data || webshims.data(elem, 'mediaelement');
395
+ stepSources(elem, data, options.preferFlash || undefined, _srces);
396
+ };
397
+
398
+
399
+ $(document).bind('ended', function(e){
400
+ var data = webshims.data(e.target, 'mediaelement');
401
+ if( supportsLoop && (!data || data.isActive == 'html5') && !$.prop(e.target, 'loop')){return;}
402
+ setTimeout(function(){
403
+ if( $.prop(e.target, 'paused') || !$.prop(e.target, 'loop') ){return;}
404
+ $(e.target).prop('currentTime', 0).play();
405
+ }, 1);
406
+
407
+ });
408
+ if(!supportsLoop){
409
+ webshims.defineNodeNamesBooleanProperty(['audio', 'video'], 'loop');
410
+ }
411
+
412
+ ['audio', 'video'].forEach(function(nodeName){
413
+ var supLoad = webshims.defineNodeNameProperty(nodeName, 'load', {
414
+ prop: {
415
+ value: function(){
416
+ var data = webshims.data(this, 'mediaelement');
417
+ selectSource(this, data);
418
+ if(hasNative && (!data || data.isActive == 'html5') && supLoad.prop._supvalue){
419
+ supLoad.prop._supvalue.apply(this, arguments);
420
+ }
421
+ }
422
+ }
423
+ });
424
+ nativeCanPlayType[nodeName] = webshims.defineNodeNameProperty(nodeName, 'canPlayType', {
425
+ prop: {
426
+ value: function(type){
427
+ var ret = '';
428
+ if(hasNative && nativeCanPlayType[nodeName].prop._supvalue){
429
+ ret = nativeCanPlayType[nodeName].prop._supvalue.call(this, type);
430
+ if(ret == 'no'){
431
+ ret = '';
432
+ }
433
+ }
434
+ if(!ret && hasSwf){
435
+ type = $.trim((type || '').split(';')[0]);
436
+ if(mediaelement.swfMimeTypes.indexOf(type) != -1){
437
+ ret = 'maybe';
438
+ }
439
+ }
440
+ return ret;
441
+ }
442
+ }
443
+ });
444
+ });
445
+ webshims.onNodeNamesPropertyModify(['audio', 'video'], ['src', 'poster'], {
446
+ set: function(){
447
+ var elem = this;
448
+ var baseData = webshims.data(elem, 'mediaelementBase') || webshims.data(elem, 'mediaelementBase', {});
449
+ clearTimeout(baseData.loadTimer);
450
+ baseData.loadTimer = setTimeout(function(){
451
+ selectSource(elem);
452
+ elem = null;
453
+ }, 9);
454
+ }
455
+ });
456
+
457
+ var initMediaElements = function(){
458
+
459
+ webshims.addReady(function(context, insertedElement){
460
+ $('video, audio', context)
461
+ .add(insertedElement.filter('video, audio'))
462
+ .each(function(){
463
+ if($.browser.msie && webshims.browserVersion > 8 && $.prop(this, 'paused') && !$.prop(this, 'readyState') && $(this).is('audio[preload="none"][controls]:not([autoplay])')){
464
+ $(this).prop('preload', 'metadata').mediaLoad();
465
+ } else {
466
+ selectSource(this);
467
+ }
468
+
469
+
470
+
471
+ if(hasNative){
472
+ var bufferTimer;
473
+ var lastBuffered;
474
+ var elem = this;
475
+ var getBufferedString = function(){
476
+ var buffered = $.prop(elem, 'buffered');
477
+ if(!buffered){return;}
478
+ var bufferString = "";
479
+ for(var i = 0, len = buffered.length; i < len;i++){
480
+ bufferString += buffered.end(i);
481
+ }
482
+ return bufferString;
483
+ };
484
+ var testBuffer = function(){
485
+ var buffered = getBufferedString();
486
+ if(buffered != lastBuffered){
487
+ lastBuffered = buffered;
488
+ $(elem).triggerHandler('progress');
489
+ }
490
+ };
491
+
492
+ $(this)
493
+ .bind('play loadstart progress', function(e){
494
+ if(e.type == 'progress'){
495
+ lastBuffered = getBufferedString();
496
+ }
497
+ clearTimeout(bufferTimer);
498
+ bufferTimer = setTimeout(testBuffer, 999);
499
+ })
500
+ .bind('emptied stalled mediaerror abort suspend', function(e){
501
+ if(e.type == 'emptied'){
502
+ lastBuffered = false;
503
+ }
504
+ clearTimeout(bufferTimer);
505
+ })
506
+ ;
507
+ }
508
+
509
+ })
510
+ ;
511
+ });
512
+ };
513
+
514
+ if(Modernizr.track && !bugs.track){
515
+ webshims.defineProperty(TextTrack.prototype, 'shimActiveCues', {
516
+ get: function(){
517
+ return this._shimActiveCues || this.activeCues;
518
+ }
519
+ });
520
+ }
521
+ //set native implementation ready, before swf api is retested
522
+ if(hasNative){
523
+ webshims.isReady('mediaelement-core', true);
524
+ initMediaElements();
525
+ webshims.ready('WINDOWLOAD mediaelement', loadThird);
526
+ } else {
527
+ webshims.ready('mediaelement-swf', initMediaElements);
528
+ }
529
+ $(function(){
530
+ webshims.loader.loadList(['track-ui']);
531
+ });
532
+
533
+ });
534
+ })(jQuery, Modernizr, jQuery.webshims);/*
535
+ * todos:
536
+ * - decouple muted/volume (needs improvement)
537
+ * - implement video <-> flashcanvas pro API
538
+ * - improve buffered-property with youtube/rtmp
539
+ * - use jwplayer5 api instead of old flash4 api
540
+ */
541
+
542
+ jQuery.webshims.register('mediaelement-swf', function($, webshims, window, document, undefined, options){
543
+ "use strict";
544
+ var SENDEVENT = 'sendEvent';
545
+ var mediaelement = webshims.mediaelement;
546
+ var swfobject = window.swfobject;
547
+ var hasNative = Modernizr.audio && Modernizr.video;
548
+ var hasFlash = swfobject.hasFlashPlayerVersion('9.0.115');
549
+ var loadedSwf = 0;
550
+ var getProps = {
551
+ paused: true,
552
+ ended: false,
553
+ currentSrc: '',
554
+ duration: window.NaN,
555
+
556
+ readyState: 0,
557
+ networkState: 0,
558
+ videoHeight: 0,
559
+ videoWidth: 0,
560
+ error: null,
561
+ buffered: {
562
+ start: function(index){
563
+ if(index){
564
+ webshims.error('buffered index size error');
565
+ return;
566
+ }
567
+ return 0;
568
+ },
569
+ end: function(index){
570
+ if(index){
571
+ webshims.error('buffered index size error');
572
+ return;
573
+ }
574
+ return 0;
575
+ },
576
+ length: 0
577
+ }
578
+ };
579
+ var getPropKeys = Object.keys(getProps);
580
+
581
+ var getSetProps = {
582
+ currentTime: 0,
583
+ volume: 1,
584
+ muted: false
585
+ };
586
+ var getSetPropKeys = Object.keys(getSetProps);
587
+
588
+ var playerStateObj = $.extend({
589
+ isActive: 'html5',
590
+ activating: 'html5',
591
+ wasSwfReady: false,
592
+ _bufferedEnd: 0,
593
+ _bufferedStart: 0,
594
+ _metadata: false,
595
+ _durationCalcs: -1,
596
+ _callMeta: false,
597
+ currentTime: 0,
598
+ _ppFlag: undefined
599
+ }, getProps, getSetProps);
600
+
601
+ var idRep = /^jwplayer-/;
602
+ var getSwfDataFromID = function(id){
603
+
604
+ var elem = document.getElementById(id.replace(idRep, ''));
605
+ if(!elem){return;}
606
+ var data = webshims.data(elem, 'mediaelement');
607
+ return data.isActive == 'third' ? data : null;
608
+ };
609
+
610
+
611
+ var getSwfDataFromElem = function(elem){
612
+ try {
613
+ (elem.nodeName);
614
+ } catch(er){
615
+ return null;
616
+ }
617
+ var data = webshims.data(elem, 'mediaelement');
618
+ return (data && data.isActive== 'third') ? data : null;
619
+ };
620
+
621
+ var trigger = function(elem, evt){
622
+ evt = $.Event(evt);
623
+ evt.preventDefault();
624
+ $.event.trigger(evt, undefined, elem);
625
+ };
626
+
627
+ var playerSwfPath = options.playerPath || webshims.cfg.basePath + "jwplayer/" + (options.playerName || "player.swf");
628
+ var jwplugin = options.pluginPath || webshims.cfg.basePath +'swf/jwwebshims.swf';
629
+
630
+ webshims.extendUNDEFProp(options.jwParams, {
631
+ allowscriptaccess: 'always',
632
+ allowfullscreen: 'true',
633
+ wmode: 'transparent'
634
+ });
635
+ webshims.extendUNDEFProp(options.jwVars, {
636
+ screencolor: 'ffffffff'
637
+ });
638
+ webshims.extendUNDEFProp(options.jwAttrs, {
639
+ bgcolor: '#000000'
640
+ });
641
+
642
+ var getDuration = function(data, obj){
643
+ var curDuration = data.duration;
644
+ if(curDuration && data._durationCalcs > 0){return;}
645
+ try {
646
+ data.duration = data.jwapi.getPlaylist()[0].duration;
647
+ if(!data.duration || data.duration <= 0 || data.duration === data._lastDuration){
648
+ data.duration = curDuration;
649
+ }
650
+ } catch(er){}
651
+ if(data.duration && data.duration != data._lastDuration){
652
+ trigger(data._elem, 'durationchange');
653
+ if(data._elemNodeName == 'audio' || data._callMeta){
654
+ mediaelement.jwEvents.Model.META($.extend({duration: data.duration}, obj), data);
655
+ }
656
+ data._durationCalcs--;
657
+ } else {
658
+ data._durationCalcs++;
659
+ }
660
+ };
661
+ var setReadyState = function(readyState, data){
662
+ if(readyState < 3){
663
+ clearTimeout(data._canplaythroughTimer);
664
+ }
665
+ if(readyState >= 3 && data.readyState < 3){
666
+ data.readyState = readyState;
667
+ trigger(data._elem, 'canplay');
668
+ clearTimeout(data._canplaythroughTimer);
669
+ data._canplaythroughTimer = setTimeout(function(){
670
+ setReadyState(4, data);
671
+ }, 4000);
672
+ }
673
+ if(readyState >= 4 && data.readyState < 4){
674
+ data.readyState = readyState;
675
+ trigger(data._elem, 'canplaythrough');
676
+ }
677
+ data.readyState = readyState;
678
+ };
679
+
680
+ $.extend($.event.customEvent, {
681
+ updatemediaelementdimensions: true,
682
+ flashblocker: true,
683
+ swfstageresize: true,
684
+ mediaelementapichange: true
685
+ });
686
+
687
+ mediaelement.jwEvents = {
688
+ View: {
689
+
690
+ PLAY: function(obj){
691
+ var data = getSwfDataFromID(obj.id);
692
+ if(!data || data.stopPlayPause){return;}
693
+ data._ppFlag = true;
694
+ if(data.paused == obj.state){
695
+ data.paused = !obj.state;
696
+ if(data.ended){
697
+ data.ended = false;
698
+ }
699
+ trigger(data._elem, obj.state ? 'play' : 'pause');
700
+ }
701
+ }
702
+ },
703
+ Model: {
704
+
705
+ BUFFER: function(obj){
706
+ var data = getSwfDataFromID(obj.id);
707
+ if(!data || !('percentage' in obj) || data._bufferedEnd == obj.percentage){return;}
708
+ data.networkState = (obj.percentage == 100) ? 1 : 2;
709
+ if(isNaN(data.duration) || (obj.percentage > 5 && obj.percentage < 25) || (obj.percentage === 100)){
710
+ getDuration(data, obj);
711
+ }
712
+
713
+ if(data.ended){
714
+ data.ended = false;
715
+ }
716
+ if(!data.duration){
717
+ return;
718
+ }
719
+ if(obj.percentage > 2 && obj.percentage < 20){
720
+ setReadyState(3, data);
721
+ } else if(obj.percentage > 20){
722
+ setReadyState(4, data);
723
+ }
724
+ if(data._bufferedEnd && (data._bufferedEnd > obj.percentage)){
725
+ data._bufferedStart = data.currentTime || 0;
726
+ }
727
+
728
+ data._bufferedEnd = obj.percentage;
729
+ data.buffered.length = 1;
730
+ if(obj.percentage == 100){
731
+ data.networkState = 1;
732
+ setReadyState(4, data);
733
+ }
734
+ $.event.trigger('progress', undefined, data._elem, true);
735
+ },
736
+ META: function(obj, data){
737
+
738
+ data = data && data.networkState ? data : getSwfDataFromID(obj.id);
739
+
740
+ if(!data){return;}
741
+ if( !('duration' in obj) ){
742
+ data._callMeta = true;
743
+ return;
744
+ }
745
+
746
+ if( data._metadata && (!obj.height || data.videoHeight == obj.height) && (obj.duration === data.duration) ){return;}
747
+
748
+ data._metadata = true;
749
+
750
+ var oldDur = data.duration;
751
+ if(obj.duration){
752
+ data.duration = obj.duration;
753
+ }
754
+ data._lastDuration = data.duration;
755
+ if(obj.height || obj.width){
756
+ data.videoHeight = obj.height || 0;
757
+ data.videoWidth = obj.width || 0;
758
+ }
759
+ if(!data.networkState){
760
+ data.networkState = 2;
761
+ }
762
+ if(data.readyState < 1){
763
+ setReadyState(1, data);
764
+ }
765
+ if(data.duration && oldDur !== data.duration){
766
+ trigger(data._elem, 'durationchange');
767
+ }
768
+
769
+ trigger(data._elem, 'loadedmetadata');
770
+ },
771
+ TIME: function(obj){
772
+ var data = getSwfDataFromID(obj.id);
773
+ if(!data || data.currentTime === obj.position){return;}
774
+ data.currentTime = obj.position;
775
+ if(data.duration && data.duration < data.currentTime){
776
+ getDuration(data, obj);
777
+ }
778
+ if(data.readyState < 2){
779
+ setReadyState(2, data);
780
+ }
781
+ if(data.ended){
782
+ data.ended = false;
783
+ }
784
+ trigger(data._elem, 'timeupdate');
785
+
786
+ },
787
+ STATE: function(obj){
788
+ var data = getSwfDataFromID(obj.id);
789
+ if(!data){return;}
790
+ switch(obj.newstate) {
791
+ case 'BUFFERING':
792
+
793
+ if(data.ended){
794
+ data.ended = false;
795
+ }
796
+ setReadyState(1, data);
797
+ trigger(data._elem, 'waiting');
798
+ break;
799
+ case 'PLAYING':
800
+ data.paused = false;
801
+ data._ppFlag = true;
802
+ if(!data.duration){
803
+ getDuration(data, obj);
804
+ }
805
+ if(data.readyState < 3){
806
+ setReadyState(3, data);
807
+ }
808
+ if(data.ended){
809
+ data.ended = false;
810
+ }
811
+ trigger(data._elem, 'playing');
812
+ break;
813
+ case 'PAUSED':
814
+ if(!data.paused && !data.stopPlayPause){
815
+ data.paused = true;
816
+ data._ppFlag = true;
817
+ trigger(data._elem, 'pause');
818
+ }
819
+ break;
820
+ case 'COMPLETED':
821
+ if(data.readyState < 4){
822
+ setReadyState(4, data);
823
+ }
824
+ data.ended = true;
825
+ trigger(data._elem, 'ended');
826
+ break;
827
+ }
828
+ }
829
+ }
830
+ ,Controller: {
831
+
832
+ ERROR: function(obj){
833
+ var data = getSwfDataFromID(obj.id);
834
+ if(!data){return;}
835
+ mediaelement.setError(data._elem, obj.message);
836
+ },
837
+ SEEK: function(obj){
838
+ var data = getSwfDataFromID(obj.id);
839
+ if(!data){return;}
840
+ if(data.ended){
841
+ data.ended = false;
842
+ }
843
+ if(data.paused){
844
+ try {
845
+ data.jwapi[SENDEVENT]('play', 'false');
846
+ } catch(er){}
847
+ }
848
+ if(data.currentTime != obj.position){
849
+ data.currentTime = obj.position;
850
+ trigger(data._elem, 'timeupdate');
851
+ }
852
+
853
+
854
+ },
855
+ VOLUME: function(obj){
856
+ var data = getSwfDataFromID(obj.id);
857
+ if(!data){return;}
858
+ var newVolume = obj.percentage / 100;
859
+ if(data.volume == newVolume){return;}
860
+ data.volume = newVolume;
861
+ trigger(data._elem, 'volumechange');
862
+ },
863
+ MUTE: function(obj){
864
+ if(obj.state){return;}
865
+ var data = getSwfDataFromID(obj.id);
866
+ if(!data){return;}
867
+ if(data.muted == obj.state){return;}
868
+ data.muted = obj.state;
869
+ trigger(data._elem, 'volumechange');
870
+ }
871
+ }
872
+ };
873
+
874
+ var initEvents = function(data){
875
+ var passed = true;
876
+ $.each(mediaelement.jwEvents, function(mvcName, evts){
877
+ $.each(evts, function(evtName){
878
+ try {
879
+ data.jwapi['add'+ mvcName +'Listener'](evtName, 'jQuery.webshims.mediaelement.jwEvents.'+ mvcName +'.'+ evtName);
880
+ } catch(er){
881
+ passed = false;
882
+ return false;
883
+ }
884
+ });
885
+ });
886
+ return passed;
887
+ };
888
+
889
+ var workActionQueue = function(data){
890
+ var actionLen = data.actionQueue.length;
891
+ var i = 0;
892
+ var operation;
893
+ if(actionLen && data.isActive == 'third'){
894
+ while(data.actionQueue.length && actionLen > i){
895
+ i++;
896
+ operation = data.actionQueue.shift();
897
+ data.jwapi[operation.fn].apply(data.jwapi, operation.args);
898
+ }
899
+ }
900
+ if(data.actionQueue.length){
901
+ data.actionQueue = [];
902
+ }
903
+ };
904
+ var startAutoPlay = function(data){
905
+ if(!data){return;}
906
+ if( (data._ppFlag === undefined && ($.prop(data._elem, 'autoplay')) || !data.paused)){
907
+ setTimeout(function(){
908
+ if(data.isActive == 'third' && (data._ppFlag === undefined || !data.paused)){
909
+ try {
910
+ $(data._elem).play();
911
+ } catch(er){}
912
+ }
913
+ }, 1);
914
+ }
915
+ };
916
+
917
+ var startIntrinsicDimension = function(data){
918
+ if(!data || data._elemNodeName != 'video'){return;}
919
+ var img;
920
+ var widthAuto;
921
+ var heightAuto;
922
+ var lastIntrinsicSize = {};
923
+ var shadowElem;
924
+ var errorTimer;
925
+ var blockResize;
926
+ var lastSize;
927
+ var setSize = function(width, height){
928
+ if(!height || !width || height < 1 || width < 1 || data.isActive != 'third'){return;}
929
+ if(img){
930
+ img.remove();
931
+ img = false;
932
+ }
933
+ lastIntrinsicSize.width = width;
934
+ lastIntrinsicSize.height = height;
935
+ clearTimeout(errorTimer);
936
+ widthAuto = data._elem.style.width == 'auto';
937
+ heightAuto = data._elem.style.height == 'auto';
938
+
939
+ if(!widthAuto && !heightAuto){return;}
940
+ var curSize;
941
+ shadowElem = shadowElem || $(data._elem).getShadowElement();
942
+ var cur;
943
+ if(widthAuto && !heightAuto){
944
+ cur = shadowElem.height();
945
+ width *= cur / height;
946
+ height = cur;
947
+ } else if(!widthAuto && heightAuto){
948
+ cur = shadowElem.width();
949
+ height *= cur / width;
950
+ width = cur;
951
+ }
952
+ blockResize = true;
953
+ setTimeout(function(){
954
+ blockResize = false;
955
+ }, 9);
956
+
957
+ shadowElem.css({width: width, height: height});
958
+ };
959
+ var setPosterSrc = function(){
960
+ if(data.isActive != 'third' || ($.prop(data._elem, 'readyState') && $.prop(this, 'videoWidth'))){return;}
961
+ var posterSrc = $.prop(data._elem, 'poster');
962
+ if(!posterSrc){return;}
963
+ widthAuto = data._elem.style.width == 'auto';
964
+ heightAuto = data._elem.style.height == 'auto';
965
+ if(!widthAuto && !heightAuto){return;}
966
+ if(img){
967
+ img.remove();
968
+ img = false;
969
+ }
970
+ img = $('<img style="position: absolute; height: auto; width: auto; top: 0px; left: 0px; visibility: hidden;" />');
971
+ img
972
+ .bind('load error alreadycomplete', function(e){
973
+ clearTimeout(errorTimer);
974
+
975
+ var elem = this;
976
+ var width = elem.naturalWidth || elem.width || elem.offsetWidth;
977
+ var height = elem.naturalHeight || elem.height || elem.offsetHeight;
978
+
979
+ if(height && width){
980
+ setSize(width, height);
981
+ elem = null;
982
+ } else {
983
+ setTimeout(function(){
984
+ width = elem.naturalWidth || elem.width || elem.offsetWidth;
985
+ height = elem.naturalHeight || elem.height || elem.offsetHeight;
986
+ setSize(width, height);
987
+ if(img){
988
+ img.remove();
989
+ img = false;
990
+ }
991
+ elem = null;
992
+ }, 9);
993
+ }
994
+ $(this).unbind();
995
+ })
996
+ .prop('src', posterSrc)
997
+ .appendTo('body')
998
+ .each(function(){
999
+ if(this.complete || this.error){
1000
+ $(this).triggerHandler('alreadycomplete');
1001
+ } else {
1002
+ clearTimeout(errorTimer);
1003
+ errorTimer = setTimeout(function(){
1004
+ $(data._elem).triggerHandler('error');
1005
+ }, 9999);
1006
+ }
1007
+ })
1008
+ ;
1009
+ };
1010
+
1011
+ $(data._elem)
1012
+ .bind('loadedmetadata', function(){
1013
+ setSize($.prop(this, 'videoWidth'), $.prop(this, 'videoHeight'));
1014
+ })
1015
+ .bind('emptied', setPosterSrc)
1016
+ .bind('swfstageresize updatemediaelementdimensions', function(){
1017
+ if(blockResize){return;}
1018
+ setSize(lastIntrinsicSize.width, lastIntrinsicSize.height);
1019
+ })
1020
+ .bind('emptied', function(){
1021
+ lastIntrinsicSize = {};
1022
+ })
1023
+ .triggerHandler('swfstageresize')
1024
+ ;
1025
+
1026
+ setPosterSrc();
1027
+ if($.prop(data._elem, 'readyState')){
1028
+ setSize($.prop(data._elem, 'videoWidth'), $.prop(data._elem, 'videoHeight'));
1029
+ }
1030
+ };
1031
+
1032
+ mediaelement.playerResize = function(id){
1033
+ if(!id){return;}
1034
+ var elem = document.getElementById(id.replace(idRep, ''));
1035
+
1036
+ if(elem){
1037
+ $(elem).triggerHandler('swfstageresize');
1038
+ }
1039
+ elem = null;
1040
+ };
1041
+
1042
+
1043
+ $(document).bind('emptied', function(e){
1044
+ var data = getSwfDataFromElem(e.target);
1045
+ startAutoPlay(data);
1046
+ });
1047
+
1048
+ var localConnectionTimer;
1049
+ mediaelement.jwPlayerReady = function(jwData){
1050
+ var data = getSwfDataFromID(jwData.id);
1051
+ var passed = true;
1052
+ var i = 0;
1053
+ var doneFn = function(){
1054
+ if(i > 9){return;}
1055
+ i++;
1056
+ if(initEvents(data)){
1057
+ if(!data.wasSwfReady){
1058
+ var version = parseFloat( jwData.version, 10);
1059
+ if(version < 5.1 || version >= 6){
1060
+ webshims.warn('mediaelement-swf is only testet with jwplayer 5.6+');
1061
+ }
1062
+ } else {
1063
+ $(data._elem).mediaLoad();
1064
+
1065
+ }
1066
+ data.wasSwfReady = true;
1067
+ data.tryedReframeing = 0;
1068
+ workActionQueue(data);
1069
+ startAutoPlay(data);
1070
+ } else {
1071
+ clearTimeout(data.reframeTimer);
1072
+ data.reframeTimer = setTimeout(doneFn, 9 * i);
1073
+ if(i > 2 && data.tryedReframeing < 9){
1074
+ data.tryedReframeing++;
1075
+ data.shadowElem.css({overflow: 'visible'});
1076
+ setTimeout(function(){
1077
+ data.shadowElem.css({overflow: 'hidden'});
1078
+ }, 16);
1079
+ }
1080
+ }
1081
+ };
1082
+ if(!data || !data.jwapi){return;}
1083
+ if(!data.tryedReframeing){
1084
+ data.tryedReframeing = 0;
1085
+ }
1086
+ clearTimeout(localConnectionTimer);
1087
+ data.jwData = jwData;
1088
+ data.shadowElem.removeClass('flashblocker-assumed');
1089
+ $.prop(data._elem, 'volume', data.volume);
1090
+ $.prop(data._elem, 'muted', data.muted);
1091
+ doneFn();
1092
+
1093
+ };
1094
+
1095
+ var addMediaToStopEvents = $.noop;
1096
+ if(hasNative){
1097
+ var stopEvents = {
1098
+ play: 1,
1099
+ playing: 1
1100
+ };
1101
+ var hideEvtArray = ['play', 'pause', 'playing', 'canplay', 'progress', 'waiting', 'ended', 'loadedmetadata', 'durationchange', 'emptied'];
1102
+ var hidevents = hideEvtArray.map(function(evt){
1103
+ return evt +'.webshimspolyfill';
1104
+ }).join(' ');
1105
+
1106
+ var hidePlayerEvents = function(event){
1107
+ var data = webshims.data(event.target, 'mediaelement');
1108
+ if(!data){return;}
1109
+ var isNativeHTML5 = ( event.originalEvent && event.originalEvent.type === event.type );
1110
+ if( isNativeHTML5 == (data.activating == 'third') ){
1111
+ event.stopImmediatePropagation();
1112
+ if(stopEvents[event.type] && data.isActive != data.activating){
1113
+ $(event.target).pause();
1114
+ }
1115
+ }
1116
+ };
1117
+
1118
+ addMediaToStopEvents = function(elem){
1119
+ $(elem)
1120
+ .unbind(hidevents)
1121
+ .bind(hidevents, hidePlayerEvents)
1122
+ ;
1123
+ hideEvtArray.forEach(function(evt){
1124
+ webshims.moveToFirstEvent(elem, evt);
1125
+ });
1126
+ };
1127
+ addMediaToStopEvents(document);
1128
+ }
1129
+
1130
+
1131
+ mediaelement.setActive = function(elem, type, data){
1132
+ if(!data){
1133
+ data = webshims.data(elem, 'mediaelement');
1134
+ }
1135
+ if(!data || data.isActive == type){return;}
1136
+ if(type != 'html5' && type != 'third'){
1137
+ webshims.warn('wrong type for mediaelement activating: '+ type);
1138
+ }
1139
+ var shadowData = webshims.data(elem, 'shadowData');
1140
+ data.activating = type;
1141
+ $(elem).pause();
1142
+ data.isActive = type;
1143
+ if(type == 'third'){
1144
+ shadowData.shadowElement = shadowData.shadowFocusElement = data.shadowElem[0];
1145
+ $(elem).addClass('swf-api-active nonnative-api-active').hide().getShadowElement().show();
1146
+ } else {
1147
+ $(elem).removeClass('swf-api-active nonnative-api-active').show().getShadowElement().hide();
1148
+ shadowData.shadowElement = shadowData.shadowFocusElement = false;
1149
+ }
1150
+ $(elem).trigger('mediaelementapichange');
1151
+ };
1152
+
1153
+
1154
+
1155
+ var resetSwfProps = (function(){
1156
+ var resetProtoProps = ['_bufferedEnd', '_bufferedStart', '_metadata', '_ppFlag', 'currentSrc', 'currentTime', 'duration', 'ended', 'networkState', 'paused', 'videoHeight', 'videoWidth', '_callMeta', '_durationCalcs'];
1157
+ var len = resetProtoProps.length;
1158
+ return function(data){
1159
+
1160
+ if(!data){return;}
1161
+ var lenI = len;
1162
+ var networkState = data.networkState;
1163
+ setReadyState(0, data);
1164
+ while(--lenI){
1165
+ delete data[resetProtoProps[lenI]];
1166
+ }
1167
+ data.actionQueue = [];
1168
+ data.buffered.length = 0;
1169
+ if(networkState){
1170
+ trigger(data._elem, 'emptied');
1171
+ }
1172
+ };
1173
+ })();
1174
+
1175
+ var setElementDimension = function(data, hasControls){
1176
+ var elem = data._elem;
1177
+ var box = data.shadowElem;
1178
+ $(elem)[hasControls ? 'addClass' : 'removeClass']('webshims-controls');
1179
+ if(data._elemNodeName == 'audio' && !hasControls){
1180
+ box.css({width: 0, height: 0});
1181
+ } else {
1182
+ box.css({
1183
+ width: elem.style.width || $(elem).width(),
1184
+ height: elem.style.height || $(elem).height()
1185
+ });
1186
+ }
1187
+ };
1188
+
1189
+ mediaelement.createSWF = function( elem, canPlaySrc, data ){
1190
+ if(!hasFlash){
1191
+ setTimeout(function(){
1192
+ $(elem).mediaLoad(); //<- this should produce a mediaerror
1193
+ }, 1);
1194
+ return;
1195
+ }
1196
+
1197
+ if(loadedSwf < 1){
1198
+ loadedSwf = 1;
1199
+ } else {
1200
+ loadedSwf++;
1201
+ }
1202
+ var vars = $.extend({}, options.jwVars, {
1203
+ image: $.prop(elem, 'poster') || '',
1204
+ file: canPlaySrc.srcProp
1205
+ });
1206
+ var elemVars = $(elem).data('jwvars') || {};
1207
+
1208
+ if(!data){
1209
+ data = webshims.data(elem, 'mediaelement');
1210
+ }
1211
+
1212
+ if(data && data.swfCreated){
1213
+ mediaelement.setActive(elem, 'third', data);
1214
+ resetSwfProps(data);
1215
+ data.currentSrc = canPlaySrc.srcProp;
1216
+ $.extend(vars, elemVars);
1217
+ options.changeJW(vars, elem, canPlaySrc, data, 'load');
1218
+ queueSwfMethod(elem, SENDEVENT, ['LOAD', vars]);
1219
+ return;
1220
+ }
1221
+
1222
+
1223
+ var hasControls = $.prop(elem, 'controls');
1224
+ var elemId = 'jwplayer-'+ webshims.getID(elem);
1225
+ var params = $.extend(
1226
+ {},
1227
+ options.jwParams,
1228
+ $(elem).data('jwparams')
1229
+ );
1230
+ var elemNodeName = elem.nodeName.toLowerCase();
1231
+ var attrs = $.extend(
1232
+ {},
1233
+ options.jwAttrs,
1234
+ {
1235
+ name: elemId,
1236
+ id: elemId
1237
+ },
1238
+ $(elem).data('jwattrs')
1239
+ );
1240
+ var box = $('<div class="polyfill-'+ (elemNodeName) +' polyfill-mediaelement" id="wrapper-'+ elemId +'"><div id="'+ elemId +'"></div>')
1241
+ .css({
1242
+ position: 'relative',
1243
+ overflow: 'hidden'
1244
+ })
1245
+ ;
1246
+ data = webshims.data(elem, 'mediaelement', webshims.objectCreate(playerStateObj, {
1247
+ actionQueue: {
1248
+ value: []
1249
+ },
1250
+ shadowElem: {
1251
+ value: box
1252
+ },
1253
+ _elemNodeName: {
1254
+ value: elemNodeName
1255
+ },
1256
+ _elem: {
1257
+ value: elem
1258
+ },
1259
+ currentSrc: {
1260
+ value: canPlaySrc.srcProp
1261
+ },
1262
+ swfCreated: {
1263
+ value: true
1264
+ },
1265
+ buffered: {
1266
+ value: {
1267
+ start: function(index){
1268
+ if(index >= data.buffered.length){
1269
+ webshims.error('buffered index size error');
1270
+ return;
1271
+ }
1272
+ return 0;
1273
+ },
1274
+ end: function(index){
1275
+ if(index >= data.buffered.length){
1276
+ webshims.error('buffered index size error');
1277
+ return;
1278
+ }
1279
+ return ( (data.duration - data._bufferedStart) * data._bufferedEnd / 100) + data._bufferedStart;
1280
+ },
1281
+ length: 0
1282
+ }
1283
+ }
1284
+ }));
1285
+
1286
+ setElementDimension(data, hasControls);
1287
+
1288
+ box.insertBefore(elem);
1289
+
1290
+ if(hasNative){
1291
+ $.extend(data, {volume: $.prop(elem, 'volume'), muted: $.prop(elem, 'muted')});
1292
+ }
1293
+
1294
+ $.extend(vars,
1295
+ {
1296
+ id: elemId,
1297
+ controlbar: hasControls ? options.jwVars.controlbar || (elemNodeName == 'video' ? 'over' : 'bottom') : (elemNodeName == 'video') ? 'none' : 'bottom',
1298
+ icons: ''+ (hasControls && elemNodeName == 'video')
1299
+ },
1300
+ elemVars,
1301
+ {playerready: 'jQuery.webshims.mediaelement.jwPlayerReady'}
1302
+ );
1303
+ if(vars.plugins){
1304
+ vars.plugins += ','+jwplugin;
1305
+ } else {
1306
+ vars.plugins = jwplugin;
1307
+ }
1308
+
1309
+
1310
+ webshims.addShadowDom(elem, box);
1311
+
1312
+ addMediaToStopEvents(elem);
1313
+
1314
+ mediaelement.setActive(elem, 'third', data);
1315
+
1316
+ options.changeJW(vars, elem, canPlaySrc, data, 'embed');
1317
+
1318
+ $(elem).bind('updatemediaelementdimensions updateshadowdom', function(){
1319
+ setElementDimension(data, $.prop(elem, 'controls'));
1320
+ });
1321
+
1322
+ startIntrinsicDimension(data);
1323
+
1324
+ swfobject.embedSWF(playerSwfPath, elemId, "100%", "100%", "9.0.0", false, vars, params, attrs, function(swfData){
1325
+
1326
+ if(swfData.success){
1327
+ data.jwapi = swfData.ref;
1328
+
1329
+ if(!hasControls){
1330
+ $(swfData.ref).attr('tabindex', '-1').css('outline', 'none');
1331
+ }
1332
+ setTimeout(function(){
1333
+ if((!swfData.ref.parentNode && box[0].parentNode) || swfData.ref.style.display == "none"){
1334
+ box.addClass('flashblocker-assumed');
1335
+ $(elem).trigger('flashblocker');
1336
+ webshims.warn("flashblocker assumed");
1337
+ }
1338
+ $(swfData.ref).css({'minHeight': '2px', 'minWidth': '2px', display: 'block'});
1339
+ }, 9);
1340
+ if(!localConnectionTimer){
1341
+ clearTimeout(localConnectionTimer);
1342
+ localConnectionTimer = setTimeout(function(){
1343
+ var flash = $(swfData.ref);
1344
+ if(flash[0].offsetWidth > 1 && flash[0].offsetHeight > 1 && location.protocol.indexOf('file:') === 0){
1345
+ webshims.error("Add your local development-directory to the local-trusted security sandbox: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html");
1346
+ } else if(flash[0].offsetWidth < 2 || flash[0].offsetHeight < 2) {
1347
+ webshims.info("JS-SWF connection can't be established on hidden or unconnected flash objects");
1348
+ }
1349
+ flash = null;
1350
+ }, 8000);
1351
+ }
1352
+ }
1353
+ });
1354
+ };
1355
+
1356
+
1357
+ var queueSwfMethod = function(elem, fn, args, data){
1358
+ data = data || getSwfDataFromElem(elem);
1359
+ if(data){
1360
+ if(data.jwapi && data.jwapi[fn]){
1361
+ data.jwapi[fn].apply(data.jwapi, args || []);
1362
+ } else {
1363
+ //todo add to queue
1364
+ data.actionQueue.push({fn: fn, args: args});
1365
+ if(data.actionQueue.length > 10){
1366
+ setTimeout(function(){
1367
+ if(data.actionQueue.length > 5){
1368
+ data.actionQueue.shift();
1369
+ }
1370
+ }, 99);
1371
+ }
1372
+ }
1373
+ return data;
1374
+ }
1375
+ return false;
1376
+ };
1377
+
1378
+ ['audio', 'video'].forEach(function(nodeName){
1379
+ var descs = {};
1380
+ var mediaSup;
1381
+ var createGetProp = function(key){
1382
+ if(nodeName == 'audio' && (key == 'videoHeight' || key == 'videoWidth')){return;}
1383
+
1384
+ descs[key] = {
1385
+ get: function(){
1386
+ var data = getSwfDataFromElem(this);
1387
+ if(data){
1388
+ return data[key];
1389
+ } else if(hasNative && mediaSup[key].prop._supget) {
1390
+ return mediaSup[key].prop._supget.apply(this);
1391
+ } else {
1392
+ return playerStateObj[key];
1393
+ }
1394
+ },
1395
+ writeable: false
1396
+ };
1397
+ };
1398
+ var createGetSetProp = function(key, setFn){
1399
+ createGetProp(key);
1400
+ delete descs[key].writeable;
1401
+ descs[key].set = setFn;
1402
+ };
1403
+
1404
+ createGetSetProp('volume', function(v){
1405
+ var data = getSwfDataFromElem(this);
1406
+ if(data){
1407
+ v *= 100;
1408
+ if(!isNaN(v)){
1409
+ var muted = data.muted;
1410
+ if(v < 0 || v > 100){
1411
+ webshims.error('volume greater or less than allowed '+ (v / 100));
1412
+ }
1413
+
1414
+ queueSwfMethod(this, SENDEVENT, ['VOLUME', v], data);
1415
+ if(muted){
1416
+ try {
1417
+ data.jwapi.sendEvent('mute', 'true');
1418
+ } catch(er){}
1419
+ }
1420
+ v /= 100;
1421
+ if(data.volume == v || data.isActive != 'third'){return;}
1422
+ data.volume = v;
1423
+ trigger(data._elem, 'volumechange');
1424
+ data = null;
1425
+ }
1426
+ } else if(mediaSup.volume.prop._supset) {
1427
+ return mediaSup.volume.prop._supset.apply(this, arguments);
1428
+ }
1429
+ });
1430
+
1431
+ createGetSetProp('muted', function(m){
1432
+ var data = getSwfDataFromElem(this);
1433
+ if(data){
1434
+ m = !!m;
1435
+ queueSwfMethod(this, SENDEVENT, ['mute', ''+m], data);
1436
+ if(data.muted == m || data.isActive != 'third'){return;}
1437
+ data.muted = m;
1438
+ trigger(data._elem, 'volumechange');
1439
+ data = null;
1440
+ } else if(mediaSup.muted.prop._supset) {
1441
+ return mediaSup.muted.prop._supset.apply(this, arguments);
1442
+ }
1443
+ });
1444
+
1445
+
1446
+ createGetSetProp('currentTime', function(t){
1447
+ var data = getSwfDataFromElem(this);
1448
+ if(data){
1449
+ t *= 1;
1450
+ if (!isNaN(t)) {
1451
+ if(data.paused){
1452
+ clearTimeout(data.stopPlayPause);
1453
+ data.stopPlayPause = setTimeout(function(){
1454
+ data.paused = true;
1455
+ data.stopPlayPause = false;
1456
+ }, 50);
1457
+ }
1458
+ queueSwfMethod(this, SENDEVENT, ['SEEK', '' + t], data);
1459
+
1460
+ if(data.paused){
1461
+ if(data.readyState > 0){
1462
+ data.currentTime = t;
1463
+ trigger(data._elem, 'timeupdate');
1464
+ }
1465
+ try {
1466
+ data.jwapi[SENDEVENT]('play', 'false');
1467
+ } catch(er){}
1468
+
1469
+ }
1470
+ }
1471
+
1472
+ } else if(mediaSup.currentTime.prop._supset) {
1473
+ return mediaSup.currentTime.prop._supset.apply(this, arguments);
1474
+ }
1475
+ });
1476
+
1477
+ ['play', 'pause'].forEach(function(fn){
1478
+ descs[fn] = {
1479
+ value: function(){
1480
+ var data = getSwfDataFromElem(this);
1481
+ if(data){
1482
+ if(data.stopPlayPause){
1483
+ clearTimeout(data.stopPlayPause);
1484
+ }
1485
+ queueSwfMethod(this, SENDEVENT, ['play', fn == 'play'], data);
1486
+ setTimeout(function(){
1487
+ if(data.isActive == 'third'){
1488
+ data._ppFlag = true;
1489
+ if(data.paused != (fn != 'play')){
1490
+ data.paused = fn != 'play';
1491
+ trigger(data._elem, fn);
1492
+ }
1493
+ }
1494
+ }, 1);
1495
+ } else if(mediaSup[fn].prop._supvalue) {
1496
+ return mediaSup[fn].prop._supvalue.apply(this, arguments);
1497
+ }
1498
+ }
1499
+ };
1500
+ });
1501
+
1502
+ getPropKeys.forEach(createGetProp);
1503
+
1504
+ webshims.onNodeNamesPropertyModify(nodeName, 'controls', function(val, boolProp){
1505
+ var data = getSwfDataFromElem(this);
1506
+ $(this)[boolProp ? 'addClass' : 'removeClass']('webshims-controls');
1507
+
1508
+ if(data){
1509
+ try {
1510
+ queueSwfMethod(this, boolProp ? 'showControls' : 'hideControls', [nodeName], data);
1511
+ } catch(er){
1512
+ webshims.warn("you need to generate a crossdomain.xml");
1513
+ }
1514
+ if(nodeName == 'audio'){
1515
+ setElementDimension(data, boolProp);
1516
+ }
1517
+ $(data.jwapi).attr('tabindex', boolProp ? '0' : '-1');
1518
+ }
1519
+ });
1520
+
1521
+ mediaSup = webshims.defineNodeNameProperties(nodeName, descs, 'prop');
1522
+ });
1523
+
1524
+ if(hasFlash){
1525
+ var oldClean = $.cleanData;
1526
+ var gcBrowser = $.browser.msie && webshims.browserVersion < 9;
1527
+ var flashNames = {
1528
+ object: 1,
1529
+ OBJECT: 1
1530
+ };
1531
+ $.cleanData = function(elems){
1532
+ var i, len, prop;
1533
+ if(elems && (len = elems.length) && loadedSwf){
1534
+
1535
+ for(i = 0; i < len; i++){
1536
+ if(flashNames[elems[i].nodeName]){
1537
+ if(SENDEVENT in elems[i]){
1538
+ loadedSwf--;
1539
+ try {
1540
+ elems[i][SENDEVENT]('play', false);
1541
+ } catch(er){}
1542
+ }
1543
+ if(gcBrowser){
1544
+ try {
1545
+ for (prop in elems[i]) {
1546
+ if (typeof elems[i][prop] == "function") {
1547
+ elems[i][prop] = null;
1548
+ }
1549
+ }
1550
+ } catch(er){}
1551
+ }
1552
+ }
1553
+ }
1554
+
1555
+ }
1556
+ return oldClean.apply(this, arguments);
1557
+ };
1558
+ }
1559
+
1560
+ if(!hasNative){
1561
+
1562
+ ['poster', 'src'].forEach(function(prop){
1563
+ webshims.defineNodeNamesProperty(prop == 'src' ? ['audio', 'video', 'source'] : ['video'], prop, {
1564
+ //attr: {},
1565
+ reflect: true,
1566
+ propType: 'src'
1567
+ });
1568
+ });
1569
+
1570
+
1571
+ ['autoplay', 'controls'].forEach(function(name){
1572
+ webshims.defineNodeNamesBooleanProperty(['audio', 'video'], name);
1573
+ });
1574
+
1575
+ webshims.defineNodeNamesProperties(['audio', 'video'], {
1576
+ HAVE_CURRENT_DATA: {
1577
+ value: 2
1578
+ },
1579
+ HAVE_ENOUGH_DATA: {
1580
+ value: 4
1581
+ },
1582
+ HAVE_FUTURE_DATA: {
1583
+ value: 3
1584
+ },
1585
+ HAVE_METADATA: {
1586
+ value: 1
1587
+ },
1588
+ HAVE_NOTHING: {
1589
+ value: 0
1590
+ },
1591
+ NETWORK_EMPTY: {
1592
+ value: 0
1593
+ },
1594
+ NETWORK_IDLE: {
1595
+ value: 1
1596
+ },
1597
+ NETWORK_LOADING: {
1598
+ value: 2
1599
+ },
1600
+ NETWORK_NO_SOURCE: {
1601
+ value: 3
1602
+ }
1603
+
1604
+ }, 'prop');
1605
+ }
1606
+
1607
+ });