// File /js/layout_functions.js BEGIN function set_selected_item(selector_id, item_value) { if(item_value == '') return; var selector = document.getElementById(selector_id); for(i=0;i 0) { popW.toString().length > 0?param = "width=" + popW + ",":param =""; popH.toString().length > 0?param += "height=" + popH+ ",":param +=""; popL.toString().length > 0?param += "left=" + popL+ ",":param +=""; popT.toString().length > 0?param += "top=" + popT+ ",":param +=""; param+="titlebar=" + flgTitle.toString() + ","; param+="toolbar=" + flgTool.toString() + ","; param+="status=" + flgStatus.toString() + ","; param+="menubar=" + flgMenu.toString() + ","; param+="resizable=" + flgResize.toString() + ","; param+="scrollbars=" + flgScroll.toString() + ","; param+="location=" + flgLocation.toString() + ","; param=param.substr(0,param.length-1); return window.open(thePage,'test',param); } } function rw_openPopup(thePage,idWin,popW,popH) { w = screen.availWidth; h = screen.availHeight; var leftPos = (w-popW)/2, topPos = (h-popH)/2; return window.open(thePage,idWin,"left=" + leftPos + ",top=" + topPos + ",width="+ popW +",height=" + popH + ",toolbar=no,status=no,titlebar=no,menubar=no,resizable=yes,scrollbars=yes") } function openDialog(thePage,idWin,popW,popH) { w = screen.availWidth; h = screen.availHeight; var leftPos = (w-popW)/2, topPos = (h-popH)/2; return window.showModalDialog (thePage,idWin,"dialogLeft:" + leftPos + "px;dialogTop:" + topPos + "px;dialogWidth:"+ popW +"px;dialogHeight:" + popH + "px;status:no;scroll:no") } //obfuscate mailto links in source code until mouseover - link will be c, if c missing then a@b //note corresponding function in StdTools.asp function obfuscateMail(a,b,c) { document.write("" + (c?c:a+'@'+b) + ""); } /**************** String trim function **************************/ function trimString (str) { str = this != window? this : str; return str.replace(/^\s+/g, '').replace(/\s+$/g, ''); } String.prototype.trim = trimString; /**************** Helper functions for keycheck functions below *********************************/ function isControlKey(key) { var controlKeys ="8;9;13;27;37;38;39;40;35;36;"; return (controlKeys.indexOf(key+";") >= 0) } function GetKeyCode(e) { if(!e)e = window.event; return(e.which?e.which:e.keyCode); } /**************** Key check functions *************************************/ // Use this code like so: onKeyPress="return IsDigit(event);" // Note that this won't prevent copy/paste with the mouse! function IsDigit(e) {// whole numbers only (8=delete) var key = GetKeyCode(e); if(((key < 48) || (key > 57)) && (!isControlKey(key))) {return false}; } function IsPosNumber(e) {// positive decimal numbers (46 = '.') var key = GetKeyCode(e); if(((key < 48) || (key > 57)) && (key != 46) && (!isControlKey(key))) return false; } function IsWholeNumber(e) {// positive or negative Whole numbers (45= '-') var key = GetKeyCode(e); if(((key < 48) || (key > 57)) && (key != 45) && (!isControlKey(key))) return false; } function IsNumber(e) {// positive or negative decimal numbers (45='-', 46 = '.') var key = GetKeyCode(e); if(((key < 48) || (key > 57)) && (key != 45) && (key != 46) && (!isControlKey(key))) return false; } //http://www.remote.org/jochen/mail/info/chars.html function isValidEmail(s) { mail = "^.+@[^\\.].*\\.[a-zA-Z]{2,}$"; //probably over-tolerant, but doesn't really matter //was: mail = "^\\w+((-\\w+)|(\\.\\w+))*\\@[A-Za-z0-9]+((\\.|-)[A-Za-z0-9]+)*\\.[A-Za-z0-9]{2,4}$"; var reMail = new RegExp(mail); return(reMail.test(s)); } //Check for MULTIPLE comma or semi-colon separated emails function isValidEmails(s) { myregexp=/.+@[^\.].*\.[a-zA-Z]{2,}([,;]\s*.+@[^\.].*\.[a-zA-Z]{2,})*/; //was: myregexp=/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*([,;]\s*\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*)*/; return(s.match(myregexp)); } function isURL (s) { machine = "[A-Za-z0-9]+((\\.|(\\-)+)[A-Za-z0-9]+)*(/[A-Za-z0-9]+)?"; var reURL = new RegExp("^" + machine + "$"); return (reURL.test(s)); } function isDate(s) { if(s=="") return(true); var arr = s.split("."); d=Number(arr[0]); m=Number(arr[1])-1; y=Number(arr[2]); with (new Date(y,m,d)) { return (getMonth() == m && getDate() == d && getFullYear() == y); } } /************* Helper functions *********************/ //shortcuts function g(id) {return document.getElementById(id);} //shortcuts function gv(id) {return g(id).value.trim();} //stop event propagation function stopPropagate(e) { if (!e) var e = window.event; e.cancelBubble = true; e.returnValue=false; if (e.stopPropagation) e.stopPropagation(); if (e.preventDefault) e.preventDefault(); } //function to add/remove multiple classes function classAdd(el,cls,addOrRemove) { if(el.className) { //already has a class if(el.className.indexOf(cls)>=0) { if(!addOrRemove) // if has this class and remove el.className=el.className.replace(cls,'').trim(); } else { //doesn't have this class, but has a class if(addOrRemove) //only add if necessary! el.className+=' ' + cls; } } else { //no class yet if(addOrRemove) //if add el.className=cls; } } //form reset function doReset(frm) { coll=frm.elements; for (i=0; i= maxLen) { // Alert message if maximum limit is reached. // If required Alert can be removed. var msg = "You have reached your maximum limit of characters allowed"; alert(msg); // Reached the Maximum length so trim the textarea inputtxt.value = inputtxt.value.substring(0, maxLen); //this.blur(); return true; } } /*************** Flash object embedding (to be proved) ************************************************/ /** * FlashObject v1.3c: Flash detection and embed - http://blog.deconcept.com/flashobject/ * * FlashObject is (c) 2006 Geoff Stearns and is released under the MIT License: * http://www.opensource.org/licenses/mit-license.php * */ if(typeof com=="undefined"){var com=new Object();} if(typeof com.deconcept=="undefined"){com.deconcept=new Object();} if(typeof com.deconcept.util=="undefined"){com.deconcept.util=new Object();} if(typeof com.deconcept.FlashObjectUtil=="undefined"){com.deconcept.FlashObjectUtil=new Object();} com.deconcept.FlashObject=function(_1,id,w,h,_5,c,_7,_8,_9,_a,_b){ if(!document.createElement||!document.getElementById){return;} this.DETECT_KEY=_b?_b:"detectflash"; this.skipDetect=com.deconcept.util.getRequestParameter(this.DETECT_KEY); this.params=new Object(); this.variables=new Object(); this.attributes=new Array(); this.useExpressInstall=_7; if(_1){this.setAttribute("swf",_1);} if(id){this.setAttribute("id",id);} if(w){this.setAttribute("width",w);} if(h){this.setAttribute("height",h);} if(_5){this.setAttribute("version",new com.deconcept.PlayerVersion(_5.toString().split(".")));} this.installedVer=com.deconcept.FlashObjectUtil.getPlayerVersion(this.getAttribute("version"),_7); if(c){this.addParam("bgcolor",c);} var q=_8?_8:"high"; this.addParam("quality",q); var _d=(_9)?_9:window.location; this.setAttribute("xiRedirectUrl",_d); this.setAttribute("redirectUrl",""); if(_a){this.setAttribute("redirectUrl",_a);} }; com.deconcept.FlashObject.prototype={setAttribute:function(_e,_f){ this.attributes[_e]=_f; },getAttribute:function(_10){ return this.attributes[_10]; },addParam:function(_11,_12){ this.params[_11]=_12; },getParams:function(){ return this.params; },addVariable:function(_13,_14){ this.variables[_13]=_14; },getVariable:function(_15){ return this.variables[_15]; },getVariables:function(){ return this.variables; },createParamTag:function(n,v){ var p=document.createElement("param"); p.setAttribute("name",n); p.setAttribute("value",v); return p; },getVariablePairs:function(){ var _19=new Array(); var key; var _1b=this.getVariables(); for(key in _1b){_19.push(key+"="+_1b[key]);} return _19; },getFlashHTML:function(){ var _1c=""; if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){ if(this.getAttribute("doExpressInstall")){ this.addVariable("MMplayerType","PlugIn"); } _1c="0){_1c+="flashvars=\""+_1f+"\"";} _1c+="/>"; }else{ if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","ActiveX");} _1c=""; _1c+="\""; var _20=this.getParams(); for(var key in _20){_1c+="";} var _22=this.getVariablePairs().join("&"); if(_22.length>0){_1c+=""; }_1c+="";} return _1c; },write:function(_23){ if(this.useExpressInstall){ var _24=new com.deconcept.PlayerVersion([6,0,65]); if(this.installedVer.versionIsValid(_24)&&!this.installedVer.versionIsValid(this.getAttribute("version"))){ this.setAttribute("doExpressInstall",true); this.addVariable("MMredirectURL",escape(this.getAttribute("xiRedirectUrl"))); document.title=document.title.slice(0,47)+" - Flash Player Installation"; this.addVariable("MMdoctitle",document.title);} }else{this.setAttribute("doExpressInstall",false);} if(this.skipDetect||this.getAttribute("doExpressInstall")||this.installedVer.versionIsValid(this.getAttribute("version"))){ var n=(typeof _23=="string")?document.getElementById(_23):_23; n.innerHTML=this.getFlashHTML(); }else{if(this.getAttribute("redirectUrl")!=""){document.location.replace(this.getAttribute("redirectUrl"));}}}}; com.deconcept.FlashObjectUtil.getPlayerVersion=function(_26,_27){ var _28=new com.deconcept.PlayerVersion(0,0,0); if(navigator.plugins&&navigator.mimeTypes.length){ var x=navigator.plugins["Shockwave Flash"]; if(x&&x.description){_28=new com.deconcept.PlayerVersion(x.description.replace(/([a-z]|[A-Z]|\s)+/,"").replace(/(\s+r|\s+b[0-9]+)/,".").split("."));} }else{ try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); for(var i=3;axo!=null;i++){ axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+i); _28=new com.deconcept.PlayerVersion([i,0,0]);}} catch(e){} if(_26&&_28.major>_26.major){return _28;} if(!_26||((_26.minor!=0||_26.rev!=0)&&_28.major==_26.major)||_28.major!=6||_27){ try{ _28=new com.deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(",")); }catch(e){}}} return _28; }; com.deconcept.PlayerVersion=function(_2c){ this.major=parseInt(_2c[0])||0; this.minor=parseInt(_2c[1])||0; this.rev=parseInt(_2c[2])||0; }; com.deconcept.PlayerVersion.prototype.versionIsValid=function(fv){ if(this.majorfv.major){return true;} if(this.minorfv.minor){return true;} if(this.rev-1)?q.indexOf("&",_30):q.length; if(q.length>1&&_30>-1){ return q.substring(q.indexOf("=",_30)+1,_31);}}return ""; },removeChildren:function(n){ while(n.hasChildNodes()){ n.removeChild(n.firstChild);}}}; if(Array.prototype.push==null){ Array.prototype.push=function(_33){ this[this.length]=_33; return this.length;};} var getQueryParamValue=com.deconcept.util.getRequestParameter; var FlashObject=com.deconcept.FlashObject; /************* Right click desactivation for links or images **********************************/ // oncontextmenu=nocontextmenu() function nocontextmenu() { event.cancelBubble = true event.returnValue = false; return false; } // onmousedown=norightclick() function norightclick(e) { if (window.Event) { if (e.which == 2 || e.which == 3) return false; } else if (event.button == 2 || event.button == 3) { event.cancelBubble = true event.returnValue = false; return false; } } /************************* end Right click desactivation ***********************************/ //----------------------------------------------------------------------------------------------------- // tdc : 17.10.2007 The following JavaScript code was added to test whether this new version of the Flash // player supports the FLV new Flash format //----------------------------------------------------------------------------------------------------- /** * SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/ * * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License: * http://www.opensource.org/licenses/mit-license.php * */ if(typeof deconcept == "undefined") var deconcept = new Object(); if(typeof deconcept.util == "undefined") deconcept.util = new Object(); if(typeof deconcept.SWFObjectUtil == "undefined") deconcept.SWFObjectUtil = new Object(); deconcept.SWFObject = function(swf, id, w, h, ver, c, quality, xiRedirectUrl, redirectUrl, detectKey) { if (!document.getElementById) { return; } this.DETECT_KEY = detectKey ? detectKey : 'detectflash'; this.skipDetect = deconcept.util.getRequestParameter(this.DETECT_KEY); this.params = new Object(); this.variables = new Object(); this.attributes = new Array(); if(swf) { this.setAttribute('swf', swf); } if(id) { this.setAttribute('id', id); } if(w) { this.setAttribute('width', w); } if(h) { this.setAttribute('height', h); } if(ver) { this.setAttribute('version', new deconcept.PlayerVersion(ver.toString().split("."))); } this.installedVer = deconcept.SWFObjectUtil.getPlayerVersion(); if (!window.opera && document.all && this.installedVer.major > 7) { // only add the onunload cleanup if the Flash Player version supports External Interface and we are in IE deconcept.SWFObject.doPrepUnload = true; } if(c) { this.addParam('bgcolor', c); } var q = quality ? quality : 'high'; this.addParam('quality', q); this.setAttribute('useExpressInstall', false); this.setAttribute('doExpressInstall', false); var xir = (xiRedirectUrl) ? xiRedirectUrl : window.location; this.setAttribute('xiRedirectUrl', xir); this.setAttribute('redirectUrl', ''); if(redirectUrl) { this.setAttribute('redirectUrl', redirectUrl); } } deconcept.SWFObject.prototype = { useExpressInstall: function(path) { this.xiSWFPath = !path ? "expressinstall.swf" : path; this.setAttribute('useExpressInstall', true); }, setAttribute: function(name, value){ this.attributes[name] = value; }, getAttribute: function(name){ return this.attributes[name]; }, addParam: function(name, value){ this.params[name] = value; }, getParams: function(){ return this.params; }, addVariable: function(name, value){ this.variables[name] = value; }, getVariable: function(name){ return this.variables[name]; }, getVariables: function(){ return this.variables; }, getVariablePairs: function(){ var variablePairs = new Array(); var key; var variables = this.getVariables(); for(key in variables){ variablePairs[variablePairs.length] = key +"="+ variables[key]; } return variablePairs; }, getSWFHTML: function() { var swfNode = ""; if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) { // netscape plugin architecture if (this.getAttribute("doExpressInstall")) { this.addVariable("MMplayerType", "PlugIn"); this.setAttribute('swf', this.xiSWFPath); } swfNode = ' 0){ swfNode += 'flashvars="'+ pairs +'"'; } swfNode += '/>'; } else { // PC IE if (this.getAttribute("doExpressInstall")) { this.addVariable("MMplayerType", "ActiveX"); this.setAttribute('swf', this.xiSWFPath); } swfNode = ''; swfNode += ''; var params = this.getParams(); for(var key in params) { swfNode += ''; } var pairs = this.getVariablePairs().join("&"); if(pairs.length > 0) {swfNode += '';} swfNode += ""; } return swfNode; }, write: function(elementId){ if(this.getAttribute('useExpressInstall')) { // check to see if we need to do an express install var expressInstallReqVer = new deconcept.PlayerVersion([6,0,65]); if (this.installedVer.versionIsValid(expressInstallReqVer) && !this.installedVer.versionIsValid(this.getAttribute('version'))) { this.setAttribute('doExpressInstall', true); this.addVariable("MMredirectURL", escape(this.getAttribute('xiRedirectUrl'))); document.title = document.title.slice(0, 47) + " - Flash Player Installation"; this.addVariable("MMdoctitle", document.title); } } if(this.skipDetect || this.getAttribute('doExpressInstall') || this.installedVer.versionIsValid(this.getAttribute('version'))){ var n = (typeof elementId == 'string') ? document.getElementById(elementId) : elementId; n.innerHTML = this.getSWFHTML(); return true; }else{ if(this.getAttribute('redirectUrl') != "") { document.location.replace(this.getAttribute('redirectUrl')); } } return false; } } /* ---- detection functions ---- */ deconcept.SWFObjectUtil.getPlayerVersion = function(){ var PlayerVersion = new deconcept.PlayerVersion([0,0,0]); if(navigator.plugins && navigator.mimeTypes.length){ var x = navigator.plugins["Shockwave Flash"]; if(x && x.description) { PlayerVersion = new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split(".")); } }else if (navigator.userAgent && navigator.userAgent.indexOf("Windows CE") >= 0){ // if Windows CE var axo = 1; var counter = 3; while(axo) { try { counter++; axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+ counter); // document.write("player v: "+ counter); PlayerVersion = new deconcept.PlayerVersion([counter,0,0]); } catch (e) { axo = null; } } } else { // Win IE (non mobile) // do minor version lookup in IE, but avoid fp6 crashing issues // see http://blog.deconcept.com/2006/01/11/getvariable-setvariable-crash-internet-explorer-flash-6/ try{ var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); }catch(e){ try { var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); PlayerVersion = new deconcept.PlayerVersion([6,0,21]); axo.AllowScriptAccess = "always"; // error if player version < 6.0.47 (thanks to Michael Williams @ Adobe for this code) } catch(e) { if (PlayerVersion.major == 6) { return PlayerVersion; } } try { axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); } catch(e) {} } if (axo != null) { PlayerVersion = new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(",")); } } return PlayerVersion; } deconcept.PlayerVersion = function(arrVersion){ this.major = arrVersion[0] != null ? parseInt(arrVersion[0]) : 0; this.minor = arrVersion[1] != null ? parseInt(arrVersion[1]) : 0; this.rev = arrVersion[2] != null ? parseInt(arrVersion[2]) : 0; } deconcept.PlayerVersion.prototype.versionIsValid = function(fv){ if(this.major < fv.major) return false; if(this.major > fv.major) return true; if(this.minor < fv.minor) return false; if(this.minor > fv.minor) return true; if(this.rev < fv.rev) return false; return true; } /* ---- get value of query string param ---- */ deconcept.util = { getRequestParameter: function(param) { var q = document.location.search || document.location.hash; if (param == null) { return 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 pairs[i].substring((pairs[i].indexOf("=")+1)); } } } return ""; } } /* fix for video streaming bug */ deconcept.SWFObjectUtil.cleanupSWFs = function() { var objects = document.getElementsByTagName("OBJECT"); for (var i = objects.length - 1; i >= 0; i--) { objects[i].style.display = 'none'; for (var x in objects[i]) { if (typeof objects[i][x] == 'function') { objects[i][x] = function(){}; } } } } // fixes bug in some fp9 versions see http://blog.deconcept.com/2006/07/28/swfobject-143-released/ if (deconcept.SWFObject.doPrepUnload) { if (!deconcept.unloadSet) { deconcept.SWFObjectUtil.prepUnload = function() { __flash_unloadHandler = function(){}; __flash_savedUnloadHandler = function(){}; window.attachEvent("onunload", deconcept.SWFObjectUtil.cleanupSWFs); } window.attachEvent("onbeforeunload", deconcept.SWFObjectUtil.prepUnload); deconcept.unloadSet = true; } } /* add document.getElementById if needed (mobile IE < 5) */ if (!document.getElementById && document.all) { document.getElementById = function(id) { return document.all[id]; }} /* add some aliases for ease of use/backwards compatibility */ var getQueryParamValue = deconcept.util.getRequestParameter; var FlashObject = deconcept.SWFObject; // for legacy support var SWFObject = deconcept.SWFObject; // File /js/LibUtils.js END // File /js/ajax-son.js BEGIN function ajax_son(file) { this.xmlHttp = null; this.actionFile = file; this.asynchronous = true; this.method = 'post'; this.contentType = 'application/x-www-form-urlencoded'; this.encoding = 'UTF-8'; this.executeJS = false; this.executeJSON = false; // internal this.url = ''; this.params = ''; this.addsHeader = ''; this.vars = new Array(); this.responseStatus = new Array(2); this.onLoading = function() { }; this.onLoaded = function() { }; this.onInteractive = function() { }; this.onComplete = function() { }; this.onError = function() { }; this.onFail = function() { }; this.xmlHttpVersions = ["MSXML2.XMLHTTP.6.0", "MSXML2.XMLHTTP.5.0", "MSXML2.xmlHttp.4.0", "MSXML2.xmlHttp.3.0", "MSXML2.xmlHttp", "Microsoft.xmlHttp"]; /** * Create XMLHttpRequest **/ this.create = function() { try { this.xmlHttp = new XMLHttpRequest(); } catch(e) { for(var i = 0; i < this.xmlHttpVersions.length && !this.xmlHttp; i++) { try { this.xmlHttp = new ActiveXObject(this.xmlHttpVersions[i]); } catch (e) { } } } if(!this.xmlHttp) { this.failed = true; } }; this.run = function(params) { if(this.failed) { this.onFail(); } else { this.params = this.encodeURL(params); var self = this; var headers = { 'X-Requested-With': 'xmlHttpRequest', 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' }; // add user headers if(typeof this.addsHeader == 'object') { for(var i = 0; i < this.addsHeader.length; i++) { tmp = this.addsHeader[i].split(':'); headers[tmp[0]] = tmp[1]; } } if(this.method == 'post') { headers['Content-Type'] = this.contentType + (this.encoding ? '; charset=' + this.encoding : ''); headers['Content-Length'] = this.params.length; this.url = this.actionFile; } else { this.url = this.actionFile + '?' + this.params; } this.xmlHttp.open(this.method.toUpperCase(), this.url, this.asynchronous); for(var name in headers) { try { this.xmlHttp.setRequestHeader(name, headers[name]); } catch (e) { } } this.xmlHttp.onreadystatechange = function() { switch (self.xmlHttp.readyState) { case 1: self.onLoading(); break; case 2: self.onLoaded(); break; case 3: self.onInteractive(); break; case 4: self.response = self.xmlHttp.responseText; self.responseXML = self.xmlHttp.responseXML; self.responseStatus[0] = self.xmlHttp.status; self.responseStatus[1] = self.xmlHttp.statusText; if (self.executeJS && self.getHeader('Content-Type') == 'text/javascript') { self.evalJS(); } if (self.responseStatus[0] == "200") { self.onComplete(); } else { self.onError(); } break; } }; if(this.method == 'post') { this.xmlHttp.send(this.params); } else { this.xmlHttp.send(null); } if (!this.asynchronous) { if(this.xmlHttp.status == 200) { this.response = this.xmlHttp.responseText; this.onComplete(); } } } }; /** * Get header by "name" **/ this.getHeader = function(name) { try { return this.xmlHttp.getResponseHeader(name); } catch(e) { return false; } }; /** * Execute Javascript **/ this.evalJS = function() { try { eval(this.response); } catch(e) { } }; /* this.evalJSON = function() { // }; */ this.encodeURL = function(params) { var _array = params.split('&'); for (i = 0; i < _array.length; i++) { var urlVars = _array[i].split("="); this.vars[urlVars[0]] = encodeURIComponent(urlVars[1]); } var tmp = new Array(); var tmpURL = ""; for(key in this.vars) { if (typeof(this.vars[key]) != 'function') { tmp[tmp.length] = key + "=" + this.vars[key]; } } return tmp.join("&"); }; this.create(); } // File /js/ajax-son.js END // File /js/shadowbox-lib.js BEGIN /** * A base library for Shadowbox used as a standalone (without another base * library/adapter combination). * * This file is part of Shadowbox. * * Shadowbox is an online media viewer application that supports all of the * web's most popular media publishing formats. Shadowbox is written entirely * in JavaScript and CSS and is highly customizable. Using Shadowbox, website * authors can showcase a wide assortment of media in all major browsers without * navigating users away from the linking page. * * Shadowbox is released under version 3.0 of the Creative Commons Attribution- * Noncommercial-Share Alike license. This means that it is absolutely free * for personal, noncommercial use provided that you 1) make attribution to the * author and 2) release any derivative work under the same or a similar * license. * * If you wish to use Shadowbox for commercial purposes, licensing information * can be found at http://mjijackson.com/shadowbox/. * * @author Michael J. I. Jackson * @copyright 2007-2008 Michael J. I. Jackson * @license http://creativecommons.org/licenses/by-nc-sa/3.0/ * @version SVN: $Id: shadowbox-base.js 103 2008-06-27 06:19:21Z mjijackson $ */ // create the Shadowbox object first var Shadowbox = {}; Shadowbox.lib = function(){ // local style camelizing for speed var styleCache = {}; var camelRe = /(-[a-z])/gi; var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); }; var toCamel = function(style){ var camel; if(!(camel = styleCache[style])){ camel = styleCache[style] = style.replace(camelRe, camelFn); } return camel; }; var view = document.defaultView; var alphaRe = /alpha\([^\)]*\)/gi; /** * Sets the opacity of the given element to the specified level. * * @param {HTMLElement} el The element * @param {Number} opacity The opacity to use * @return void * @private * @static */ var setOpacity = function(el, opacity){ var s = el.style; if(window.ActiveXObject){ // IE s.zoom = 1; // give "layout" s.filter = (s.filter || '').replace(alphaRe, '') + (opacity == 1 ? '' : ' alpha(opacity=' + (opacity * 100) + ')'); }else{ s.opacity = opacity; } }; return { adapter: 'standalone', /** * Gets the value of the style on the given element. This function * adapted from Ext.Element.getStyle(). * * @param {HTMLElement} el The DOM element * @param {String} style The name of the style (e.g. margin-top) * @return {mixed} The value of the given style * @public * @static */ getStyle: function(){ return view && view.getComputedStyle ? function(el, style){ var v, cs, camel; if(style == 'float') style = 'cssFloat'; if(v = el.style[style]) return v; if(cs = view.getComputedStyle(el, '')){ return cs[toCamel(style)]; } return null; } : function(el, style){ var v, cs, camel; if(style == 'opacity'){ if(typeof el.style.filter == 'string'){ var m = el.style.filter.match(/alpha\(opacity=(.+)\)/i); if(m){ var fv = parseFloat(m[1]); if(!isNaN(fv)) return (fv ? fv / 100 : 0); } } return 1; }else if(style == 'float'){ style = 'styleFloat'; } var camel = toCamel(style); if(v = el.style[camel]) return v; if(cs = el.currentStyle) return cs[camel]; return null; }; }(), /** * Sets the style on the given element to the given value. May be an * object to specify multiple values. This function adapted from * Ext.Element.setStyle(). * * @param {HTMLElement} el The DOM element * @param {String/Object} style The name of the style to set if a * string, or an object of name => * value pairs * @param {String} value The value to set the given style to * @return void * @public * @static */ setStyle: function(el, style, value){ if(typeof style == 'string'){ var camel = toCamel(style); if(camel == 'opacity'){ setOpacity(el, value); }else{ el.style[camel] = value; } }else{ for(var s in style){ this.setStyle(el, s, style[s]); } } }, /** * Gets a reference to the given element. * * @param {String/HTMLElement} el The element to fetch * @return {HTMLElement} A reference to the element * @public * @static */ get: function(el){ return typeof el == 'string' ? document.getElementById(el) : el; }, /** * Removes an element from the DOM. * * @param {HTMLElement} el The element to remove * @return void * @public * @static */ remove: function(el){ el.parentNode.removeChild(el); }, /** * Gets the target of the given event. The event object passed will be * the same object that is passed to listeners registered with * addEvent(). * * @param {mixed} e The event object * @return {HTMLElement} The event's target element * @public * @static */ getTarget: function(e){ var t = e.target ? e.target : e.srcElement; return t.nodeType == 3 ? t.parentNode : t; }, /** * Gets the page X/Y coordinates of the mouse event in an [x, y] array. * The page coordinates should be relative to the document, and not the * viewport. The event object provided here will be the same object that * is passed to listeners registered with addEvent(). * * @param {mixed} e The event object * @return {Array} The page X/Y coordinates * @public * @static */ getPageXY: function(e){ var x = e.pageX || (e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft)); var y = e.pageY || (e.clientY + (document.documentElement.scrollTop || document.body.scrollTop)); return [x, y]; }, /** * Prevents the event's default behavior. The event object here will * be the same object that is passed to listeners registered with * addEvent(). * * @param {mixed} e The event object * @return void * @public * @static */ preventDefault: function(e){ if(e.preventDefault){ e.preventDefault(); }else{ e.returnValue = false; } }, /** * Gets the key code of the given event object (keydown). The event * object here will be the same object that is passed to listeners * registered with addEvent(). * * @param {mixed} e The event object * @return {Number} The key code of the event * @public * @static */ keyCode: function(e){ return e.which ? e.which : e.keyCode; }, /** * Adds an event listener to the given element. It is expected that this * function will be passed the event as its first argument. * * @param {HTMLElement} el The DOM element to listen to * @param {String} name The name of the event to register * (i.e. 'click', 'scroll', etc.) * @param {Function} handler The event handler function * @return void * @public * @static */ addEvent: function(el, name, handler){ if(el.addEventListener){ el.addEventListener(name, handler, false); }else if(el.attachEvent){ el.attachEvent('on' + name, handler); } }, /** * Removes an event listener from the given element. * * @param {HTMLElement} el The DOM element to stop listening to * @param {String} name The name of the event to stop * listening for (i.e. 'click') * @param {Function} handler The event handler function * @return void * @public * @static */ removeEvent: function(el, name, handler){ if(el.removeEventListener){ el.removeEventListener(name, handler, false); }else if(el.detachEvent){ el.detachEvent('on' + name, handler); } }, /** * Appends an HTML fragment to the given element. * * @param {HTMLElement} el The element to append to * @param {String} html The HTML fragment to use * @return void * @public * @static */ append: function(el, html){ if(el.insertAdjacentHTML){ el.insertAdjacentHTML('BeforeEnd', html); }else if(el.lastChild){ var range = el.ownerDocument.createRange(); range.setStartAfter(el.lastChild); var frag = range.createContextualFragment(html); el.appendChild(frag); }else{ el.innerHTML = html; } } }; }(); // File /js/shadowbox-lib.js END // File /js/shadowbox.js BEGIN /** * The Shadowbox class. * * This file is part of Shadowbox. * * Shadowbox is an online media viewer application that supports all of the * web's most popular media publishing formats. Shadowbox is written entirely * in JavaScript and CSS and is highly customizable. Using Shadowbox, website * authors can showcase a wide assortment of media in all major browsers without * navigating users away from the linking page. * * Shadowbox is released under version 3.0 of the Creative Commons Attribution- * Noncommercial-Share Alike license. This means that it is absolutely free * for personal, noncommercial use provided that you 1) make attribution to the * author and 2) release any derivative work under the same or a similar * license. * * If you wish to use Shadowbox for commercial purposes, licensing information * can be found at http://mjijackson.com/shadowbox/. * * @author Michael J. I. Jackson * @copyright 2007-2008 Michael J. I. Jackson * @license http://creativecommons.org/licenses/by-nc-sa/3.0/ * @version SVN: $Id: shadowbox.js 108 2008-07-11 04:19:01Z mjijackson $ */ if(typeof Shadowbox == 'undefined'){ throw 'Unable to load Shadowbox, no base library adapter found'; } /** * The Shadowbox class. Used to display different media on a web page using a * Lightbox-like effect. * * Useful resources: * * - http://www.alistapart.com/articles/byebyeembed * - http://www.w3.org/TR/html401/struct/objects.html * - http://www.dyn-web.com/dhtml/iframes/ * - http://www.apple.com/quicktime/player/specs.html * - http://www.apple.com/quicktime/tutorials/embed2.html * - http://www.howtocreate.co.uk/wrongWithIE/?chapter=navigator.plugins * - http://msdn.microsoft.com/en-us/library/ms532969.aspx * - http://support.microsoft.com/kb/316992 * * @class Shadowbox * @author Michael J. I. Jackson * @singleton */ (function(){ /** * The current version of Shadowbox. * * @var String * @private */ var version = '2.0'; /** * Contains the default options for Shadowbox. * * @var Object * @private */ var options = { /** * Enable all animations besides fades. * * @var Boolean */ animate: true, /** * Enable fade animations. * * @var Boolean */ animateFade: true, /** * Specifies the sequence of the height and width animations. May be * 'wh' (width then height), 'hw' (height then width), or 'sync' (both * at the same time). Of course this will only work if animate is true. * * @var String */ animSequence: 'wh', /** * The path to flvplayer.swf. * * @var String */ flvPlayer: 'js/player/flvplayer.swf', /** * Listen to the overlay for clicks. If the user clicks the overlay, * it will trigger Shadowbox.close(). * * @var Boolean */ modal: false, /** * The color to use for the modal overlay (in hex). * * @var String */ overlayColor: '#000', /** * The opacity to use for the modal overlay. * * @var Number */ overlayOpacity: 0.8, /** * The default background color to use for Flash movies (in hex). * * @var String */ flashBgColor: '#000000', /** * Automatically play movies. * * @var Boolean */ autoplayMovies: true, /** * Enable movie controllers on movie players. * * @var Boolean */ showMovieControls: true, /** * A delay (in seconds) to use for slideshows. If set to anything other * than 0, this value determines an interval at which Shadowbox will * automatically proceed to the next piece in the gallery. * * @var Number */ slideshowDelay: 0, /** * The duration of the resizing animations (in seconds). * * @var Number */ resizeDuration: 0.55, /** * The duration of the fading animations (in seconds). * * @var Number */ fadeDuration: 0.35, /** * Show the navigation controls. * * @var Boolean */ displayNav: true, /** * Enable continuous galleries. When this is true, users will be able * to skip to the first gallery image from the last using next and vice * versa. * * @var Boolean */ continuous: false, /** * Display the gallery counter. * * @var Boolean */ displayCounter: true, /** * This option may be either 'default' or 'skip'. The default counter is * a simple '1 of 5' message. The skip counter displays a link for each * piece in the gallery that enables a user to skip directly to any * piece. * * @var String */ counterType: 'default', /** * Limits the number of counter links that will be displayed in a "skip" * style counter. If the actual number of gallery elements is greater * than this value, the counter will be restrained to the elements * immediately preceeding and following the current element. * * @var Number */ counterLimit: 10, /** * The amount of padding to maintain around the viewport edge (in * pixels). This only applies when the image is very large and takes up * the entire viewport. * * @var Number */ viewportPadding: 20, /** * How to handle content that is too large to display in its entirety * (and is resizable). A value of 'resize' will resize the content while * preserving aspect ratio and display it at the smaller resolution. If * the content is an image, a value of 'drag' will display the image at * its original resolution but it will be draggable within Shadowbox. A * value of 'none' will display the content at its original resolution * but it may be cropped. * * @var String */ handleOversize: 'resize', /** * An exception handling function that will be called whenever * Shadowbox should throw an exception. Will be passed the error * message as its first argument. * * @var Function */ handleException: null, /** * The mode to use when handling unsupported media. May be either * 'remove' or 'link'. If it is 'remove', the unsupported gallery item * will merely be removed from the gallery. If it is the only item in * the gallery, the link will simply be followed. If it is 'link', a * link will be provided to the appropriate plugin page in place of the * gallery element. * * @var String */ handleUnsupported: 'link', /** * The initial height of Shadowbox (in pixels). * * @var Number */ initialHeight: 160, /** * The initial width of Shadowbox (in pixels). * * @var Number */ initialWidth: 320, /** * Enable keyboard control. * * @var Boolean */ enableKeys: true, /** * A hook function to be fired when Shadowbox opens. The single argument * will be the current gallery element. * * @var Function */ onOpen: null, /** * A hook function to be fired when Shadowbox finishes loading its * content. The single argument will be the current gallery element on * display. * * @var Function */ onFinish: null, /** * A hook function to be fired when Shadowbox changes from one gallery * element to the next. The single argument will be the current gallery * element that is about to be displayed. * * @var Function */ onChange: null, /** * A hook function that will be fired when Shadowbox closes. The single * argument will be the gallery element most recently displayed. * * @var Function */ onClose: null, /** * Skips calling Shadowbox.setup() in init(). This means that it must * be called later manually. * * @var Boolean */ skipSetup: false, /** * An object containing names of plugins and links to their respective * download pages. * * @var Object */ errors: { fla: { name: 'Flash', url: 'http://www.adobe.com/products/flashplayer/' }, qt: { name: 'QuickTime', url: 'http://www.apple.com/quicktime/download/' }, wmp: { name: 'Windows Media Player', url: 'http://www.microsoft.com/windows/windowsmedia/' }, f4m: { name: 'Flip4Mac', url: 'http://www.flip4mac.com/wmv_download.htm' } }, /** * A map of players to the file extensions they support. Each member of * this object is the name of a player (with one exception), whose value * is an array of file extensions that player will "play". The one * exception to this rule is the "qtwmp" member, which contains extensions * that may be played using either QuickTime or Windows Media Player. * * - img: Image file extensions * - swf: Flash SWF file extensions * - flv: Flash video file extensions (will be played by JW FLV player) * - qt: Movie file extensions supported by QuickTime * - wmp: Movie file extensions supported by Windows Media Player * - qtwmp: Movie file extensions supported by both QuickTime and Windows Media Player * - iframe: File extensions that will be display in an iframe * * IMPORTANT: If this object is to be modified, it must be copied in its * entirety and tweaked because it is not merged recursively with the * default. Also, any modifications must be passed into Shadowbox.init * for speed reasons. * * @var Object ext */ ext: { img: ['png', 'jpg', 'jpeg', 'gif', 'bmp'], swf: ['swf'], flv: ['flv'], qt: ['dv', 'mov', 'moov', 'movie', 'mp4'], wmp: ['asf', 'wm', 'wmv'], qtwmp: ['avi', 'mpg', 'mpeg'], iframe: ['asp', 'aspx', 'cgi', 'cfm', 'htm', 'html', 'pl', 'php', 'php3', 'php4', 'php5', 'phtml', 'rb', 'rhtml', 'shtml', 'txt', 'vbs'] } }; // shorthand var SB = Shadowbox; var SL = SB.lib; /** * Stores the default set of options in case a custom set of options is used * on a link-by-link basis so we can restore them later. * * @var Object * @private */ var default_options; /** * An object containing some regular expressions we'll need later. Compiled * up front for speed. * * @var Object * @private */ var RE = { domain: /:\/\/(.*?)[:\/]/, // domain prefix inline: /#(.+)$/, // inline element id rel: /^(light|shadow)box/i, // rel attribute format gallery: /^(light|shadow)box\[(.*?)\]/i, // rel attribute format for gallery link unsupported: /^unsupported-(\w+)/, // unsupported media type param: /\s*([a-z_]*?)\s*=\s*(.+)\s*/, // rel string parameter empty: /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i // elements that don't have children }; /** * A cache of options for links that have been set up for use with * Shadowbox. * * @var Array * @private */ var cache = []; /** * An array containing the gallery objects currently being viewed. In the * case of non-gallery items, this will only hold one object. * * @var Array * @private */ var gallery; /** * The array index of the current gallery that is currently being viewed. * * @var Number * @private */ var current; /** * The current content object. * * @var Object * @private */ var content; /** * The id to use for content objects. * * @var String * @private */ var content_id = 'shadowbox_content'; /** * Holds the current dimensions of Shadowbox as calculated by * setDimensions(). Contains the following properties: * * - height: The total height of #shadowbox * - width: The total width of #shadowbox * - inner_h: The height of #shadowbox_body * - inner_w: The width of #shadowbox_body * - top: The top to use for #shadowbox * - resize_h: The height to use for resizable content * - resize_w: The width to use for resizable content * - drag: True if dragging should be enabled (oversized image) * * @var Object * @private */ var dims; /** * Keeps track of whether or not Shadowbox has been initialized. We never * want to initialize twice. * * @var Boolean * @private */ var initialized = false; /** * Keeps track of whether or not Shadowbox is activated. * * @var Boolean * @private */ var activated = false; /** * The timeout id for the slideshow transition function. * * @var Number * @private */ var slide_timer; /** * Keeps track of the time at which the current slideshow frame was * displayed. * * @var Number * @private */ var slide_start; /** * The delay on which the next slide will display. * * @var Number * @private */ var slide_delay = 0; /** * These parameters for simple browser detection. Adapted from Ext.js. * * @var Object * @private */ var ua = navigator.userAgent.toLowerCase(); var client = { isStrict: document.compatMode == 'CSS1Compat', isOpera: ua.indexOf('opera') > -1, isIE: ua.indexOf('msie') > -1, isIE7: ua.indexOf('msie 7') > -1, isSafari: /webkit|khtml/.test(ua), isWindows: ua.indexOf('windows') != -1 || ua.indexOf('win32') != -1, isMac: ua.indexOf('macintosh') != -1 || ua.indexOf('mac os x') != -1, isLinux: ua.indexOf('linux') != -1 }; client.isBorderBox = client.isIE && !client.isStrict; client.isSafari3 = client.isSafari && !!(document.evaluate); client.isGecko = ua.indexOf('gecko') != -1 && !client.isSafari; /** * You're not sill using IE6 are you? * * @var Boolean * @private */ // var ltIE7 = client.isIE && !client.isIE7; var ltIE7 = client.isIE; /** * Contains plugin support information. Each property of this object is a * boolean indicating whether that plugin is supported. * * - fla: Flash player * - qt: QuickTime player * - wmp: Windows Media player * - f4m: Flip4Mac plugin * * @var Object * @private */ var plugins; // detect plugin support if(navigator.plugins && navigator.plugins.length){ var detectPlugin = function(plugin_name){ var detected = false; for (var i = 0, len = navigator.plugins.length; i < len; ++i){ if(navigator.plugins[i].name.indexOf(plugin_name) > -1){ detected = true; break; } } return detected; }; var f4m = detectPlugin('Flip4Mac'); plugins = { fla: detectPlugin('Shockwave Flash'), qt: detectPlugin('QuickTime'), wmp: !f4m && detectPlugin('Windows Media'), // if it's Flip4Mac, it's not really WMP f4m: f4m }; }else{ var detectPlugin = function(plugin_name){ var detected = false; try{ var axo = new ActiveXObject(plugin_name); if(axo) detected = true; }catch(e){} return detected; }; plugins = { fla: detectPlugin('ShockwaveFlash.ShockwaveFlash'), qt: detectPlugin('QuickTime.QuickTime'), wmp: detectPlugin('wmplayer.ocx'), f4m: false }; } /** * Applies all properties of e to o. * * @param Object o The original object * @param Object e The extension object * @return Object The original object with all properties * of the extension object applied * @private */ var apply = function(o, e){ for(var p in e) o[p] = e[p]; return o; }; /** * Determines if the given object is an anchor/area element. * * @param mixed el The object to check * @return Boolean True if the object is a link element * @private */ var isLink = function(el){ return el && typeof el.tagName == 'string' && (el.tagName.toUpperCase() == 'A' || el.tagName.toUpperCase() == 'AREA'); }; /** * Gets the height of the viewport in pixels. Note: This function includes * scrollbars in Safari 3. * * @return Number The height of the viewport * @public * @static */ SL.getViewportHeight = function(){ var h = window.innerHeight; // Safari var mode = document.compatMode; if((mode || client.isIE) && !client.isOpera){ h = client.isStrict ? document.documentElement.clientHeight : document.body.clientHeight; } return h; }; /** * Gets the width of the viewport in pixels. Note: This function includes * scrollbars in Safari 3. * * @return Number The width of the viewport * @public * @static */ SL.getViewportWidth = function(){ var w = window.innerWidth; // Safari var mode = document.compatMode; if(mode || client.isIE){ w = client.isStrict ? document.documentElement.clientWidth : document.body.clientWidth; } return w; }; /** * Creates an HTML string from an object representing HTML elements. Based * on Ext.DomHelper's createHtml. * * @param Object obj The HTML definition object * @return String An HTML string * @public * @static */ SL.createHTML = function(obj){ var html = '<' + obj.tag; for(var attr in obj){ if(attr == 'tag' || attr == 'html' || attr == 'children') continue; if(attr == 'cls'){ html += ' class="' + obj['cls'] + '"'; }else{ html += ' ' + attr + '="' + obj[attr] + '"'; } } if(RE.empty.test(obj.tag)){ html += '/>'; }else{ html += '>'; var cn = obj.children; if(cn){ for(var i = 0, len = cn.length; i < len; ++i){ html += this.createHTML(cn[i]); } } if(obj.html) html += obj.html; html += ''; } return html; }; /** * Easing function used for animations. Based on a cubic polynomial. * * @param Number x The state of the animation (% complete) * @return Number The adjusted easing value * @private * @static */ var ease = function(x){ return 1 + Math.pow(x - 1, 3); }; /** * Animates any numeric (not color) style of the given element from its * current state to the given value. Defaults to using pixel-based * measurements. * * @param HTMLElement el The DOM element to animate * @param String p The property to animate (in camelCase) * @param mixed to The value to animate to * @param Number d The duration of the animation (in * seconds) * @param Function cb A callback function to call when the * animation completes * @return void * @private * @static */ var animate = function(el, p, to, d, cb){ var from = parseFloat(SL.getStyle(el, p)); if(isNaN(from)) from = 0; if(from == to){ if(typeof cb == 'function') cb(); return; // nothing to animate } var delta = to - from; var op = p == 'opacity'; var unit = op ? '' : 'px'; // default unit is px var fn = function(ease){ SL.setStyle(el, p, from + ease * delta + unit); }; // cancel the animation here if set in the options if(!options.animate && !op || op && !options.animateFade){ fn(1); if(typeof cb == 'function') cb(); return; } d *= 1000; // convert to milliseconds var begin = new Date().getTime(); var end = begin + d; var timer = setInterval(function(){ var time = new Date().getTime(); if(time >= end){ // end of animation clearInterval(timer); fn(1); if(typeof cb == 'function') cb(); }else{ fn(ease((time - begin) / d)); } }, 10); // 10 ms interval is minimum on WebKit }; /** * A utility function used by the fade functions to clear the opacity * style setting of the given element. Required in some cases for IE. * * @param HTMLElement el The DOM element * @return void * @private */ var clearOpacity = function(el){ var s = el.style; if(client.isIE){ if(typeof s.filter == 'string' && (/alpha/i).test(s.filter)){ // careful not to overwrite other filters! s.filter = s.filter.replace(/[\w\.]*alpha\(.*?\);?/i, ''); } }else{ s.opacity = ''; s['-moz-opacity'] = ''; s['-khtml-opacity'] = ''; } }; /** * Gets the computed height of the given element, including padding and * borders. * * @param HTMLElement el The element * @return Number The computed height of the element * @private */ var getComputedHeight = function(el){ var h = Math.max(el.offsetHeight, el.clientHeight); if(!h){ h = parseInt(SL.getStyle(el, 'height'), 10) || 0; if(!client.isBorderBox){ h += parseInt(SL.getStyle(el, 'padding-top'), 10) + parseInt(SL.getStyle(el, 'padding-bottom'), 10) + parseInt(SL.getStyle(el, 'border-top-width'), 10) + parseInt(SL.getStyle(el, 'border-bottom-width'), 10); } } return h; }; /** * Determines the player needed to display the file at the given URL. If * the file type is not supported, the return value will be 'unsupported'. * If the file type is not supported but the correct player can be * determined, the return value will be 'unsupported-*' where * will be the * player abbreviation (e.g. 'qt' = QuickTime). * * @param String url The url of the file * @return String The name of the player to use * @private */ var getPlayer = function(url){ var m = url.match(RE.domain); var d = m && document.domain == m[1]; // same domain if(url.indexOf('#') > -1 && d) return 'inline'; var q = url.indexOf('?'); if(q > -1) url = url.substring(0, q); // strip query string for player detection purposes if(RE.img.test(url)) return 'img'; if(RE.swf.test(url)) return plugins.fla ? 'swf' : 'unsupported-swf'; if(RE.flv.test(url)) return plugins.fla ? 'flv' : 'unsupported-flv'; if(RE.qt.test(url)) return plugins.qt ? 'qt' : 'unsupported-qt'; if(RE.wmp.test(url)){ if(plugins.wmp) return 'wmp'; if(plugins.f4m) return 'qt'; if(client.isMac) return plugins.qt ? 'unsupported-f4m' : 'unsupported-qtf4m'; return 'unsupported-wmp'; }else if(RE.qtwmp.test(url)){ if(plugins.qt) return 'qt'; if(plugins.wmp) return 'wmp'; return client.isMac ? 'unsupported-qt' : 'unsupported-qtwmp'; }else if(!d || RE.iframe.test(url)){ return 'iframe'; } return 'unsupported'; // same domain, not supported }; /** * Handles all clicks on links that have been set up to work with Shadowbox * and cancels the default event behavior when appropriate. * * @param {Event} ev The click event object * @return void * @private */ var handleClick = function(ev){ // get anchor/area element var link; if(isLink(this)){ link = this; // jQuery, Prototype, YUI }else{ link = SL.getTarget(ev); // Ext, standalone while(!isLink(link) && link.parentNode){ link = link.parentNode; } } //SL.preventDefault(ev); // good for debugging if(link){ SB.open(link); if(gallery.length) SL.preventDefault(ev); // stop event } }; /** * Toggles the display of the nav control with the given id on and off. * * @param String id The id of the navigation control * @param Boolean on True to toggle on, false to toggle off * @return void * @private */ var toggleNav = function(id, on){ var el = SL.get('shadowbox_nav_' + id); if(el) el.style.display = on ? '' : 'none'; }; /** * Builds the content for the title and information bars. * * @param Function cb A callback function to execute after the * bars are built * @return void * @private */ var buildBars = function(cb){ var obj = gallery[current]; var title_i = SL.get('shadowbox_title_inner'); // build the title title_i.innerHTML = obj.title || ''; // build the nav var nav = SL.get('shadowbox_nav'); if(nav){ var c, n, pl, pa, p; // need to build the nav? if(options.displayNav){ c = true; // next & previous links var len = gallery.length; if(len > 1){ if(options.continuous){ n = p = true; // show both }else{ n = (len - 1) > current; // not last in gallery, show next p = current > 0; // not first in gallery, show previous } } // in a slideshow? if(options.slideshowDelay > 0 && hasNext()){ pa = slide_timer != 'paused'; pl = !pa; } }else{ c = n = pl = pa = p = false; } toggleNav('close', c); toggleNav('next', n); toggleNav('play', pl); toggleNav('pause', pa); toggleNav('previous', p); } // build the counter var counter = SL.get('shadowbox_counter'); if(counter){ var co = ''; // need to build the counter? if(options.displayCounter && gallery.length > 1){ if(options.counterType == 'skip'){ // limit the counter? var i = 0, len = gallery.length, end = len; var limit = parseInt(options.counterLimit); if(limit < len){ // support large galleries var h = Math.round(limit / 2); i = current - h; if(i < 0) i += len; end = current + (limit - h); if(end > len) end -= len; } while(i != end){ if(i == len) i = 0; co += ''; } }else{ // default co = (current + 1) + ' ' + SB.LANG.of + ' ' + len; } } counter.innerHTML = co; } cb(); }; /** * Hides the title and info bars. * * @param Boolean anim True to animate the transition * @param Function cb A callback function to execute after the * animation completes * @return void * @private */ var hideBars = function(anim, cb){ var obj = gallery[current]; var title = SL.get('shadowbox_title'); var info = SL.get('shadowbox_info'); var title_i = SL.get('shadowbox_title_inner'); var info_i = SL.get('shadowbox_info_inner'); var close_top = SL.get('shadowbox_close_top'); // build bars after they are hidden var fn = function(){ buildBars(cb); }; var title_h = getComputedHeight(title); var info_h = getComputedHeight(info) * -1; if(anim){ // animate the transition animate(title_i, 'margin-top', title_h, 0.35); animate(info_i, 'margin-top', info_h, 0.35, fn); animate(close_top, 'margin-top', title_h, 0.35); }else{ SL.setStyle(title_i, 'margin-top', title_h + 'px'); SL.setStyle(info_i, 'margin-top', info_h + 'px'); SL.setStyle(close_top, 'margin-top', title_h + 'px'); fn(); } }; /** * Shows the title and info bars. * * @param Function cb A callback function to execute after the * animation completes * @return void * @private */ var showBars = function(cb){ var title_i = SL.get('shadowbox_title_inner'); var info_i = SL.get('shadowbox_info_inner'); var close_top = SL.get('shadowbox_close_top'); var title = SL.get('shadowbox_title'); var t = title_i.innerHTML != ''; // is there a title to display? //if(t) { if(!isColl) { animate(title_i, 'margin-top', 0, 0.35); animate(close_top, 'margin-top', 0, 0.35); } else { if(ltIE7){ animate(title, 'height', '-30', 0.35); } else { animate(title, 'height', 0, 0.35); } } animate(info_i, 'margin-top', 0, 0.35, cb); }; /** * Loads the Shadowbox with the current piece. * * @return void * @private */ var loadContent = function(){ var obj = gallery[current]; if(!obj) return; // invalid var changing = false; if(content){ content.remove(); // remove old content first changing = true; // changing from some previous content } // determine player, inline is really just HTML var p = obj.player == 'inline' ? 'html' : obj.player; // make sure player is loaded if(typeof SB[p] != 'function'){ SB.raise('Unknown player ' + obj.player); } content = new SB[p](content_id, obj); // instantiate new content object listenKeys(false); // disable the keyboard temporarily toggleLoading(true); hideBars(changing, function(){ // if changing, animate the bars transition if(!content) return; // if opening, clear #shadowbox display if(!changing){ SL.get('shadowbox').style.display = ''; } var fn = function(){ resizeContent(function(){ if(!content) return; showBars(function(){ if(!content) return; // append content just before hiding the loading layer SL.get('shadowbox_body_inner').innerHTML = SL.createHTML(content.markup(dims)); toggleLoading(false, function(){ if(!content) return; if(typeof content.onLoad == 'function'){ content.onLoad(); // call onLoad callback if present } if(options.onFinish && typeof options.onFinish == 'function'){ options.onFinish(gallery[current]); // fire onFinish handler } if(slide_timer != 'paused'){ SB.play(); // kick off next slide } listenKeys(true); // re-enable the keyboard }); }); }); }; if(typeof content.ready != 'undefined'){ // does the object have a ready property? var id = setInterval(function(){ // if so, wait for the object to be ready if(content){ if(content.ready){ clearInterval(id); // clean up id = null; fn(); } }else{ // content has been removed clearInterval(id); id = null; } }, 100); }else{ fn(); } }); // preload neighboring gallery images if(gallery.length > 1){ var next = gallery[current + 1] || gallery[0]; if(next.player == 'img'){ var a = new Image(); a.src = next.content; } var prev = gallery[current - 1] || gallery[gallery.length - 1]; if(prev.player == 'img'){ var b = new Image(); b.src = prev.content; } } }; /** * Calculates the dimensions for Shadowbox, taking into account the borders * and surrounding elements of the shadowbox_body. If the height/width * combination is too large for Shadowbox and handleOversize option is set * to 'resize', the resized dimensions will be returned (preserving the * original aspect ratio). Otherwise, the originally calculated dimensions * will be used. Stores all dimensions in the private dims variable. * * @param Number height The content player height * @param Number width The content player width * @param Boolean resizable True if the content is able to be * resized. Defaults to false. * @return void * @private */ var setDimensions = function(height, width, resizable){ resizable = resizable || false; var sb = SL.get('shadowbox_body'); var h = height = parseInt(height); var w = width = parseInt(width); var view_h = SL.getViewportHeight(); var view_w = SL.getViewportWidth(); //For IE scroll to begin of page and disable scrolling if(client.isIE) { window.scroll(0,0); document.body.scroll = 'No'; } // calculate the max width var border_w = parseInt(SL.getStyle(sb, 'border-left-width'), 10) + parseInt(SL.getStyle(sb, 'border-right-width'), 10); var extra_w = border_w + 2 * options.viewportPadding; if(w + extra_w >= view_w){ w = view_w - extra_w; } // calculate the max height var border_h = parseInt(SL.getStyle(sb, 'border-top-width'), 10) + parseInt(SL.getStyle(sb, 'border-bottom-width'), 10); var bar_h = getComputedHeight(SL.get('shadowbox_title')) + getComputedHeight(SL.get('shadowbox_info')); var extra_h = border_h + 2 * options.viewportPadding + bar_h; if(h + extra_h >= view_h){ h = view_h - extra_h; } // handle oversized content var drag = false; var resize_h = height; var resize_w = width; var handle = options.handleOversize; if(resizable && (handle == 'resize' || handle == 'drag')){ var change_h = (height - h) / height; var change_w = (width - w) / width; if(handle == 'resize'){ if(change_h > change_w){ w = Math.round((width / height) * h); }else if(change_w > change_h){ h = Math.round((height / width) * w); } // adjust resized height or width accordingly resize_w = w; resize_h = h; }else{ // drag on oversized images only var link = gallery[current]; if(link) drag = link.player == 'img' && (change_h > 0 || change_w > 0); } } // update dims dims = { height: h + border_h + bar_h, width: w + border_w, inner_h: h, inner_w: w, top: (view_h - (h + extra_h)) / 2 + options.viewportPadding, resize_h: resize_h, resize_w: resize_w, drag: drag }; }; /** * Resizes Shadowbox to the given height and width. If the callback * parameter is given, the transition will be animated and the callback * function will be called when the animation completes. Note: The private * content variable must be updated before calling this function. * * @param Function cb A callback function to execute after the * content has been resized * @return void * @private */ var resizeContent = function(cb){ if(!content) return; // no content // set new dimensions setDimensions(content.height, content.width, content.resizable); if(cb){ switch(options.animSequence){ case 'hw': adjustHeight(dims.inner_h, dims.top, true, function(){ adjustWidth(dims.width, true, cb); }); break; case 'wh': adjustWidth(dims.width, true, function(){ adjustHeight(dims.inner_h, dims.top, true, cb); }); break; case 'sync': default: adjustWidth(dims.width, true); adjustHeight(dims.inner_h, dims.top, true, cb); } }else{ // window resize adjustWidth(dims.width, false); adjustHeight(dims.inner_h, dims.top, false); var c = SL.get(content_id); if(c){ // resize resizable content when in resize mode if(content.resizable && options.handleOversize == 'resize'){ c.height = dims.resize_h; c.width = dims.resize_w; } // fix draggable positioning if enlarging viewport if(gallery[current].player == 'img' && options.handleOversize == 'drag'){ var top = parseInt(SL.getStyle(c, 'top')); if(top + content.height < dims.inner_h){ SL.setStyle(c, 'top', dims.inner_h - content.height + 'px'); } var left = parseInt(SL.getStyle(c, 'left')); if(left + content.width < dims.inner_w){ SL.setStyle(c, 'left', dims.inner_w - content.width + 'px'); } } } } }; /** * Adjusts the height of #shadowbox_body and centers #shadowbox vertically * in the viewport. * * @param Number height The height to use for #shadowbox_body * @param Number top The top to use for #shadowbox * @param Boolean anim True to animate the transition * @param Function cb A callback to use when the animation * completes * @return void * @private */ var adjustHeight = function(height, top, anim, cb){ height = parseInt(height); // adjust the height var sb = SL.get('shadowbox_body'); if(anim){ if(!isColl){ animate(sb, 'height', height, options.resizeDuration); } else { animate(sb, 'height', 1200, options.resizeDuration); } }else{ SL.setStyle(sb, 'height', height + 'px'); } // adjust the top var s = SL.get('shadowbox'); if(anim){ if(isColl){ animate(s, 'top', '-5', options.resizeDuration, cb); } else { animate(s, 'top', top, options.resizeDuration, cb); } }else{ SL.setStyle(s, 'top', top + 'px'); if(typeof cb == 'function') cb(); } }; /** * Adjusts the width of #shadowbox. * * @param Number width The width to use for #shadowbox * @param Boolean anim True to animate the transition * @param Function cb A callback to use when the animation * completes * @return void * @private */ var adjustWidth = function(width, anim, cb){ width = parseInt(width); // adjust the width var s = SL.get('shadowbox'); if(anim){ if(!isColl){ animate(s, 'width', width, options.resizeDuration, cb); } else { animate(s, 'width', 1600, options.resizeDuration, cb); } }else{ SL.setStyle(s, 'width', width + 'px'); if(typeof cb == 'function') cb(); } }; /** * Sets up a listener on the document for keystrokes. * * @param Boolean on True to enable the listener, false to turn * it off * @return void * @private */ var listenKeys = function(on){ if(!options.enableKeys) return; SL[(on ? 'add' : 'remove') + 'Event'](document, 'keydown', handleKey); }; /** * A listener function that is fired when a key is pressed. * * @param mixed e The event object * @return void * @private */ var handleKey = function(e){ var code = SL.keyCode(e); // attempt to prevent default key action SL.preventDefault(e); if(code == 81 || code == 88 || code == 27){ // q, x, or esc SB.close(); }else if(code == 37){ // left arrow SB.previous(); }else if(code == 39){ // right arrow SB.next(); }else if(code == 32){ // space bar SB[(typeof slide_timer == 'number' ? 'pause' : 'play')](); } }; /** * Toggles the visibility of the "loading" layer. * * @param Boolean on True to toggle on, false to toggle off * @param Function cb The callback function to call when toggling * completes * @return void * @private */ var toggleLoading = function(on, cb){ var loading = SL.get('shadowbox_loading'); if(on){ loading.style.display = ''; if(typeof cb == 'function') cb(); }else{ var p = gallery[current].player; var anim = (p == 'img' || p == 'html'); // fade on images & html var fn = function(){ loading.style.display = 'none'; clearOpacity(loading); if(typeof cb == 'function') cb(); }; if(anim){ animate(loading, 'opacity', 0, options.fadeDuration, fn); }else{ fn(); } } }; /** * Sets the top of the container element. This is only necessary in IE6 * where the container uses absolute positioning instead of fixed. * * @return void * @private */ var fixTop = function(){ SL.get('shadowbox_container').style.top = document.documentElement.scrollTop + 'px'; }; /** * Sets the height of the overlay element to the full viewport height. This * is only necessary in IE6 where the container uses absolute positioning * instead of fixed, thus restricting the size of the overlay element. * * @return void * @private */ var fixHeight = function(){ SL.get('shadowbox_overlay').style.height = SL.getViewportHeight() + 'px'; }; /** * Determines if there is a next piece to display in the current gallery. * * @return bool True if there is another piece, false otherwise * @private */ var hasNext = function(){ return gallery.length > 1 && (current != gallery.length - 1 || options.continuous); }; /** * Toggles the visibility of #shadowbox_container and sets its size (if on * IE6). Also toggles the visibility of elements ( elements, while Firefox has trouble with * s. * * @param Function cb A callback to call after toggling on, absent * when toggling off * @return void * @private */ var toggleVisible = function(cb){ var els, v = (cb) ? 'hidden' : 'visible'; var hide = ['select', 'object', 'embed']; // tags to hide for(var i = 0; i < hide.length; ++i){ els = document.getElementsByTagName(hide[i]); for(var j = 0, len = els.length; j < len; ++j){ els[j].style.visibility = v; } } // resize & show container var so = SL.get('shadowbox_overlay'); var sc = SL.get('shadowbox_container'); var sb = SL.get('shadowbox'); if(cb){ // set overlay color/opacity SL.setStyle(so, { backgroundColor: options.overlayColor, opacity: 0 }); if(!options.modal) SL.addEvent(so, 'click', SB.close); if(ltIE7){ // fix container top & overlay height before showing fixTop(); fixHeight(); SL.addEvent(window, 'scroll', fixTop); } // fade in animation sb.style.display = 'none'; // will be cleared in loadContent() sc.style.visibility = 'visible'; animate(so, 'opacity', parseFloat(options.overlayOpacity), options.fadeDuration, cb); }else{ SL.removeEvent(so, 'click', SB.close); if(ltIE7) SL.removeEvent(window, 'scroll', fixTop); // fade out effect sb.style.display = 'none'; animate(so, 'opacity', 0, options.fadeDuration, function(){ sc.style.visibility = 'hidden'; sb.style.display = ''; clearOpacity(so); }); } }; /** * Initializes the Shadowbox environment. Loads the skin (if necessary), * compiles the player matching regular expressions, and sets up the * window resize listener. * * @param Object opts (optional) The default options to use * @return void * @public * @static */ Shadowbox.init = function(opts){ // don't initialize twice if(initialized) return; // make sure language is loaded if(typeof SB.LANG == 'undefined'){ SB.raise('No Shadowbox language loaded'); return; } // make sure skin is loaded if(typeof SB.SKIN == 'undefined'){ SB.raise('No Shadowbox skin loaded'); return; } // apply custom options apply(options, opts || {}); // add markup var markup = SB.SKIN.markup.replace(/\{(\w+)\}/g, function(m, p){ return SB.LANG[p]; }); var bd = document.body || document.documentElement; SL.append(bd, markup); // several fixes for IE6 if(ltIE7){ // give the container absolute positioning SL.setStyle(SL.get('shadowbox_container'), 'position', 'absolute'); // give shadowbox_body "layout"...whatever that is SL.get('shadowbox_body').style.zoom = 1; // use AlphaImageLoader for transparent PNG support var png = SB.SKIN.png_fix; if(png && png.constructor == Array){ for(var i = 0; i < png.length; ++i){ var el = SL.get(png[i]); if(el){ var match = SL.getStyle(el, 'background-image').match(/url\("(.*\.png)"\)/); if(match){ SL.setStyle(el, { backgroundImage: 'none', filter: 'progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,src=' + match[1] + ',sizingMethod=scale);' }); } } } } } // compile file type regular expressions here for speed for(var e in options.ext){ RE[e] = new RegExp('\.(' + options.ext[e].join('|') + ')\s*$', 'i'); } // set up window resize event handler var id; SL.addEvent(window, 'resize', function(){ // use 50 ms event buffering to prevent jerky window resizing if(id){ clearTimeout(id); id = null; } id = setTimeout(function(){ var s = SL.get('shadowbox'); if(ltIE7) fixHeight(); if(!isColl) resizeContent(); }, 50); }); if(!options.skipSetup) SB.setup(); initialized = true; }; /** * Dynamically loads the specified skin for use with Shadowbox. If the skin * is included already in the page via the appropriate