rooturl = '/';apiKey = '';jacket = true;/** * @author WW */ window.ie8 = navigator.appVersion.indexOf('MSIE 8.0') > -1; window.ie7 = navigator.appVersion.indexOf('MSIE 7.0') > -1; window.ie6 = navigator.appVersion.indexOf('MSIE 6.0') > -1; if(ie8) ie6 = ie7 = false; if(ie7) ie6 = false; //Fix some IE6 issues if(window.ie6){ if (document.all && document.styleSheets && document.styleSheets[0] && document.styleSheets[0].addRule){ new Asset.javascript(rooturl+(jacket ? 'javascript/?iepngfix_tilebg' : 'webapp/shared/javascript/?iepngfix_tilebg')); var htcurl = jacket ? rooturl+'webapp/templates/styles/' : rooturl+'webapp/templates/default/styles/'; document.styleSheets[0].addRule('input', 'behavior: url('+htcurl+'/pngfix.htc)'); document.styleSheets[0].addRule('body', 'behavior: url('+htcurl+'/csshover.htc)'); document.styleSheets[0].addRule('body', 'behavior: url('+htcurl+'/minmax.htc)'); document.styleSheets[0].addRule('div', 'behavior: url('+htcurl+'/minmax.htc)'); document.styleSheets[0].addRule('div', 'behavior: url('+htcurl+'/pngfix.htc)'); document.styleSheets[0].addRule('img', 'behavior: url('+htcurl+'/pngfix.htc)'); } } /** * Class Ajax_Hash * * Allows easier manipulation of the location.hash string. * Fires an event onChange whenever a hash variable is * changed using setValue(key, value) * * hash = new AJAX.Hash; * * getHash - mostly internal, returns an object * getValue(key) - gets the value stored in the hash key * setValue(key,value) - sets the key to the specified value * * hash.setValue('mykey', 'myvalue'); * alert(hash.getValue('mykey')); * * => would alert 'myvalue' */ var Ajax_Hash = new Class({ initialize: function(){ Ajax_Hash.implement(new Events); this.lastChange = ''; this.importHash(); }, getHash: function() { var ret = new Object(); var curhash = location.hash.substring(1); if(curhash.length > 0) { curhash = curhash.split('|'); curhash.each(function(curitem,i) { curitem = curitem.split('='); if(curitem.length == 2) eval('ret["'+curitem[0]+'"] = "'+curitem[1]+'"'); }); } return ret; }, getValue: function(key) { var curhash = this.getHash(); var ret = eval('curhash["'+key+'"]'); if(ret=='undefined') ret = undefined; return ret; }, setValue: function(key, value) { var curhash = this.getHash(); var oldvalue = curhash[key]; eval('curhash["'+key+'"] = "'+value+'"'); var str = new Array(); for(var i in curhash) if(curhash[i] !== undefined && curhash[i] != 'undefined') str.push(i+'='+curhash[i]); location.hash = str.join('|'); if(oldvalue != value) this.fireEvent('onChange', [key, value, this.lastChange]); this.lastChange = key; }, importHash: function() { var hash = this.getHash(); for(var i in hash) this.setValue(i, hash[i]); } }); /** * Ajax_Queue * * Automated AJAX calling queue. Will automatically begin checking * for a Request to be added to it when initialised into a variable, * and then continue to execute any future Request's that are added * * the submit URL will be set to rooturl + 'ajax.php' if not defined * and the method will be set to post * * queue = new AJAX.Queue; * queue.addToQueue(new Request({})); */ var Ajax_Queue = new Class({ initialize: function(){ this.queue = []; this.startTimer(); }, addToQueue: function(calldata){ this.queue.push(calldata); }, startTimer: function(){ this.timer = this.doQueue.periodical(300, this); }, doQueue: function(){ if(this.queue.length > 0) { $clear(this.timer); var call = this.queue.shift(); call.addEvent('onComplete', this.doQueue.bind(this)); if(call.options.url == '') call.options.url = rooturl + 'ajax.php'; if(call.method == undefined) call.method = 'post'; call.send(); } else { $clear(this.timer); this.startTimer(); } } }); /** * class AJAX * * Wraps up AJAX functions. * * AJAX.Hash - manipulation of the location.hash string * to allow Back/Forward navigation * * AJAX.Queue - queue for Ajax.Request calls so they run * one after the other without having to check * if an AJAX call is in progress. Requires one * parameter of type AJAX.Call */ var AJAX = new Class(); AJAX.Hash = Ajax_Hash; AJAX.Queue = Ajax_Queue; var ajax_hash = new AJAX.Hash; var ajax_queue = new AJAX.Queue; /** * [].eachDelayed(delay, function(), bind) */ Array.implement({ eachDelayed: function (delay, fn, bind) { var self = this, i = 0; (function () { fn.call(bind, self[i], i, self); if (++i < self.length) { setTimeout(arguments.callee, delay); } })(); } }); function waitForCSS(css, func){ var chkObj = { 'css': css, 'callback': func, 'timer': 0, 'bind': this, 'func': function(){ for(var i = 0; i < document.styleSheets.length; i++){ if(document.styleSheets[i].href.contains(this.css)){ $clear(this.timer); this.callback.attempt([], this.bind); } } } }; chkObj.timer = chkObj.func.periodical(50, chkObj); } /* * scaleDimensions(objectWidth, objectHeight, maxWidth, maxHeight) * * Scales a width/height based on a maximum width/height it can fit into. * If the passed in dimensions are smaller, the values will be scaled up * For larger dimensions, they will be scaled down to fit in the maximum * sizes specified. If you set overflow = true, the dimensions will be scaled up * to overflow the box but cover the entire area of the box. * * Returns an [object] * return.width - new width of object based on scale * return.height - new height of object based on scale * return.left - offset to use to keep the object centered horizontally * return.top - offset to use to keep the object centered vertically * return.ratio - ratio that was used to scale the parameters */ function scaleDimensions(objectWidth, objectHeight, maxWidth, maxHeight, overflow){ if(!$defined(overflow) || overflow != true) overflow = false; var object = {'ratio': maxWidth / objectWidth}; if (eval('maxHeight / objectHeight ' + (overflow ? '>' : '<') + ' object.ratio')) object.ratio = maxHeight / objectHeight; object.width = objectWidth * object.ratio; object.height = objectHeight * object.ratio; object.left = (maxWidth / 2) - (object.width / 2); object.top = (maxHeight / 2) - (object.height / 2); return object; } /* * setupMorph(eElement, sDisplayStyle) * * Sets up the morph event of an element as to hide it when * its opacity is morphed to 0 or to show it when its * opacity is morphed from 0 * * sDisplayStyle is optional, defaults to 'block' which is * usually ok. * * Can be set up with class="defaultMorph" on elements */ function setupMorph(eElement, sDisplayStyle, iDuration){ if(!$defined(iDuration)) iDuration = 1; if(!$defined(sDisplayStyle)) sDisplayStyle = 'block'; eElement = $(eElement); eElement.setStyle('opacity', 0); eElement.set('morph', {'duration': iDuration * 1000}); eElement.get('morph').addEvents({ 'onStart': function(e){var show = true; $try(function(){show = this.to.opacity[0].value != 0;}.bind(this)); if(e.getStyle('opacity') == 0 && show) e.style.display = sDisplayStyle;}, 'onComplete': function(e){if(e.getStyle('opacity') == 0) e.style.display = 'none';} }); } /* * fadeImages(eElement, iDuration, iFadeDelay) * * Fades between all the images in an element showing each * for iDuration seconds */ function fadeImages(eElement, iDuration, iFadeDelay){ if(!$defined(window._fadeImages_autoRotate)) window._fadeImages_autoRotate = []; if(!$defined(iFadeDelay)) iFadeDelay = 1; if(!$defined(iDuration)) iDuration = 5; var eImages = ($type(eElement) == 'string' ? $(eElement) : eElement); if(eImages.getStyle('position') != 'relative' && eImages.getStyle('position') != 'absolute' && eImages.getStyle('position') != 'fixed') eImages.style.position = 'relative'; eImages = eImages.getElements('img'); if(eImages.length == 0) return; $each(eImages, function(img){img.setStyles({'position': 'absolute', 'top': 0, 'left': 0}); setupMorph(img, 'block', iFadeDelay);}); eImages[0].setStyles({'opacity': 1, 'display': 'block'}); var rotateFunction = function(eImages){ if(!this.curImage) this.curImage = 0; this.curImage += 1; if(this.curImage > eImages.length - 1) this.curImage = 0; $each(eImages, function(img, i){img.morph({'opacity': i == this.curImage ? 1 : 0})}.bind(this)); }; window._fadeImages_autoRotate.include(rotateFunction.periodical(iDuration * 1000, rotateFunction, [eImages])); window.addEvent('beforeunload', function(){ for(var i = window._fadeImages_autoRotate.length - 1; i >= 0; i--) $clear(window._fadeImages_autoRotate[i]); }); } /* * hideDialog(eElement) / showDialog(eElement); * * Shows an element in modal form. */ function hideDialog(eElement) { if($type(eElement) == 'string') eElement = $(eElement); eElement.morph({'opacity': 0}); } function showDialog(eElement,eWidth,eHeight) { if($type(eElement) == 'string') eElement = $(eElement); if(eElement.retrieve('dialog', false) == false){ setupMorph(eElement); eElement.store('dialog', true); } eElement.inject(document.body); eElement.morph({'opacity': 1}); if(!$defined(eWidth)) eWidth = eElement.getCoordinates().width; if(!$defined(eHeight)) eHeight = eElement.getCoordinates().height; eElement.setStyles({ 'width': eWidth, 'height': eHeight }); eElement.setStyles({ 'position': 'absolute', 'z-index': 320000 + (isNaN(parseInt(eElement.getStyle('z-index'))) ? 0 : parseInt(eElement.getStyle('z-index'))), 'left': window.getScrollLeft() + (getWindowSize().width / 2) - (eElement.getCoordinates().width / 2), 'top': window.getScrollTop() + (getWindowSize().height / 2) - (eElement.getCoordinates().height / 2) }); } /* * hideModal(eElement) / showModal(eElement); * * Shows an element in modal form. */ function hideModal(eElement) { if($type(eElement) == 'string') eElement = $(eElement); var eDiv = eElement.getParent(); eDiv.morph({'opacity': 0}); } function showModal(eElement,preventClickClose) { if(!$defined(preventClickClose)) preventClickClose = false; var eDiv; if($type(eElement) == 'string') eElement = $(eElement); if(eElement.retrieve('modal', false) == false){ eDiv = new Element('div', { 'styles': { 'opacity': 0, 'display': 'none', 'position': 'fixed', 'width': '100%', 'height': '100%', 'top': 0, 'left': 0, 'z-index': 40000, 'background': 'url('+rooturl+'webapp/shared/javascript/resources/ModalDialog/ModalDialog_blackback.png)' }, 'events': { 'click': function(e){ if(!preventClickClose && e.target == eDiv) hideModal(eElement); } } }); eElement.setStyles({ 'display': 'block', 'position': 'absolute' }); eElement.inject(eDiv); eElement.store('modal', true); eDiv.inject(document.body); setupMorph(eDiv); window.addEvent('resize', function(){ eDiv.setStyles('width', document.body.clientWidth); eElement.setStyles({ 'left': (eDiv.getCoordinates().width / 2) - (eElement.getCoordinates().width / 2), 'top': (eDiv.getCoordinates().height / 2) - (eElement.getCoordinates().height / 2) }); }); } else { eDiv = eElement.getParent(); } eDiv.morph({'opacity': 1}); window.fireEvent('resize'); } Element.implement({ showModal: function(preventClickClose){ showModal(this,preventClickClose); }, hideModal: function(){ hideModal(this); }, showDialog: function(eWidth,eHeight){ showDialog(this,eWidth,eHeight); }, hideDialog: function(){ hideDialog(this); }, fadeImages: function(iDuration, iFadeDelay){ fadeImages(this, iDuration, iFadeDelay); } }); function getWindowSize() { var myWidth = 0, myHeight = 0; if( typeof( window.innerWidth ) == 'number' ) { //Non-IE myWidth = window.innerWidth; myHeight = window.innerHeight; } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) { //IE 6+ in 'standards compliant mode' myWidth = document.documentElement.clientWidth; myHeight = document.documentElement.clientHeight; } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) { //IE 4 compatible myWidth = document.body.clientWidth; myHeight = document.body.clientHeight; } return {'width': myWidth,'height': myHeight}; } function log(){ if(window.debugService){ if(arguments.length == 2 && arguments[1] === true) window.debugService.inspect($type(arguments[0]), arguments[0]); else for(var i = 0; i < arguments.length; i++) window.debugService.trace(arguments[i]); }else if(window.console && console.log) { if(arguments.length == 1 && $type(arguments[0]) == 'object' || arguments.length == 2 && $type(arguments[0]) == 'object' && arguments[1] === true) console.dir(arguments[0]); else if(arguments.length == 1) console.log(arguments[0]); else console.log(arguments); }else if(Debug.writeln){ for(var i = 0; i < arguments.length; i++) Debug.writeln(arguments[i]); } } function fadeBackgrounds(){ iDuration = $('backgrounds').className; if(iDuration == '') iDuration = 5; var eImages = $('backgrounds'); if(eImages.getStyle('position') != 'relative' && eImages.getStyle('position') != 'absolute' && eImages.getStyle('position') != 'fixed') eImages.setStyle('position', 'relative'); eImages = eImages.getElements('img'); if(eImages.length == 0) return; window._fadeBackgrounds = true; $each(eImages, function(img){setupMorph(img);}); var curImage = 0; window._fadeBackgrounds_autoRotate = function(){ curImage += 1; if(curImage > eImages.length - 1) curImage = 0; $each(eImages, function(img, i){img.morph({'opacity': i == curImage ? 1 : 0})}); }; eImages[0].setStyles({'opacity': 1, 'display': 'block'}); window._fadeBackgrounds_autoRotate.periodical(iDuration * 1000); //time between image switches in milliseconds window.addEvent('resize', function(){bgImageFix();}); window.addEvent('beforeunload', function(){ $clear(window._fadeBackgrounds_autoRotate); }); } function bgImageFix(){ var imgs = $('backgrounds').getElements('img'); var style = $('backgrounds').retrieve('style', {}); var wSize = getWindowSize(); $each(imgs, function(img){ img.setStyles({ 'left': style.margin == 'auto' ? wSize.width / 2 - img.width / 2 : img.getStyle('left'), 'position': 'absolute' }); }); } function createHoverBackground(eElement, withClickState){ if(!$defined(withClickState) || withClickState !== true) var withClickState = false; window.getAndStoreDivDetails = function(target){ target = $(target); var pngFix = false; if(window.ie6){ if(!target.retrieve('root')) target = target.getParent(); target.store('outer', true); target.store('pngFix', true); pngFix = true; } var returnData = {'height': 0, 'bgPos': 0, 'pngFix': pngFix, 'target': target}; var divHeight = parseInt(target.retrieve('height', 0)); if(divHeight == 0) { divHeight = parseInt(target.getStyle('height')); target.store('height', divHeight); if(pngFix){ var eDiv = target.getElement('div'); try{ var bgPos = eDiv.getStyle('clip').split(' '); }catch(ex){ target.store('height', 0); return; } bgPos[0] = parseInt(bgPos[0].substring(bgPos[0].indexOf('(')+1)); bgPos[1] = parseInt(bgPos[1]); bgPos[2] = parseInt(bgPos[2]); bgPos[3] = parseInt(bgPos[3]); target.store('top', parseInt(eDiv.getStyle('top'))); divHeight = parseInt(target.getStyle('height')); target.store('innerHeight', parseInt(eDiv.getStyle('height'))); target.store('height', divHeight); } else if(Browser.Engine.trident) var bgPos = parseInt(target.getStyle('background-position-y')); else { var bgPos = target.getStyle('background-position').split(' '); bgPos[0] = parseInt(bgPos[0]); bgPos[1] = parseInt(bgPos[1]); } target.store('background-position', bgPos); } returnData.top = parseInt(target.retrieve('top', 0)); returnData.height = divHeight; if(pngFix) { returnData.pngFix = true; returnData.innerHeight = target.retrieve('innerHeight', 0); } returnData.bgPos = target.retrieve('background-position'); return returnData; }; if(eElement.get('tag') == 'input') eElement.value = ''; eElement.style.cursor = 'pointer'; eElement.disable = function(){ this.style.cursor = 'auto'; this.store('holdDown', false); this.fireEvent('mouseleave', {'target': this}); this.store('disabled', true); if(this.get('tag') != 'input') this.setStyle('opacity', 0.5); }.bind(eElement); eElement.enable = function(){ this.style.cursor = 'pointer'; this.store('disabled', false); if(this.get('tag') != 'input') this.setStyle('opacity', 1); }.bind(eElement); eElement.enable(); eElement.isdisabled = function(){ return this.retrieve('disabled', false); }.bind(eElement); window.addEvent('beforeunload', function(){ eElement.removeEvents(); try{ delete eElement.disable; delete eElement.enable; delete eElement.isdisabled; }catch(ex){} eElement.disable = null; eElement.enable = null; eElement.isdisabled = null; }.bind(this)); var events = { 'mouseenter': function(e){ var targetData = getAndStoreDivDetails(e.target); if(!targetData || !targetData.target) return; if(targetData.target.retrieve('holdDown', false) == true) return; if(targetData.target.retrieve('disabled', false) == true) return; if(targetData.pngFix) { var eDiv = targetData.target.getElement('div'); var bgPos = $A(targetData.bgPos); bgPos[0] += targetData.height; bgPos[2] += targetData.height; bgPos = 'rect('+bgPos.join('px ')+'px)'; eDiv.setStyles({ 'clip': bgPos, 'top': targetData.top - targetData.height, 'height': targetData.innerHeight + targetData.height }); } else if(Browser.Engine.trident) targetData.target.setStyle('background-position-y', (targetData.bgPos - targetData.height) + 'px'); else targetData.target.setStyle('background-position', targetData.bgPos[0] + 'px ' + (targetData.bgPos[1] - targetData.height) + 'px'); }, 'mouseleave': function(e){ var targetData = getAndStoreDivDetails(e.target); if(!targetData || !targetData.target) return; if(targetData.target.retrieve('holdDown', false) == true) return; if(targetData.pngFix) { var eDiv = targetData.target.getElement('div'); eDiv.setStyles({ 'clip': 'rect('+targetData.bgPos.join('px ')+'px)', 'top': targetData.top, 'height': targetData.innerHeight }); } else if(Browser.Engine.trident) targetData.target.setStyle('background-position-y', targetData.bgPos + 'px'); else targetData.target.setStyle('background-position', targetData.bgPos[0] + 'px ' + targetData.bgPos[1] + 'px'); } }; if(withClickState) { events.mousedown = function(e){ var targetData = getAndStoreDivDetails(e.target); if(targetData.target.retrieve('disabled', false) == true) return; if(targetData.pngFix) { var eDiv = targetData.target.getElement('div'); var bgPos = $A(targetData.bgPos); bgPos[0] += targetData.height*2; bgPos[2] += targetData.height*2; bgPos = 'rect('+bgPos.join('px ')+'px)'; eDiv.setStyles({ 'clip': bgPos, 'top': targetData.top - targetData.height*2, 'height': targetData.innerHeight + targetData.height*2 }); } else if(Browser.Engine.trident) targetData.target.setStyle('background-position-y', (targetData.bgPos - (targetData.height * 2)) + 'px'); else targetData.target.setStyle('background-position', targetData.bgPos[0] + 'px ' + (targetData.bgPos[1] - (targetData.height *2)) + 'px'); }; events.mouseup = function(e){ var target = $(e.target); if(target.retrieve('holdDown', false) == true) return; if(Browser.Engine.trident4) target.getParent().fireEvent('mouseenter', e); else target.fireEvent('mouseenter', e); }; } eElement.store('root', true); eElement.addEvents(events); } function buildRatings(field, rating){ if(!$defined(rating)) var rating = field.value; var divRating = field.retrieve('divRating', false); if(divRating == false) { divRating = new Element('div', { 'class': 'rating' }).inject(field, 'after'); divRating.addEvents({ 'mousemove': function(e){ if(e.target.get('tag') == 'img'){ buildRatings(field, e.target.retrieve('rating')); } }, 'mouseleave': function(e){ buildRatings(field); } }); for(var i = 0; i < 5; i++){ var img = new Element('img', { 'src': rooturl + 'webapp/shared/icon/?star' + (rating > i ? '' : '_grey') + '.png', 'width': 16, 'height': 16, 'alt': 'Star', 'events': { 'click': function(e){ e.target.retrieve('field').value = e.target.retrieve('rating'); buildRatings(e.target.retrieve('field')); } } }).inject(divRating); img.store('rating', i + 1); img.store('field', field); } field.store('divRating', divRating); buildRatings(field); return; } var imgs = divRating.getElements('img'); for(var i = 0; i < 5; i++) imgs[i].src = rooturl + 'webapp/shared/icon/?star' + (rating > i ? '' : '_grey') + '.png' } /* * Site-wide setup functions: * * - setupMorph() called on all class=".defaultMorph" elements * - replacement of all links to open in a new window * - fadeImages() called on all class=".fadeImages" * - all elements will toggle their src parameters with _off/_on */ window.addEvent('domready', function(){ $each($$('.defaultMorph'), function(eElement){setupMorph(eElement);}); $each($$('.fadeImages'), function(eElement){ var iFadeDelay = 1; var iDuration = 5; if(eElement.className.length > 11){ var tDuration, tFadeDelay; var elClass = eElement.className; tDuration = elClass.substring(elClass.indexOf('fadeImages')+11); tDuration = tDuration.substring(0, tDuration.indexOf(' ') > -1 ? tDuration.indexOf(' ') : tDuration.length); if(tDuration - 0 == parseInt(tDuration)) iDuration = tDuration; tFadeDelay = elClass.substring(elClass.indexOf('fadeImages')+11); tFadeDelay = tFadeDelay.substring(tDuration.toString().length+1); tFadeDelay = tFadeDelay.substring(0, tFadeDelay.indexOf(' ') > -1 ? tFadeDelay.indexOf(' ') : tFadeDelay.length); if(tFadeDelay - 0 == parseInt(tFadeDelay)) iFadeDelay = tFadeDelay; } fadeImages(eElement, iDuration, iFadeDelay); }); $each($$('a[rel="external"]'), function(eA){ eA.addEvent('click', function(e){ e.preventDefault(); if(window.pageTracker && pageTracker._trackPageview) pageTracker._trackPageview(eA.getProperty('href')); window.open(eA.getProperty('href'), '_blank'); }); window.addEvent('beforeunload', function(){this.removeEvents()}.bind(eA)); }); $each($$('img.hover,input.hover'), function(eElement){eElement.setStyle('cursor', 'pointer');eElement.addEvents({'mouseenter': function(e){eElement.src = eElement.src.replace('_off','_on');},'mouseleave': function(e){eElement.src = eElement.src.replace('_on','_off');}});}); $each($$('.hoverbg'), function(eElement){ createHoverBackground(eElement); }); if($('backgrounds')){ $('backgrounds').inject(document.body, 'top'); $('backgrounds').setStyles({ 'z-index': -1, 'position': 'fixed', 'overflow': 'hidden' }); for(var i = 0; i < document.styleSheets.length; i++){ var rules = document.styleSheets[i].cssRules; if(!$defined(rules)) rules = document.styleSheets[i].rules; for(var j = 0; j < rules.length; j++){ if(rules[j].selectorText.toLowerCase() == '#backgrounds img'){ var style = {}; if(rules[j].style.marginLeft.toLowerCase() == 'auto') style.margin = 'auto'; $('backgrounds').store('style', style); } } } bgImageFix(); fadeBackgrounds(); } $each($$('input.rating'), buildRatings); $each($$('input.boolean'), function(input){ var hidden = new Element('input', { 'type': 'hidden', 'name': input.name, 'value': input.checked ? '1' : '0' }).inject(input, 'after'); input.checked = input.value == '1' ? true : false; input.setProperty('name', ''); input.addEvent('change', function(e){ hidden.value = e.target.checked ? '1' : '0'; }.bind(this)); }); });; /* Milkbox - required: mootools.js v1.2b2+ v1.1 - added keyboard navigation and overlay fade out when closeMilkbox() is executed. by Luca Reghellin (http://www.reghellin.com) April 2008, MIT-style license. Inspiration from Slimbox by Christophe Beyls (http://www.digitalia.be) and from THE VERY FIRST MAN ON THE MOON: Lokesh Dhakar (http://www.lokeshdhakar.com/projects/lightbox2/) AND OF COURSE, SPECIAL THANKS TO THE MOOTOOLS DEVELOPERS */ var Milkbox = new Class({ Implements:Options, options:{//set all the options here overlayOpacity:0.7, topPosition:80, initialWidth:250, initialHeight:250, resizeDuration:500, resizeTransition:'sine:in:out',/*function (ex. Transitions.Sine.easeIn) or string (ex. 'quint:out')*/ hoverBackgroundPosition:'0 -23px' }, initialize: function(options){ var cssurl = rooturl + 'webapp/shared/javascript/resources/mootools.milkbox/milkbox.css'; var loadedcss = false; for(var i=0; i < document.styleSheets.length; i++) if(document.styleSheets[i].href && document.styleSheets[i].href.indexOf(cssurl) > -1) loadedcss = true; if(!loadedcss) new Asset.css(cssurl); this.setOptions(options); this.galleries = []; this.currentImage = null; this.currentIndex = null; this.currentGallery = null; this.specialDescription = null;//for showThisImage this.mode = null;//'singleImage','imageGallery','showThisImage' this.closed = true; this.busy = true;//to control keyboard events this.loadedImages = [];//to check the preloaded images this.initMilkbox(); },//end init initMilkbox:function(){ this.prepareGalleries(); this.prepareHTML(); this.prepareEffects(); this.prepareEvents(); if(this.galleries.length == 0){ return; }; }, //runs only 1 time per gallery openMilkbox:function(gallery,index,width,height){ this.overlay.setStyles({ 'top': -$(window).getScroll().y,'height':$(window).getScrollSize().y+$(window).getScroll().y }); this.center.addClass('mbLoading'); this.center.setStyle('top',$(window).getScroll().y+this.options.topPosition); this.currentGallery = gallery; this.currentIndex = index; this.overlay.tween('opacity',this.options.overlayOpacity);//onComplete: center.tween opacity if(gallery.length == 1){ this.mode = 'singleImage'; this.loadImages(gallery[index].href,undefined,width,height); } else { this.mode = 'imageGallery'; var images = gallery.map(function(item){ return item.href; }); $$(this.prev, this.next, this.count).setStyles({'display':'block'}); var border = this.center.getStyle('border-right-width').toInt();//border-right is just ok for design purposes.. var navWidth = this.prev.getSize().x+this.next.getSize().x+this.close.getSize().x+border; this.navigation.setStyle('width',navWidth); this.description.setStyle('margin-right',navWidth); var next = (index != images.length-1) ? images[index+1] : images[0]; var prev = (index != 0) ? images[index-1] : images[images.length-1]; var preloads = (prev == next) ? prev : [prev,next]; //if gallery.length == 2, then prev == next this.loadImages(images[index],preloads,width,height); } this.closed = false; }, //call with js showThisImage:function(image,description){ this.mode = 'showThisImage'; this.specialDescription = description; this.overlay.setStyles({ 'top': -$(window).getScroll().y,'height':$(window).getScrollSize().y+$(window).getScroll().y }); this.center.addClass('mbLoading'); this.center.setStyle('top',$(window).getScroll().y+this.options.topPosition); this.overlay.tween('opacity',this.options.overlayOpacity);//onComplete: center.tween opacity this.loadImages(image); this.closed = false; }, //see loadImages() showImage:function(image){ if(this.closed){ return; };//if you close the FastBox and an onload event is still running var imageBoxSize = this.image.getSize(); this.image.setStyles({'opacity':0, 'width':'', 'height':''}); if(image.remote) { var imageSize = new Hash({'width': image.options.width, 'height':image.options.height}).map(function(item, index){ return item.toInt(); }); } else { var imageSize = new Hash(image.getProperties('width','height')).map(function(item, index){ return item.toInt(); }); } var maxwidth = this.options.maxWidth; var maxheight = this.options.maxHeight; if(maxwidth || maxheight) { if(maxwidth == undefined) maxwidth = imageSize.width; if(maxheight == undefined) maxheight = imageSize.height; var scale = maxwidth / imageSize.width; if(maxheight /imageSize.height< scale) scale = maxheight / imageSize.height; width = Math.floor(imageSize.width * scale); height = Math.floor(imageSize.height * scale); this.image.setProperties({width: width, height: height}); imageSize.width = width; imageSize.height = height; } var centerSize = new Hash(this.center.getStyles('width','height')).map(function(item, index){ return item.toInt(); }); var targetSize = {}; if(imageSize.width != centerSize.width){ targetSize.width = imageSize.width; targetSize.marginLeft = -(imageSize.width/2).round(); }; var gap = (imageBoxSize.y > 0) ? centerSize.height - imageBoxSize.y : 0; var targetHeight = imageSize.height + gap; targetSize.height = targetHeight; //so nav doesn't move when you click next/prev this.image.setStyles({'width':imageSize.width, 'height':imageSize.height}); this.center.removeClass('mbLoading'); this.center.morph(targetSize);//onComplete: show all items }, loadImages:function(currentImage,preloads,width,height){ if(width) { this.currentImage = new Swiff(currentImage, { 'width': width, 'height': height }); if(!this.loadedImages.contains(currentImage)){ this.loadedImages.push(currentImage); };//see next/prev events $$(this.description,this.navigation).setStyle('visibility','hidden'); this.navigation.setStyle('height','');//reset the height setted in center.morph.onComplete $$(this.next,this.prev,this.close).setStyle('backgroundPosition','0 0'); this.closed = false; this.showImage(this.currentImage); return; } var loadImage = new Asset.image(currentImage, { onload:function(img){ this.currentImage = img; if(!this.loadedImages.contains(currentImage)){ this.loadedImages.push(currentImage); };//see next/prev events $$(this.description,this.navigation).setStyle('visibility','hidden'); this.navigation.setStyle('height','');//reset the height setted in center.morph.onComplete $$(this.next,this.prev,this.close).setStyle('backgroundPosition','0 0'); this.showImage(this.currentImage); }.bindWithEvent(this)}); if(preloads && !this.loadedImages.contains(preloads)){ var preloadImage = new Asset.images(preloads, { onload:function(img){ if(!this.loadedImages.contains(preloadImage)){ this.loadedImages.push(preloadImage); };//see next/prev events }.bindWithEvent(this)}); }; }, //all the main events prepareEvents:function(){ //galleries this.galleries.each(function(gallery){ $$(gallery).addEvent('click',function(e){ var button=($(e.target).match('a')) ? $(e.target) : $(e.target).getParent('a'); e.preventDefault(); this.openMilkbox(gallery, gallery.indexOf(button), button.retrieve('width', null), button.retrieve('height', null)); }.bindWithEvent(this)); },this); //next, prev, see next_prev_aux() this.next.addEvent('click',this.next_prev_aux.bindWithEvent(this,'next')); this.prev.addEvent('click',this.next_prev_aux.bindWithEvent(this,'prev')); //keyboard next/prev/close $(window.document).addEvent('keydown',function(e){ if(this.mode != 'imageGallery' || this.busy == true){ return; }; if(e.key == 'right' || e.key == 'space'){ this.next_prev_aux(e,'next'); } else if(e.key == 'left'){ this.next_prev_aux(e,'next'); } else if(e.key == 'esc'){ this.closeMilkbox(); }; }.bindWithEvent(this)); //css hover doesn't work in ie6, so I must do it via js... $$(this.next,this.prev,this.close).addEvents({ 'mouseover':function(e){ var button=($(e.target).match('a')) ? $(e.target) : $(e.target).getParent('a'); button.setStyle('backgroundPosition',this.options.hoverBackgroundPosition); }.bindWithEvent(this), 'mouseout':function(){ this.setStyle('backgroundPosition','0 0'); } }); //overlay this.overlay.get('tween').addEvent('onComplete',function(){ if(this.overlay.getStyle('opacity') == this.options.overlayOpacity){ this.center.tween('opacity',1); } else if(this.overlay.getStyle('opacity') == 0) { this.overlay.setStyles({'height':'','top':''}); }; }.bindWithEvent(this)); //center this.center.get('morph').addEvent('onComplete',function(){ this.image.grab(this.currentImage); if(!this.currentImage.options) { this.currentImage.setProperties({width: this.image.getProperty('width'),height: this.image.getProperty('height')}); } this.image.tween('opacity',1); var d = (!(this.mode == 'showThisImage')) ? this.currentGallery[this.currentIndex].getProperty('title') : this.specialDescription; if($chk(d)){ this.description.set('html', d) }; if(this.mode == 'imageGallery'){ this.count.appendText((this.currentIndex+1)+' of '+this.currentGallery.length); } var currentCenterHeight = this.center.getStyle('height').toInt(); this.navigation.setStyle('height',this.bottom.getStyle('height').toInt());//to have the right-border height == total bottom height var bottomSize = this.bottom.getSize().y; var imageY = this.currentImage.options ? this.currentImage.options.height : this.image.getSize().y; var imageX = this.currentImage.options ? this.currentImage.options.width : this.image.getSize().x; //after the 1st time, currentCenterHeight is always > this.image.getSize().y var targetOffset = (currentCenterHeight > imageY) ? (this.bottom.getSize().y+imageY)-currentCenterHeight : bottomSize; this.bottom.setStyle('display','none');//to avoid rendering problems during setFinalHeight this.center.retrieve('setFinalHeight').start(currentCenterHeight,parseInt(currentCenterHeight)+parseInt(targetOffset)); }.bindWithEvent(this)); this.center.retrieve('setFinalHeight').addEvent('onComplete',function(){ this.bottom.setStyles({'visibility':'visible','display':'block'}); $$(this.description,this.navigation).setStyle('visibility','visible'); //reset overlay height based on position and height var scrollSize = $(window).getScrollSize().y; var scrollTop = $(window).getScroll().y; this.currentImage.inject(this.image, 'top'); this.overlay.setStyle('height',scrollSize+scrollTop); this.busy = false; }.bindWithEvent(this)); //reset overlay height and position onResize window.addEvent('resize',function(){ if(this.overlay.getStyle('opacity') == 0){ return; };//resize only if visible var scrollSize = $(window).getScrollSize().y; var scrollTop = $(window).getScroll().y; this.overlay.setStyles({ 'height':scrollSize+scrollTop,'top':-scrollTop }); }.bindWithEvent(this)); //close $$(this.overlay,this.image,this.close).addEvent('click',function(e){ if(e.target.get('tag') == 'object') return;this.closeMilkbox(); }.bindWithEvent(this)); }, next_prev_aux:function(e,direction){ e.preventDefault(); this.busy = true; if(direction == "next"){ var i= (this.currentIndex != this.currentGallery.length-1) ? this.currentIndex += 1 : this.currentIndex = 0; var _i= (this.currentIndex != this.currentGallery.length-1) ? this.currentIndex + 1 : 0; } else { var i= (this.currentIndex != 0) ? this.currentIndex -= 1 : this.currentIndex = this.currentGallery.length-1; var _i= (this.currentIndex != 0) ? this.currentIndex - 1 : this.currentGallery.length-1; }; this.image.empty(); this.description.empty(); this.count.empty(); if(!this.loadedImages.contains(this.currentGallery[i].href)){ this.center.addClass('muLoading'); }; this.loadImages(this.currentGallery[i].href,this.currentGallery[_i].href); }, closeMilkbox:function(){ this.cancelAllEffects(); this.currentImage = null; this.currentIndex = null; this.currentGallery = null; $$(this.prev, this.next, this.count).setStyle('display','none'); var border = this.center.getStyle('border-right-width').toInt(); var navWidth = this.close.getSize().x+border; this.navigation.setStyles({'width':navWidth,'height':'','visibility':'hidden'}); this.description.setStyle('margin-right',navWidth); this.description.empty(); this.bottom.setStyles({'visibility':'hidden','display':''}); this.image.setStyles({'opacity':0, 'width':'', 'height':''}); this.image.empty(); this.count.empty(); this.center.setStyles({'opacity':0,'width':this.options.initialWidth,'height':this.options.initialHeight,'marginLeft':-(this.options.initialWidth/2)}); this.overlay.tween('opacity',0);//see onComplete in prepareEvents() this.mode = null; this.closed = true; }, cancelAllEffects:function(){ this.overlay.get('tween').cancel(); this.center.get('morph').cancel(); this.center.get('tween').cancel(); this.center.retrieve('setFinalHeight').cancel(); this.image.get('tween').cancel(); }, prepareEffects:function(){ this.overlay.set('tween',{ duration:'short',link:'cancel' }); this.center.set('tween',{ duration:'short',link:'chain' }); this.center.set('morph',{ duration:this.options.resizeDuration,link:'chain',transition:this.options.resizeTransition }); this.center.store('setFinalHeight',new Fx.Tween(this.center,{'property':'height', 'duration':'short'})); this.image.set('tween',{ link:'chain' }); }, prepareGalleries:function(){ var families = []; var milkbox_a = []; $$('a').each(function(a){ //test 'milkbox' and link extension, and collect all milkbox links if(a.rel && a.rel.test(/^milkbox/i) && (a.href.contains('.gif') || a.href.contains('.jpg') || a.href.contains('.png') || a.href.contains('.swf'))){ if(a.rel.length>7 && !families.contains(a.rel)){ families.push(a.rel); }; milkbox_a.push(a); } },this); //console.log(milkbox_a) //create an array of arrays with all galleries milkbox_a.each(function(a){ $(a).store('href',a.href); $(a).store('rel',a.rel); if(a.rel.length > 7){ var rel = a.rel; if(a.rel.indexOf(',') > -1){ $(a).store('width', rel.substring(rel.indexOf(',')+1, rel.indexOf(',', rel.indexOf(',')+1))); $(a).store('height', rel.substring(rel.indexOf(',', rel.indexOf(',')+1)+1, rel.indexOf(']'))); rel = rel.substring(0, rel.indexOf(',')) + ']'; } families.each(function(f,i){ if(a.rel == f){ if(!this.galleries[i]){ this.galleries[i] = [] }; this.galleries[i].push($(a)); }; },this); } else { this.galleries.push([$(a)]); }; },this); //console.log(this.galleries) }, prepareHTML:function(){ this.overlay = new Element('div', { 'id':'mbOverlay','styles':{ 'opacity':'0','visibility':'visible', 'z-index': 9990 }}).inject($(document.body)); this.center = new Element('div', {'id':'mbCenter', 'styles':{'width':this.options.initialWidth, 'z-index': 9991,'height':this.options.initialHeight,'marginLeft':-(this.options.initialWidth/2),'opacity':0}}).inject($(document.body)); this.image = new Element('div', {'id':'mbImage', 'styles':{'z-index': 9992}}).inject(this.center); this.bottom = new Element('div',{'id':'mbBottom', 'styles':{'z-index': 9993}}).inject(this.center).setStyle('visibility','hidden'); this.navigation = new Element('div',{'id':'mbNavigation', 'styles':{'z-index': 9994}}).setStyle('visibility','hidden'); this.description = new Element('div',{'id':'mbDescription', 'styles':{'z-index': 9995}}).setStyle('visibility','hidden'); this.bottom.adopt(this.navigation, this.description, new Element('div',{'class':'clear', 'styles':{'z-index': 9992}})); this.close = new Element('a',{'id':'mbCloseLink'}); this.next = new Element('a',{'id':'mbNextLink'}); this.prev = new Element('a',{'id':'mbPrevLink'}); this.count = new Element('span',{'id':'mbCount'}); $$(this.next, this.prev, this.count).setStyle('display','none'); this.navigation.adopt(this.close, this.next, this.prev,new Element('div',{'class':'clear'}), this.count); } });//END MILKBOX; window.addEvent('domready', function(){ Milkbox = new Milkbox(); }); ;