1/** 2 * jQuery Lightbox 3 * @author Warren Krewenki 4 * 5 * This package is distributed under the BSD license. 6 * For full license information, see LICENSE.TXT 7 * 8 * Based on Lightbox 2 by Lokesh Dhakar (http://www.huddletogether.com/projects/lightbox2/) 9 * 10 * 11 **/ 12 13(function($) { 14 $.fn.lightbox = function(options) { 15 // build main options 16 var opts = $.extend({}, $.fn.lightbox.defaults, options); 17 18 $(window).resize(resizeOverlayToFitWindow); 19 20 return $(this).on(opts.triggerEvent,function(){ 21 // initialize the lightbox 22 initialize(); 23 showLightbox(this); 24 return false; 25 }); 26 /* 27 # Initialize the lightbox by creating our html and reading some image data 28 # This method is called by the constructor after any click events trigger it 29 # You will never call it by itself, to my knowledge. 30 */ 31 function initialize() { 32 $('#overlay, #lightbox').remove(); 33 opts.inprogress = false; 34 35 // if jsonData, build the imageArray from data provided in JSON format 36 if (opts.jsonData && opts.jsonData.length > 0) { 37 var parser = opts.jsonDataParser ? opts.jsonDataParser : $.fn.lightbox.parseJsonData; 38 opts.imageArray = []; 39 opts.imageArray = parser(opts.jsonData); 40 } 41 42 var outerImage = '<div id="outerImageContainer"><div id="imageContainer"><iframe id="lightboxIframe"></iframe><img id="lightboxImage" /><div id="hoverNav"><a href="javascript://" title="' + opts.strings.prevLinkTitle + '" id="prevLink"></a><a href="javascript://" id="nextLink" title="' + opts.strings.nextLinkTitle + '"></a></div><div id="loading"><a href="javascript://" id="loadingLink"><img src="'+opts.fileLoadingImage+'"></a></div></div></div>'; 43 var imageData = '<div id="imageDataContainer" class="clearfix"><div id="imageData"><div id="imageDetails"><span id="caption"></span><span id="numberDisplay"></span></div><div id="bottomNav">'; 44 45 if (opts.displayHelp) { 46 imageData += '<span id="helpDisplay">' + opts.strings.help + '</span>'; 47 } 48 49 imageData += '<a href="javascript://" id="bottomNavClose" title="' + opts.strings.closeTitle + '"><img src="'+opts.fileBottomNavCloseImage+'"></a></div></div></div>'; 50 51 var string; 52 53 if (opts.navbarOnTop) { 54 string = '<div id="overlay"></div><div id="lightbox">' + imageData + outerImage + '</div>'; 55 $("body").append(string); 56 $("#imageDataContainer").addClass('ontop'); 57 } else { 58 string = '<div id="overlay"></div><div id="lightbox">' + outerImage + imageData + '</div>'; 59 $("body").append(string); 60 } 61 62 if (opts.imageScroll === true) { 63 $('#lightbox').css('position', 'fixed') 64 } 65 66 $("#overlay, #lightbox").click(function(){ end(); }).hide(); 67 $("#loadingLink, #bottomNavClose").click(function(){ end(); return false;}); 68 $('#outerImageContainer').width(opts.widthCurrent).height(opts.heightCurrent); 69 $('#imageDataContainer').width(opts.widthCurrent); 70 71 if (!opts.imageClickClose) { 72 $("#lightboxImage").click(function(){ return false; }); 73 $("#hoverNav").click(function(){ return false; }); 74 } 75 76 return true; 77 }; 78 79 /* 80 # Get the document and window width/heigh 81 # 82 # Examples 83 # 84 # getPageSize() 85 # # => [1024,768,1024,768] 86 # 87 # Returns a numerically indexed array of document width/height and window width/height 88 */ 89 function getPageSize() { 90 var jqueryPageSize = new Array($(document).width(),$(document).height(), $(window).width(), $(window).height()); 91 return jqueryPageSize; 92 }; 93 94 function getPageScroll() { 95 var xScroll, yScroll; 96 97 if (self.pageYOffset) { 98 yScroll = self.pageYOffset; 99 xScroll = self.pageXOffset; 100 } else if (document.documentElement && (document.documentElement.scrollTop || document.documentElement.scrollLeft)){ // Explorer 6 Strict, Firefox 101 yScroll = document.documentElement.scrollTop; 102 xScroll = document.documentElement.scrollLeft; 103 } else if (document.body) {// all other Explorers 104 yScroll = document.body.scrollTop; 105 xScroll = document.body.scrollLeft; 106 } 107 108 var arrayPageScroll = new Array(xScroll,yScroll); 109 return arrayPageScroll; 110 }; 111 112 /* 113 # Deploy the sexy overlay and display the lightbox 114 # 115 # imageObject - the jQuery object passed via the click event in the constructor 116 # 117 # Examples 118 # 119 # showLightbox($('#CheesusCrust')) 120 # 121 # Returns a boolean true, because it's got nothing else to return. It should give visual feedback when run 122 */ 123 function showLightbox(imageObject) { 124 /** 125 * select, embed and object tags render over the lightbox in some browsers 126 * Right now, the best way to fix it is to hide them, but that can trigger reloading of some flash content 127 * I don't have a better fix for this right now, but I want ot leave this comment here so you and I both 128 * know that i'm aware of it, and I would love to fix it, if you have any suggestions. 129 **/ 130 $("select, embed, object").hide(); 131 132 // Resize and display the sexy, sexy overlay. 133 resizeOverlayToFitWindow(); 134 $("#overlay").hide().css({ opacity : opts.overlayOpacity }).fadeIn(); 135 imageNum = 0; 136 137 // if data is not provided by jsonData parameter 138 if (!opts.jsonData) { 139 opts.imageArray = []; 140 // if image is NOT part of a set.. 141 if ((!getImageSetOf(imageObject) || (getImageSetOf(imageObject) == '')) && !opts.allSet) { 142 // add single image to Lightbox.imageArray 143 opts.imageArray.push(new Array(imageObject.href, opts.displayTitle ? imageObject.title : '')); 144 } else { 145 // if image is part of a set.. 146 $("a").each(function() { 147 if(this.href && (getImageSetOf(this) == getImageSetOf(imageObject))) { 148 opts.imageArray.push(new Array(this.href, opts.displayTitle ? this.title : '')); 149 } 150 }); 151 } 152 } 153 154 if (opts.imageArray.length > 1) { 155 for (i = 0; i < opts.imageArray.length; i++) { 156 for (j = opts.imageArray.length - 1; j > i; j--) { 157 if (opts.imageArray[i][0] == opts.imageArray[j][0]) { 158 opts.imageArray.splice(j, 1); 159 } 160 } 161 } 162 163 while (opts.imageArray[imageNum][0] != imageObject.href) { 164 imageNum++; 165 } 166 } 167 168 // calculate top and left offset for the lightbox 169 var arrayPageScroll = getPageScroll(); 170 var lightboxTop = arrayPageScroll[1] + ($(window).height() / 10); 171 var lightboxLeft = arrayPageScroll[0]; 172 $('#lightbox').css({top: lightboxTop+'px', left: lightboxLeft+'px'}).show(); 173 174 if (!opts.slideNavBar) { 175 $('#imageData').hide(); 176 } 177 178 changeImage(imageNum); 179 }; 180 181 function changeImage(imageNum) { 182 if (opts.inprogress == false) { 183 opts.inprogress = true; 184 185 // update global var
186 opts.activeImage = imageNum; 187 188 // hide elements during transition 189 $('#loading').show(); 190 $('#lightboxImage, #hoverNav, #prevLink, #nextLink').hide(); 191 192 // delay preloading image until navbar will slide up 193 if (opts.slideNavBar) { 194 $('#imageDataContainer').hide(); 195 $('#imageData').hide(); 196 } 197 doChangeImage(); 198 } 199 }; 200 201 function doChangeImage() { 202 var imgPreloader = new Image(); 203 204 // once image is preloaded, resize image container 205 imgPreloader.onload = function() { 206 var newWidth = imgPreloader.width; 207 var newHeight = imgPreloader.height; 208 209 if (opts.scaleImages) { 210 newWidth = parseInt(opts.xScale * newWidth); 211 newHeight = parseInt(opts.yScale * newHeight); 212 } 213 214 if (opts.fitToScreen) { 215 var arrayPageSize = getPageSize(); 216 var ratio; 217 var initialPageWidth = arrayPageSize[2] - 2 * opts.borderSize; 218 var initialPageHeight = arrayPageSize[3] - 200; 219 220 var dI = initialPageWidth/initialPageHeight; 221 var dP = imgPreloader.width/imgPreloader.height; 222 223 if ((imgPreloader.height > initialPageHeight) || (imgPreloader.width > initialPageWidth)) { 224 if (dI > dP) { 225 newWidth = parseInt((initialPageHeight/imgPreloader.height) * imgPreloader.width); 226 newHeight = initialPageHeight; 227 } else { 228 newHeight = parseInt((initialPageWidth/imgPreloader.width) * imgPreloader.height); 229 newWidth = initialPageWidth; 230 } 231 } 232 } 233 234 $('#lightboxImage'). 235 attr('src', opts.imageArray[opts.activeImage][0]). 236 width(newWidth). 237 height(newHeight); 238 239 resizeImageContainer(newWidth, newHeight); 240 }; 241 242 imgPreloader.src = opts.imageArray[opts.activeImage][0]; 243 }; 244 245 function end() { 246 disableKeyboardNav(); 247 $('#lightbox').hide(); 248 $('#overlay').fadeOut(); 249 $('select, object, embed').show(); 250 }; 251 252 function preloadNeighborImages() { 253 var preloadPrevImage, preloadNextImage; 254 if (opts.loopImages && opts.imageArray.length > 1) { 255 preloadNextImage = new Image(); 256 preloadNextImage.src = opts.imageArray[(opts.activeImage == (opts.imageArray.length - 1)) ? 0 : opts.activeImage + 1][0]; 257 258 preloadPrevImage = new Image(); 259 preloadPrevImage.src = opts.imageArray[(opts.activeImage == 0) ? (opts.imageArray.length - 1) : opts.activeImage - 1][0]; 260 } else { 261 if ((opts.imageArray.length - 1) > opts.activeImage) { 262 preloadNextImage = new Image(); 263 preloadNextImage.src = opts.imageArray[opts.activeImage + 1][0]; 264 } 265 if (opts.activeImage > 0) { 266 preloadPrevImage = new Image(); 267 preloadPrevImage.src = opts.imageArray[opts.activeImage - 1][0]; 268 } 269 } 270 }; 271 272 function resizeImageContainer(imgWidth, imgHeight) { 273 // get current width and height 274 opts.widthCurrent = $("#outerImageContainer").outerWidth(); 275 opts.heightCurrent = $("#outerImageContainer").outerHeight(); 276 277 // get new width and height 278 var widthNew = Math.max(350, imgWidth + (opts.borderSize * 2)); 279 var heightNew = (imgHeight + (opts.borderSize * 2)); 280 281 // calculate size difference between new and old image, and resize if necessary 282 wDiff = opts.widthCurrent - widthNew; 283 hDiff = opts.heightCurrent - heightNew; 284 285 $('#imageDataContainer').animate({width: widthNew},opts.resizeSpeed,'linear'); 286 $('#outerImageContainer').animate({width: widthNew},opts.resizeSpeed,'linear', function() { 287 $('#outerImageContainer').animate({height: heightNew},opts.resizeSpeed,'linear', function() { 288 showImage(); 289 }); 290 }); 291 292 afterTimeout = function () { 293 $('#prevLink').height(imgHeight); 294 $('#nextLink').height(imgHeight); 295 }; 296 297 // if new and old image are same size and no scaling transition is necessary, 298 // do a quick pause to prevent image flicker. 299 if((hDiff == 0) && (wDiff == 0)) { 300 setTimeout(afterTimeout, 100); 301 } else { 302 // otherwise just trigger the height and width change 303 afterTimeout(); 304 } 305 306 }; 307 308 function showImage() { 309 $('#loading').hide(); 310 $('#lightboxImage').fadeIn("fast"); 311 updateDetails(); 312 preloadNeighborImages(); 313 314 opts.inprogress = false;
315 }; 316 317 function updateDetails() { 318 $('#numberDisplay').html(''); 319 320 if (opts.imageArray[opts.activeImage][1]) { 321 $('#caption').html(opts.imageArray[opts.activeImage][1]).show(); 322 } 323 324 // if image is part of set display 'Image x of x' 325 if (opts.imageArray.length > 1) { 326 var nav_html; 327 328 nav_html = opts.strings.image + (opts.activeImage + 1) + opts.strings.of + opts.imageArray.length; 329 330 if (opts.displayDownloadLink) { 331 nav_html += "<a href='" + opts.imageArray[opts.activeImage][0] + "'>" + opts.strings.download + "</a>"; 332 } 333 334 if (!opts.disableNavbarLinks) { 335 // display previous / next text links 336 if ((opts.activeImage) > 0 || opts.loopImages) { 337 nav_html = '<a title="' + opts.strings.prevLinkTitle + '" href="#" id="prevLinkText">' + opts.strings.prevLinkText + "</a>" + nav_html; 338 } 339 340 if (((opts.activeImage + 1) < opts.imageArray.length) || opts.loopImages) { 341 nav_html += '<a title="' + opts.strings.nextLinkTitle + '" href="#" id="nextLinkText">' + opts.strings.nextLinkText + "</a>"; 342 } 343 } 344 345 $('#numberDisplay').html(nav_html).show(); 346 } 347 348 if (opts.slideNavBar) { 349 $("#imageData").slideDown(opts.navBarSlideSpeed); 350 } else { 351 $("#imageData").show(); 352 } 353 354 resizeOverlayToFitWindow(); 355 updateNav(); 356 }; 357 358 /* 359 # Resize the sexy overlay to fit the constraints of your current viewing environment 360 # 361 # This should now happen whenever a window is resized, so you should always see a full overlay 362 */ 363 function resizeOverlayToFitWindow(){ 364 $('#overlay').css({width: $(document).width(), height: $(document).height()}); 365 // ^^^^^^^ <- sexy! 366 }; 367 368 function updateNav() { 369 if (opts.imageArray.length > 1) { 370 $('#hoverNav').show(); 371 372 // if loopImages is true, always show next and prev image buttons 373 if(opts.loopImages) { 374 $('#prevLink,#prevLinkText').show().click(function() { 375 changeImage((opts.activeImage == 0) ? (opts.imageArray.length - 1) : opts.activeImage - 1); 376 return false; 377 }); 378 379 $('#nextLink,#nextLinkText').show().click(function() { 380 changeImage((opts.activeImage == (opts.imageArray.length - 1)) ? 0 : opts.activeImage + 1); 381 return false; 382 }); 383 384 } else { 385 // if not first image in set, display prev image button 386 if(opts.activeImage != 0) { 387 $('#prevLink,#prevLinkText').show().click(function() { 388 changeImage(opts.activeImage - 1); 389 return false; 390 }); 391 } 392 393 // if not last image in set, display next image button 394 if(opts.activeImage != (opts.imageArray.length - 1)) { 395 $('#nextLink,#nextLinkText').show().click(function() { 396 changeImage(opts.activeImage +1); 397 return false; 398 }); 399 } 400 } 401 402 } 403 enableKeyboardNav(); 404 405 }; 406 407 function keyboardAction(e) { 408 var o = e.data.opts; 409 var keycode = e.keyCode; 410 var escapeKey = 27; 411 412 var key = String.fromCharCode(keycode).toLowerCase(); 413 414 // close lightbox 415 if ((key == 'x') || (key == 'o') || (key == 'c') || (keycode == escapeKey)) { 416 end(); 417 418 // display previous image 419 } else if ((key == 'p') || (keycode == 37)) { 420 if(o.loopImages) { 421 disableKeyboardNav(); 422 changeImage((o.activeImage == 0) ? (o.imageArray.length - 1) : o.activeImage - 1); 423 } else if (o.activeImage != 0) { 424 disableKeyboardNav(); 425 changeImage(o.activeImage - 1); 426 } 427 428 // display next image 429 } else if ((key == 'n') || (keycode == 39)) { 430 if (opts.loopImages) { 431 disableKeyboardNav(); 432 changeImage((o.activeImage == (o.imageArray.length - 1)) ? 0 : o.activeImage + 1); 433 } else if (o.activeImage != (o.imageArray.length - 1)) { 434 disableKeyboardNav(); 435 changeImage(o.activeImage + 1); 436 } 437 } 438 }; 439 440 function enableKeyboardNav() { 441 $(document).bind('keydown', {opts: opts}, keyboardAction); 442 }; 443 444 function disableKeyboardNav() { 445 $(document).unbind('keydown'); 446 }; 447 448 function getImageSetOf(imageObject) { 449 var set_name = imageObject.rel; 450 if (!set_name || set_name == '') { 451 set_name = $(imageObject).attr('data-lightbox-set'); 452 } 453 return set_name; 454 }; 455 }; 456 457 $.fn.lightbox.parseJsonData = function(data) { 458 var imageArray = []; 459 460 $.each(data, function() { 461 imageArray.push(new Array(this.url, this.title)); 462 }); 463 464 return imageArray; 465 }; 466 467 $.fn.lightbox.defaults = { 468 triggerEvent: "click", 469 allSet: false, 470 fileLoadingImage: '/images/loading.gif', 471 fileBottomNavCloseImage: '/Portals/_default/skins/arona/images/close.gif', 472 overlayOpacity: 0.6, 473 borderSize: 10, 474 imageArray: new Array, 475 activeImage: null, 476 imageScroll: false, 477 inprogress: false, 478 resizeSpeed: 350, 479 widthCurrent: 250, 480 heightCurrent: 250, 481 scaleImages: false, 482 xScale: 1, 483 yScale: 1, 484 displayTitle: true, 485 navbarOnTop: false, 486 displayDownloadLink: false, 487 slideNavBar: false, 488 navBarSlideSpeed: 350, 489 displayHelp: false, 490 strings: { 491 help: ' \u2190 / P - imagen anterior\u00a0\u00a0\u00a0\u00a0\u2192 / N - imagen siguiente\u00a0\u00a0\u00a0\u00a0ESC / X - close image gallery', 492 prevLinkTitle: 'imagen anterior', 493 nextLinkTitle: 'imagen siguiente', 494 prevLinkText: '« Anterior', 495 nextLinkText: 'Siguiente »', 496 closeTitle: 'cerrar galerÃa de imagenes', 497 image: 'Imagen ', 498 of: ' de ', 499 download: 'Descargar' 500 }, 501 fitToScreen: false, 502 disableNavbarLinks: false, 503 loopImages: false, 504 imageClickClose: true, 505 jsonData: null, 506 jsonDataParser: null 507 }; 508})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.