1/** 2 * jQuery Lightbox 3 * Version 0.5 - 11/29/2007 4 * @author Warren Krewenki 5 * 6 * This package is distributed under the BSD license. 7 * For full license information, see LICENSE.TXT 8 * 9 * Based on Lightbox 2 by Lokesh Dhakar (http://www.huddletogether.com/projects/lightbox2/) 10 * Originally written to make use of the Prototype framework, and Script.acalo.us, now altered to use jQuery. 11 * 12 * 13 **/ 14 15(function($){ 16 17 $.fn.lightbox = function(options){ 18 // build main options 19 var opts = $.extend({}, $.fn.lightbox.defaults, options); 20 21 return this.each(function(){ 22 $(this).click(function(){ 23 // initalize the lightbox 24 initialize(); 25 start(this); 26 return false; 27 }); 28 }); 29 30 /** 31 * initalize() 32 * 33 * @return void 34 * @author Warren Krewenki 35 */ 36 37 function initialize() { 38 $('#overlay').remove(); 39 $('#lightbox').remove(); 40 opts.inprogress = false; 41 42 // if jsonData, build the imageArray from data provided in JSON format 43 if(opts.jsonData && opts.jsonData.length > 0) { 44 var parser = opts.jsonDataParser ? opts.jsonDataParser : $.fn.lightbox.parseJsonData; 45 opts.imageArray = []; 46 opts.imageArray = parser(opts.jsonData); 47 } 48 49 var outerImage = '<div id="outerImageContainer"><div id="imageContainer"><iframe id="lightboxIframe" /><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>'; 50 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">'; 51 52 if (opts.displayHelp) 53 imageData += '<span id="helpDisplay">' + opts.strings.help + '</span>'; 54 55 imageData += '<a href="javascript://" id="bottomNavClose" title="' + opts.strings.closeTitle + '"><img src="'+opts.fileBottomNavCloseImage+'"></a></div></div></div>'; 56 57 var string; 58 59 if (opts.navbarOnTop) { 60 string = '<div id="overlay"></div><div id="lightbox">' + imageData + outerImage + '</div>'; 61 $("body").append(string); 62 $("#imageDataContainer").addClass('ontop'); 63 } else { 64 string = '<div id="overlay"></div><div id="lightbox">' + outerImage + imageData + '</div>'; 65 $("body").append(string); 66 } 67 68 $("#overlay").click(function(){ end(); }).hide(); 69 $("#lightbox").click(function(){ end();}).hide(); 70 $("#loadingLink").click(function(){ end(); return false;}); 71 $("#bottomNavClose").click(function(){ end(); return false; }); 72 $('#outerImageContainer').width(opts.widthCurrent).height(opts.heightCurrent); 73 $('#imageDataContainer').width(opts.widthCurrent); 74 75 if (!opts.imageClickClose) { 76 $("#lightboxImage").click(function(){ return false; }); 77 $("#hoverNav").click(function(){ return false; }); 78 } 79 }; 80 81 function getPageSize() { 82 var jqueryPageSize = new Array($(document).width(),$(document).height(), $(window).width(), $(window).height()); 83 return jqueryPageSize; 84 }; 85 86 function getPageScroll() { 87 var xScroll, yScroll; 88 89 if (self.pageYOffset) { 90 yScroll = self.pageYOffset; 91 xScroll = self.pageXOffset; 92 } else if (document.documentElement && document.documentElement.scrollTop){ // Explorer 6 Strict 93 yScroll = document.documentElement.scrollTop; 94 xScroll = document.documentElement.scrollLeft; 95 } else if (document.body) {// all other Explorers 96 yScroll = document.body.scrollTop; 97 xScroll = document.body.scrollLeft; 98 } 99 100 var arrayPageScroll = new Array(xScroll,yScroll); 101 return arrayPageScroll; 102 }; 103 104 function pause(ms) { 105 var date = new Date(); 106 var curDate = null; 107 do{curDate = new Date();} 108 while(curDate - date < ms); 109 }; 110 111 function start(imageLink) { 112 $("select, embed, object").hide(); 113 var arrayPageSize = getPageSize(); 114 $("#overlay").hide().css({width: '100%', height: arrayPageSize[1]+'px', opacity : opts.overlayOpacity}).fadeIn(); 115 imageNum = 0; 116 117 // if data is not provided by jsonData parameter 118 if(!opts.jsonData) { 119 opts.imageArray = []; 120 // if image is NOT part of a set.. 121 if(!imageLink.rel || (imageLink.rel == '')){ 122 // add single image to Lightbox.imageArray 123 opts.imageArray.push(new Array(imageLink.href, opts.displayTitle ? imageLink.title + imageLink.rev : '')); 124 } else { 125 // if image is part of a set.. 126 $("a").each(function(){ 127 if(this.href && (this.rel == imageLink.rel)){ 128 opts.imageArray.push(new Array(this.href, opts.displayTitle ? this.title + this.rev : '')); 129 } 130 }); 131 } 132 } 133 134 if(opts.imageArray.length > 1) { 135 for(i = 0; i < opts.imageArray.length; i++){ 136 for(j = opts.imageArray.length-1; j>i; j--){ 137 if(opts.imageArray[i][0] == opts.imageArray[j][0]){ 138 opts.imageArray.splice(j,1); 139 } 140 } 141 } 142 while(opts.imageArray[imageNum][0] != imageLink.href) { imageNum++;} 143 } 144 145 // calculate top and left offset for the lightbox 146 var arrayPageScroll = getPageScroll(); 147 var lightboxTop = arrayPageScroll[1] + (arrayPageSize[3] / 10); 148 var lightboxLeft = arrayPageScroll[0]; 149 $('#lightbox').css({top: lightboxTop+'px', left: lightboxLeft+'px'}).show(); 150 151 152 if (!opts.slideNavBar) 153 $('#imageData').hide(); 154 155 changeImage(imageNum); 156 }; 157 158 function changeImage(imageNum) { 159 if(opts.inprogress == false){ 160 opts.inprogress = true; 161 opts.activeImage = imageNum; // update global var 162 163 // hide elements during transition 164 $('#loading').show(); 165 $('#lightboxImage').hide(); 166 $('#hoverNav').hide(); 167 $('#prevLink').hide(); 168 $('#nextLink').hide(); 169 170 if (opts.slideNavBar) { // delay preloading image until navbar will slide up 171 // $('#imageDataContainer').slideUp(opts.navBarSlideSpeed, $.fn.doChangeImage); 172 $('#imageDataContainer').hide(); 173 $('#imageData').hide(); 174 doChangeImage(); 175 } else { 176 doChangeImage(); 177 } 178 } 179 }; 180 181 function doChangeImage() { 182 183 imgPreloader = new Image(); 184 185 // once image is preloaded, resize image container 186 imgPreloader.onload=function(){ 187 var newWidth = imgPreloader.width; 188 var newHeight = imgPreloader.height; 189 190 191 if (opts.fitToScreen) { 192 var arrayPageSize = getPageSize(); 193 var ratio; 194 var initialPageWidth = arrayPageSize[2] - 2 * opts.borderSize; 195 var initialPageHeight = arrayPageSize[3] - 200; 196 197 if (imgPreloader.height > initialPageHeight) 198 { 199 newWidth = parseInt((initialPageHeight/imgPreloader.height) * imgPreloader.width); 200 newHeight = initialPageHeight; 201 } 202 else if (imgPreloader.width > initialPageWidth) 203 { 204 newHeight = parseInt((initialPageWidth/imgPreloader.width) * imgPreloader.height); 205 newWidth = initialPageWidth; 206 } 207 } 208 209 $('#lightboxImage').attr('src', opts.imageArray[opts.activeImage][0]) 210 .width(newWidth).height(newHeight);
211 resizeImageContainer(newWidth, newHeight); 212 }; 213 214 imgPreloader.src = opts.imageArray[opts.activeImage][0]; 215 }; 216 217 function end() { 218 disableKeyboardNav(); 219 $('#lightbox').hide(); 220 $('#overlay').fadeOut(); 221 $('select, object, embed').show(); 222 }; 223 224 function preloadNeighborImages(){ 225 if(opts.loopImages && opts.imageArray.length > 1) { 226 preloadNextImage = new Image(); 227 preloadNextImage.src = opts.imageArray[(opts.activeImage == (opts.imageArray.length - 1)) ? 0 : opts.activeImage + 1][0] 228 229 preloadPrevImage = new Image(); 230 preloadPrevImage.src = opts.imageArray[(opts.activeImage == 0) ? (opts.imageArray.length - 1) : opts.activeImage - 1][0] 231 } else { 232 if((opts.imageArray.length - 1) > opts.activeImage){ 233 preloadNextImage = new Image(); 234 preloadNextImage.src = opts.imageArray[opts.activeImage + 1][0]; 235 } 236 if(opts.activeImage > 0){ 237 preloadPrevImage = new Image(); 238 preloadPrevImage.src = opts.imageArray[opts.activeImage - 1][0]; 239 } 240 } 241 }; 242 243 function resizeImageContainer(imgWidth, imgHeight) { 244 // get current width and height 245 opts.widthCurrent = $("#outerImageContainer").outerWidth(); 246 opts.heightCurrent = $("#outerImageContainer").outerHeight(); 247 248 // get new width and height 249 var widthNew = Math.max(350, imgWidth + (opts.borderSize * 2)); 250 var heightNew = (imgHeight + (opts.borderSize * 2)); 251 252 // scalars based on change from old to new 253 opts.xScale = ( widthNew / opts.widthCurrent) * 100; 254 opts.yScale = ( heightNew / opts.heightCurrent) * 100; 255 256 // calculate size difference between new and old image, and resize if necessary 257 wDiff = opts.widthCurrent - widthNew; 258 hDiff = opts.heightCurrent - heightNew; 259 260 $('#imageDataContainer').animate({width: widthNew},opts.resizeSpeed,'linear'); 261 $('#outerImageContainer').animate({width: widthNew},opts.resizeSpeed,'linear',function(){ 262 $('#outerImageContainer').animate({height: heightNew},opts.resizeSpeed,'linear',function(){ 263 showImage(); 264 }); 265 }); 266 267 // if new and old image are same size and no scaling transition is necessary, 268 // do a quick pause to prevent image flicker. 269 if((hDiff == 0) && (wDiff == 0)){ 270 if (jQuery.browser.msie){ pause(250); } else { pause(100);} 271 } 272 273 $('#prevLink').height(imgHeight); 274 $('#nextLink').height(imgHeight); 275 }; 276 277 function showImage() { 278 $('#loading').hide(); 279 $('#lightboxImage').fadeIn("fast"); 280 updateDetails(); 281 preloadNeighborImages(); 282 283 opts.inprogress = false; 284 }; 285 286 function updateDetails() { 287 288 $('#numberDisplay').html(''); 289 290 if(opts.imageArray[opts.activeImage][1]){ 291 $('#caption').html(opts.imageArray[opts.activeImage][1]).show(); 292 } 293 294 // if image is part of set display 'Image x of x' 295 if(opts.imageArray.length > 1){ 296 var nav_html; 297 298 nav_html = opts.strings.image + (opts.activeImage + 1) + opts.strings.of + opts.imageArray.length; 299 300 if (!opts.disableNavbarLinks) { 301 // display previous / next text links 302 if ((opts.activeImage) > 0 || opts.loopImages) { 303 nav_html = '<a title="' + opts.strings.prevLinkTitle + '" href="#" id="prevLinkText">' + opts.strings.prevLinkText + "</a>" + nav_html; 304 } 305 306 if (((opts.activeImage + 1) < opts.imageArray.length) || opts.loopImages) { 307 nav_html += '<a title="' + opts.strings.nextLinkTitle + '" href="#" id="nextLinkText">' + opts.strings.nextLinkText + "</a>"; 308 } 309 } 310 311 $('#numberDisplay').html(nav_html).show(); 312 } 313 314 if (opts.slideNavBar) { 315 $("#imageData").slideDown(opts.navBarSlideSpeed); 316 } else { 317 $("#imageData").show(); 318 } 319 320 var arrayPageSize = getPageSize(); 321 $('#overlay').height(arrayPageSize[1]); 322 updateNav(); 323 }; 324 325 function updateNav() { 326 if(opts.imageArray.length > 1){ 327 $('#hoverNav').show(); 328 329 // if loopImages is true, always show next and prev image buttons 330 if(opts.loopImages) { 331 $('#prevLink,#prevLinkText').show().click(function(){ 332 changeImage((opts.activeImage == 0) ? (opts.imageArray.length - 1) : opts.activeImage - 1); return false; 333 }); 334 335 $('#nextLink,#nextLinkText').show().click(function(){ 336 changeImage((opts.activeImage == (opts.imageArray.length - 1)) ? 0 : opts.activeImage + 1); return false; 337 }); 338 339 } else { 340 // if not first image in set, display prev image button 341 if(opts.activeImage != 0){ 342 $('#prevLink,#prevLinkText').show().click(function(){ 343 changeImage(opts.activeImage - 1); return false; 344 }); 345 } 346 347 // if not last image in set, display next image button 348 if(opts.activeImage != (opts.imageArray.length - 1)){ 349 $('#nextLink,#nextLinkText').show().click(function(){ 350 351 changeImage(opts.activeImage +1); return false; 352 }); 353 } 354 } 355 356 enableKeyboardNav(); 357 } 358 }; 359 360 function keyboardAction(e) { 361 var o = e.data.opts 362 var keycode = e.keyCode; 363 var escapeKey = 27; 364 365 var key = String.fromCharCode(keycode).toLowerCase(); 366 367 if((key == 'x') || (key == 'o') || (key == 'c') || (keycode == escapeKey)){ // close lightbox 368 end(); 369 } else if((key == 'p') || (keycode == 37)){ // display previous image 370 if(o.loopImages) { 371 disableKeyboardNav(); 372 changeImage((o.activeImage == 0) ? (o.imageArray.length - 1) : o.activeImage - 1); 373 } 374 else if(o.activeImage != 0){ 375 disableKeyboardNav(); 376 changeImage(o.activeImage - 1); 377 } 378 } else if((key == 'n') || (keycode == 39)){ // display next image 379 if (opts.loopImages) { 380 disableKeyboardNav(); 381 changeImage((o.activeImage == (o.imageArray.length - 1)) ? 0 : o.activeImage + 1); 382 } 383 else if(o.activeImage != (o.imageArray.length - 1)){ 384 disableKeyboardNav(); 385 changeImage(o.activeImage + 1); 386 } 387 } 388 }; 389 390 function enableKeyboardNav() { 391 $(document).bind('keydown', {opts: opts}, keyboardAction); 392 }; 393 394 function disableKeyboardNav() { 395 $(document).unbind('keydown'); 396 }; 397 398 }; 399 400 $.fn.lightbox.parseJsonData = function(data) { 401 var imageArray = []; 402 403 $.each(data, function(){ 404 imageArray.push(new Array(this.url, this.title)); 405 }); 406 407 return imageArray; 408 }; 409 410 $.fn.lightbox.defaults = { 411 fileLoadingImage : '/public/lightbox/images/loading.gif', 412 fileBottomNavCloseImage : '/public/lightbox/images/closelabel.gif', 413 overlayOpacity : 0.8, 414 borderSize : 10, 415 imageArray : new Array, 416 activeImage : null, 417 inprogress : false, 418 resizeSpeed : 350, 419 widthCurrent: 250, 420 heightCurrent: 250, 421 xScale : 1, 422 yScale : 1, 423 displayTitle: true, 424 navbarOnTop: false, 425 slideNavBar: false, // slide nav bar up/down between image resizing transitions 426 navBarSlideSpeed: 350, 427 displayHelp: false, 428 strings : { 429 help: ' \u2190 / P - previous image\u00a0\u00a0\u00a0\u00a0\u2192 / N - next image\u00a0\u00a0\u00a0\u00a0ESC / X - close image gallery', 430 prevLinkTitle: 'previous image', 431 nextLinkTitle: 'next image', 432 prevLinkText: '« Previous', 433 nextLinkText: 'Next »', 434 closeTitle: 'close image gallery', 435 image: 'Image ', 436 of: ' of ' 437 }, 438 fitToScreen: false, // resize images if they are bigger than window 439 disableNavbarLinks: false, 440 loopImages: false, 441 imageClickClose: true, 442 jsonData: null, 443 jsonDataParser: null 444 }; 445 446})(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.