/** * This file is part of jQuery Lightbox * Copyright (C) 2007-2010 Benjamin Arthur Lupton * http://www.balupton.com/projects/jquery-lightbox * * jQuery Lightbox is free software; You can redistribute it and/or modify it under the terms of * the GNU Affero General Public License version 3 as published by the Free Software Foundation. * You don't have to do anything special to accept the license and you don’t have to notify * anyone which that you have made that decision. * * jQuery Lightbox is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See your chosen license for more details. * * You should have received along with jQuery Lightbox: * - A copy of the license used. * If not, see . * - A copy of our interpretation of the license used. * If not, see . * * @version 1.4.6-final * @date July 28, 2010 * @since v0.1.0-dev, December 3, 2007 * @category jquery-plugin * @package jquery-lightbox {@link http://www.balupton/projects/jquery-lightbox} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2007-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} * @example Visit {@link http://www.balupton.com/projects/jquery-lightbox} for more information. */ // Start of our jQuery Plugin (function($) { // Create our Plugin function, with $ as the argument (we pass the jQuery object over later) // More info: http://docs.jquery.com/Plugins/Authoring#Custom_Alias /** * Console Emulator * We have to convert arguments into arrays, and do this explicitly as webkit (chrome) hates function references, and arguments cannot be passed as is * @version 1.0.2 * @date August 21, 2010 * @since 0.1.0-dev, December 01, 2009 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ if ( typeof window.console !== 'object' || typeof window.console.emulated === 'undefined' ) { // Check to see if console exists if ( typeof window.console !== 'object' || !(typeof window.console.log === 'function' || typeof window.console.log === 'object') ) { // Console does not exist window.console = {}; window.console.log = window.console.debug = window.console.warn = window.console.trace = function(){}; window.console.error = function(){ var msg = "An error has occured. More information will be available in the console log."; for ( var i = 0; i < arguments.length; ++i ) { if ( typeof arguments[i] !== 'string' ) { break; } msg += "\n"+arguments[i]; } if ( typeof Error !== 'undefined' ) { throw new Error(msg); } else { throw(msg); } }; } else { // Console is object, and log does exist // Check Debug if ( typeof window.console.debug === 'undefined' ) { window.console.debug = function(){ var arr = ['console.debug:']; for(var i = 0; i < arguments.length; i++) { arr.push(arguments[i]); }; window.console.log.apply(window.console, arr); }; } // Check Warn if ( typeof window.console.warn === 'undefined' ) { window.console.warn = function(){ var arr = ['console.warn:']; for(var i = 0; i < arguments.length; i++) { arr.push(arguments[i]); }; window.console.log.apply(window.console, arr); }; } // Check Error if ( typeof window.console.error === 'undefined' ) { window.console.error = function(){ var arr = ['console.error']; for(var i = 0; i < arguments.length; i++) { arr.push(arguments[i]); }; window.console.log.apply(window.console, arr); }; } // Check Trace if ( typeof window.console.trace === 'undefined' ) { window.console.trace = function(){ window.console.error.apply(window.console, ['console.trace does not exist']); }; } } // We have been emulated window.console.emulated = true; } /** * Return a new JSON object of the old string. * Turns: * file.js?a=1&b.c=3.0&b.d=four&a_false_value=false&a_null_value=null * Into: * {"a":1,"b":{"c":3,"d":"four"},"a_false_value":false,"a_null_value":null} * @version 1.1.0 * @date July 16, 2010 * @since 1.0.0, June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ String.prototype.queryStringToJSON = String.prototype.queryStringToJSON || function ( ) { // Turns a params string or url into an array of params // Prepare var params = String(this); // Remove url if need be params = params.substring(params.indexOf('?')+1); // params = params.substring(params.indexOf('#')+1); // Change + to %20, the %20 is fixed up later with the decode params = params.replace(/\+/g, '%20'); // Do we have JSON string if ( params.substring(0,1) === '{' && params.substring(params.length-1) === '}' ) { // We have a JSON string return eval(decodeURIComponent(params)); } // We have a params string params = params.split(/\&(amp\;)?/); var json = {}; // We have params for ( var i = 0, n = params.length; i < n; ++i ) { // Adjust var param = params[i] || null; if ( param === null ) { continue; } param = param.split('='); if ( param === null ) { continue; } // ^ We now have "var=blah" into ["var","blah"] // Get var key = param[0] || null; if ( key === null ) { continue; } if ( typeof param[1] === 'undefined' ) { continue; } var value = param[1]; // ^ We now have the parts // Fix key = decodeURIComponent(key); value = decodeURIComponent(value); try { // value can be converted value = eval(value); } catch ( e ) { // value is a normal string } // Set // window.console.log({'key':key,'value':value}, split); var keys = key.split('.'); if ( keys.length === 1 ) { // Simple json[key] = value; } else { // Advanced (Recreating an object) var path = '', cmd = ''; // Ensure Path Exists $.each(keys,function(ii,key){ path += '["'+key.replace(/"/g,'\\"')+'"]'; jsonCLOSUREGLOBAL = json; // we have made this a global as closure compiler struggles with evals cmd = 'if ( typeof jsonCLOSUREGLOBAL'+path+' === "undefined" ) jsonCLOSUREGLOBAL'+path+' = {}'; eval(cmd); json = jsonCLOSUREGLOBAL; delete jsonCLOSUREGLOBAL; }); // Apply Value jsonCLOSUREGLOBAL = json; // we have made this a global as closure compiler struggles with evals valueCLOSUREGLOBAL = value; // we have made this a global as closure compiler struggles with evals cmd = 'jsonCLOSUREGLOBAL'+path+' = valueCLOSUREGLOBAL'; eval(cmd); json = jsonCLOSUREGLOBAL; delete jsonCLOSUREGLOBAL; delete valueCLOSUREGLOBAL; } // ^ We now have the parts added to your JSON object } return json; }; /** * Remove a element, or a set of elements from an array * @version 1.0.0 * @date June 30, 2010 * @copyright John Resig * @license MIT License - {@link http://opensource.org/licenses/mit-license.php} */ Array.prototype.remove = function(from, to) { var rest = this.slice((to || from) + 1 || this.length); this.length = from < 0 ? this.length + from : from; return this.push.apply(this, rest); }; /** * Get a element from an array at [index] * if [current] is set, then set this index as the current index (we don't care if it doesn't exist) * @version 1.0.1 * @date July 09, 2010 * @since 1.0.0 June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.get = function(index, current) { // Determine if ( index === 'first' ) { index = 0; } else if ( index === 'last' ) { index = this.length-1; } else if ( index === 'prev' ) { index = this.index-1; } else if ( index === 'next' ) { index = this.index+1; } else if ( !index && index !== 0 ) { index = this.index; } // Set current? if ( current||false !== false ) { this.setIndex(index); } // Return return this.exists(index) ? this[index] : undefined; }; /** * Apply the function [fn] to each element in the array * @version 1.0.0 * @date June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.each = function(fn){ for (var i = 0; i < this.length; ++i) { if (fn(i, this[i], this) === false) break; } return this; } /** * Checks whether the index is a valid index * @version 1.0.0 * @date July 09, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.validIndex = function(index){ return index >= 0 && index < this.length; }; /** * Set the current index of the array * @version 1.0.0 * @date June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.setIndex = function(index){ if ( this.validIndex(index) ) { this.index = index; } else { this.index = null; } return this; }; /** * Get the current index of the array * If [index] is passed then set that as the current, and return it's value * @version 1.0.0 * @date June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.current = function(index){ return this.get(index, true); }; /** * Get whether or not the array is empty * @version 1.0.0 * @date June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.isEmpty = function(){ return this.length === 0; }; /** * Get whether or not the array has only one item * @version 1.0.0 * @date June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.isSingle = function(){ return this.length === 1; }; /** * Get whether or not the array is not empty * @version 1.0.0 * @date June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.isNotEmpty = function(){ return this.length !== 0; }; /** * Get whether or not the array has more than one item * @version 1.0.0 * @date June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.isNotEmpty = function(){ return this.length > 1; }; /** * Get whether or not the current index is the last one * @version 1.0.0 * @date June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.isLast = function(index){ index = typeof index === 'undefined' ? this.index : index; return !this.isEmpty() && index === this.length-1; } /** * Get whether or not the current index is the first one * @version 1.0.0 * @date June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.isFirst = function(index){ index = typeof index === 'undefined' ? this.index : index; return !this.isEmpty() && index === 0; } /** * Clear the array * @version 1.0.0 * @date June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.clear = function(){ this.length = 0; }; /** * Set the index as the next one, and get the item * @version 1.0.0 * @date June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.next = function(update){ return this.get(this.index+1, update); }; /** * Set the index as the previous one, and get the item * @version 1.0.0 * @date June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.prev = function(update){ return this.get(this.index-1, update); }; /** * Reset the index * @version 1.0.0 * @date June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.reset = function(){ this.index = null; return this; }; /** * Set the [index] to the [item] * @version 1.0.0 * @date June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.set = function(index, item){ // We want to set the item if ( index < this.length && index >= 0 ) { this[index] = item; } else { throw new Error('Array.prototype.set: [index] above this.length'); // return false; } return this; }; /** * Set the index as the next item, and return it. * If we reach the end, then start back at the beginning. * @version 1.0.0 * @date June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.loop = function(){ if ( !this.index && this.index !== 0 ) { // index is not a valid value return this.current(0); } return this.next(); }; /** * Add the [arguments] to the array * @version 1.0.0 * @date June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.add = function(){ this.push.apply(this,arguments); return this; }; /** * Insert the [item] at the [index] or at the end of the array * @version 1.0.0 * @date June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.insert = function(index, item){ if ( typeof index !== 'number' ) { index = this.length; } index = index<=this.length ? index : this.length; var rest = this.slice(index); this.length = index; this.push(item); this.push.apply(this, rest); return this; }; /** * Get whether or not the index exists in the array * @version 1.0.0 * @date July 09, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.exists = Array.prototype.exists || function(index){ return typeof this[index] !== 'undefined'; }; /** * Get whether or not the value exists in the array * @version 1.0.0 * @date June 30, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html} */ Array.prototype.has = Array.prototype.has || function(value){ var has = false; for ( var i=0, n=this.length; i 0 ) { // Description exists image.description = image.title.substring(s+2) || image.description; image.title = image.title.substring(0,s) || image.title; } } else { image = null; } } else if ( obj.src ) { // We are a image object image = $.extend(this.image,obj); } else { image = null; } if ( image ) { image.id = image.id || image.src+image.title+image.description; } return image; } this.images.create = function(obj){ var images = this; if ( obj.each ) { obj.each(function(index,item){ images.create(item); }); return; } var image = images.prepare(obj); if ( !image ) { window.console.error('We dont know what we have:', obj, image); } else { images.push(image); } return images; }; } else if ( typeof options.files === 'object' ) { // We have custom files // Prepend baseurl to files options.files = prepend(options.files, this.baseurl); } else { // Don't have any files, so no need to perform domReady domReady = false; } // ------------------- // Apply options for ( var i in this.options ) { // Cycle through the options var name = this.options[i]; if ( (typeof options[name] === 'object') && (typeof this[name] === 'object') ) { // We have a group like text or files this[name] = $.extend(true, this[name], options[name]); } else if ( typeof options[name] !== 'undefined' ) { // We have that option, so apply it this[name] = options[name]; } } delete i; // ------------------- // Figure out what to do // Handle IE6 if ( initial && navigator.userAgent.indexOf('MSIE 6') >= 0 ) { // Is IE6 this.ie6 = true; } else { // We are not IE6 this.ie6 = false; } // ------------------- // Handle our DOM if ( domReady || typeof options.download_link !== 'undefined' || typeof options.colorBlend !== 'undefined' || typeof options.files === 'object' || typeof options.text === 'object' || typeof options.show_linkback !== 'undefined' || typeof options.scroll_with !== 'undefined' ) { // We have reason to handle the dom $(function() { // DOM is ready, so fire our DOM handler $.Lightbox.domReady(); }); } // ------------------- // Finish Up // All good return true; }, domReady: function ( ) { // ------------------- // Include resources // Grab resources var bodyEl = document.getElementsByTagName($.browser.safari ? 'head' : 'body')[0]; var stylesheets = this.files.styles; var scripts = this.files.scripts; // colorBlend if ( this.colorBlend === true && typeof $.colorBlend === 'undefined' ) { // Force colorBlend this.colorBlend = true; // Leave file in place to be loaded } else { // We either have colorBlend or we don't this.colorBlend = typeof $.colorBlend !== 'undefined'; // Remove colorBlend file delete scripts.colorBlend; } // Include stylesheets for ( stylesheet in stylesheets ) { var linkEl = document.createElement('link'); linkEl.type = 'text/css'; linkEl.rel = 'stylesheet'; linkEl.media = 'screen'; linkEl.href = stylesheets[stylesheet]; linkEl.id = 'lightbox-stylesheet-'+stylesheet.replace(/[^a-zA-Z0-9]/g, ''); $('#'+linkEl.id).remove(); bodyEl.appendChild(linkEl); } // Include javascripts delete scripts.lightbox; // prevent us from including ourself for ( script in scripts ) { var scriptEl = document.createElement('script'); scriptEl.type = 'text/javascript'; scriptEl.src = scripts[script]; scriptEl.id = 'lightbox-script-'+script.replace(/[^a-zA-Z0-9]/g, ''); $('#'+scriptEl.id).remove(); bodyEl.appendChild(scriptEl); } // Cleanup delete scripts; delete stylesheets; delete bodyEl; // ------------------- // Append display // Append markup $('#lightbox,#lightbox-overlay').remove(); $('body').append(''); // Update Boxes - for some crazy reason this has to be before the hide in safari and konqueror this.resizeBoxes(); this.repositionBoxes(); // Hide $('#lightbox,#lightbox-overlay,#lightbox-overlay-text-interact').hide(); // ------------------- // Browser specifics // Handle IE6 if ( this.ie6 && this.ie6_support ) { // Support IE6 // IE6 does not support fixed positioning so absolute it // ^ This is okay as we disable scrolling $('#lightbox-overlay').css({ position: 'absolute', top: '0px', left: '0px' }); } // ------------------- // Preload Images // Cycle and preload $.each(this.files.images, function() { // Proload the image var preloader = new Image(); preloader.onload = function() { preloader.onload = null; preloader = null; }; preloader.src = this; }); // ------------------- // Apply events // If the window resizes, act appropriatly $(window).unbind('resize').resize(function () { // The window has been resized $.Lightbox.resizeBoxes('resized'); }); // If the window scrolls, act appropriatly if ( this.scroll === 'follow' ) { // We want to $(window).scroll(function () { // The window has scrolled $.Lightbox.repositionBoxes(); }); } // Prev $('#lightbox-nav-btnPrev').unbind().preventDefault().hover(function() { // over $(this).css({ 'background' : 'url(' + $.Lightbox.files.images.prev + ') left 45% no-repeat' }); },function() { // out $(this).css({ 'background' : 'transparent url(' + $.Lightbox.files.images.blank + ') no-repeat' }); }).lastclick(function() { $.Lightbox.showImage('prev'); return false; }); // Next $('#lightbox-nav-btnNext').unbind().preventDefault().hover(function() { // over $(this).css({ 'background' : 'url(' + $.Lightbox.files.images.next + ') right 45% no-repeat' }); },function() { // out $(this).css({ 'background' : 'transparent url(' + $.Lightbox.files.images.blank + ') no-repeat' }); }).lastclick(function() { $.Lightbox.showImage('next'); return false; }); // Help if ( this.show_linkback ) { // Linkback exists so add handler $('#lightbox-overlay-text-about a').preventDefault().lastclick(function(){window.open($.Lightbox.text.about.link); return false;}); } $('#lightbox-overlay-text-close').unbind().hover( function(){ $('#lightbox-overlay-text-interact').fadeIn(); }, function(){ $('#lightbox-overlay-text-interact').fadeOut(); } ); // Image link if ( this.download_link ) { $('#lightbox-caption-title').preventDefault().lastclick(function(){window.open($(this).attr('href')); return false;}); } // Assign close clicks $('#lightbox-overlay, #lightbox, #lightbox-loading-link, #lightbox-btnClose').unbind().preventDefault().lastclick(function() { $.Lightbox.finish(); return false; }); // ------------------- // Finish Up // Relify if ( this.auto_relify ) { // We want to relify, no the user this.relify(); } // All good return true; }, relify: function ( ) { // Create event // var groups = {}; var groups_n = 0; var orig_rel = this.rel; // Create the groups $.each($('[rel*='+orig_rel+']'), function(index, obj){ // Get the group var rel = $(obj).attr('rel'); // Are we really a group if ( rel === orig_rel ) { // We aren't rel = groups_n; // we are individual } // Does the group exist if ( typeof groups[rel] === 'undefined' ) { // Make the group groups[rel] = []; groups_n++; } // Append the image groups[rel].push(obj); }); // Lightbox groups $.each(groups, function(index, group){ $(group).lightbox(); }); // Done return true; }, init: function ( image, images ) { // Init a batch of lightboxes // Establish images if ( typeof images === 'undefined' ) { images = image; image = 0; } // Clear this.images.clear(); // Add images this.images.create(images); // Do we need to bother if ( this.images.isEmpty() ) { // No images window.console.warn('WARNING', 'Lightbox started, but no images: ', image, images); return false; } // Set current if ( !this.images.current(image) ) { // No images window.console.warn('WARNING', 'Could not find current image: ', image, this.images); return false; } // Done return true; }, start: function ( ) { // Display the lightbox // We are alive this.visible = true; // Adjust scrolling if ( this.scroll === 'disable' ) { // $(document.body).css('overflow', 'hidden'); } // Fix attention seekers $('embed, object, select').css('visibility', 'hidden');//.hide(); - don't use this, give it a go, find out why! // Resize the boxes appropriatly this.resizeBoxes('general'); // Reposition the Boxes this.repositionBoxes({'speed':0}); // Hide things $('#lightbox-infoFooter').hide(); // we hide this here because it makes the display smoother $('#lightbox-image,#lightbox-nav,#lightbox-nav-btnPrev,#lightbox-nav-btnNext,#lightbox-infoBox').hide(); // Display the boxes $('#lightbox-overlay').css('opacity',this.opacity).fadeIn(400, function(){ // Show the lightbox $('#lightbox').fadeIn(300); // Display first image if ( !$.Lightbox.showImage() ) { $.Lightbox.finish(); return false; } }); // All done return true; }, finish: function ( ) { // Get rid of lightbox // Hide lightbox $('#lightbox').hide(); $('#lightbox-overlay').fadeOut(function() { $('#lightbox-overlay').hide(); }); // Fix attention seekers $('embed, object, select').css({ 'visibility' : 'visible' });//.show(); // Kill current image this.images.reset(); // Adjust scrolling if ( this.scroll === 'disable' ) { // $(document.body).css('overflow', 'visible'); } // We are dead this.visible = false; }, resizeBoxes: function ( type ) { // Resize the boxes // Used on transition or window resize // Resize Overlay if ( type !== 'transition' ) { // We don't care for transition var $body = $(this.ie6 ? document.body : document); $('#lightbox-overlay').css({ width: $body.width(), height: $body.height() }); delete $body; } // Handle cases switch ( type ) { case 'general': // general resize (start of lightbox) return true; break; case 'resized': // window was resized if ( this.auto_resize === false ) { // Stop // Reposition this.repositionBoxes({'nHeight':nHeight, 'speed':this.speed}); return true; } case 'transition': // transition between images default: // unknown break; } // Get image var image = this.images.current(); if ( !image || !image.width || !this.visible ) { // No image or no visible lightbox, so we don't care //window.console.warn('A resize occured while no image or no lightbox...'); return false; } // Resize image box // i:image, w:window, b:box, c:current, n:new, d:difference // Get image dimensions var iWidth = image.width; var iHeight = image.height; // Get window dimensions var wWidth = $(window).width(); var wHeight = $(window).height(); // Check if we are in size // Lightbox can take up 4/5 of size if ( this.auto_resize !== false ) { // We want to auto resize var maxWidth = Math.floor(wWidth*(4/5)); var maxHeight = Math.floor(wHeight*(4/5)); var resizeRatio; while ( iWidth > maxWidth || iHeight > maxHeight ) { // We need to resize if ( iWidth > maxWidth ) { // Resize width, then height proportionally resizeRatio = maxWidth/iWidth; iWidth = maxWidth; iHeight = Math.floor(iHeight*resizeRatio); } if ( iHeight > maxHeight ) { // Resize height, then width proportionally resizeRatio = maxHeight/iHeight; iHeight = maxHeight; iWidth = Math.floor(iWidth*resizeRatio); } } } // Get current width and height var cWidth = $('#lightbox-imageBox').width(); var cHeight = $('#lightbox-imageBox').height(); // Get the width and height of the selected image plus the padding // padding*2 for both sides (left+right || top+bottom) var nWidth = (iWidth + (this.padding * 2)); var nHeight = (iHeight + (this.padding * 2)); // Diferences var dWidth = cWidth - nWidth; var dHeight = cHeight - nHeight; // Set the overlay buttons height and the infobox width // Other dimensions specified by CSS $('#lightbox-nav-btnPrev,#lightbox-nav-btnNext').css('height', nHeight); $('#lightbox-infoBox').css('width', nWidth); // Handle final action if ( type === 'transition' ) { // We are transition // Do we need to wait? (just a nice effect to counter the other if ( dWidth === 0 && dHeight === 0 ) { // We are the same size this.pause(this.speed/3); this.showImage(null, 3); } else { // We are not the same size // Animate $('#lightbox-image').width(iWidth).height(iHeight); $('#lightbox-imageBox').animate({width: nWidth, height: nHeight}, this.speed, function ( ) { $.Lightbox.showImage(null, 3); } ); } } else { // We are a resize // Animate Lightbox $('#lightbox-image').animate({width:iWidth, height:iHeight}, this.speed); $('#lightbox-imageBox').animate({width: nWidth, height: nHeight}, this.speed); } // Reposition this.repositionBoxes({'nHeight':nHeight, 'speed':this.speed}); // Done return true; }, repositioning: false, // are we currently repositioning reposition_failsafe: false, // failsafe repositionBoxes: function ( options ) { // Prepare if ( this.repositioning ) { // Already here this.reposition_failsafe = true; return null; } this.repositioning = true; // Options options = $.extend({}, options); options.callback = options.callback || null; options.speed = options.speed || 'slow'; // Get page scroll var pageScroll = this.getPageScroll(); // Figure it out // alert($(window).height()+"\n"+$(document.body).height()+"\n"+$(document).height()); // var nHeight = options.nHeight || parseInt($('#lightbox').height(),10) || $(document).height()/3; var nHeight = options.nHeight || parseInt($('#lightbox').height(),10); // Display lightbox in center // var nTop = pageScroll.yScroll + ($(document.body).height() /*frame height*/ - nHeight) / 2.5; var nTop = pageScroll.yScroll + ($(window).height() /*frame height*/ - nHeight) / 2.5; var nLeft = pageScroll.xScroll; // Animate var css = { left: nLeft, top: nTop }; if (options.speed) { $('#lightbox').animate(css, 'slow', function(){ if ( $.Lightbox.reposition_failsafe ) { // Fire again $.Lightbox.repositioning = $.Lightbox.reposition_failsafe = false; $.Lightbox.repositionBoxes(options); } else { // Done $.Lightbox.repositioning = false; if ( options.callback ) { // Call the user callback options.callback(); } } }); } else { $('#lightbox').css(css); if ( this.reposition_failsafe ) { // Fire again this.repositioning = this.reposition_failsafe = false; this.repositionBoxes(options); } else { // Done this.repositioning = false; } } // Done return true; }, visible: false, showImage: function ( image, step ){ // Default step step = step || 1; // Make the image the current image, or get the current image = this.images.current(image) || this.images.get('first',true); if ( !image ) { return; } // What do we need to do switch ( step ) { // --------------------------------- // We need to preload case 1: // Disable keyboard nav this.KeyboardNav_Disable(); // Show the loading image $('#lightbox-loading').show(); // Hide things $('#lightbox-image,#lightbox-nav,#lightbox-nav-btnPrev,#lightbox-nav-btnNext,#lightbox-infoBox').hide(); // Remove show info events $('#lightbox-imageBox').unbind(); // ^ Why? Because otherwise when the image is changing, the info pops out, not good! // Check if we need to preload if ( image.width && image.height ) { // We don't // Continue to next step this.showImage(null, 2); } else { // We do // Create preloader var preloader = new Image(); // Set callback preloader.onload = function() { // We have preloaded the image // Update image with our new info image.width = preloader.width; image.height = preloader.height; // Continue to next step $.Lightbox.showImage(null, 2); // Kill preloader preloader.onload = null; preloader = null; }; // Start preload preloader.src = image.src; } // Done break; // --------------------------------- // Resize the container case 2: // Apply image changes $('#lightbox-image').attr('src', image.src); // Set container border (Moved here for Konqueror fix - Credits to Blueyed) if ( typeof this.padding === 'undefined' || this.padding === null || isNaN(this.padding) ) { // Autodetect this.padding = parseInt($('#lightbox-imageContainer').css('padding-left'), 10) || parseInt($('#lightbox-imageContainer').css('padding'), 10) || 0; } // Use colorBlend? if ( this.colorBlend ) { // We have colorBlend // Background $('#lightbox-overlay').animate({'backgroundColor':image.color}, this.speed*2); // Border $('#lightbox-imageBox').css('borderColor', image.color); } // Resize boxes this.resizeBoxes('transition'); // ^ contains callback to next step // Done break; // --------------------------------- // Display the image case 3: // Hide loading $('#lightbox-loading').hide(); // Animate image $('#lightbox-image').fadeIn(this.speed*1.5, function() { $.Lightbox.showImage(null, 4); }); // Start the proloading of other images this.preloadNeighbours(); // Fire custom handler show if ( this.handlers.show !== null ) { // Fire it this.handlers.show(image); } // Done break; // --------------------------------- // Set image info / Set navigation case 4: // --------------------------------- // Set image info // Hide and set image info var $title = $('#lightbox-caption-title').html(image.title || 'Untitled'); if ( this.download_link ) { $title.attr('href', this.download_link ? image.src : ''); } delete $title; $('#lightbox-caption-seperator').html(image.description ? ': ' : ''); $('#lightbox-caption-description').html(image.description || ' '); // If we have a set, display image position if ( this.images.length > 1 ) { // Display $('#lightbox-currentNumber').html(this.text.image + ' ' + ( this.images.index + 1 ) + ' ' + this.text.of + ' ' + this.images.length); } else { // Empty $('#lightbox-currentNumber').html(' '); } // --------------------------------- // Info events // Apply event $('#lightbox-imageBox').unbind('mouseover').mouseover(function(){ $('#lightbox-infoBox:not(:visible)').stop().slideDown('fast'); }); // Apply event $('#lightbox-infoBox').unbind('mouseover').mouseover(function(){ $('#lightbox-infoFooter:not(:visible)').stop().slideDown('fast'); }); // Forced show? if ( this.show_extended_info === true ) { // Force show $('#lightbox-imageBox').trigger('mouseover'); $('#lightbox-infoBox').trigger('mouseover'); } else if ( this.show_info === true ) { // Force show $('#lightbox-imageBox').trigger('mouseover'); } // --------------------------------- // Set navigation // Instead to define this configuration in CSS file, we define here. And it's need to IE. Just. $('#lightbox-nav-btnPrev, #lightbox-nav-btnNext').css({ 'background' : 'transparent url(' + this.files.images.blank + ') no-repeat' }); // If not first, show previous button if ( !this.images.isFirst() ) { // Not first, show button $('#lightbox-nav-btnPrev').show(); } // If not last, show next button if ( !this.images.isLast() ) { // Not first, show button $('#lightbox-nav-btnNext').show(); } // Make navigation current / show it $('#lightbox-nav').show(); // Enable keyboard navigation this.KeyboardNav_Enable(); // Done break; // --------------------------------- // Error handling default: window.console.error('Don\'t know what to do: ', image, step); return this.showImage(image, 1); // break; } // All done return true; }, preloadNeighbours: function ( ) { // Preload all neighbour images // Do we need to do this? if ( this.images.isSingle() || this.images.isEmpty() ) { return true; } // Get current image var image = this.images.current(); var index = this.images.index; if ( !image ) { return image; } var objNext; // Load previous var prev = this.images.prev(); if ( prev ) { objNext = new Image(); objNext.src = prev.src; } this.images.setIndex(index); // reset // Load next var next = this.images.next(); if ( next ) { objNext = new Image(); objNext.src = next.src; } this.images.setIndex(index); // reset }, // -------------------------------------------------- // Things we don't really care about KeyboardNav_Enable: function ( ) { $(document).keydown(function(objEvent) { $.Lightbox.KeyboardNav_Action(objEvent); }); }, KeyboardNav_Disable: function ( ) { $(document).unbind('keydown'); }, KeyboardNav_Action: function ( objEvent ) { // Prepare objEvent = objEvent || window.event; // Get the keycode var keycode = objEvent.keyCode; var escapeKey = objEvent.DOM_VK_ESCAPE /* moz */ || 27; // Get key var key = String.fromCharCode(keycode).toLowerCase(); // Close? if ( key === this.keys.close || keycode === escapeKey ) { return $.Lightbox.finish(); } // Prev? if ( key === this.keys.prev || keycode === 37 ) { // We want previous return $.Lightbox.showImage('prev'); } // Next? if ( key === this.keys.next || keycode === 39 ) { // We want next return $.Lightbox.showImage('next'); } // Unknown return true; }, getPageScroll: function ( ) { var xScroll, yScroll; if (self.pageYOffset) { // Some browser yScroll = self.pageYOffset; xScroll = self.pageXOffset; } else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict yScroll = document.documentElement.scrollTop; xScroll = document.documentElement.scrollLeft; } else if (document.body) { // All other browsers yScroll = document.body.scrollTop; xScroll = document.body.scrollLeft; } var arrayPageScroll = {'xScroll':xScroll,'yScroll':yScroll}; return arrayPageScroll; }, pause: function ( ms ) { var date = new Date(); var curDate = null; do { curDate = new Date(); } while ( curDate - date < ms); } }); // We have finished extending/defining our LightboxClass // -------------------------------------------------- // Finish up // Instantiate if ( typeof $.Lightbox === 'undefined' ) { // $.Lightbox = new $.LightboxClass(); } // Finished definition })(jQuery); // We are done with our plugin, so lets call it with jQuery as the argument