webshims-rails 1.12.5 → 1.12.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/lib/webshims-rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/webshims/polyfiller.js +111 -132
  4. data/vendor/assets/javascripts/webshims/shims/combos/1.js +40 -37
  5. data/vendor/assets/javascripts/webshims/shims/combos/10.js +217 -36
  6. data/vendor/assets/javascripts/webshims/shims/combos/11.js +151 -29
  7. data/vendor/assets/javascripts/webshims/shims/combos/12.js +70 -93
  8. data/vendor/assets/javascripts/webshims/shims/combos/13.js +70 -93
  9. data/vendor/assets/javascripts/webshims/shims/combos/14.js +90 -13
  10. data/vendor/assets/javascripts/webshims/shims/combos/15.js +202 -59
  11. data/vendor/assets/javascripts/webshims/shims/combos/16.js +208 -70
  12. data/vendor/assets/javascripts/webshims/shims/combos/17.js +151 -29
  13. data/vendor/assets/javascripts/webshims/shims/combos/18.js +155 -30
  14. data/vendor/assets/javascripts/webshims/shims/combos/19.js +79 -20
  15. data/vendor/assets/javascripts/webshims/shims/combos/2.js +109 -47
  16. data/vendor/assets/javascripts/webshims/shims/combos/20.js +79 -20
  17. data/vendor/assets/javascripts/webshims/shims/combos/21.js +80 -87
  18. data/vendor/assets/javascripts/webshims/shims/combos/22.js +66 -83
  19. data/vendor/assets/javascripts/webshims/shims/combos/23.js +4 -10
  20. data/vendor/assets/javascripts/webshims/shims/combos/25.js +79 -20
  21. data/vendor/assets/javascripts/webshims/shims/combos/26.js +66 -7
  22. data/vendor/assets/javascripts/webshims/shims/combos/28.js +100 -25
  23. data/vendor/assets/javascripts/webshims/shims/combos/3.js +192 -47
  24. data/vendor/assets/javascripts/webshims/shims/combos/30.js +193 -49
  25. data/vendor/assets/javascripts/webshims/shims/combos/31.js +103 -36
  26. data/vendor/assets/javascripts/webshims/shims/combos/32.js +5 -3
  27. data/vendor/assets/javascripts/webshims/shims/combos/33.js +1 -2
  28. data/vendor/assets/javascripts/webshims/shims/combos/34.js +2048 -0
  29. data/vendor/assets/javascripts/webshims/shims/combos/4.js +156 -20
  30. data/vendor/assets/javascripts/webshims/shims/combos/5.js +151 -29
  31. data/vendor/assets/javascripts/webshims/shims/combos/6.js +152 -31
  32. data/vendor/assets/javascripts/webshims/shims/combos/7.js +199 -60
  33. data/vendor/assets/javascripts/webshims/shims/combos/8.js +197 -58
  34. data/vendor/assets/javascripts/webshims/shims/combos/9.js +218 -38
  35. data/vendor/assets/javascripts/webshims/shims/combos/97.js +1004 -0
  36. data/vendor/assets/javascripts/webshims/shims/combos/98.js +1283 -0
  37. data/vendor/assets/javascripts/webshims/shims/combos/99.js +204 -1248
  38. data/vendor/assets/javascripts/webshims/shims/dom-extend.js +66 -7
  39. data/vendor/assets/javascripts/webshims/shims/es5.js +4 -1
  40. data/vendor/assets/javascripts/webshims/shims/form-combat.js +3 -3
  41. data/vendor/assets/javascripts/webshims/shims/form-core.js +36 -27
  42. data/vendor/assets/javascripts/webshims/shims/form-datalist.js +1 -2
  43. data/vendor/assets/javascripts/webshims/shims/form-fixrangechange.js +137 -0
  44. data/vendor/assets/javascripts/webshims/shims/form-message.js +90 -13
  45. data/vendor/assets/javascripts/webshims/shims/form-number-date-ui.js +129 -15
  46. data/vendor/assets/javascripts/webshims/shims/form-shim-extend.js +9 -10
  47. data/vendor/assets/javascripts/webshims/shims/form-shim-extend2.js +886 -985
  48. data/vendor/assets/javascripts/webshims/shims/form-validation.js +78 -174
  49. data/vendor/assets/javascripts/webshims/shims/form-validators.js +39 -26
  50. data/vendor/assets/javascripts/webshims/shims/forms-picker.js +45 -17
  51. data/vendor/assets/javascripts/webshims/shims/geolocation.js +10 -3
  52. data/vendor/assets/javascripts/webshims/shims/jme/b.js +71 -246
  53. data/vendor/assets/javascripts/webshims/shims/jme/c.js +133 -1002
  54. data/vendor/assets/javascripts/webshims/shims/jme/controls.css +62 -23
  55. data/vendor/assets/javascripts/webshims/shims/jme/controls.scss +73 -10
  56. data/vendor/assets/javascripts/webshims/shims/jme/mediacontrols-lazy.js +1117 -0
  57. data/vendor/assets/javascripts/webshims/shims/jme/p.js +603 -0
  58. data/vendor/assets/javascripts/webshims/shims/jpicker/jpicker.css +5 -2
  59. data/vendor/assets/javascripts/webshims/shims/mediaelement-core.js +4 -10
  60. data/vendor/assets/javascripts/webshims/shims/mediaelement-jaris.js +4 -1
  61. data/vendor/assets/javascripts/webshims/shims/range-ui.js +22 -14
  62. data/vendor/assets/javascripts/webshims/shims/styles/forms-ext.css +29 -344
  63. data/vendor/assets/javascripts/webshims/shims/styles/forms-picker.css +362 -0
  64. data/vendor/assets/javascripts/webshims/shims/styles/scss/forms-ext.scss +6 -483
  65. data/vendor/assets/javascripts/webshims/shims/styles/scss/forms-picker.scss +488 -0
  66. data/vendor/assets/javascripts/webshims/shims/styles/scss/shim-ext.scss +2 -0
  67. data/vendor/assets/javascripts/webshims/shims/styles/scss/shim.scss +10 -2
  68. data/vendor/assets/javascripts/webshims/shims/styles/shim.css +6 -2
  69. data/vendor/assets/javascripts/webshims/shims/swf/JarisFLVPlayer.swf +0 -0
  70. data/vendor/assets/javascripts/webshims/shims/track-ui.js +8 -1
  71. data/vendor/assets/javascripts/webshims/shims/track.js +66 -83
  72. metadata +12 -5
  73. data/vendor/assets/javascripts/webshims/shims/$ajax.js +0 -862
  74. data/vendor/assets/javascripts/webshims/shims/combos/24.js +0 -2087
