vendor/assets/javascripts/webshims/shims/combos/99.js in webshims-rails-1.14.3 vs vendor/assets/javascripts/webshims/shims/combos/99.js in webshims-rails-1.14.4

- old
+ new

@@ -1,18 +1,21 @@ -webshims.register('jme', function($, webshims, window, doc, undefined){ +webshims.register('jmebase', function($, webshims, window, doc, undefined){ "use strict"; var props = {}; var fns = {}; var slice = Array.prototype.slice; var readyLength = 0; var options = $.extend({selector: '.mediaplayer'}, webshims.cfg.mediaelement.jme); var baseSelector = options.selector; webshims.cfg.mediaelement.jme = options; + if(!$.jme){ + $.jme = {}; + } - $.jme = { + $.extend($.jme, { pluginsClasses: [], pluginsSel: '', plugins: {}, props: props, fns: fns, @@ -54,10 +57,14 @@ } else if(options.i18n && options.i18n[name]){ plugin.text = options.i18n[name]; } this.runPlugin('.'+plugin.className); }, + configmenuPlugins: {}, + addToConfigmenu: function(name, create){ + this.configmenuPlugins[name] = create; + }, defineMethod: function(name, fn){ fns[name] = fn; }, defineProp: function(name, desc){ if(!desc){ @@ -93,20 +100,24 @@ if(setValue != 'noDataSet'){ $.jme.data(elem, name, setValue); } } } - }; + }); $.fn.jmeProp = function(name, value){ return $.access( this, $.jme.prop, name, value, arguments.length > 1 ); }; $.fn.jmeFn = function(fn){ var args = slice.call( arguments, 1 ); var ret; this.each(function(){ + if(!$.jme.data(this).media){ + $(this).closest(baseSelector).jmePlayer(); + webshims.warn('jmeFn called to early or on wrong element!'); + } ret = (fns[fn] || $.prop(this, fn)).apply(this, args); if(ret !== undefined){ return false; } }); @@ -180,15 +191,13 @@ }; $.fn.jmePlayer = function(opts){ return this.each(function(){ - if(opts){ - $.jme.data(this, $.extend(true, {}, opts)); - } - var mediaUpdateFn, canPlay, removeCanPlay, canplayTimer, lastState, stopEmptiedEvent; + + var mediaUpdateFn, canPlay, removeCanPlay, canplayTimer, lastState, stopEmptiedEvent, forceRender; var media = $('audio, video', this).eq(0); var base = $(this); var jmeData = $.jme.data(this); var mediaData = $.jme.data(media[0]); @@ -196,11 +205,13 @@ base.addClass(media.prop('nodeName').toLowerCase()+'player'); mediaData.player = base; mediaData.media = media; if(!jmeData.media){ - + forceRender = function(){ + base[0].className = base[0].className; + }; removeCanPlay = function(){ media.off('canplay', canPlay); clearTimeout(canplayTimer); }; canPlay = function(){ @@ -255,10 +266,11 @@ } if(state){ lastState = state; base.attr('data-state', state); + setTimeout(forceRender); } }; jmeData.media = media; @@ -338,21 +350,21 @@ var src = data.media.prop('src'); if(src){ return [{src: src}]; } srces = $.map($('source', data.media).get(), function(source){ + var i, len; var src = { src: $.prop(source, 'src') }; - var tmp = $.attr(source, 'media'); - if(tmp){ - src.media = tmp; + var attributes = source.attributes; + + for(i = 0, len = attributes.length; i < len; i++){ + if(!('specified' in attributes[i]) || attributes[i].specified){ + src[attributes[i].nodeName] = attributes[i].nodeValue; + } } - tmp = $.attr(source, 'type'); - if(tmp){ - src.type = tmp; - } return src; }); return srces; }, set: function(elem, srces){ @@ -419,33 +431,32 @@ $.jme.data(data.player[0], 'controlElements', oldControls.add(controls)); data.player.triggerHandler('controlsadded'); } }); - webshims.isReady('jme', true); - webshims.addReady($.jme.initJME); - webshims._polyfill(['mediaelement']); - webshims.isReady('jme-base', true); - if(webshims.cfg.debug !== false){ - $(function(){ - if(document.getElementsByTagName('video').length && !document.querySelector(baseSelector)){ - webshims.warn("found video element but video wasn't wrapped inside a ."+ baseSelector +" element. Will not add control UI"); - } - }); - } + webshims.ready('DOM mediaelement', function(){ + webshims.isReady('jme', true); + webshims.addReady($.jme.initJME); + webshims.isReady('jme-base', true); + + if(webshims.cfg.debug !== false && document.getElementsByTagName('video').length && !document.querySelector(baseSelector)){ + webshims.warn("found video element but video wasn't wrapped inside a ."+ baseSelector +" element. Will not add control UI"); + } + }); + }); ;webshims.register('mediacontrols', function($, webshims, window){ "use strict"; var pseudoClasses = 'pseudoClasses'; var options = webshims.cfg.mediaelement.jme; var baseSelector = options.selector; var jme = $.jme; - var unknowStructure = '<div class="{%class%}"></div>' + var unknownStructure = '<div class="{%class%}"></div>'; var btnStructure = '<button class="{%class%}" type="button" aria-label="{%text%}"></button>'; - var slideStructure = '<div class="{%class%} media-range"></div>'; + var slideStructure = '<div class="{%class%} media-range" aria-label="{%text%}"></div>'; var timeStructure = '<div class="{%class%}">00:00</div>'; var noVolumeClass = (function(){ var audio; var ret = ''; @@ -473,11 +484,11 @@ cache[template] = template.replace(regTemplate, function(match, matchName){ var plugin = jme.plugins[matchName]; if(plugin){ if(!plugin.structure){ webshims.warn('no structure option provided for plugin: '+ matchName +'. Fallback to standard div'); - plugin.structure = unknowStructure; + plugin.structure = unknownStructure; } return plugin.structure.replace('{%class%}', matchName).replace('{%text%}', plugin.text || ''); } return match; }); @@ -578,39 +589,78 @@ data.player.attr('data-playersize', size.name); data.player.attr('data-playersizes', size.names); } }; })(); + var $poster = $('<div class="ws-poster" />').insertAfter(data.media); var posterState = (function(){ - var lastPosterState, lastYoutubeState; + var lastPosterState, lastYoutubeState, lastPoster; var hasFlash = window.swfmini && swfmini.hasFlashPlayerVersion('10.0.3'); var regYt = /youtube\.com\/[watch\?|v\/]+/i; + + var isInitial = data.media.prop('paused'); + if(isInitial){ + data.player.addClass('initial-state'); + } + if(!('backgroundSize' in $poster[0].style)){ + data.player.addClass('no-backgroundsize'); + } + data.media.on('playing waiting seeked seeking', function(){ + if(isInitial){ + isInitial = false; + data.player.removeClass('initial-state'); + } + }); return function(){ - var hasPoster = !!data.media.attr('poster'); - var hasYt = (hasFlash && hasPoster) ? false : regYt.test(data.media.prop('currentSrc') || ''); + var poster = data.media.attr('poster'); + var hasPoster = !!poster; + var currentSrc = data.media.prop('currentSrc') || ''; + var isYt = regYt.test(currentSrc); + var hasYt = (hasFlash && hasPoster) ? false : isYt; + + if(!hasPoster && isYt){ + poster = currentSrc.match(/(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/ ]{11})/i) || ''; + if(poster){ + poster = 'https://img.youtube.com/vi/'+ poster[1] +'/0.jpg'; + hasPoster = !!poster; + } + } + + if(lastPoster !== poster){ + lastPoster = poster; + $poster[0].style.backgroundImage = poster ? 'url('+poster+')' : ''; + } + if(lastPosterState !== hasPoster){ lastPosterState = hasPoster; data.player[hasPoster ? 'removeClass' : 'addClass']('no-poster'); } + if(data.media.prop('paused')){ + data.player.addClass('initial-state'); + isInitial = true; + } + if(lastYoutubeState !== hasYt){ lastYoutubeState = hasYt; data.player[hasYt ? 'addClass' : 'removeClass']('has-ytposter'); } }; })(); userActivity._create(data.player, data.media, data.player); - data.media.on('emptied', posterState); + data.media.on('emptied loadstart', function(){ + setTimeout(posterState); + }); playerSize(); posterState(); webshims.ready('dom-support', function(){ data.player.onWSOff('updateshadowdom', playerSize); - controls.add(data._controlbar).addClass(webshims.shadowClass); + controls.add(data._controlbar).add($poster).addClass(webshims.shadowClass); webshims.addShadowDom(); }); } } else if(!value) { @@ -639,20 +689,21 @@ jme.registerPlugin('volume-slider', { structure: slideStructure, - + text: 'volume level', _create: lazyLoadPlugin() }); jme.registerPlugin('time-slider', { structure: slideStructure, options: { format: ['mm', 'ss'] }, + text: 'time position', _create: lazyLoadPlugin() }); jme.defineProp('format', { @@ -723,25 +774,48 @@ structure: btnStructure, text: 'enter fullscreen / exit fullscreen', _create: lazyLoadPlugin() }); + jme.registerPlugin('mediaconfigmenu', { + structure: btnStructure, + text: 'configuration', + _create: lazyLoadPlugin() + }); + jme.registerPlugin('captions', { structure: btnStructure, text: 'subtitles', _create: function(control, media, base){ - var trackElems = media.find('track'); + var trackElems = media.find('track').filter(':not([kind]), [kind="subtitles"], [data-kind="subtitles"], [kind="captions"], [data-kind="captions"]'); control.wsclonedcheckbox = $(control).clone().attr({role: 'checkbox'}).insertBefore(control); base.attr('data-tracks', trackElems.length > 1 ? 'many' : trackElems.length); control.attr('aria-haspopup', 'true'); lazyLoadPlugin().apply(this, arguments); } }); + + jme.registerPlugin('chapters', { + structure: btnStructure, + text: 'chapters', + _create: function(control, media, base){ + var trackElems = media.find('track').filter('[kind="chapters"], [data-kind="chapters"]'); + control.attr('aria-haspopup', 'true'); + if(trackElems.length){ + webshims._polyfill(['track']); + base.addClass('has-chapter-tracks'); + } + lazyLoadPlugin().apply(this, arguments); + } + }); + + + webshims.ready(webshims.cfg.mediaelement.plugins.concat(['mediaelement', 'jme-base']), function(){ if(!options.barTemplate){ - 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>'; + options.barTemplate = '<div class="play-pause-container">{{play-pause}}</div><div class="playlist-container"><div class="playlist-box"><div class="playlist-button-container">{{playlist-prev}}</div><div class="playlist-button-container">{{playlist-next}}</div></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="chapters-container"><div class="chapters-controls mediamenu-wrapper">{{chapters}}</div></div><div class="subtitle-container mediamenu-wrapper"><div class="subtitle-controls">{{captions}}</div></div><div class="mediaconfig-container"><div class="mediaconfig-controls mediamenu-wrapper">{{mediaconfigmenu}}</div></div><div class="fullscreen-container">{{fullscreen}}</div>'; } if(!options.barStructure){ options.barStructure = '<div class="jme-media-overlay"></div><div class="jme-controlbar'+ noVolumeClass +'" tabindex="-1"><div class="jme-cb-box"></div></div>'; }