Created
January 25, 2009 18:17
-
-
Save knewter/52487 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Media Player Plugin | |
This plugin sets up a Media player that can handle MP3 and OGG Vorbis formats | |
A flash object is used for MP3 and the <audio> tag (if supported) is for OGG Vorbis. | |
Copyright (c) 2008 Radio New Zealand | |
Author: Richard Hulse | |
This software is released under the GNU GPL version 2 or later. <http://www.opensource.org/licenses/gpl-2.0.php> | |
*/ | |
(function(jQuery) { | |
// the Flash player that will play the MP3 files | |
var MP3 = null; | |
// the audio element that will play the ogg files | |
var VORBIS = null; | |
// the media object that gets used | |
var M = null; | |
// the data about the current media | |
var media = { | |
pan : 0, | |
volume : 50, | |
volume_max : 100, | |
volume_increment : 5, | |
// these are used to work around flash not reseting its position on stop | |
// so we track the state and return 0 instead of the (apparently) wrong flash value | |
// also means the plugin works the same for <audio> and flash implementations | |
playing : false, | |
// times are stored in seconds | |
time_paused_at : 0, | |
time_current : 0, | |
current_url : '', | |
// values for seek tracking | |
seeking : false, | |
seek_pos_current : 0, | |
seek_pos_prev : 0 | |
}; | |
var controls = { | |
seeking : false // the slider is seeking (as distinct from the underlying player component) | |
}; | |
var metadata = { | |
asset_id : 0, | |
title : '', | |
description : '', | |
duration : 0, | |
url : '', | |
length : 0, | |
media_type : '' | |
} | |
// Set to true if you want to only use the <audio> tag | |
var ignore_flash = false; | |
// this is how often to update the position count (in seconds) | |
var udpate_position_interval = 0.1; | |
// Public Variables and Methods | |
jQuery.mediaPlayer = { | |
initialise: function( settings ) { | |
MP3 = new mp3_player( settings, this.events ); | |
// send initial volume and position | |
this.events.onMediaVolume(); | |
jQuery.periodic( this.events.onMediaPosition, { frequency: udpate_position_interval } ); | |
}, | |
load: function( metadata ) { | |
// grab the source | |
if( metadata.attachToId){ | |
media.current_url = jQuery(metadata.attachToId).attr('src'); | |
type = jQuery( '#' + metadata.attachToId).attr('type'); | |
if ( type.match( /codecs=theora/ )){ | |
metadata.media_type = 'theora'; | |
} | |
else if( type.match( /codecs=vorbis/ )){ | |
metadata.media_type = 'vorbis'; | |
} | |
} | |
else{ | |
media.current_url = metadata.url; | |
} | |
switch( metadata.media_type ){ | |
case 'vorbis' : M = new vorbis_player( metadata, this.events ); | |
break; | |
case 'theora' : M = new theora_player( metadata, this.events ); | |
break; | |
case 'mp3' : M = MP3; | |
break; | |
} | |
M.load(media.current_url); | |
}, | |
stop: function() { | |
media.time_current = 0; | |
media.time_paused_at = 0; | |
M.stop(); | |
}, | |
play: function( position ) { | |
// do we resume or start at the stated position | |
media.time_current = (media.time_paused_at) ? media.time_paused_at : ( position ? position : 0); | |
M.play(media.time_current); | |
}, | |
pause: function() { | |
media.time_current = media.time_paused_at = M.pause(); | |
}, | |
louder: function() { | |
if ( media.volume >= media.volume_max ){ | |
return; | |
} | |
media.volume += media.volume_increment; | |
M.volume( media.volume ); | |
}, | |
quieter: function() { | |
if ( media.volume <= 0.0 ) { | |
return; | |
} | |
media.volume -= media.volume_increment; | |
M.volume( media.volume ); | |
}, | |
elapsedTime: function() { | |
current_position(); | |
}, | |
getVolume: function() { | |
return media.volume; | |
}, | |
getDuration: function( format ) { | |
if( format ){ | |
return formatTime(M.duration()); | |
} | |
else { | |
return M.duration(); | |
} | |
}, | |
seekTo: function(pos_in_secs) { | |
// save the current postion | |
media.seek_pos_current = pos_in_secs; | |
update_media_timer(pos_in_secs) | |
if( ! controls.seeking ){ | |
// if we are not seeking then pause and setup our function | |
controls.seeking = true; | |
M.pause(true); // true means we are pausing to seek | |
// the seekMonitor checks to see if seeking has completed and | |
// then restarts the player. The delay is to allow keyboard | |
// users a chance to nudge the value | |
jQuery.periodic( seekMonitor, { frequency : 1.0 } ); | |
} | |
}, | |
isPlaying: function() { | |
return media.playing; | |
}, | |
isPaused: function() { | |
return ( media.time_paused_at > 0 ) ? true : false; | |
}, | |
isStopped: function() { | |
if( ! media.playing && ! jQuery.mediaPlayer.isPaused() ){ | |
return true; | |
} | |
return false; | |
}, | |
// called directy by the flash movie and triggered by events from <audio> | |
events : { | |
// events from the flash player | |
onMediaComplete: function() { | |
jQuery.mediaPlayer.stop(); | |
media.playing = false; | |
sendEvent( "mediaStop" ); | |
}, | |
onFlashLoaded: function() { | |
if( MP3 ){ | |
MP3.flashLoaded(); | |
} | |
update_controls(); | |
}, | |
onMediaLoaded: function() { | |
sendEvent( "mediaLoaded" ); | |
}, | |
onMediaStop: function() { | |
media.playing = false; | |
sendEvent( "mediaStop" ); | |
update_controls(); | |
}, | |
onMediaPause: function() { | |
media.playing = false; | |
sendEvent( "mediaPause" ); | |
}, | |
onMediaPlay: function() { | |
media.playing = true; | |
sendEvent( "mediaPlay" ); | |
}, | |
onMediaVolume: function() { | |
sendEvent( "mediaVolumeChange", { volume: media.volume}) | |
}, | |
onMediaPosition: function() { | |
if( media.playing ){ | |
update_controls(); | |
} | |
return true; | |
} | |
} | |
}; | |
//Private Functions | |
function sendEvent ( event, params ) { | |
jQuery(document).trigger( event, params ) | |
} | |
function update_controls() { | |
update_media_timer(); | |
update_media_slider(); | |
} | |
function update_media_timer( set_position ) { | |
// stop updating if the audio is seeking | |
if( media.seeking ){ | |
return; | |
} | |
var position = set_position || current_position(); | |
var readable_position = formatTime(position); | |
sendEvent( "mediaTimerChange", { position: readable_position }); | |
} | |
function update_media_slider() { | |
// stop updating if the audio is seeking | |
if( media.seeking ){ | |
return; | |
} | |
var position = current_position(); | |
position = Math.floor(position); | |
sendEvent( "mediaSliderChange", { position : position }); | |
} | |
function seekMonitor(){ | |
/* | |
this is set up at the start of a seek operation to monitor | |
the seek is stable. THis is to stop lots of seeks | |
being sent until the slider has stopped moving | |
*/ | |
var duration = M.duration() || 0; | |
duration = Math.floor(duration); | |
if( media.seek_pos_current == media.seek_pos_prev ) { | |
controls.seeking = false; | |
media.time_current = media.time_paused_at = media.seek_pos_current; | |
M.play(media.time_current); | |
// returning false stop the periodic | |
return false; | |
} | |
else{ | |
media.seek_pos_prev = media.seek_pos_current; | |
return true; | |
} | |
} | |
function current_position() { | |
if ( jQuery.mediaPlayer.isStopped() ) { | |
return 0; | |
} | |
return M.elapsedTime(); | |
} | |
function formatTime( dur ){ | |
var difference = Math.floor(dur); | |
seconds = difference % 60; | |
difference = (difference - seconds) / 60; | |
minutes = difference % 60; | |
difference = (difference - minutes) / 60; | |
hours = difference % 24; | |
seconds = ((seconds < 10) ? "0" : "") + seconds; | |
if(hours > 0){ | |
return hours + ":" + minutes + ":" + seconds; | |
} | |
else{ | |
return minutes + ":" + seconds; | |
} | |
} | |
/* | |
Shell functions that setup the two types of objects | |
*/ | |
function vorbis_player( options, e ){ | |
return new html5_player( 'audio', options, e ); | |
} | |
function theora_player( options, e ){ | |
return new html5_player( 'video', options, e ); | |
} | |
/* | |
This is the vorbis player object that wraps an audio element and provides a | |
standadised interface to the audio player module | |
*/ | |
function html5_player( tag, options, pev) { | |
var OGG = null; | |
var current_url; | |
var media_element = null; | |
var type = ''; | |
var paused = false; | |
// do we use the provided element or make a new one? | |
if ( options.attachToId ) { | |
media_element = document.getElementById( options.attachToId ); | |
} | |
else{ | |
if ( tag == 'audio' ) { | |
type = 'audio/ogg;codecs=vorbis'; | |
el = document.createElement('audio'); | |
if ( canPlayType( el, type ) == 'probably' ) { | |
media_element = el; | |
} | |
} | |
else { | |
type = 'video/ogg;codecs=theora'; | |
el = document.createElement('video'); | |
if ( canPlayType( el, type ) == 'probably' ) { | |
media_element = el; | |
} | |
} | |
} | |
if ( media_element ) { | |
// attach our events | |
jQuery(media_element) | |
.bind('ended', function(e, m){ | |
pev.onMediaComplete(); | |
}) | |
.bind('seeking', function(e, m){ | |
media.seeking = true; | |
}) | |
.bind('seeked', function(e, m){ | |
media.seeking = false; | |
}) | |
.bind('loadedmetadata', function(e, m){ | |
pev.onMediaLoaded(); | |
}); | |
// only append new elements | |
if ( ! options.attachToId ) { | |
jQuery("body").append(media_element) | |
jQuery(media_element).attr({ | |
type : type | |
}); | |
} | |
else { | |
// turn off any existing controls | |
jQuery(media_element).removeAttr( 'controls' ); | |
} | |
OGG = media_element | |
} | |
this.load = function(url){ | |
current_url = url; | |
jQuery(media_element).attr({ | |
src: current_url | |
}); | |
setOGGVolume( 50 ); | |
OGG.muted = false; | |
}; | |
this.play = function(pos_in_secs){ | |
// if we are paused there is no need to seek as | |
// the element (unlike flash) knows where it is already | |
if ( ! paused ) { | |
try{ | |
OGG.currentTime = pos_in_secs; | |
}catch(e){} | |
} | |
OGG.play(); | |
pev.onMediaPlay(); | |
}; | |
this.stop = function(){ | |
OGG.pause(); | |
paused = false; | |
// this is really a seek | |
OGG.currentTime = 0; | |
pev.onMediaStop(); | |
}; | |
this.pause = function(pausing_to_seek){ | |
// if we've paused to seek, then this is not a 'real' pause | |
// the play function WILL need to seek at the end of the see | |
if ( ! pausing_to_seek ) { | |
paused = true; | |
} | |
else{ | |
paused = false; | |
} | |
OGG.pause(); | |
pev.onMediaPause(); | |
return OGG.currentTime; | |
}; | |
this.volume = function(){ | |
setOGGVolume( media.volume ); | |
pev.onMediaVolume(); | |
}; | |
this.duration = function(){ | |
return OGG.duration || 0; | |
}; | |
this.elapsedTime = function(){ | |
// this is the current time that has been seeked to | |
return OGG.currentTime; | |
}; | |
function setOGGVolume( vol ) { | |
OGG.volume = media.volume / 100; | |
} | |
} | |
/* | |
this is the mp3 player object (a flash movie) that wraps an audio element and provides | |
a standadised interface to the audio player module | |
*/ | |
function mp3_player(options, pev) { | |
var MP3 = null; | |
var flash = { | |
path : "audioplayer.swf", | |
vars : {}, | |
params : { | |
allowScriptAccess: 'always', | |
wMode: 'transparent', | |
swLiveConnect: true | |
}, | |
ver : "8.0.0", | |
width : 1, | |
height: 1, | |
exp: "expressInstall.swf", | |
replace : "mp3-player p", | |
attribs : { | |
id:"flashplayer", | |
name:"flashplayer" | |
}, | |
loading : false | |
}; | |
var current_url; | |
// a place to save the first commands if we have to wait for the flash object to load | |
var saved_cmd = []; | |
jQuery.extend(flash, options); | |
f = flash; | |
// initialisation routine | |
jQuery("body").append('<div id="mp3-player"><p></p></div>'); | |
f.loading = true; | |
jQuery.swfobject.embedSWF( f.path, f.replace, f.width, f.height, f.ver, f.exp, f.vars, f.params, f.attribs); | |
// the movie has 1 seconds to load, after which we assume it has probably failed | |
jQuery.periodic(function(){ f.loading = false; return false; }, {frequency: 1.0}); | |
this.load = function(url){ | |
current_url = url; | |
}; | |
this.play = function(pos_in_secs){ | |
if( isLoading( this.play ) ) return; | |
MP3.startSound( current_url, (pos_in_secs * 1000) ); | |
pev.onMediaPlay(); | |
}; | |
this.stop = function(){ | |
if( isLoading( this.stop ) ) return; | |
MP3.stopSound( current_url ); | |
pev.onMediaStop(); | |
} | |
this.pause = function(){ | |
if( isLoading( this.pause ) ) return; | |
MP3.stopSound( current_url ); | |
pev.onMediaPause(); | |
return ( MP3.getPosition( current_url ) / 1000) || media.time_paused_at; | |
}; | |
this.volume = function(){ | |
if( isLoading( this.volume ) ) return; | |
MP3.setVolume( current_url, media.volume ); | |
pev.onMediaVolume(); | |
}; | |
this.duration = function(){ | |
if( isLoading( this.duration ) ) return 0; | |
return (MP3.getDuration(current_url) / 1000 ) || 0; | |
}; | |
this.elapsedTime = function(){ | |
if( isLoading( this.elapsedTime ) ) return 0; | |
// flash does not return 0 for position if player is stopped. Annoying | |
return ( MP3.getPosition( current_url ) / 1000 ) || 0; | |
}; | |
this.flashLoaded = function() { | |
MP3 = jQuery.swfobject.getObjectById(f.attribs.id); | |
f.loading = false; | |
// check for commands that were run before the swf was loaded | |
if ( saved_cmd.length ) { | |
jQuery.each(saved_cmd, function(index, cmd) { | |
cmd(); | |
}); | |
saved_cmd = []; | |
} | |
}; | |
function isLoading( cmd ){ | |
if ( f.loading && ! MP3 ) { | |
// commands are saved for up to 1 second while the flash movie initialises. | |
saved_cmd.push(cmd); | |
return true; | |
} | |
return false; | |
}; | |
} | |
function canPlayType( el, type ){ | |
if ( 'canPlayType' in el ){ | |
return el.canPlayType(type); | |
} | |
else if( 'volume' in el && jQuery.browser.mozilla ){ | |
// testing for volume is the fallback test for Vorbis support because | |
// for example, Safari has <audio> tag support for quicktime, so will pass this test | |
// so we test that it's mozilla too. Seems like a safe assumption for now. | |
// This will remain in until Firefox 3.1 final is released | |
return 'probably'; | |
} | |
return 'no'; | |
} | |
})(jQuery); | |
/* | |
SWFObject v2.1 <http://code.google.com/p/swfobject/> | |
Copyright (c) 2007-2008 Geoff Stearns, Michael Williams, and Bobby van der Sluis | |
This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> | |
jQuery v1.2.6 <http://jquery.com/> | |
Copyright (c) 2008 John Resig | |
This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> | |
This software is released under the GPL License <http://www.opensource.org/licenses/gpl-2.0.php> | |
jQuery SWFObject Plugin v1.0.3 <http://jquery.thewikies.com/swfobject/> | |
Copyright (c) 2008 Jonathan Neal | |
This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> | |
This software is released under the GPL License <http://www.opensource.org/licenses/gpl-2.0.php> | |
*//*jslint | |
bitwise: true, | |
browser: true, | |
eqeqeq: true, | |
forin: true, | |
onevar: false, | |
plusplus: false, | |
regexp: true, | |
undef: true, | |
white: true | |
*//*global | |
jQuery | |
ActiveXObject | |
*/ | |
(function (jQuery) { | |
jQuery.swfobject = function () { | |
var UNDEF = 'undefined', | |
OBJECT = 'object', | |
SHOCKWAVE_FLASH = 'Shockwave Flash', | |
SHOCKWAVE_FLASH_AX = 'ShockwaveFlash.ShockwaveFlash', | |
FLASH_MIME_TYPE = 'application/x-shockwave-flash', | |
EXPRESS_INSTALL_ID = 'SWFObjectExprInst', | |
win = window, | |
doc = document, | |
nav = navigator, | |
regObjArr = [], | |
objIdArr = [], | |
listenersArr = [], | |
storedAltContent = null, | |
storedAltContentId = null, | |
isExpressInstallActive = false, | |
ua, | |
fixParams, | |
showExpressInstall, | |
displayAltContent, | |
abstractAltContent, | |
createSWF, | |
createObjParam, | |
removeSWF, | |
removeObjectInIE, | |
addListener, | |
hasPlayerVersion, | |
createCSS, | |
setVisibility, | |
urlEncodeIfNecessary, | |
cleanup; | |
ua = function () { | |
var w3cdom = typeof doc.getElementById !== UNDEF && typeof doc.getElementsByTagName !== UNDEF && typeof doc.createElement !== UNDEF, | |
playerVersion = [0, 0, 0], | |
d = null; | |
if (typeof nav.plugins !== UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] === OBJECT) { | |
d = nav.plugins[SHOCKWAVE_FLASH].description; | |
if (d && !(typeof nav.mimeTypes !== UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { | |
d = d.replace(/^[\S|\s]*\s+(\S+\s+\S+$)/, '$1'); | |
playerVersion[0] = parseInt(d.replace(/^([\S|\s]*)\.[\S|\s]*$/, '$1'), 10); | |
playerVersion[1] = parseInt(d.replace(/^[\S|\s]*\.([\S|\s]*)\s[\S|\s]*$/, '$1'), 10); | |
playerVersion[2] = /r/.test(d) ? parseInt(d.replace(/^[\S|\s]*r([\S|\s]*)$/, '$1'), 10) : 0; | |
} | |
} | |
else if (typeof win.ActiveXObject !== UNDEF) { | |
var a = null, fp6Crash = false; | |
try { | |
a = new ActiveXObject(SHOCKWAVE_FLASH_AX + '.7'); | |
} | |
catch (e) { | |
try { | |
a = new ActiveXObject(SHOCKWAVE_FLASH_AX + '.6'); | |
playerVersion = [6, 0, 21]; | |
a.AllowScriptAccess = 'always'; | |
} | |
catch (ee) { | |
if (playerVersion[0] === 6) { | |
fp6Crash = true; | |
} | |
} | |
if (!fp6Crash) { | |
try { | |
a = new ActiveXObject(SHOCKWAVE_FLASH_AX); | |
} | |
catch (eee) {} | |
} | |
} | |
if (!fp6Crash && a) { | |
try { | |
d = a.GetVariable('$version'); | |
if (d) { | |
d = d.split(' ')[1].split(','); | |
playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)]; | |
} | |
} | |
catch (eeee) {} | |
} | |
} | |
var u = nav.userAgent.toLowerCase(), | |
p = nav.platform.toLowerCase(); | |
return { | |
w3cdom: w3cdom, | |
pv: playerVersion, | |
webkit: jQuery.browser.safari ? jQuery.browser.version : false, | |
ie: jQuery.browser.msie, | |
win: p ? /win/.test(p) : /win/.test(u), | |
mac: p ? /mac/.test(p) : /mac/.test(u) | |
}; | |
}(); | |
jQuery(function () { | |
var rl = regObjArr.length; | |
for (var i = 0; i < rl; i++) { | |
var id = regObjArr[i].id; | |
if (ua.pv[0] > 0) { | |
var obj = jQuery('#' + id); | |
if (obj.length) { | |
regObjArr[i].width = obj.attr('width') ? obj.attr('width') : '0'; | |
regObjArr[i].height = obj.attr('height') ? obj.attr('height') : '0'; | |
if (hasPlayerVersion(regObjArr[i].swfVersion)) { | |
if (ua.webkit && ua.webkit < 312) { | |
fixParams(obj[0]); | |
} | |
setVisibility(id, true); | |
} | |
else if (regObjArr[i].expressInstall && !isExpressInstallActive && hasPlayerVersion('6.0.65') && (ua.win || ua.mac)) { | |
showExpressInstall(regObjArr[i]); | |
} | |
else { | |
displayAltContent(obj[0]); | |
} | |
} | |
} | |
else { | |
setVisibility(id, true); | |
} | |
} | |
}); | |
fixParams = function (obj) { | |
obj = jQuery(obj); | |
var nestedObj = obj.find('object'); | |
if (nestedObj.length) { | |
var e = jQuery('<embed />'), a = nestedObj[0].attributes; | |
if (a) { | |
for (var i = 0; i < a.length; i++) { | |
e.attr((a[i].nodeName === 'DATA') ? 'src' : a[i].nodeName, a[i].nodeValue); | |
} | |
} | |
nestedObj.children().each(function () { | |
if (this.nodeType === 1 && this.nodeName === 'PARAM') { | |
e.attr(jQuery(this).attr('name'), jQuery(this).attr('value')); | |
} | |
}); | |
obj.replaceWith(e); | |
} | |
}; | |
showExpressInstall = function (regObj) { | |
isExpressInstallActive = true; | |
var obj = jQuery('#' + regObj.id); | |
if (obj.length) { | |
if (regObj.altContentId) { | |
var ac = jQuery('#' + regObj.altContentId)[0]; | |
if (ac) { | |
storedAltContent = ac; | |
storedAltContentId = regObj.altContentId; | |
} | |
} | |
else { | |
storedAltContent = abstractAltContent(obj[0]); | |
} | |
if (!/%$/.test(regObj.width) && parseInt(regObj.width, 10) < 310) { | |
regObj.width = '310'; | |
} | |
if (!/%$/.test(regObj.height) && parseInt(regObj.height, 10) < 137) { | |
regObj.height = '137'; | |
} | |
doc.title = doc.title.slice(0, 47) + ' - Flash Player Installation'; | |
var pt = ua.ie && ua.win ? 'ActiveX' : 'PlugIn', | |
dt = doc.title, | |
fv = "MMredirectURL=" + win.location + "&MMplayerType=" + pt + "&MMdoctitle=" + dt, | |
replaceId = regObj.id; | |
if (ua.ie && ua.win && obj[0].readyState !== 4) { | |
replaceId += 'SWFObjectNew'; | |
var newObj = jQuery('<div id="' + replaceId + '" />'); | |
obj.before(newObj); | |
obj.css('display', 'none'); | |
var fn = function () { | |
obj.remove(); | |
}; | |
addListener(win, 'onload', fn); | |
} | |
createSWF({ | |
data: regObj.expressInstall, | |
id: EXPRESS_INSTALL_ID, | |
width: regObj.width, | |
height: regObj.height | |
}, { | |
flashvars: fv | |
}, replaceId); | |
} | |
}; | |
displayAltContent = function (obj) { | |
obj = jQuery(obj); | |
if (ua.ie && ua.win && obj[0].readyState !== 4) { | |
var el = jQuery('<div/>'); | |
obj.before(el); | |
el.replaceWith(jQuery(abstractAltContent(obj[0]))); | |
obj.css('display', 'none'); | |
var fn = function () { | |
obj.remove(); | |
}; | |
addListener(win, 'onload', fn); | |
} | |
else { | |
obj.replaceWith(jQuery(abstractAltContent(obj[0]))); | |
} | |
}; | |
abstractAltContent = function (obj) { | |
obj = jQuery(obj); | |
var ac = jQuery('<div />'); | |
if (ua.win && ua.ie) { | |
ac.html(obj.html()); | |
} | |
else { | |
obj.find('object').children().each(function () { | |
if (!(this.nodeType === 1 && this.nodeName === 'PARAM') && !(this.nodeType === 8)) { | |
jQuery(this.cloneNode(true)).appendTo(ac); | |
} | |
}); | |
} | |
return ac[0]; | |
}; | |
createSWF = function (attObj, parObj, id) { | |
var r, el = jQuery('#' + id); | |
if (el.length) { | |
if (typeof attObj.id === UNDEF) { | |
attObj.id = id; | |
} | |
if (ua.ie && ua.win) { | |
var att = ''; | |
for (var i in attObj) { | |
if (attObj[i] !== Object.prototype[i]) { | |
if (i.toLowerCase() === 'data') { | |
parObj.movie = attObj[i]; | |
} | |
else if (i.toLowerCase() === 'styleclass') { | |
att += ' class="' + attObj[i] + '"'; | |
} | |
else if (i.toLowerCase() !== 'classid') { | |
att += ' ' + i + '="' + attObj[i] + '"'; | |
} | |
} | |
} | |
var par = ''; | |
for (var j in parObj) { | |
if (parObj[j] !== Object.prototype[j]) { | |
par += '<param name="' + j + '" value="' + parObj[j] + '" />'; | |
} | |
} | |
el[0].outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '</object>'; | |
objIdArr[objIdArr.length] = attObj.id; | |
r = jQuery('#' + attObj.id)[0]; | |
} | |
else if (ua.webkit && ua.webkit < 312) { | |
var e = jQuery('<embed type="' + FLASH_MIME_TYPE + '" />'); | |
for (var k in attObj) { | |
if (attObj[k] !== Object.prototype[k]) { | |
if (k.toLowerCase() === 'data') { | |
e.attr('src', attObj[k]); | |
} | |
else if (k.toLowerCase() === 'styleclass') { | |
e.attr('class', attObj[k]); | |
} | |
else if (k.toLowerCase() !== 'classid') { | |
e.attr(k, attObj[k]); | |
} | |
} | |
} | |
for (var l in parObj) { | |
if (parObj[l] !== Object.prototype[l]) { | |
if (l.toLowerCase() !== 'movie') { | |
e.attr(l, parObj[l]); | |
} | |
} | |
} | |
el.replaceWith(e); | |
r = e[0]; | |
} | |
else { | |
var o = jQuery('<object type="' + FLASH_MIME_TYPE + '" />'); | |
for (var m in attObj) { | |
if (attObj[m] !== Object.prototype[m]) { | |
if (m.toLowerCase() === 'styleclass') { | |
o.attr('class', attObj[m]); | |
} | |
else if (m.toLowerCase() !== 'classid') { | |
o.attr(m, attObj[m]); | |
} | |
} | |
} | |
for (var n in parObj) { | |
if (parObj[n] !== Object.prototype[n] && n.toLowerCase() !== 'movie') { | |
createObjParam(o[0], n, parObj[n]); | |
} | |
} | |
el.replaceWith(o); | |
r = o[0]; | |
} | |
} | |
return r; | |
}; | |
createObjParam = function (el, pName, pValue) { | |
jQuery(el).append(jQuery('<param name="' + pName + '" value="' + pValue + '" />')); | |
}; | |
removeSWF = function (id) { | |
var obj = jQuery('#' + id); | |
if (obj && (obj[0].nodeName === 'OBJECT' || obj[0].nodeName === 'EMBED')) { | |
if (ua.ie && ua.win) { | |
if (obj[0].readyState === 4) { | |
removeObjectInIE(id); | |
} | |
else { | |
win.attachEvent('onload', function () { | |
removeObjectInIE(id); | |
}); | |
} | |
} | |
else { | |
obj.remove(); | |
} | |
} | |
}; | |
removeObjectInIE = function (id) { | |
var obj = jQuery('#' + id); | |
if (obj.length) { | |
for (var i in obj[0]) { | |
if (typeof obj[0][i] === 'function') { | |
obj[0][i] = null; | |
} | |
} | |
obj.remove(); | |
} | |
}; | |
addListener = function (target, eventType, fn) { | |
target.attachEvent(eventType, fn); | |
listenersArr[listenersArr.length] = [target, eventType, fn]; | |
}; | |
hasPlayerVersion = function (rv) { | |
var pv = ua.pv, v = rv.split("."); | |
v[0] = parseInt(v[0], 10); | |
v[1] = parseInt(v[1], 10) || 0; | |
v[2] = parseInt(v[2], 10) || 0; | |
return (pv[0] > v[0] || (pv[0] === v[0] && pv[1] > v[1]) || (pv[0] === v[0] && pv[1] === v[1] && pv[2] >= v[2])) ? true : false; | |
}; | |
createCSS = function (sel, decl) { | |
if (ua.ie && ua.mac) { | |
return; | |
} | |
var h = jQuery('head'), s = jQuery('<style media="screen" type="text/css" />'); | |
if (!(ua.ie && ua.win) && typeof doc.createTextNode !== UNDEF) { | |
jQuery(doc.createTextNode(sel + ' {' + decl + '}')).appendTo(s); | |
} | |
s.appendTo(h); | |
if (ua.ie && ua.win && typeof doc.styleSheets !== UNDEF && doc.styleSheets.length > 0) { | |
var ls = doc.styleSheets[doc.styleSheets.length - 1]; | |
if (typeof ls.addRule === OBJECT) { | |
ls.addRule(sel, decl); | |
} | |
} | |
}; | |
setVisibility = function (id, isVisible) { | |
var v = isVisible ? 'visible' : 'hidden', obj = jQuery('#' + id); | |
if (obj.length) { | |
jQuery(function () { | |
obj.css('visibility', v); | |
}); | |
} | |
else { | |
createCSS('#' + id, 'visibility: ' + v); | |
} | |
}; | |
urlEncodeIfNecessary = function (s) { | |
var regex = /[\\\"<>\.;]/; | |
var hasBadChars = regex.exec(s) !== null; | |
return hasBadChars ? encodeURIComponent(s) : s; | |
}; | |
cleanup = function () { | |
if (ua.ie && ua.win) { | |
window.attachEvent('onunload', function () { | |
var ll = listenersArr.length; | |
for (var i = 0; i < ll; i++) { | |
listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]); | |
} | |
var il = objIdArr.length; | |
for (var j = 0; j < il; j++) { | |
removeSWF(objIdArr[j]); | |
} | |
for (var k in ua) { | |
ua[k] = null; | |
} | |
ua = null; | |
for (var l in jQuery.swfobject) { | |
jQuery.swfobject[l] = null; | |
} | |
jQuery.swfobject = null; | |
}); | |
} | |
}(); | |
return { | |
registerObject: function (objectIdStr, swfVersionStr, xiSwfUrlStr) { | |
if (!ua.w3cdom || !objectIdStr || !swfVersionStr) { | |
return; | |
} | |
var regObj = {}; | |
regObj.id = objectIdStr; | |
regObj.swfVersion = swfVersionStr; | |
regObj.expressInstall = xiSwfUrlStr ? xiSwfUrlStr : false; | |
regObjArr[regObjArr.length] = regObj; | |
setVisibility(objectIdStr, false); | |
}, | |
getObjectById: function (objectIdStr) { | |
var r = null; | |
if (ua.w3cdom) { | |
var o = jQuery('#' + objectIdStr); | |
if (o.length) { | |
var n = o.find(OBJECT)[0]; | |
if (!n || (n && typeof o.SetVariable !== UNDEF)) { | |
r = o[0]; | |
} | |
else if (typeof n.SetVariable !== UNDEF) { | |
r = n; | |
} | |
} | |
} | |
return r; | |
}, | |
createCSS: function (sel, decl) { | |
if (ua.w3cdom) { | |
createCSS(sel, decl); | |
} | |
}, | |
createSWF: function (attObj, parObj, replaceElemIdStr) { | |
if (ua.w3cdom) { | |
return createSWF(attObj, parObj, replaceElemIdStr); | |
} | |
else { | |
return undefined; | |
} | |
}, | |
embedSWF: function (swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj) { | |
if (!ua.w3cdom || !swfUrlStr || !replaceElemIdStr || !widthStr || !heightStr || !swfVersionStr) { | |
return; | |
} | |
widthStr += ''; | |
heightStr += ''; | |
if (hasPlayerVersion(swfVersionStr)) { | |
setVisibility(replaceElemIdStr, false); | |
var att = {}; | |
if (attObj && typeof attObj === OBJECT) { | |
for (var i in attObj) { | |
if (attObj[i] !== Object.prototype[i]) { | |
att[i] = attObj[i]; | |
} | |
} | |
} | |
att.data = swfUrlStr; | |
att.width = widthStr; | |
att.height = heightStr; | |
var par = {}; | |
if (parObj && typeof parObj === OBJECT) { | |
for (var j in parObj) { | |
if (parObj[j] !== Object.prototype[j]) { | |
par[j] = parObj[j]; | |
} | |
} | |
} | |
if (flashvarsObj && typeof flashvarsObj === OBJECT) { | |
for (var k in flashvarsObj) { | |
if (flashvarsObj[k] !== Object.prototype[k]) { | |
if (typeof par.flashvars !== UNDEF) { | |
par.flashvars += '&' + k + '=' + flashvarsObj[k]; | |
} | |
else { | |
par.flashvars = k + '=' + flashvarsObj[k]; | |
} | |
} | |
} | |
} | |
jQuery(function () { | |
createSWF(att, par, replaceElemIdStr); | |
if (att.id === replaceElemIdStr) { | |
setVisibility(replaceElemIdStr, true); | |
} | |
}); | |
} | |
else if (xiSwfUrlStr && !isExpressInstallActive && hasPlayerVersion('6.0.65') && (ua.win || ua.mac)) { | |
isExpressInstallActive = true; | |
setVisibility(replaceElemIdStr, false); | |
jQuery(function () { | |
var regObj = {}; | |
regObj.id = regObj.altContentId = replaceElemIdStr; | |
regObj.width = widthStr; | |
regObj.height = heightStr; | |
regObj.expressInstall = xiSwfUrlStr; | |
showExpressInstall(regObj); | |
}); | |
} | |
}, | |
expressInstallCallback: function () { | |
if (isExpressInstallActive && storedAltContent) { | |
var obj = jQuery('#' + EXPRESS_INSTALL_ID); | |
if (obj.length) { | |
obj.replaceWith(jQuery(storedAltContent)); | |
if (storedAltContentId) { | |
setVisibility(storedAltContentId, true); | |
if (ua.ie && ua.win) { | |
jQuery(storedAltContent).css('display', 'block'); | |
} | |
} | |
storedAltContent = null; | |
storedAltContentId = null; | |
isExpressInstallActive = false; | |
} | |
} | |
}, | |
getFlashPlayerVersion: function () { | |
return { | |
major: ua.pv[0], | |
minor: ua.pv[1], | |
release: ua.pv[2] | |
}; | |
}, | |
getQueryParamValue: function (param) { | |
var q = doc.location.search || doc.location.hash; | |
if (param === null) { | |
return urlEncodeIfNecessary(q); | |
} | |
if (q) { | |
var pairs = q.substring(1).split('&'); | |
for (var i = 0; i < pairs.length; i++) { | |
if (pairs[i].substring(0, pairs[i].indexOf('=')) === param) { | |
return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf('=') + 1))); | |
} | |
} | |
} | |
return ''; | |
}, | |
hasFlashPlayerVersion: hasPlayerVersion, | |
removeSWF: function (objElemIdStr) { | |
if (ua.w3cdom) { | |
removeSWF(objElemIdStr); | |
} | |
} | |
}; | |
}(); | |
})(jQuery); | |
/* | |
* jquery-periodic.js | |
* | |
* Adds a "periodic" function to jQuery which takes a callback and options for the frequency (in seconds) and a | |
* boolean for allowing parallel execution of the callback function (shielded from exceptions by a try..finally block. | |
* The first parameter passed to the callback is a controller object. | |
* | |
* Return falsy value from the callback function to end the periodic execution. | |
* | |
* For a callback which initiates an asynchronous process: | |
* There is a boolean in the controller object which will prevent the callback from executing while it is "true". | |
* Be sure to reset this boolean to false when your asynchronous process is complete, or the periodic execution | |
* won't continue. | |
* | |
* To stop the periodic execution, you can also call the "stop" method | |
of the controller object, instead of returning | |
* false from the callback function. | |
* | |
*/ | |
jQuery.periodic = function (callback, options) { | |
callback = callback || (function() { return false; }); | |
options = jQuery.extend({ }, | |
{ frequency : 10, | |
allowParallelExecution : false}, | |
options); | |
var currentlyExecuting = false; | |
var timer; | |
var controller = { | |
stop : function () { | |
if (timer) { | |
window.clearInterval(timer); | |
timer = null; | |
} | |
}, | |
currentlyExecuting : false, | |
currentlyExecutingAsync : false | |
}; | |
timer = window.setInterval(function() { | |
if (options.allowParallelExecution || !(controller.currentlyExecuting || controller.currentlyExecutingAsync)){ | |
try { | |
controller.currentlyExecuting = true; | |
if (!(callback(controller))) { | |
controller.stop(); | |
} | |
} finally { | |
controller.currentlyExecuting = false; | |
} | |
} | |
}, options.frequency * 1000); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment