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,1004 @@
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.ready('jme DOM', function(){
403
+ "use strict";
404
+ var webshims = window.webshims;
405
+ var $ = webshims.$;
406
+ var jme = $.jme;
407
+ var listId = 0;
408
+ var btnStructure = '<button class="{%class%}" type="button" aria-label="{%text%}"></button>';
409
+
410
+ function PlaylistList(data){
411
+ this._data = data;
412
+ this.lists = {};
413
+
414
+ this.on('showcontrolschange', this._updateControlsClass);
415
+ }
416
+
417
+ $.extend(PlaylistList.prototype, {
418
+ on: function(){
419
+ $.fn.on.apply($(this), arguments);
420
+ },
421
+ off: function(){
422
+ $.fn.off.apply($(this), arguments);
423
+ },
424
+ _getListId: function(list){
425
+ var id;
426
+ if(typeof list == 'string'){
427
+ id = list;
428
+ } else {
429
+ id = list.id;
430
+ }
431
+ return id;
432
+ },
433
+ _updateControlsClass: function(){
434
+ this._data.player[this.getShowcontrolsList() ? 'addClass' : 'removeClass']('has-playlist');
435
+ },
436
+ add: function(list, opts){
437
+
438
+ list = new Playlist(list, this, opts);
439
+ if(!list.id){
440
+ listId++;
441
+ list.id = 'list-'+listId;
442
+ }
443
+ this.lists[list.id] = list;
444
+
445
+ if(list.options.showcontrols){
446
+ this._data.player.addClass('has-playlist');
447
+ }
448
+
449
+ return list;
450
+ },
451
+ remove: function(list){
452
+ var id = this._getListId(list);
453
+ if(this.lists[id]){
454
+ this.lists[id]._remove();
455
+ delete this.lists[id];
456
+ }
457
+ if(!this.getShowcontrolsList()){
458
+ this._data.player.removeClass('has-playlist');
459
+ }
460
+ },
461
+ getAutoplayList: function(){
462
+ var clist = null;
463
+ $.each(this.lists, function(id, list){
464
+ if(list.options.autoplay){
465
+ clist = list;
466
+ return false;
467
+ }
468
+ });
469
+ return clist;
470
+ },
471
+ getShowcontrolsList: function(){
472
+ var clist = null;
473
+ $.each(this.lists, function(id, list){
474
+ if(list.options.showcontrols){
475
+ clist = list;
476
+ return false;
477
+ }
478
+ });
479
+ return clist;
480
+ }
481
+
482
+ });
483
+
484
+ function Playlist(list, parent, opts){
485
+ this.list = list || [];
486
+ this.playlists = parent;
487
+ this.media = parent._data.media;
488
+ this.player = parent._data.player;
489
+ this.options = $.extend(true, {}, Playlist.defaults, opts);
490
+ this.options.itemTmpl = this.options.itemTmpl.trim();
491
+
492
+ this.deferred = $.Deferred();
493
+ this._selectedIndex = -1;
494
+ this._selectedItem = null;
495
+ this.$rendered = null;
496
+
497
+ this._detectListType();
498
+
499
+ this.autoplay(this.options.autoplay);
500
+
501
+ this.deferred.done(function(){
502
+ this._addEvents(this);
503
+ if(this.options.defaultSelected == 'auto' && !this.media.jmeProp('srces').length){
504
+ this.options.defaultSelected = 0;
505
+ }
506
+ if(this.list[this.options.defaultSelected]){
507
+ this.selectedIndex(this.options.defaultSelected);
508
+ }
509
+ this._fire('addlist');
510
+ });
511
+ }
512
+
513
+ Playlist.getText = function($elem){
514
+ return $elem.attr('content') || ($elem.text() || '').trim();
515
+ };
516
+ Playlist.getUrl = function($elem){
517
+ return $elem.attr('content') || $elem.attr('url') || $elem.attr('href') || $elem.attr('src') || ($elem.text() || '').trim();
518
+ };
519
+
520
+ Playlist.defaults = {
521
+ loop: false,
522
+ autoplay: false,
523
+ defaultSelected: 'auto',
524
+ addItemEvents: true,
525
+ showcontrols: true,
526
+ ajax: {},
527
+ itemTmpl: '<li class="list-item">' +
528
+ '<% if(typeof poster == "string" && poster) {%><img src="<%=poster%>" /><% }%>' +
529
+ '<h3><%=title%></h3>' +
530
+ '<% if(typeof description == "string" && description) {%><div class="item-description"><%=description%></div><% }%>' +
531
+ '</li>',
532
+ renderer: function(item, template){
533
+ return $.jme.tmpl(template, item);
534
+ },
535
+ mapDom: function(element){
536
+
537
+ return {
538
+ title: Playlist.getText($('[itemprop="name"], h1, h2, h3, h4, h5, h6, a', element)),
539
+ srces: $('[itemprop="contentUrl"], a[type^="video"], a[type^="audio"]', element).map(function(){
540
+ var tmp;
541
+ var src = {src: Playlist.getUrl($(this))};
542
+ if(this.nodeName.toLowerCase() == 'a'){
543
+ tmp = $.prop(this, 'type');
544
+ } else {
545
+ tmp = Playlist.getText($('[itemprop="encodingFormat"]', element));
546
+ }
547
+ if(tmp){
548
+ src.type = tmp;
549
+ }
550
+ tmp = $.attr(this, 'data-media');
551
+ if(tmp){
552
+ src.media = tmp;
553
+ }
554
+ return src;
555
+ }).get(),
556
+ tracks: $('a[type="text/vtt"]').map(mapTrackUrl).get(),
557
+ poster: Playlist.getUrl($('[itemprop="thumbnailUrl"], a[type^="image"], img', element)) || null,
558
+ description: Playlist.getText($('[itemprop="description"], .item-description, p', element)) || null
559
+ };
560
+ },
561
+ mapUrl: function(opts, callback){
562
+ $.ajax($.extend(opts, {
563
+ success: function(data){
564
+ var list;
565
+ if($.isArray(data)){
566
+ list = data;
567
+ } else if(data.responseData && data.responseData.feed){
568
+ data = data.responseData.feed;
569
+ list = (data.entries || []).map(mapJsonFeed);
570
+ } else {
571
+ list = [];
572
+ $('item', data).each(function(){
573
+ var srces = $('enclosure, media\\:content', this)
574
+ .filter('[type^="video"], [type^="audio"]')
575
+ .map(mapUrl)
576
+ .get()
577
+ ;
578
+ if(srces.length){
579
+ list.push({
580
+ title: $('title', this).html(),
581
+ srces: srces,
582
+ publishedDate: $('pubDate', this).html() || null,
583
+ description: $('description', this).text() || null,
584
+ poster: Playlist.getUrl($('itunes\\:image, media\\:thumbnail, enclosure[type^="image"], media\\:content[type^="image"]', this)) || null,
585
+ author: $('itunes\\:author', this).html() || null,
586
+ duration: $('itunes\\:duration', this).html() || null,
587
+ tracks: $('media\\:subTitle', this).map(mapTrackUrl).get() || null
588
+ });
589
+ }
590
+ });
591
+ }
592
+ if(list != data){
593
+ list.fullData = data;
594
+ }
595
+ callback(list);
596
+ }
597
+ }));
598
+ }
599
+ };
600
+
601
+ function mapJsonFeed(item){
602
+ item.description = item.description || item.content;
603
+ item.srces = [];
604
+ (item.mediaGroups || []).forEach(function(mediagroup){
605
+ (mediagroup.contents || []).forEach(function(itemSrc){
606
+ itemSrc.src = itemSrc.src || itemSrc.url;
607
+ item.srces.push(itemSrc);
608
+ });
609
+ });
610
+ return item;
611
+ }
612
+
613
+ function mapTrackUrl(){
614
+ return {
615
+ src: $.attr(this, 'href'),
616
+ srclang: $.attr(this, 'lang'),
617
+ label: $.attr(this, 'data-label')
618
+ };
619
+ }
620
+
621
+ function mapUrl(){
622
+ return {
623
+ src: $.attr(this, 'url') || $.attr(this, 'href'),
624
+ type: $.attr(this, 'type')
625
+ };
626
+ }
627
+
628
+ function filterNode(){
629
+ return this.nodeType == 1;
630
+ }
631
+
632
+ $.extend(Playlist.prototype, {
633
+ on: function(){
634
+ $.fn.on.apply($(this), arguments);
635
+ },
636
+ off: function(){
637
+ $.fn.off.apply($(this), arguments);
638
+ },
639
+ _detectListType: function(){
640
+ var fullData;
641
+ if(typeof this.list == 'string'){
642
+ this._createListFromUrl();
643
+ return;
644
+ }
645
+ if(this.list.nodeName || (this.list.length > 0 && this.list[0].nodeName)){
646
+ this._createListFromDom();
647
+ } else if(this.list.responseData && this.list.responseData.feed){
648
+ fullData = this.list.responseData.feed;
649
+ this.list = (fullData.entries || []).map(mapJsonFeed);
650
+ this.list.fullData = fullData;
651
+ }
652
+ this.deferred.resolveWith(this);
653
+
654
+ },
655
+ _createListFromUrl: function(){
656
+ var that = this;
657
+ this.options.ajax.url = this.list;
658
+ this.options.mapUrl(this.options.ajax, function(list){
659
+ that.list = list;
660
+ that.deferred.resolveWith(that);
661
+ });
662
+ },
663
+ _createListFromDom: function(){
664
+ var that = this;
665
+
666
+ this.$rendered = $(this.list).eq(0);
667
+ this.list = [];
668
+
669
+ if(this.$rendered){
670
+ this._addDomList();
671
+ this.list = this.$rendered.children().map(function(){
672
+ return that._createItemFromDom(this);
673
+ }).get();
674
+ }
675
+ },
676
+ _createItemFromDom: function(dom){
677
+ var item = this.options.mapDom(dom);
678
+ this._addItemData(item, dom);
679
+ return item;
680
+ },
681
+ _fire: function(evt, extra){
682
+ var evt = $.Event(evt);
683
+ $(this).triggerHandler(evt, extra);
684
+ $(this.playlists).triggerHandler(evt, $.merge([{list: this}], extra || []));
685
+ if(this.$rendered){
686
+ this.$rendered.triggerHandler(evt, extra);
687
+ }
688
+ },
689
+ _addDomList: function(){
690
+ this.$rendered
691
+ .attr({
692
+ 'data-autoplay': this.options.autoplay,
693
+ 'data-loop': this.options.loop
694
+ })
695
+ .addClass('media-playlist')
696
+ .data('playlist', this)
697
+ ;
698
+ },
699
+ _addItemData: function(item, dom){
700
+ var that = this;
701
+ item.$item = $(dom).data('itemData', item);
702
+
703
+ if(item == this._selectedItem){
704
+ item.$item.addClass('selected-item');
705
+ }
706
+ if(this.options.addItemEvents){
707
+ item.$item.on('click.playlist', function(e){
708
+ if(that.options.addItemEvents){
709
+ that.playItem(item, e);
710
+ return false;
711
+ }
712
+ });
713
+ }
714
+ },
715
+ _addEvents: function(that){
716
+ var o = that.options;
717
+ var onEnded = function(e){
718
+ if(o.autoplay){
719
+ that.playNext(e);
720
+ }
721
+ };
722
+ this.media.on('ended', onEnded);
723
+ this._remove = function(){
724
+ that.media.off('ended', onEnded);
725
+ that.autoplay(false);
726
+
727
+ if(that.$rendered){
728
+ that.$rendered.remove();
729
+ }
730
+
731
+ that._fire('removelist');
732
+ };
733
+ },
734
+ _remove: function(){
735
+ this._fire('removelist');
736
+ },
737
+ render: function(callback){
738
+ if(this.$rendered){
739
+ callback(this.$rendered, this.player, this);
740
+ } else {
741
+ this.deferred.done(function(){
742
+ var nodeName;
743
+ var that = this;
744
+ var items = [];
745
+ if(!this.$rendered){
746
+ $.each(this.list, function(i, item){
747
+ var domItem = $($.parseHTML(that.options.renderer(item, that.options.itemTmpl))).filter(filterNode)[0];
748
+ that._addItemData(item, domItem);
749
+ items.push(domItem);
750
+ });
751
+ nodeName = (items[0] && items[0].nodeName || '').toLowerCase();
752
+
753
+ switch (nodeName){
754
+ case 'li':
755
+ this.$rendered = $.parseHTML('<ul />');
756
+ break;
757
+ case 'option':
758
+ this.$rendered = $.parseHTML('<select />');
759
+ break;
760
+ default:
761
+ this.$rendered = $.parseHTML('<div />');
762
+ break;
763
+ }
764
+ this.$rendered = $(this.$rendered).html(items);
765
+ this._addDomList();
766
+ }
767
+ callback(this.$rendered, this.player, this);
768
+ });
769
+ }
770
+ },
771
+ /*
772
+
773
+ addItem: function(item, pos){
774
+
775
+ },
776
+ removeItem: function(item){
777
+
778
+ },
779
+ */
780
+ _loadItem: function(item){
781
+ var media = this.media;
782
+ media.attr('poster', item.poster || '');
783
+
784
+ $('track', media).remove();
785
+
786
+ $.each(item.tracks || [], function(i, track){
787
+ $('<track />').attr(track).appendTo(media);
788
+ });
789
+
790
+ media.jmeProp('srces', item.srces);
791
+ },
792
+ _getItem: function(item){
793
+ if(item && (item.nodeName || item.jquery || typeof item == 'string')){
794
+ item = $(item).data('itemData');
795
+ }
796
+ return item;
797
+ },
798
+ playItem: function(item, e){
799
+ var media;
800
+ this.selectedItem(item, e);
801
+ if(item){
802
+ media = this.media.play();
803
+ setTimeout(function(){
804
+ media.play();
805
+ }, 9);
806
+ }
807
+ },
808
+ selectedIndex: function(index, e){
809
+ if(arguments.length){
810
+ this.selectedItem(this.list[index], e);
811
+ } else {
812
+ return this._selectedIndex;
813
+ }
814
+ },
815
+
816
+ selectedItem: function(item, e){
817
+ var oldItem, found;
818
+
819
+ if(arguments.length){
820
+ found = -1;
821
+ item = this._getItem(item);
822
+ if(item){
823
+ $.each(this.list, function(i){
824
+ if(item == this){
825
+ found = i;
826
+ return false;
827
+ }
828
+ });
829
+ }
830
+
831
+ if(found >= 0){
832
+ this._loadItem(this.list[found]);
833
+ }
834
+
835
+ if(found != this._selectedIndex){
836
+ oldItem = this._selectedItem || null;
837
+ if(oldItem && oldItem.$item){
838
+ oldItem.$item.removeClass('selected-item');
839
+ }
840
+ this._selectedItem = this.list[found] || null;
841
+ this._selectedIndex = found;
842
+ if(this._selectedItem && this._selectedItem.$item){
843
+ this._selectedItem.$item.addClass('selected-item');
844
+ }
845
+ if(oldItem !== this._selectedItem){
846
+ this._fire('itemchange', [{oldItem: oldItem, from: e || null}]);
847
+ }
848
+ }
849
+
850
+ } else {
851
+ return this._selectedItem;
852
+ }
853
+ },
854
+ playNext: function(){
855
+ var item = this.getNext();
856
+ if(item){
857
+ this.playItem(item);
858
+ }
859
+ },
860
+ playPrev: function(){
861
+ var item = this.getPrev();
862
+ if(item){
863
+ this.playItem(item);
864
+ }
865
+ },
866
+ getNext: function(){
867
+ var index = this._selectedIndex + 1;
868
+ return this.list[index] || (this.options.loop ? this.list[0] : null);
869
+ },
870
+ getPrev: function(){
871
+ var index = this._selectedIndex - 1;
872
+ return this.list[index] || (this.options.loop ? this.list[this.list.length - 1] : null);
873
+ }
874
+ });
875
+
876
+ [{name: 'autoplay', fn: 'getAutoplayList'}, {name: 'showcontrols', fn: 'getShowcontrolsList'}, {name: 'loop'}].forEach(function(desc){
877
+ Playlist.prototype[desc.name] = function(value){
878
+ var curList;
879
+ if(arguments.length){
880
+ value = !!value;
881
+
882
+ if(value && desc.fn){
883
+ curList = this.playlists[desc.fn]();
884
+ if(curList && curList != this){
885
+ curList[desc.name](false);
886
+ }
887
+ }
888
+
889
+ if(this.options[desc.name] != value){
890
+ this.options[desc.name] = value;
891
+ if(this.$rendered){
892
+ this.$rendered.attr('data-'+desc.name, value);
893
+ }
894
+ this._fire(desc.name+'change');
895
+ }
896
+ } else {
897
+ return this.options[desc.name];
898
+ }
899
+ }
900
+ });
901
+
902
+ jme.defineProp('playlists', {
903
+ writable: false,
904
+ get: function(elem){
905
+ var data = $.jme.data(elem);
906
+
907
+ if(elem != data.player[0]){return null;}
908
+ if(!data.playlists){
909
+ data.playlists = new PlaylistList(data);
910
+ }
911
+ return data.playlists;
912
+ }
913
+ });
914
+
915
+ jme.defineMethod('addPlaylist', function(list, options){
916
+ var playlists = $.jme.prop(this, 'playlists');
917
+ if(playlists && playlists.add){
918
+ return playlists.add(list, options);
919
+ }
920
+ return null;
921
+ });
922
+
923
+ [
924
+ {name: 'playlist-prev', text: 'previous', get: 'getPrev', play: 'playPrev'},
925
+ {name: 'playlist-next', text: 'next', get: 'getNext', play: 'playNext'}
926
+ ]
927
+ .forEach(function(desc){
928
+ $.jme.registerPlugin(desc.name, {
929
+ structure: btnStructure,
930
+ text: desc.text,
931
+ _create: function(control, media, base){
932
+ var cList;
933
+ var playlists = base.jmeProp('playlists');
934
+
935
+ function itemChange(){
936
+ var item = cList[desc.get]();
937
+ if(item){
938
+ control.prop({'disabled': false, title: item.title});
939
+ } else {
940
+ control.prop({'disabled': true, title: ''});
941
+ }
942
+ }
943
+
944
+ function listchange(){
945
+ var newClist = playlists.getShowcontrolsList();
946
+ if(newClist != cList){
947
+ if(cList){
948
+ cList.off('itemchange', itemChange);
949
+ }
950
+ cList = newClist;
951
+ if(cList){
952
+ cList.on('itemchange', itemChange);
953
+ itemChange();
954
+ }
955
+ }
956
+ }
957
+
958
+ control.on('click', function(){
959
+ if(cList){
960
+ cList[desc.play]();
961
+ }
962
+ });
963
+
964
+ playlists.on({
965
+ 'addlist removelist showcontrolschange':listchange
966
+ });
967
+ listchange();
968
+ }
969
+ });
970
+ })
971
+ ;
972
+
973
+
974
+ // Simple JavaScript Templating
975
+ (function() {
976
+ var cache = {};
977
+ $.jme.tmpl = function tmpl(str, data) {
978
+ // Figure out if we're getting a template, or if we need to
979
+ // load the template - and be sure to cache the result.
980
+ if(!cache[str]){
981
+ cache[str] = new Function("obj",
982
+ "var p=[],print=function(){p.push.apply(p,arguments);};" +
983
+
984
+ // Introduce the data as local variables using with(){}
985
+ "with(obj){p.push('" +
986
+
987
+ // Convert the template into pure JavaScript
988
+ str.replace(/[\r\t\n]/g, " ")
989
+ .replace(/'(?=[^%]*%>)/g,"\t")
990
+ .split("'").join("\\'")
991
+ .split("\t").join("'")
992
+ .replace(/<%=(.+?)%>/g, "',$1,'")
993
+ .split("<%").join("');")
994
+ .split("%>").join("p.push('")
995
+ + "');}return p.join('');");
996
+ }
997
+
998
+ // Provide some basic currying to the user
999
+ return data ? cache[str](data) : cache[str];
1000
+ };
1001
+ })();
1002
+ $.jme.Playlist = Playlist;
1003
+ webshims.isReady('playlist', true);
1004
+ });