@@ -0,0 +1,1283 @@
1
+ webshims.register('jme', function($, webshims, window, doc, undefined){
2
+ "use strict";
3
+ var props = {};
4
+ var fns = {};
5
+ var slice = Array.prototype.slice;
6
+
7
+ var options = $.extend({selector: '.mediaplayer'}, webshims.cfg.mediaelement.jme);
8
+ webshims.cfg.mediaelement.jme = options;
9
+
10
+
11
+ $.jme = {
12
+ plugins: {},
13
+ data: function(elem, name, value){
14
+ var data = $(elem).data('jme') || $.data(elem, 'jme', {});
15
+ if(value === undefined){
16
+ return (name) ? data[name] : data;
17
+ } else {
18
+ data[name] = value;
19
+ }
20
+ },
21
+ registerPlugin: function(name, plugin){
22
+ this.plugins[name] = plugin;
23
+ if(!plugin.nodeName){
24
+ plugin.nodeName = '';
25
+ }
26
+ if(!plugin.className){
27
+ plugin.className = name;
28
+ }
29
+
30
+ options[name] = $.extend(plugin.options || {}, options[name]);
31
+
32
+ if(options[name] && options[name].text){
33
+ plugin.text = options[name].text;
34
+ } else if(options.i18n && options.i18n[name]){
35
+ plugin.text = options.i18n[name];
36
+ }
37
+ },
38
+ defineMethod: function(name, fn){
39
+ fns[name] = fn;
40
+ },
41
+ defineProp: function(name, desc){
42
+ if(!desc){
43
+ desc = {};
44
+ }
45
+ if(!desc.set){
46
+ if(desc.readonly){
47
+ desc.set = function(){
48
+ throw(name +' is readonly');
49
+ };
50
+ } else {
51
+ desc.set = $.noop;
52
+ }
53
+ }
54
+ if(!desc.get){
55
+ desc.get = function(elem){
56
+ return $.jme.data(elem, name);
57
+ };
58
+ }
59
+ props[name] = desc;
60
+ },
61
+ prop: function(elem, name, value){
62
+ if(!props[name]){
63
+ return $.prop(elem, name, value);
64
+ }
65
+ if(value === undefined){
66
+ return props[name].get( elem );
67
+ } else {
68
+ var setValue = props[name].set(elem, value);
69
+ if(setValue === undefined){
70
+ setValue = value;
71
+ }
72
+ if(setValue != 'noDataSet'){
73
+ $.jme.data(elem, name, setValue);
74
+ }
75
+ }
76
+ }
77
+ };
78
+
79
+ $.fn.jmeProp = function(name, value){
80
+ return $.access( this, $.jme.prop, name, value, arguments.length > 1 );
81
+ };
82
+
83
+ $.fn.jmeFn = function(fn){
84
+ var args = slice.call( arguments, 1 );
85
+ var ret;
86
+ this.each(function(){
87
+ ret = (fns[fn] || $.prop(this, fn)).apply(this, args);
88
+ if(ret !== undefined){
89
+ return false;
90
+ }
91
+ });
92
+ return (ret !== undefined) ? ret : this;
93
+ };
94
+ var idlStates = {
95
+ emptied: 1,
96
+ pause: 1
97
+ };
98
+ var unwaitingEvents = {
99
+ canplay: 1, canplaythrough: 1
100
+ };
101
+
102
+
103
+ var baseSelector = options.selector;
104
+
105
+ $.jme.initJME = function(context, insertedElement){
106
+ $(baseSelector, context).add(insertedElement.filter(baseSelector)).jmePlayer();
107
+ };
108
+
109
+
110
+ $.jme.getDOMList = function(attr){
111
+ var list = [];
112
+ if(!attr){
113
+ attr = [];
114
+ }
115
+ if(typeof attr == 'string'){
116
+ attr = attr.split(' ');
117
+ }
118
+ $.each(attr, function(i, id){
119
+ if(id){
120
+ id = document.getElementById(id);
121
+ if(id){
122
+ list.push(id);
123
+ }
124
+ }
125
+ });
126
+ return list;
127
+ };
128
+
129
+
130
+ $.jme.getButtonText = function(button, classes){
131
+ var isCheckbox;
132
+ var lastState;
133
+ var txtChangeFn = function(state){
134
+ if(lastState === state){return;}
135
+ lastState = state;
136
+
137
+
138
+ button
139
+ .removeClass(classes[(state) ? 0 : 1])
140
+ .addClass(classes[state])
141
+ ;
142
+
143
+ if(isCheckbox){
144
+ button.prop('checked', !!state);
145
+ (button.data('checkboxradio') || {refresh: $.noop}).refresh();
146
+ }
147
+ };
148
+
149
+ if (button.is('[type="checkbox"], [type="radio"]')){
150
+ button.prop('checked', function(){
151
+ return this.defaultChecked;
152
+ });
153
+ isCheckbox = true;
154
+ } else if(button.is('a')){
155
+ button.on('click', function(e){
156
+ e.preventDefault();
157
+ });
158
+ }
159
+
160
+ return txtChangeFn;
161
+ };
162
+
163
+ $.fn.jmePlayer = function(opts){
164
+
165
+ return this.each(function(){
166
+ if(opts){
167
+ $.jme.data(this, $.extend(true, {}, opts));
168
+ }
169
+
170
+ var mediaUpdateFn, canPlay, removeCanPlay, canplayTimer, lastState, stopEmptiedEvent;
171
+ var media = $('audio, video', this).eq(0);
172
+ var base = $(this);
173
+
174
+ var jmeData = $.jme.data(this);
175
+ var mediaData = $.jme.data(media[0]);
176
+
177
+
178
+ base.addClass(media.prop('nodeName').toLowerCase()+'player');
179
+ mediaData.player = base;
180
+ mediaData.media = media;
181
+ if(!jmeData.media){
182
+
183
+ removeCanPlay = function(){
184
+ media.off('canplay', canPlay);
185
+ clearTimeout(canplayTimer);
186
+ };
187
+ canPlay = function(){
188
+ var state = (media.prop('paused')) ? 'idle' : 'playing';
189
+ base.attr('data-state', state);
190
+ };
191
+ mediaUpdateFn = function(e){
192
+ var state = e.type;
193
+ var readyState;
194
+ var paused;
195
+ removeCanPlay();
196
+
197
+ if(unwaitingEvents[state] && lastState != 'waiting'){
198
+ return;
199
+ }
200
+
201
+ if(stopEmptiedEvent && state == 'emptied'){
202
+ return;
203
+ }
204
+
205
+ if(state == 'ended' || $.prop(this, 'ended')){
206
+ state = 'ended';
207
+ } else if(state == 'waiting'){
208
+
209
+ if($.prop(this, 'readyState') > 2){
210
+ state = '';
211
+ } else {
212
+ canplayTimer = setTimeout(function(){
213
+ if(media.prop('readyState') > 2){
214
+ canPlay();
215
+ }
216
+ }, 9);
217
+ media.on('canPlay', canPlay);
218
+ }
219
+
220
+ } else if(idlStates[state]){
221
+ state = 'idle';
222
+ } else {
223
+ readyState = $.prop(this, 'readyState');
224
+ paused = $.prop(this, 'paused');
225
+ if(!paused && readyState < 3){
226
+ state = 'waiting';
227
+ } else if(!paused && readyState > 2){
228
+ state = 'playing';
229
+ } else {
230
+ state = 'idle';
231
+ }
232
+ }
233
+
234
+ if(state == 'idle' && base._seekpause){
235
+ state = false;
236
+ }
237
+
238
+ if(state){
239
+ lastState = state;
240
+ base.attr('data-state', state);
241
+ }
242
+ };
243
+
244
+
245
+ jmeData.media = media;
246
+ jmeData.player = base;
247
+ media
248
+ .on('ended emptied play', (function(){
249
+ var timer;
250
+ var releaseEmptied = function(){
251
+ stopEmptiedEvent = false;
252
+ };
253
+ var ended = function(){
254
+ removeCanPlay();
255
+ media.jmeFn('pause');
256
+ if(!options.noReload && media.prop('ended') && media.prop('paused') && !media.prop('autoplay') && !media.prop('loop') && !media.hasClass('no-reload')){
257
+ stopEmptiedEvent = true;
258
+ media.jmeFn('load');
259
+ base.attr('data-state', 'ended');
260
+ setTimeout(releaseEmptied);
261
+
262
+ }
263
+ };
264
+ return function(e){
265
+
266
+ clearTimeout(timer);
267
+ if(e.type == 'ended' && !options.noReload && !media.prop('autoplay') && !media.prop('loop') && !media.hasClass('no-reload')){
268
+ timer = setTimeout(ended);
269
+ }
270
+ };
271
+ })())
272
+ .on('emptied waiting canplay canplaythrough playing ended pause mediaerror', mediaUpdateFn)
273
+ .on('volumechange updateJMEState', function(){
274
+ var volume = $.prop(this, 'volume');
275
+ base[!volume || $.prop(this, 'muted') ? 'addClass' : 'removeClass']('state-muted');
276
+
277
+ if(volume < 0.01){
278
+ volume = 'no';
279
+ } else if(volume < 0.36){
280
+ volume = 'low';
281
+ } else if(volume < 0.7){
282
+ volume = 'medium';
283
+ } else {
284
+ volume = 'high';
285
+ }
286
+ base.attr('data-volume', volume);
287
+ })
288
+ ;
289
+
290
+ if(mediaUpdateFn){
291
+ media.on('updateJMEState', mediaUpdateFn).triggerHandler('updateJMEState');
292
+ }
293
+ }
294
+ });
295
+ };
296
+
297
+
298
+ $.jme.defineProp('isPlaying', {
299
+ get: function(elem){
300
+ return (!$.prop(elem, 'ended') && !$.prop(elem, 'paused') && $.prop(elem, 'readyState') > 1 && !$.data(elem, 'mediaerror'));
301
+ },
302
+ readonly: true
303
+ });
304
+
305
+ $.jme.defineProp('player', {
306
+ readonly: true
307
+ });
308
+
309
+ $.jme.defineProp('media', {
310
+ readonly: true
311
+ });
312
+
313
+ $.jme.defineProp('srces', {
314
+ get: function(elem){
315
+ var srces;
316
+ var data = $.jme.data(elem);
317
+ var src = data.media.prop('src');
318
+ if(src){
319
+ return [{src: src}];
320
+ }
321
+ srces = $.map($('source', data.media).get(), function(source){
322
+ var src = {
323
+ src: $.prop(source, 'src')
324
+ };
325
+ var tmp = $.attr(source, 'media');
326
+ if(tmp){
327
+ src.media = tmp;
328
+ }
329
+ tmp = $.attr(source, 'type');
330
+ if(tmp){
331
+ src.type = tmp;
332
+ }
333
+ return src;
334
+ });
335
+ return srces;
336
+ },
337
+ set: function(elem, srces){
338
+ var data = $.jme.data(elem);
339
+
340
+ var setSrc = function(i, src){
341
+ if(typeof src == 'string'){
342
+ src = {src: src};
343
+ }
344
+ $(document.createElement('source')).attr(src).appendTo(data.media);
345
+ };
346
+ data.media.removeAttr('src').find('source').remove();
347
+ if($.isArray(srces)){
348
+ $.each(srces, setSrc);
349
+ } else {
350
+ setSrc(0, srces);
351
+ }
352
+ data.media.jmeFn('load');
353
+ return 'noDataSet';
354
+ }
355
+ });
356
+
357
+ $.jme.defineMethod('togglePlay', function(){
358
+ $(this).jmeFn( ( props.isPlaying.get(this) ) ? 'pause' : 'play' );
359
+ });
360
+
361
+
362
+ $.jme.defineMethod('addControls', function(controls){
363
+ var data = $.jme.data(this) || {};
364
+
365
+ if(!data.media){return;}
366
+ var oldControls = $.jme.data(data.player[0], 'controlElements') || $([]);
367
+ controls = $(controls);
368
+ $.each($.jme.plugins, function(name, plugin){
369
+ controls
370
+ .filter('.'+plugin.className)
371
+ .add(controls.find('.'+plugin.className))
372
+ .each(function(){
373
+ var control = $(this);
374
+ var options = $.jme.data(this);
375
+ options.player = data.player;
376
+ options.media = data.media;
377
+ if(options._rendered){return;}
378
+ options._rendered = true;
379
+
380
+ if(plugin.options){
381
+ $.each(plugin.options, function(option, value){
382
+ if(!(option in options)){
383
+ options[option] = value;
384
+ }
385
+ });
386
+ }
387
+ plugin._create(control, data.media, data.player, options);
388
+ control = null;
389
+ })
390
+ ;
391
+ });
392
+
393
+ $.jme.data(data.player[0], 'controlElements', oldControls.add(controls));
394
+
395
+ data.player.triggerHandler('controlsadded');
396
+ });
397
+
398
+
399
+ webshims.addReady($.jme.initJME);
400
+ webshims._polyfill(['mediaelement']);
401
+ });
402
+ ;webshims.register('mediacontrols', function($, webshims, window){
403
+ "use strict";
404
+ var pseudoClasses = 'pseudoClasses';
405
+
406
+ var options = webshims.cfg.mediaelement.jme;
407
+ var baseSelector = options.selector;
408
+
409
+ var btnStructure = '<button class="{%class%}" type="button" aria-label="{%text%}"></button>';
410
+ var slideStructure = '<div class="{%class%} media-range"></div>';
411
+ var timeStructure = '<div class="{%class%}">00:00</div>';
412
+
413
+ var noVolumeClass = (function(){
414
+ var audio;
415
+ var ret = '';
416
+ if(typeof window.Audio == 'function'){
417
+ audio = new Audio();
418
+ audio.volume = 0.55;
419
+ ret = audio.volume = 0.55 ? '' : ' no-volume-api';
420
+ }
421
+ return ret;
422
+ })();
423
+
424
+ var getBarHtml = (function(){
425
+ var cache = {};
426
+ var regTemplate = /\{\{(.+?)\}\}/igm;
427
+
428
+ return function(template, invalidCache){
429
+ if(!template){
430
+ template = options.barTemplate;
431
+ }
432
+ if(!cache[template] || invalidCache){
433
+ cache[template] = template.replace(regTemplate, function(match, matchName){
434
+ var plugin = $.jme.plugins[matchName];
435
+ if(plugin && plugin.structure){
436
+ return plugin.structure.replace('{%class%}', matchName).replace('{%text%}', plugin.text || '');
437
+ }
438
+ return match;
439
+ });
440
+ }
441
+
442
+ return cache[template] || '';
443
+ };
444
+ })();
445
+
446
+ var loadLazy = function(){
447
+ if(!loadLazy.loaded){
448
+ loadLazy.loaded = true;
449
+ webshims.loader.loadList(['mediacontrols-lazy', 'range-ui']);
450
+ }
451
+ };
452
+ var lazyLoadPlugin = function(fn){
453
+ if(!fn){
454
+ fn = '_create';
455
+ }
456
+ var rfn = function(c, media){
457
+ var obj = this;
458
+ var args = arguments;
459
+ loadLazy();
460
+ webshims.ready('mediacontrols-lazy', function(){
461
+ if(rfn != obj[fn] && $.data(media[0])){
462
+ return obj[fn].apply(obj, args);
463
+ } else {
464
+ webshims.error('stop too much recursion');
465
+ }
466
+ });
467
+ };
468
+ return rfn;
469
+ };
470
+
471
+ if(!options.barTemplate){
472
+ options.barTemplate = '<div class="play-pause-container">{{play-pause}}</div><div class="playlist-container"><div class="playlist-box">{{playlist-prev}}{{playlist-next}}</div></div><div class="currenttime-container">{{currenttime-display}}</div><div class="progress-container">{{time-slider}}</div><div class="duration-container">{{duration-display}}</div><div class="mute-container">{{mute-unmute}}</div><div class="volume-container">{{volume-slider}}</div><div class="subtitle-container"><div class="subtitle-controls">{{captions}}</div></div><div class="fullscreen-container">{{fullscreen}}</div>';
473
+ }
474
+ if(!options.barStructure){
475
+ options.barStructure = '<div class="jme-media-overlay"></div><div class="jme-controlbar'+ noVolumeClass +'" tabindex="-1"><div class="jme-cb-box"></div></div>';
476
+ }
477
+
478
+ webshims.loader.addModule('mediacontrols-lazy', {
479
+ src: 'jme/mediacontrols-lazy'
480
+ });
481
+
482
+ var userActivity = {
483
+ _create: lazyLoadPlugin()
484
+ };
485
+ $.jme.plugins.useractivity = userActivity;
486
+
487
+ $.jme.defineProp('controlbar', {
488
+ set: function(elem, value){
489
+ value = !!value;
490
+ var controls, playerSize;
491
+ var data = $.jme.data(elem);
492
+ var controlBar = $('div.jme-mediaoverlay, div.jme-controlbar', data.player);
493
+ var structure = '';
494
+ if(value && !controlBar[0]){
495
+ if(data._controlbar){
496
+ data._controlbar.appendTo(data.player);
497
+ } else {
498
+ data.media.prop('controls', false);
499
+
500
+ structure = getBarHtml();
501
+ data._controlbar = $( options.barStructure );
502
+ controlBar = data._controlbar.find('div.jme-cb-box').addClass('media-controls');
503
+ controls = data._controlbar.filter('.jme-media-overlay').addClass('play-pause');
504
+ controls = controls.add( controlBar );
505
+ $(structure).appendTo(controlBar);
506
+ data._controlbar.appendTo(data.player);
507
+ data.player.jmeFn('addControls', controls);
508
+
509
+ playerSize = (function(){
510
+ var lastSize;
511
+ var sizes = [
512
+ {size: 290, name: 'xx-small'},
513
+ {size: 380, name: 'x-small'},
514
+ {size: 490, name: 'small'},
515
+ {size: 756, name: 'medium'},
516
+ {size: 1024, name: 'large'}
517
+ ];
518
+
519
+ var len = sizes.length;
520
+ return function(){
521
+ var size = 'x-large';
522
+ var i = 0;
523
+ var width = data.player.outerWidth();
524
+ var fSize = Math.max(parseInt(data.player.css('fontSize'), 10) || 16, 13);
525
+
526
+ width = width * (16 / fSize);
527
+ for(; i < len; i++){
528
+ if(sizes[i].size >= width){
529
+ size = sizes[i].name;
530
+ break;
531
+ }
532
+ }
533
+
534
+ if(lastSize != size){
535
+ lastSize = size;
536
+ data.player.attr('data-playersize', size);
537
+ }
538
+ };
539
+ })();
540
+
541
+
542
+ userActivity._create(data.player, data.media, data.player);
543
+
544
+ playerSize();
545
+ webshims.ready('dom-support', function(){
546
+ data.player.onWSOff('updateshadowdom', playerSize);
547
+ webshims.addShadowDom();
548
+ });
549
+ }
550
+
551
+ } else if(!value) {
552
+ controlBar.detach();
553
+ }
554
+ controlBar = null;
555
+ controls = null;
556
+ return value;
557
+ }
558
+ });
559
+
560
+ $.jme.registerPlugin('play-pause', {
561
+
562
+ structure: btnStructure,
563
+ text: 'play / pause',
564
+ _create: lazyLoadPlugin()
565
+ });
566
+
567
+ $.jme.registerPlugin('mute-unmute', {
568
+
569
+ structure: btnStructure,
570
+ text: 'mute / unmute',
571
+ _create: lazyLoadPlugin()
572
+ });
573
+
574
+
575
+ $.jme.registerPlugin('volume-slider', {
576
+ structure: slideStructure,
577
+
578
+ _create: lazyLoadPlugin()
579
+ });
580
+
581
+ $.jme.registerPlugin('time-slider', {
582
+ structure: slideStructure,
583
+
584
+ options: {
585
+ format: ['mm', 'ss']
586
+ },
587
+ _create: lazyLoadPlugin()
588
+ });
589
+
590
+
591
+ $.jme.defineProp('format', {
592
+ set: function(elem, format){
593
+ if(!$.isArray(format)){
594
+ format = format.split(':');
595
+ }
596
+ var data = $.jme.data(elem);
597
+ data.format = format;
598
+ $(elem).triggerHandler('updatetimeformat');
599
+ data.player.triggerHandler('updatetimeformat');
600
+ return 'noDataSet';
601
+ }
602
+ });
603
+
604
+ $.jme.registerPlugin('duration-display', {
605
+ structure: timeStructure,
606
+ options: {
607
+ format: "mm:ss"
608
+ },
609
+ _create: lazyLoadPlugin()
610
+ });
611
+
612
+ $.jme.defineProp('countdown', {
613
+ set: function(elem, value){
614
+
615
+ var data = $.jme.data(elem);
616
+ data.countdown = !!value;
617
+ $(elem).triggerHandler('updatetimeformat');
618
+ data.player.triggerHandler('updatetimeformat');
619
+ return 'noDataSet';
620
+ }
621
+ });
622
+
623
+ $.jme.registerPlugin('currenttime-display', {
624
+ structure: timeStructure,
625
+ options: {
626
+ format: "mm:ss",
627
+ countdown: false
628
+ },
629
+ _create: lazyLoadPlugin()
630
+ });
631
+
632
+
633
+ /**
634
+ * Added Poster Plugin
635
+ * @author mderting
636
+ */
637
+
638
+ /*
639
+ * the old technique wasn't fully bullet proof
640
+ * beside this, jme2 adovactes to use the new improved state-classes to handle visual effect on specific state (see CSS change)
641
+ */
642
+ $.jme.registerPlugin('poster-display', {
643
+ structure: '<div />',
644
+ options: {
645
+ },
646
+ _create: lazyLoadPlugin()
647
+ });
648
+
649
+
650
+ $.jme.registerPlugin('fullscreen', {
651
+
652
+ options: {
653
+ fullscreen: true,
654
+ autoplayfs: false
655
+ },
656
+ structure: btnStructure,
657
+ text: 'enter fullscreen / exit fullscreen',
658
+ _create: lazyLoadPlugin()
659
+ });
660
+
661
+
662
+ $.jme.registerPlugin('captions', {
663
+ structure: btnStructure,
664
+ text: 'subtitles',
665
+ _create: function(control, media, base){
666
+ var trackElems = media.find('track');
667
+ control.wsclonedcheckbox = $(control).clone().attr({role: 'checkbox'}).insertBefore(control);
668
+ base.attr('data-tracks', trackElems.length > 1 ? 'many' : trackElems.length);
669
+ control.attr('aria-haspopup', 'true');
670
+ lazyLoadPlugin().apply(this, arguments);
671
+ }
672
+ });
673
+
674
+ webshims.ready(webshims.cfg.mediaelement.plugins.concat(['mediaelement']), function(){
675
+ webshims.addReady(function(context, insertedElement){
676
+ $(baseSelector, context).add(insertedElement.filter(baseSelector)).jmeProp('controlbar', true);
677
+ });
678
+ });
679
+ webshims.ready('WINDOWLOAD', loadLazy);
680
+ });
681
+ ;webshims.ready('jme DOM', function(){
682
+ "use strict";
683
+ var webshims = window.webshims;
684
+ var $ = webshims.$;
685
+ var jme = $.jme;
686
+ var listId = 0;
687
+ var btnStructure = '<button class="{%class%}" type="button" aria-label="{%text%}"></button>';
688
+
689
+ function PlaylistList(data){
690
+ this._data = data;
691
+ this.lists = {};
692
+
693
+ this.on('showcontrolschange', this._updateControlsClass);
694
+ }
695
+
696
+ $.extend(PlaylistList.prototype, {
697
+ on: function(){
698
+ $.fn.on.apply($(this), arguments);
699
+ },
700
+ off: function(){
701
+ $.fn.off.apply($(this), arguments);
702
+ },
703
+ _getListId: function(list){
704
+ var id;
705
+ if(typeof list == 'string'){
706
+ id = list;
707
+ } else {
708
+ id = list.id;
709
+ }
710
+ return id;
711
+ },
712
+ _updateControlsClass: function(){
713
+ this._data.player[this.getShowcontrolsList() ? 'addClass' : 'removeClass']('has-playlist');
714
+ },
715
+ add: function(list, opts){
716
+
717
+ list = new Playlist(list, this, opts);
718
+ if(!list.id){
719
+ listId++;
720
+ list.id = 'list-'+listId;
721
+ }
722
+ this.lists[list.id] = list;
723
+
724
+ if(list.options.showcontrols){
725
+ this._data.player.addClass('has-playlist');
726
+ }
727
+
728
+ return list;
729
+ },
730
+ remove: function(list){
731
+ var id = this._getListId(list);
732
+ if(this.lists[id]){
733
+ this.lists[id]._remove();
734
+ delete this.lists[id];
735
+ }
736
+ if(!this.getShowcontrolsList()){
737
+ this._data.player.removeClass('has-playlist');
738
+ }
739
+ },
740
+ getAutoplayList: function(){
741
+ var clist = null;
742
+ $.each(this.lists, function(id, list){
743
+ if(list.options.autoplay){
744
+ clist = list;
745
+ return false;
746
+ }
747
+ });
748
+ return clist;
749
+ },
750
+ getShowcontrolsList: function(){
751
+ var clist = null;
752
+ $.each(this.lists, function(id, list){
753
+ if(list.options.showcontrols){
754
+ clist = list;
755
+ return false;
756
+ }
757
+ });
758
+ return clist;
759
+ }
760
+
761
+ });
762
+
763
+ function Playlist(list, parent, opts){
764
+ this.list = list || [];
765
+ this.playlists = parent;
766
+ this.media = parent._data.media;
767
+ this.player = parent._data.player;
768
+ this.options = $.extend(true, {}, Playlist.defaults, opts);
769
+ this.options.itemTmpl = this.options.itemTmpl.trim();
770
+
771
+ this.deferred = $.Deferred();
772
+ this._selectedIndex = -1;
773
+ this._selectedItem = null;
774
+ this.$rendered = null;
775
+
776
+ this._detectListType();
777
+
778
+ this.autoplay(this.options.autoplay);
779
+
780
+ this.deferred.done(function(){
781
+ this._addEvents(this);
782
+ if(this.options.defaultSelected == 'auto' && !this.media.jmeProp('srces').length){
783
+ this.options.defaultSelected = 0;
784
+ }
785
+ if(this.list[this.options.defaultSelected]){
786
+ this.selectedIndex(this.options.defaultSelected);
787
+ }
788
+ this._fire('addlist');
789
+ });
790
+ }
791
+
792
+ Playlist.getText = function($elem){
793
+ return $elem.attr('content') || ($elem.text() || '').trim();
794
+ };
795
+ Playlist.getUrl = function($elem){
796
+ return $elem.attr('content') || $elem.attr('url') || $elem.attr('href') || $elem.attr('src') || ($elem.text() || '').trim();
797
+ };
798
+
799
+ Playlist.defaults = {
800
+ loop: false,
801
+ autoplay: false,
802
+ defaultSelected: 'auto',
803
+ addItemEvents: true,
804
+ showcontrols: true,
805
+ ajax: {},
806
+ itemTmpl: '<li class="list-item">' +
807
+ '<% if(typeof poster == "string" && poster) {%><img src="<%=poster%>" /><% }%>' +
808
+ '<h3><%=title%></h3>' +
809
+ '<% if(typeof description == "string" && description) {%><div class="item-description"><%=description%></div><% }%>' +
810
+ '</li>',
811
+ renderer: function(item, template){
812
+ return $.jme.tmpl(template, item);
813
+ },
814
+ mapDom: function(element){
815
+
816
+ return {
817
+ title: Playlist.getText($('[itemprop="name"], h1, h2, h3, h4, h5, h6, a', element)),
818
+ srces: $('[itemprop="contentUrl"], a[type^="video"], a[type^="audio"]', element).map(function(){
819
+ var tmp;
820
+ var src = {src: Playlist.getUrl($(this))};
821
+ if(this.nodeName.toLowerCase() == 'a'){
822
+ tmp = $.prop(this, 'type');
823
+ } else {
824
+ tmp = Playlist.getText($('[itemprop="encodingFormat"]', element));
825
+ }
826
+ if(tmp){
827
+ src.type = tmp;
828
+ }
829
+ tmp = $.attr(this, 'data-media');
830
+ if(tmp){
831
+ src.media = tmp;
832
+ }
833
+ return src;
834
+ }).get(),
835
+ tracks: $('a[type="text/vtt"]').map(mapTrackUrl).get(),
836
+ poster: Playlist.getUrl($('[itemprop="thumbnailUrl"], a[type^="image"], img', element)) || null,
837
+ description: Playlist.getText($('[itemprop="description"], .item-description, p', element)) || null
838
+ };
839
+ },
840
+ mapUrl: function(opts, callback){
841
+ $.ajax($.extend(opts, {
842
+ success: function(data){
843
+ var list;
844
+ if($.isArray(data)){
845
+ list = data;
846
+ } else if(data.responseData && data.responseData.feed){
847
+ data = data.responseData.feed;
848
+ list = (data.entries || []).map(mapJsonFeed);
849
+ } else {
850
+ list = [];
851
+ $('item', data).each(function(){
852
+ var srces = $('enclosure, media\\:content', this)
853
+ .filter('[type^="video"], [type^="audio"]')
854
+ .map(mapUrl)
855
+ .get()
856
+ ;
857
+ if(srces.length){
858
+ list.push({
859
+ title: $('title', this).html(),
860
+ srces: srces,
861
+ publishedDate: $('pubDate', this).html() || null,
862
+ description: $('description', this).text() || null,
863
+ poster: Playlist.getUrl($('itunes\\:image, media\\:thumbnail, enclosure[type^="image"], media\\:content[type^="image"]', this)) || null,
864
+ author: $('itunes\\:author', this).html() || null,
865
+ duration: $('itunes\\:duration', this).html() || null,
866
+ tracks: $('media\\:subTitle', this).map(mapTrackUrl).get() || null
867
+ });
868
+ }
869
+ });
870
+ }
871
+ if(list != data){
872
+ list.fullData = data;
873
+ }
874
+ callback(list);
875
+ }
876
+ }));
877
+ }
878
+ };
879
+
880
+ function mapJsonFeed(item){
881
+ item.description = item.description || item.content;
882
+ item.srces = [];
883
+ (item.mediaGroups || []).forEach(function(mediagroup){
884
+ (mediagroup.contents || []).forEach(function(itemSrc){
885
+ itemSrc.src = itemSrc.src || itemSrc.url;
886
+ item.srces.push(itemSrc);
887
+ });
888
+ });
889
+ return item;
890
+ }
891
+
892
+ function mapTrackUrl(){
893
+ return {
894
+ src: $.attr(this, 'href'),
895
+ srclang: $.attr(this, 'lang'),
896
+ label: $.attr(this, 'data-label')
897
+ };
898
+ }
899
+
900
+ function mapUrl(){
901
+ return {
902
+ src: $.attr(this, 'url') || $.attr(this, 'href'),
903
+ type: $.attr(this, 'type')
904
+ };
905
+ }
906
+
907
+ function filterNode(){
908
+ return this.nodeType == 1;
909
+ }
910
+
911
+ $.extend(Playlist.prototype, {
912
+ on: function(){
913
+ $.fn.on.apply($(this), arguments);
914
+ },
915
+ off: function(){
916
+ $.fn.off.apply($(this), arguments);
917
+ },
918
+ _detectListType: function(){
919
+ var fullData;
920
+ if(typeof this.list == 'string'){
921
+ this._createListFromUrl();
922
+ return;
923
+ }
924
+ if(this.list.nodeName || (this.list.length > 0 && this.list[0].nodeName)){
925
+ this._createListFromDom();
926
+ } else if(this.list.responseData && this.list.responseData.feed){
927
+ fullData = this.list.responseData.feed;
928
+ this.list = (fullData.entries || []).map(mapJsonFeed);
929
+ this.list.fullData = fullData;
930
+ }
931
+ this.deferred.resolveWith(this);
932
+
933
+ },
934
+ _createListFromUrl: function(){
935
+ var that = this;
936
+ this.options.ajax.url = this.list;
937
+ this.options.mapUrl(this.options.ajax, function(list){
938
+ that.list = list;
939
+ that.deferred.resolveWith(that);
940
+ });
941
+ },
942
+ _createListFromDom: function(){
943
+ var that = this;
944
+
945
+ this.$rendered = $(this.list).eq(0);
946
+ this.list = [];
947
+
948
+ if(this.$rendered){
949
+ this._addDomList();
950
+ this.list = this.$rendered.children().map(function(){
951
+ return that._createItemFromDom(this);
952
+ }).get();
953
+ }
954
+ },
955
+ _createItemFromDom: function(dom){
956
+ var item = this.options.mapDom(dom);
957
+ this._addItemData(item, dom);
958
+ return item;
959
+ },
960
+ _fire: function(evt, extra){
961
+ var evt = $.Event(evt);
962
+ $(this).triggerHandler(evt, extra);
963
+ $(this.playlists).triggerHandler(evt, $.merge([{list: this}], extra || []));
964
+ if(this.$rendered){
965
+ this.$rendered.triggerHandler(evt, extra);
966
+ }
967
+ },
968
+ _addDomList: function(){
969
+ this.$rendered
970
+ .attr({
971
+ 'data-autoplay': this.options.autoplay,
972
+ 'data-loop': this.options.loop
973
+ })
974
+ .addClass('media-playlist')
975
+ .data('playlist', this)
976
+ ;
977
+ },
978
+ _addItemData: function(item, dom){
979
+ var that = this;
980
+ item.$item = $(dom).data('itemData', item);
981
+
982
+ if(item == this._selectedItem){
983
+ item.$item.addClass('selected-item');
984
+ }
985
+ if(this.options.addItemEvents){
986
+ item.$item.on('click.playlist', function(e){
987
+ if(that.options.addItemEvents){
988
+ that.playItem(item, e);
989
+ return false;
990
+ }
991
+ });
992
+ }
993
+ },
994
+ _addEvents: function(that){
995
+ var o = that.options;
996
+ var onEnded = function(e){
997
+ if(o.autoplay){
998
+ that.playNext(e);
999
+ }
1000
+ };
1001
+ this.media.on('ended', onEnded);
1002
+ this._remove = function(){
1003
+ that.media.off('ended', onEnded);
1004
+ that.autoplay(false);
1005
+
1006
+ if(that.$rendered){
1007
+ that.$rendered.remove();
1008
+ }
1009
+
1010
+ that._fire('removelist');
1011
+ };
1012
+ },
1013
+ _remove: function(){
1014
+ this._fire('removelist');
1015
+ },
1016
+ render: function(callback){
1017
+ if(this.$rendered){
1018
+ callback(this.$rendered, this.player, this);
1019
+ } else {
1020
+ this.deferred.done(function(){
1021
+ var nodeName;
1022
+ var that = this;
1023
+ var items = [];
1024
+ if(!this.$rendered){
1025
+ $.each(this.list, function(i, item){
1026
+ var domItem = $($.parseHTML(that.options.renderer(item, that.options.itemTmpl))).filter(filterNode)[0];
1027
+ that._addItemData(item, domItem);
1028
+ items.push(domItem);
1029
+ });
1030
+ nodeName = (items[0] && items[0].nodeName || '').toLowerCase();
1031
+
1032
+ switch (nodeName){
1033
+ case 'li':
1034
+ this.$rendered = $.parseHTML('<ul />');
1035
+ break;
1036
+ case 'option':
1037
+ this.$rendered = $.parseHTML('<select />');
1038
+ break;
1039
+ default:
1040
+ this.$rendered = $.parseHTML('<div />');
1041
+ break;
1042
+ }
1043
+ this.$rendered = $(this.$rendered).html(items);
1044
+ this._addDomList();
1045
+ }
1046
+ callback(this.$rendered, this.player, this);
1047
+ });
1048
+ }
1049
+ },
1050
+ /*
1051
+
1052
+ addItem: function(item, pos){
1053
+
1054
+ },
1055
+ removeItem: function(item){
1056
+
1057
+ },
1058
+ */
1059
+ _loadItem: function(item){
1060
+ var media = this.media;
1061
+ media.attr('poster', item.poster || '');
1062
+
1063
+ $('track', media).remove();
1064
+
1065
+ $.each(item.tracks || [], function(i, track){
1066
+ $('<track />').attr(track).appendTo(media);
1067
+ });
1068
+
1069
+ media.jmeProp('srces', item.srces);
1070
+ },
1071
+ _getItem: function(item){
1072
+ if(item && (item.nodeName || item.jquery || typeof item == 'string')){
1073
+ item = $(item).data('itemData');
1074
+ }
1075
+ return item;
1076
+ },
1077
+ playItem: function(item, e){
1078
+ var media;
1079
+ this.selectedItem(item, e);
1080
+ if(item){
1081
+ media = this.media.play();
1082
+ setTimeout(function(){
1083
+ media.play();
1084
+ }, 9);
1085
+ }
1086
+ },
1087
+ selectedIndex: function(index, e){
1088
+ if(arguments.length){
1089
+ this.selectedItem(this.list[index], e);
1090
+ } else {
1091
+ return this._selectedIndex;
1092
+ }
1093
+ },
1094
+
1095
+ selectedItem: function(item, e){
1096
+ var oldItem, found;
1097
+
1098
+ if(arguments.length){
1099
+ found = -1;
1100
+ item = this._getItem(item);
1101
+ if(item){
1102
+ $.each(this.list, function(i){
1103
+ if(item == this){
1104
+ found = i;
1105
+ return false;
1106
+ }
1107
+ });
1108
+ }
1109
+
1110
+ if(found >= 0){
1111
+ this._loadItem(this.list[found]);
1112
+ }
1113
+
1114
+ if(found != this._selectedIndex){
1115
+ oldItem = this._selectedItem || null;
1116
+ if(oldItem && oldItem.$item){
1117
+ oldItem.$item.removeClass('selected-item');
1118
+ }
1119
+ this._selectedItem = this.list[found] || null;
1120
+ this._selectedIndex = found;
1121
+ if(this._selectedItem && this._selectedItem.$item){
1122
+ this._selectedItem.$item.addClass('selected-item');
1123
+ }
1124
+ if(oldItem !== this._selectedItem){
1125
+ this._fire('itemchange', [{oldItem: oldItem, from: e || null}]);
1126
+ }
1127
+ }
1128
+
1129
+ } else {
1130
+ return this._selectedItem;
1131
+ }
1132
+ },
1133
+ playNext: function(){
1134
+ var item = this.getNext();
1135
+ if(item){
1136
+ this.playItem(item);
1137
+ }
1138
+ },
1139
+ playPrev: function(){
1140
+ var item = this.getPrev();
1141
+ if(item){
1142
+ this.playItem(item);
1143
+ }
1144
+ },
1145
+ getNext: function(){
1146
+ var index = this._selectedIndex + 1;
1147
+ return this.list[index] || (this.options.loop ? this.list[0] : null);
1148
+ },
1149
+ getPrev: function(){
1150
+ var index = this._selectedIndex - 1;
1151
+ return this.list[index] || (this.options.loop ? this.list[this.list.length - 1] : null);
1152
+ }
1153
+ });
1154
+
1155
+ [{name: 'autoplay', fn: 'getAutoplayList'}, {name: 'showcontrols', fn: 'getShowcontrolsList'}, {name: 'loop'}].forEach(function(desc){
1156
+ Playlist.prototype[desc.name] = function(value){
1157
+ var curList;
1158
+ if(arguments.length){
1159
+ value = !!value;
1160
+
1161
+ if(value && desc.fn){
1162
+ curList = this.playlists[desc.fn]();
1163
+ if(curList && curList != this){
1164
+ curList[desc.name](false);
1165
+ }
1166
+ }
1167
+
1168
+ if(this.options[desc.name] != value){
1169
+ this.options[desc.name] = value;
1170
+ if(this.$rendered){
1171
+ this.$rendered.attr('data-'+desc.name, value);
1172
+ }
1173
+ this._fire(desc.name+'change');
1174
+ }
1175
+ } else {
1176
+ return this.options[desc.name];
1177
+ }
1178
+ }
1179
+ });
1180
+
1181
+ jme.defineProp('playlists', {
1182
+ writable: false,
1183
+ get: function(elem){
1184
+ var data = $.jme.data(elem);
1185
+
1186
+ if(elem != data.player[0]){return null;}
1187
+ if(!data.playlists){
1188
+ data.playlists = new PlaylistList(data);
1189
+ }
1190
+ return data.playlists;
1191
+ }
1192
+ });
1193
+
1194
+ jme.defineMethod('addPlaylist', function(list, options){
1195
+ var playlists = $.jme.prop(this, 'playlists');
1196
+ if(playlists && playlists.add){
1197
+ return playlists.add(list, options);
1198
+ }
1199
+ return null;
1200
+ });
1201
+
1202
+ [
1203
+ {name: 'playlist-prev', text: 'previous', get: 'getPrev', play: 'playPrev'},
1204
+ {name: 'playlist-next', text: 'next', get: 'getNext', play: 'playNext'}
1205
+ ]
1206
+ .forEach(function(desc){
1207
+ $.jme.registerPlugin(desc.name, {
1208
+ structure: btnStructure,
1209
+ text: desc.text,
1210
+ _create: function(control, media, base){
1211
+ var cList;
1212
+ var playlists = base.jmeProp('playlists');
1213
+
1214
+ function itemChange(){
1215
+ var item = cList[desc.get]();
1216
+ if(item){
1217
+ control.prop({'disabled': false, title: item.title});
1218
+ } else {
1219
+ control.prop({'disabled': true, title: ''});
1220
+ }
1221
+ }
1222
+
1223
+ function listchange(){
1224
+ var newClist = playlists.getShowcontrolsList();
1225
+ if(newClist != cList){
1226
+ if(cList){
1227
+ cList.off('itemchange', itemChange);
1228
+ }
1229
+ cList = newClist;
1230
+ if(cList){
1231
+ cList.on('itemchange', itemChange);
1232
+ itemChange();
1233
+ }
1234
+ }
1235
+ }
1236
+
1237
+ control.on('click', function(){
1238
+ if(cList){
1239
+ cList[desc.play]();
1240
+ }
1241
+ });
1242
+
1243
+ playlists.on({
1244
+ 'addlist removelist showcontrolschange':listchange
1245
+ });
1246
+ listchange();
1247
+ }
1248
+ });
1249
+ })
1250
+ ;
1251
+
1252
+
1253
+ // Simple JavaScript Templating
1254
+ (function() {
1255
+ var cache = {};
1256
+ $.jme.tmpl = function tmpl(str, data) {
1257
+ // Figure out if we're getting a template, or if we need to
1258
+ // load the template - and be sure to cache the result.
1259
+ if(!cache[str]){
1260
+ cache[str] = new Function("obj",
1261
+ "var p=[],print=function(){p.push.apply(p,arguments);};" +
1262
+
1263
+ // Introduce the data as local variables using with(){}
1264
+ "with(obj){p.push('" +
1265
+
1266
+ // Convert the template into pure JavaScript
1267
+ str.replace(/[\r\t\n]/g, " ")
1268
+ .replace(/'(?=[^%]*%>)/g,"\t")
1269
+ .split("'").join("\\'")
1270
+ .split("\t").join("'")
1271
+ .replace(/<%=(.+?)%>/g, "',$1,'")
1272
+ .split("<%").join("');")
1273
+ .split("%>").join("p.push('")
1274
+ + "');}return p.join('');");
1275
+ }
1276
+
1277
+ // Provide some basic currying to the user
1278
+ return data ? cache[str](data) : cache[str];
1279
+ };
1280
+ })();
1281
+ $.jme.Playlist = Playlist;
1282
+ webshims.isReady('playlist', true);
1283
+ });