vendor/assets/javascripts/webshims/shims/combos/25.js in webshims-rails-1.14.5 vs vendor/assets/javascripts/webshims/shims/combos/25.js in webshims-rails-1.14.6

- old
+ new

@@ -58,11 +58,10 @@ })(window.webshims.$); //DOM-Extension helper webshims.register('dom-extend', function($, webshims, window, document, undefined){ "use strict"; var supportHrefNormalized = !('hrefNormalized' in $.support) || $.support.hrefNormalized; - var supportGetSetAttribute = !('getSetAttribute' in $.support) || $.support.getSetAttribute; var has = Object.prototype.hasOwnProperty; webshims.assumeARIA = true; if($('<input type="email" />').attr('type') == 'text' || $('<form />').attr('novalidate') === "" || ('required' in $('<input />')[0].attributes)){ webshims.error("IE browser modes are busted in IE10+. Please test your HTML/CSS/JS with a real IE version or at least IETester or similiar tools"); @@ -89,11 +88,10 @@ webshims.ready('WINDOWLOAD', switch$); } //shortcus - var modules = webshims.modules; var listReg = /\s*,\s*/; //proxying attribute var olds = {}; var havePolyfill = {}; @@ -474,12 +472,11 @@ } if($.isDOMReady){ (tempCache || $( document.getElementsByTagName(nodeName) )).each(fn); } }; - - var elementExtends = {}; + return { createTmpCache: function(nodeName){ if($.isDOMReady){ tempCache = tempCache || $( document.getElementsByTagName(nodeName) ); } @@ -527,10 +524,11 @@ descs.attr = {}; } }; $.extend(webshims, { + xProps: havePolyfill, getID: (function(){ var ID = new Date().getTime(); return function(elem){ elem = $(elem); var id = elem.prop('id'); @@ -540,10 +538,30 @@ elem.eq(0).prop('id', id); } return id; }; })(), + domPrefixes: ["ws", "webkit", "moz", "ms", "o"], + + prefixed: function (prop, obj){ + var i, testProp; + var ret = false; + if(obj[prop]){ + ret = prop; + } + if(!ret){ + prop = prop.charAt(0).toUpperCase() + prop.slice(1); + for(i = 0; i < webshims.domPrefixes.length; i++){ + testProp = webshims.domPrefixes[i]+prop; + if(testProp in obj){ + ret = testProp; + break; + } + } + } + return ret; + }, shadowClass: 'wsshadow-'+(Date.now()), implement: function(elem, type){ var data = elementData(elem, 'implemented') || elementData(elem, 'implemented', {}); if(data[type]){ webshims.warn(type +' already implemented for element #'+elem.id); @@ -1657,39 +1675,44 @@ try { hasXDomain = sessionStorage.getItem('wsXdomain.xml'); } catch(e){} printMessage(); if(hasXDomain == null){ - $.ajax({ - url: 'crossdomain.xml', - type: 'HEAD', - dataType: 'xml', - success: function(){ - hasXDomain = 'yes'; - }, - error: function(){ - hasXDomain = 'no'; - }, - complete: function(){ - try { - sessionStorage.setItem('wsXdomain.xml', hasXDomain); - } catch(e){} - printMessage(); - } - }); + try { + $.ajax({ + url: 'crossdomain.xml', + type: 'HEAD', + dataType: 'xml', + success: function(){ + hasXDomain = 'yes'; + }, + error: function(){ + hasXDomain = 'no'; + }, + complete: function(){ + try { + sessionStorage.setItem('wsXdomain.xml', hasXDomain); + } catch(e){} + printMessage(); + } + }); + } catch(e){} } }); } + if(document.readyState == 'complete'){ + webshims.isReady('WINDOWLOAD', true); + } }); ;webshims.register('mediaelement-jaris', function($, webshims, window, document, undefined, options){ "use strict"; - + var mediaelement = webshims.mediaelement; var swfmini = window.swfmini; var support = webshims.support; var hasNative = support.mediaelement; - var hasFlash = swfmini.hasFlashPlayerVersion('9.0.115'); + var hasFlash = swfmini.hasFlashPlayerVersion('11.3'); var loadedSwf = 0; var needsLoadPreload = 'ActiveXObject' in window && hasNative; var getProps = { paused: true, ended: false, @@ -1718,51 +1741,52 @@ }, length: 0 } }; var getPropKeys = Object.keys(getProps); - + var getSetProps = { currentTime: 0, volume: 1, muted: false }; var getSetPropKeys = Object.keys(getSetProps); - + var playerStateObj = $.extend({ isActive: 'html5', - activating: 'html5', + activating: 'html5', wasSwfReady: false, + _usermedia: null, _bufferedEnd: 0, _bufferedStart: 0, currentTime: 0, lastCalledTime: -500, _ppFlag: undefined, _calledMeta: false, lastDuration: 0, _timeDif: 0.3 }, getProps, getSetProps); - - + + var getSwfDataFromElem = function(elem){ try { (elem.nodeName); } catch(er){ return null; } var data = webshims.data(elem, 'mediaelement'); return (data && data.isActive == 'third') ? data : null; }; - + var trigger = function(elem, evt){ evt = $.Event(evt); evt.preventDefault(); $.event.trigger(evt, undefined, elem); }; - + var playerSwfPath = options.playerPath || webshims.cfg.basePath + "swf/" + (options.playerName || 'JarisFLVPlayer.swf'); - + webshims.extendUNDEFProp(options.params, { allowscriptaccess: 'always', allowfullscreen: 'true', wmode: 'transparent', allowNetworking: 'all' @@ -1772,11 +1796,12 @@ jsapi: '1' }); webshims.extendUNDEFProp(options.attrs, { bgcolor: '#000000' }); - + options.playerPath = playerSwfPath; + var setReadyState = function(readyState, data){ if(readyState < 3){ clearTimeout(data._canplaythroughTimer); } if(readyState >= 3 && data.readyState < 3){ @@ -1800,12 +1825,12 @@ if(data.seeking && Math.abs(data.currentTime - data._lastSeektime) < 2){ data.seeking = false; $(data._elem).triggerHandler('seeked'); } }; - - + + mediaelement.jarisEvent = {}; var localConnectionTimer; var onEvent = { onPlayPause: function(jaris, data, override){ var playing, type; @@ -1816,11 +1841,11 @@ } catch(e){} } else { playing = override; } if(playing == idled || playing == null){ - + data.paused = !playing; type = data.paused ? 'pause' : 'play'; data._ppFlag = true; trigger(data._elem, type); if(data.readyState < 3){ @@ -1831,11 +1856,11 @@ } } }, onSeek: function(jaris, data){ data._lastSeektime = jaris.seekTime; - + data.seeking = true; $(data._elem).triggerHandler('seeking'); clearTimeout(data._seekedTimer); data._seekedTimer = setTimeout(function(){ callSeeked(data); @@ -1847,23 +1872,23 @@ }, onNotBuffering: function(jaris, data){ setReadyState(3, data); }, onDataInitialized: function(jaris, data){ - + var oldDur = data.duration; var durDelta; data.duration = jaris.duration; if(oldDur == data.duration || isNaN(data.duration)){return;} - + if(data._calledMeta && ((durDelta = Math.abs(data.lastDuration - data.duration)) < 2)){return;} - - - + + + data.videoHeight = jaris.height; data.videoWidth = jaris.width; - + if(!data.networkState){ data.networkState = 2; } if(data.readyState < 1){ setReadyState(1, data); @@ -1915,21 +1940,21 @@ if(timeDif > data._timeDif || timeDif < -0.3){ data.lastCalledTime = data.currentTime; $.event.trigger('timeupdate', undefined, data._elem, true); } - + }, onProgress: function(jaris, data){ if(data.ended){ data.ended = false; } if(!data.duration || isNaN(data.duration)){ return; } var percentage = jaris.loaded / jaris.total; - + if(percentage > 0.02 && percentage < 0.2){ setReadyState(3, data); } else if(percentage > 0.2){ if(percentage > 0.95){ percentage = 1; @@ -1938,14 +1963,14 @@ setReadyState(4, data); } if(data._bufferedEnd && (data._bufferedEnd > percentage)){ data._bufferedStart = data.currentTime || 0; } - + data._bufferedEnd = percentage; data.buffered.length = 1; - + $.event.trigger('progress', undefined, data._elem, true); }, onPlaybackFinished: function(jaris, data){ if(data.readyState < 4){ setReadyState(4, data); @@ -1961,29 +1986,29 @@ } }, ready: (function(){ var testAPI = function(data){ var passed = true; - + try { data.api.api_get('volume'); } catch(er){ passed = false; } return passed; }; - + return function(jaris, data){ var i = 0; - + var doneFn = function(){ if(i > 9){ data.tryedReframeing = 0; return; } i++; - + data.tryedReframeing++; if(testAPI(data)){ data.wasSwfReady = true; data.tryedReframeing = 0; startAutoPlay(data); @@ -2009,29 +2034,29 @@ data.tryedReframeing = 0; } clearTimeout(localConnectionTimer); clearTimeout(data.reframeTimer); data.shadowElem.removeClass('flashblocker-assumed'); - + if(!i){ doneFn(); } else { data.reframeTimer = setTimeout(doneFn, 9); } - + }; })() }; - + onEvent.onMute = onEvent.onVolumeChange; - - + mediaelement.onEvent = onEvent; + var workActionQueue = function(data){ var actionLen = data.actionQueue.length; var i = 0; var operation; - + if(actionLen && data.isActive == 'third'){ while(data.actionQueue.length && actionLen > i){ i++; operation = data.actionQueue.shift(); try{ @@ -2048,56 +2073,56 @@ var startAutoPlay = function(data){ if(!data){return;} if( (data._ppFlag === undefined && ($.prop(data._elem, 'autoplay')) || !data.paused)){ setTimeout(function(){ if(data.isActive == 'third' && (data._ppFlag === undefined || !data.paused)){ - + try { $(data._elem).play(); data._ppFlag = true; } catch(er){} } }, 1); } - + if(data.muted){ $.prop(data._elem, 'muted', true); } if(data.volume != 1){ $.prop(data._elem, 'volume', data.volume); } }; - - + + var addMediaToStopEvents = $.noop; if(hasNative){ var stopEvents = { play: 1, playing: 1 }; var hideEvtArray = ['play', 'pause', 'playing', 'loadstart', 'canplay', 'progress', 'waiting', 'ended', 'loadedmetadata', 'durationchange', 'emptied']; var hidevents = hideEvtArray.map(function(evt){ return evt +'.webshimspolyfill'; }).join(' '); - + var hidePlayerEvents = function(event){ var data = webshims.data(event.target, 'mediaelement'); if(!data){return;} var isNativeHTML5 = ( event.originalEvent && event.originalEvent.type === event.type ); if( isNativeHTML5 == (data.activating == 'third') ){ event.stopImmediatePropagation(); - + if(stopEvents[event.type]){ if(data.isActive != data.activating){ $(event.target).pause(); } else if(isNativeHTML5){ ($.prop(event.target, 'pause')._supvalue || $.noop).apply(event.target); } } } }; - + addMediaToStopEvents = function(elem){ $(elem) .off(hidevents) .on(hidevents, hidePlayerEvents) ; @@ -2105,12 +2130,12 @@ webshims.moveToFirstEvent(elem, evt); }); }; addMediaToStopEvents(document); } - - + + mediaelement.setActive = function(elem, type, data){ if(!data){ data = webshims.data(elem, 'mediaelement'); } if(!data || data.isActive == type){return;} @@ -2128,18 +2153,18 @@ $(elem).removeClass('swf-api-active nonnative-api-active').show().getShadowElement().hide(); shadowData.shadowElement = shadowData.shadowFocusElement = false; } $(elem).trigger('mediaelementapichange'); }; - - - + + + var resetSwfProps = (function(){ - var resetProtoProps = ['_calledMeta', 'lastDuration', '_bufferedEnd', 'lastCalledTime', '_bufferedStart', '_ppFlag', 'currentSrc', 'currentTime', 'duration', 'ended', 'networkState', 'paused', 'seeking', 'videoHeight', 'videoWidth']; + var resetProtoProps = ['_calledMeta', 'lastDuration', '_bufferedEnd', 'lastCalledTime', '_usermedia', '_bufferedStart', '_ppFlag', 'currentSrc', 'currentTime', 'duration', 'ended', 'networkState', 'paused', 'seeking', 'videoHeight', 'videoWidth']; var len = resetProtoProps.length; return function(data){ - + if(!data){return;} clearTimeout(data._seekedTimer); var lenI = len; var networkState = data.networkState; setReadyState(0, data); @@ -2152,12 +2177,12 @@ if(networkState){ trigger(data._elem, 'emptied'); } }; })(); - - + + var getComputedDimension = (function(){ var dimCache = {}; var getVideoDims = function(data){ var ret, poster, img; if(dimCache[data.currentSrc]){ @@ -2175,11 +2200,11 @@ img.onload = function(){ dimCache[poster] = { width: this.width, height: this.height }; - + if(dimCache[poster].height && dimCache[poster].width){ setElementDimension(data, $.prop(data._elem, 'controls')); } else { delete dimCache[poster]; } @@ -2191,16 +2216,16 @@ } } } return ret || {width: 300, height: data._elemNodeName == 'video' ? 150 : 50}; }; - + var getCssStyle = function(elem, style){ return elem.style[style] || (elem.currentStyle && elem.currentStyle[style]) || (window.getComputedStyle && (window.getComputedStyle( elem, null ) || {} )[style]) || ''; }; var minMaxProps = ['minWidth', 'maxWidth', 'minHeight', 'maxHeight']; - + var addMinMax = function(elem, ret){ var i, prop; var hasMinMax = false; for (i = 0; i < 4; i++) { prop = getCssStyle(elem, minMaxProps[i]); @@ -2210,67 +2235,67 @@ } } return hasMinMax; }; var retFn = function(data){ - var videoDims, ratio, hasMinMax; + var videoDims, ratio; var elem = data._elem; var autos = { width: getCssStyle(elem, 'width') == 'auto', height: getCssStyle(elem, 'height') == 'auto' }; var ret = { width: !autos.width && $(elem).width(), height: !autos.height && $(elem).height() }; - + if(autos.width || autos.height){ videoDims = getVideoDims(data); ratio = videoDims.width / videoDims.height; - + if(autos.width && autos.height){ ret.width = videoDims.width; ret.height = videoDims.height; } else if(autos.width){ ret.width = ret.height * ratio; } else if(autos.height){ ret.height = ret.width / ratio; } - + if(addMinMax(elem, ret)){ data.shadowElem.css(ret); if(autos.width){ ret.width = data.shadowElem.height() * ratio; - } + } if(autos.height){ ret.height = ((autos.width) ? ret.width : data.shadowElem.width()) / ratio; } if(autos.width && autos.height){ data.shadowElem.css(ret); ret.height = data.shadowElem.width() / ratio; ret.width = ret.height * ratio; - + data.shadowElem.css(ret); ret.width = data.shadowElem.height() * ratio; ret.height = ret.width / ratio; - + } if(!webshims.support.mediaelement){ ret.width = data.shadowElem.width(); ret.height = data.shadowElem.height(); } } } return ret; }; - + return retFn; })(); - + var setElementDimension = function(data, hasControls){ var dims; - + var box = data.shadowElem; $(data._elem)[hasControls ? 'addClass' : 'removeClass']('webshims-controls'); if(data.isActive == 'third' || data.activating == 'third'){ if(data._elemNodeName == 'audio' && !hasControls){ @@ -2281,11 +2306,11 @@ data._elem.style.display = 'none'; box.css(dims); } } }; - + var bufferSrc = (function(){ var preloads = { '': 1, 'auto': 1 }; @@ -2296,21 +2321,21 @@ } preload = $.prop(elem, 'preload'); return !!(preloads[preload] || (preload == 'metadata' && $(elem).is('.preload-in-doubt, video:not([poster])'))); }; })(); - + var regs = { - A: /&amp;/g, - a: /&/g, - e: /\=/g, - q: /\?/g - }, - replaceVar = function(val){ - return (val.replace) ? val.replace(regs.A, '%26').replace(regs.a, '%26').replace(regs.e, '%3D').replace(regs.q, '%3F') : val; - }; - + A: /&amp;/g, + a: /&/g, + e: /\=/g, + q: /\?/g + }, + replaceVar = function(val){ + return (val.replace) ? val.replace(regs.A, '%26').replace(regs.a, '%26').replace(regs.e, '%3D').replace(regs.q, '%3F') : val; + }; + if('matchMedia' in window){ var allowMediaSorting = false; try { allowMediaSorting = window.matchMedia('only all').matches; } catch(er){} @@ -2320,85 +2345,71 @@ src1 = !src1.media || matchMedia( src1.media ).matches; src2 = !src2.media || matchMedia( src2.media ).matches; } catch(er){ return 0; } - return src1 == src2 ? + return src1 == src2 ? 0 : src1 ? -1 - : 1; + : 1; }; } } + mediaelement.resetSwfProps = resetSwfProps; mediaelement.createSWF = function( elem, canPlaySrc, data ){ if(!hasFlash){ setTimeout(function(){ $(elem).mediaLoad(); //<- this should produce a mediaerror }, 1); return; } - + var attrStyle = {}; if(loadedSwf < 1){ loadedSwf = 1; } else { loadedSwf++; } if(!data){ data = webshims.data(elem, 'mediaelement'); } - + if((attrStyle.height = $.attr(elem, 'height') || '') || (attrStyle.width = $.attr(elem, 'width') || '')){ $(elem).css(attrStyle); webshims.warn("width or height content attributes used. Webshims prefers the usage of CSS (computed styles or inline styles) to detect size of a video/audio. It's really more powerfull."); } - - var isRtmp = canPlaySrc.type == 'audio/rtmp' || canPlaySrc.type == 'video/rtmp'; - var vars = $.extend({}, options.vars, { - poster: replaceVar($.attr(elem, 'poster') && $.prop(elem, 'poster') || ''), - source: replaceVar(canPlaySrc.streamId || canPlaySrc.srcProp), - server: replaceVar(canPlaySrc.server || '') - }); - var elemVars = $(elem).data('vars') || {}; - - - + var box; + var streamRequest = canPlaySrc.streamrequest; + var isStream = canPlaySrc.type == 'jarisplayer/stream'; + + var hasControls = $.prop(elem, 'controls'); var elemId = 'jarisplayer-'+ webshims.getID(elem); - - var params = $.extend( - {}, - options.params, - $(elem).data('params') - ); + + var elemNodeName = elem.nodeName.toLowerCase(); - var attrs = $.extend( - {}, - options.attrs, - { - name: elemId, - id: elemId - }, - $(elem).data('attrs') - ); + var setDimension = function(){ if(data.isActive == 'third'){ setElementDimension(data, $.prop(elem, 'controls')); } }; - - var box; - + + if(isStream && !streamRequest){ + webshim.usermedia.attach(elem, canPlaySrc, data); + return; + } + if(data && data.swfCreated){ mediaelement.setActive(elem, 'third', data); - + data.currentSrc = ''; - + data.shadowElem.html('<div id="'+ elemId +'">'); - + data.api = false; data.actionQueue = []; box = data.shadowElem; resetSwfProps(data); data.currentSrc = canPlaySrc.srcProp; @@ -2423,11 +2434,11 @@ }, _elem: { value: elem }, currentSrc: { - value: canPlaySrc.srcProp + value: streamRequest ? '' : canPlaySrc.srcProp }, swfCreated: { value: true }, id: { @@ -2451,30 +2462,31 @@ }, length: 0 } } })); - - - + + + box.insertBefore(elem); - + if(hasNative){ $.extend(data, {volume: $.prop(elem, 'volume'), muted: $.prop(elem, 'muted'), paused: $.prop(elem, 'paused')}); } - + webshims.addShadowDom(elem, box); if(!webshims.data(elem, 'mediaelement')){ webshims.data(elem, 'mediaelement', data); } addMediaToStopEvents(elem); - + mediaelement.setActive(elem, 'third', data); - + setElementDimension(data, hasControls); - + $(elem) + .on({ 'updatemediaelementdimensions loadedmetadata emptied': setDimension, 'remove': function(e){ if(!e.originalEvent && mediaelement.jarisEvent[data.id] && mediaelement.jarisEvent[data.id].elem == elem){ delete mediaelement.jarisEvent[data.id]; @@ -2484,18 +2496,17 @@ } }) .onWSOff('updateshadowdom', setDimension) ; } - + if(mediaelement.jarisEvent[data.id] && mediaelement.jarisEvent[data.id].elem != elem){ webshims.error('something went wrong'); return; } else if(!mediaelement.jarisEvent[data.id]){ - + mediaelement.jarisEvent[data.id] = function(jaris){ - if(jaris.type == 'ready'){ var onReady = function(){ if(data.api){ if(!data.paused){ data.api.api_play(); @@ -2516,47 +2527,86 @@ if(data.api){ if(!data._calledMeta && isNaN(jaris.duration) && data.duration != jaris.duration && isNaN(data.duration)){ onEvent.onDataInitialized(jaris, data); } - + if(!data._ppFlag && jaris.type != 'onPlayPause'){ onEvent.onPlayPause(jaris, data); } - + if(onEvent[jaris.type]){ onEvent[jaris.type](jaris, data); } } data.duration = jaris.duration; } }; mediaelement.jarisEvent[data.id].elem = elem; } - - $.extend(vars, + + createSwf(elem, canPlaySrc, data, elemId, hasControls, elemNodeName); + + if(!streamRequest){ + trigger(data._elem, 'loadstart'); + } + }; + + var createSwf = function(elem, canPlaySrc, data, elemId, hasControls, elemNodeName){ + var vars, elemVars, params, attrs; + var isRtmp = canPlaySrc.type == 'audio/rtmp' || canPlaySrc.type == 'video/rtmp'; + var isUserStream = canPlaySrc.type == 'jarisplayer/stream'; + + vars = $.extend({}, options.vars, { + poster: replaceVar($.attr(elem, 'poster') && $.prop(elem, 'poster') || ''), + source: replaceVar(canPlaySrc.streamId || canPlaySrc.srcProp), + server: replaceVar(canPlaySrc.server || '') + }); + + elemVars = $(elem).data('vars') || {}; + + $.extend(vars, { id: elemId, evtId: data.id, - controls: ''+hasControls, + controls: ''+(!isUserStream && hasControls), autostart: 'false', nodename: elemNodeName }, elemVars ); - + if(isRtmp){ vars.streamtype = 'rtmp'; + } else if(isUserStream){ + vars.streamtype = 'usermedia'; } else if(canPlaySrc.type == 'audio/mpeg' || canPlaySrc.type == 'audio/mp3'){ vars.type = 'audio'; vars.streamtype = 'file'; } else if(canPlaySrc.type == 'video/youtube'){ vars.streamtype = 'youtube'; } + + attrs = $.extend( + {}, + options.attrs, + { + name: elemId, + id: elemId + }, + $(elem).data('attrs') + ); + + params = $.extend( + {}, + options.params, + $(elem).data('params') + ); + options.changeSWF(vars, elem, canPlaySrc, data, 'embed'); clearTimeout(data.flashBlock); - + swfmini.embedSWF(playerSwfPath, elemId, "100%", "100%", "9.0.115", false, vars, params, attrs, function(swfData){ if(swfData.success){ var fBlocker = function(){ if((!swfData.ref.parentNode && box[0].parentNode) || swfData.ref.style.display == "none"){ box.addClass('flashblocker-assumed'); @@ -2564,17 +2614,17 @@ webshims.warn("flashblocker assumed"); } $(swfData.ref).css({'minHeight': '2px', 'minWidth': '2px', display: 'block'}); }; data.api = swfData.ref; - + if(!hasControls){ $(swfData.ref).attr('tabindex', '-1').css('outline', 'none'); } - + data.flashBlock = setTimeout(fBlocker, 99); - + if(!localConnectionTimer){ clearTimeout(localConnectionTimer); localConnectionTimer = setTimeout(function(){ fBlocker(); var flash = $(swfData.ref); @@ -2584,27 +2634,28 @@ webshims.warn("JS-SWF connection can't be established on hidden or unconnected flash objects"); } flash = null; }, 8000); } + if(isUserStream){ + webshim.usermedia.request(elem, canPlaySrc, data); + } } }); - - trigger(data._elem, 'loadstart'); }; - - + + var queueSwfMethod = function(elem, fn, args, data){ data = data || getSwfDataFromElem(elem); - + if(data){ if(data.api && data.api[fn]){ data.api[fn].apply(data.api, args || []); } else { //todo add to queue data.actionQueue.push({fn: fn, args: args}); - + if(data.actionQueue.length > 10){ setTimeout(function(){ if(data.actionQueue.length > 5){ data.actionQueue.shift(); } @@ -2613,17 +2664,18 @@ } return data; } return false; }; - + mediaelement.queueSwfMethod = queueSwfMethod; + ['audio', 'video'].forEach(function(nodeName){ var descs = {}; var mediaSup; var createGetProp = function(key){ if(nodeName == 'audio' && (key == 'videoHeight' || key == 'videoWidth')){return;} - + descs[key] = { get: function(){ var data = getSwfDataFromElem(this); if(data){ return data[key]; @@ -2639,37 +2691,37 @@ var createGetSetProp = function(key, setFn){ createGetProp(key); delete descs[key].writeable; descs[key].set = setFn; }; - + createGetSetProp('seeking'); - + createGetSetProp('volume', function(v){ var data = getSwfDataFromElem(this); if(data){ v *= 1; if(!isNaN(v)){ - + if(v < 0 || v > 1){ webshims.error('volume greater or less than allowed '+ (v / 100)); } - + queueSwfMethod(this, 'api_volume', [v], data); - - + + if(data.volume != v){ data.volume = v; trigger(data._elem, 'volumechange'); } data = null; - } + } } else if(mediaSup.volume.prop._supset) { return mediaSup.volume.prop._supset.apply(this, arguments); } }); - + createGetSetProp('muted', function(m){ var data = getSwfDataFromElem(this); if(data){ m = !!m; queueSwfMethod(this, 'api_muted', [m], data); @@ -2680,36 +2732,36 @@ data = null; } else if(mediaSup.muted.prop._supset) { return mediaSup.muted.prop._supset.apply(this, arguments); } }); - - + + createGetSetProp('currentTime', function(t){ var data = getSwfDataFromElem(this); if(data){ t *= 1; if (!isNaN(t)) { queueSwfMethod(this, 'api_seek', [t], data); } - + } else if(mediaSup.currentTime.prop._supset) { return mediaSup.currentTime.prop._supset.apply(this, arguments); } }); - + ['play', 'pause'].forEach(function(fn){ descs[fn] = { value: function(){ var data = getSwfDataFromElem(this); - + if(data){ if(data.stopPlayPause){ clearTimeout(data.stopPlayPause); } queueSwfMethod(this, fn == 'play' ? 'api_play' : 'api_pause', [], data); - + data._ppFlag = true; if(data.paused != (fn != 'play')){ data.paused = fn != 'play'; trigger(data._elem, fn); } @@ -2717,31 +2769,31 @@ return mediaSup[fn].prop._supvalue.apply(this, arguments); } } }; }); - + getPropKeys.forEach(createGetProp); - + webshims.onNodeNamesPropertyModify(nodeName, 'controls', function(val, boolProp){ var data = getSwfDataFromElem(this); - + $(this)[boolProp ? 'addClass' : 'removeClass']('webshims-controls'); - + if(data){ if(nodeName == 'audio'){ setElementDimension(data, boolProp); } queueSwfMethod(this, 'api_controls', [boolProp], data); } }); - - + + webshims.onNodeNamesPropertyModify(nodeName, 'preload', function(val){ var data, baseData, elem; - - + + if(bufferSrc(this)){ data = getSwfDataFromElem(this); if(data){ queueSwfMethod(this, 'api_preload', [], data); } else if(needsLoadPreload && this.paused && !this.error && !$.data(this, 'mediaerror') && !this.readyState && !this.networkState && !this.autoplay && $(this).is(':not(.nonnative-api-active)')){ @@ -2752,13 +2804,13 @@ $(elem).mediaLoad(); }, 9); } } }); - + mediaSup = webshims.defineNodeNameProperties(nodeName, descs, 'prop'); - + if(!support.mediaDefaultMuted){ webshims.defineNodeNameProperties(nodeName, { defaultMuted: { get: function(){ return $.attr(this, 'muted') != null; @@ -2772,12 +2824,72 @@ } } }, 'prop'); } }); - - + + var addCanvasBridge = function(){ + if(!window.CanvasRenderingContext2D){ + return false; + } + var _drawImage = CanvasRenderingContext2D.prototype.drawImage; + var slice = Array.prototype.slice; + var isVideo = { + video: 1, + VIDEO: 1 + }; + var tested = {}; + + if(!_drawImage){ + webshim.error('canvas.drawImage feature is needed. In IE8 flashvanvas pro can be used'); + } + + CanvasRenderingContext2D.prototype.drawImage = function(elem){ + var data, img, args, imgData; + var context = this; + + if(isVideo[elem.nodeName] && (data = webshims.data(elem, 'mediaelement')) && data.isActive == 'third' && data.api.api_image){ + + try { + imgData = data.api.api_image(); + } catch (er){ + webshims.error(er); + } + if(!tested[data.currentSrc]){ + tested[data.currentSrc] = true; + if(imgData == null){ + webshims.error('video has to be same origin or a crossdomain.xml has to be provided. Video has to be visible for flash API'); + } + } + + args = slice.call(arguments, 1); + img = new Image(); + + //todo find a performant sync way + img.onload = function(){ + args.unshift(this); + _drawImage.apply(context, args); + img.onload = null; + }; + + img.src = 'data:image/jpeg;base64,'+imgData; + + if(img.complete){ + img.onload(); + } + return; + } + return _drawImage.apply(this, arguments); + }; + return true; + }; + + if(!addCanvasBridge()){ + webshims.ready('canvas', addCanvasBridge); + } + + if(hasFlash && $.cleanData){ var oldClean = $.cleanData; var objElem = document.createElement('object'); var noRemove = { SetVariable: 1, @@ -2787,16 +2899,16 @@ }; var flashNames = { object: 1, OBJECT: 1 }; - + $.cleanData = function(elems){ var i, len, prop; var ret = oldClean.apply(this, arguments); if(elems && (len = elems.length) && loadedSwf){ - + for(i = 0; i < len; i++){ if(flashNames[elems[i].nodeName] && 'api_destroy' in elems[i]){ loadedSwf--; try { elems[i].api_destroy(); @@ -2808,40 +2920,40 @@ } } } catch(er){console.log(er);} } } - + } return ret; }; } if(!hasNative){ - + ['poster', 'src'].forEach(function(prop){ webshims.defineNodeNamesProperty(prop == 'src' ? ['audio', 'video', 'source'] : ['video'], prop, { //attr: {}, reflect: true, propType: 'src' }); }); - + webshims.defineNodeNamesProperty(['audio', 'video'], 'preload', { reflect: true, propType: 'enumarated', defaultValue: '', limitedTo: ['', 'auto', 'metadata', 'none'] }); - + webshims.reflectProperties('source', ['type', 'media']); - - + + ['autoplay', 'controls'].forEach(function(name){ webshims.defineNodeNamesBooleanProperty(['audio', 'video'], name); }); - + webshims.defineNodeNamesProperties(['audio', 'video'], { HAVE_CURRENT_DATA: { value: 2 }, HAVE_ENOUGH_DATA: { @@ -2866,11 +2978,11 @@ value: 2 }, NETWORK_NO_SOURCE: { value: 3 } - + }, 'prop'); if(hasFlash){ webshims.ready('WINDOWLOAD', function(){ @@ -2892,10 +3004,10 @@ }; var switchOptions = function(e){ var media, error, parent; if( ($(e.target).is('audio, video') || ((parent = e.target.parentNode) && $('source', parent).last()[0] == e.target)) && - (media = $(e.target).closest('audio, video')) && !media.hasClass('nonnative-api-active') + (media = $(e.target).closest('audio, video')) && !media.hasClass('nonnative-api-active') ){ error = media.prop('error'); setTimeout(function(){ if(!media.hasClass('nonnative-api-active')){ if(error && switchErrors[error.code]){