vendor: 5,664 bytes, lines 1-132
1/*! 2 * Lightbox v2.9.0 3 * by Lokesh Dhakar 4 * 5 * More info: 6 * http://lokeshdhakar.com/projects/lightbox2/ 7 * 8 * Copyright 2007, 2015 Lokesh Dhakar 9 * Released under the MIT license 10 * https://github.com/lokesh/lightbox2/blob/master/LICENSE 11 * 12 * @preserve 13 */ 14 15// Uses Node, AMD or browser globals to create a module. 16(function (root, factory) { 17 if (typeof define === 'function' && define.amd) { 18 // AMD. Register as an anonymous module. 19 define(['jquery'], factory); 20 } else if (typeof exports === 'object') { 21 // Node. Does not work with strict CommonJS, but 22 // only CommonJS-like environments that support module.exports, 23 // like Node. 24 module.exports = factory(require('jquery')); 25 } else { 26 // Browser globals (root is window) 27 root.lightbox = factory(root.jQuery); 28 } 29}(this, function ($) { 30 31 function Lightbox(options) { 32 this.album = []; 33 this.currentImageIndex = void 0; 34 this.init(); 35 36 // options 37 this.options = $.extend({}, this.constructor.defaults); 38 this.option(options); 39 } 40 41 // Descriptions of all options available on the demo site: 42 // http://lokeshdhakar.com/projects/lightbox2/index.html#options 43 Lightbox.defaults = { 44 albumLabel: 'Image %1 of %2', 45 alwaysShowNavOnTouchDevices: false, 46 fadeDuration: 600, 47 fitImagesInViewport: true, 48 imageFadeDuration: 600, 49 // maxWidth: 800, 50 // maxHeight: 600, 51 positionFromTop: 50, 52 resizeDuration: 700, 53 showImageNumberLabel: true, 54 wrapAround: false, 55 disableScrolling: false, 56 /* 57 Sanitize Title 58 If the caption data is trusted, for example you are hardcoding it in, then leave this to false. 59 This will free you to add html tags, such as links, in the caption. 60 61 If the caption data is user submitted or from some other untrusted source, then set this to true 62 to prevent xss and other injection attacks. 63 */ 64 sanitizeTitle: false 65 }; 66 67 Lightbox.prototype.option = function(options) { 68 $.extend(this.options, options); 69 }; 70 71 Lightbox.prototype.imageCountLabel = function(currentImageNum, totalImages) { 72 return this.options.albumLabel.replace(/%1/g, currentImageNum).replace(/%2/g, totalImages); 73 }; 74 75 Lightbox.prototype.init = function() { 76 var self = this; 77 // Both enable and build methods require the body tag to be in the DOM. 78 $(document).ready(function() { 79 self.enable(); 80 self.build(); 81 }); 82 }; 83 84 // Loop through anchors and areamaps looking for either data-lightbox attributes or rel attributes 85 // that contain 'lightbox'. When these are clicked, start lightbox. 86 Lightbox.prototype.enable = function() { 87 var self = this; 88 $('body').on('click', 'a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]', function(event) { 89 self.start($(event.currentTarget)); 90 91 var mainurl = "window.open('http://www.sharethis.com/share?publisher=d1babd8d-7b6d-4f5c-9a11-8c8bfa153821&url="+$(this).data('fanphotoimageurl')+"&title="+$(this).data('fanphotoimagetitle')+"','popup','width=600,height=700,scrollbars=no,resizable=yes,toolbar=no,directories=no,location=no,menubar=no,status=no,left=50,top=0')"; 92 93 $('.lb-closeContainer a.sharepopus').attr('onclick', mainurl ) ; 94 //$('.lb-container .lb-nav a.click-here-to-download').attr('href', $(this).data('attach-id') ); 95 96 return false; 97 }); 98 }; 99 100 // Build html for the lightbox and the overlay. 101 // Attach event handlers to the new DOM elements. click click click 102 Lightbox.prototype.build = function() { 103 var self = this; 104 $('<div id="lightboxOverlay" class="lightboxOverlay"></div><div id="lightbox" class="lightbox"><div class="lb-outerContainer"><!-- here --><div class="lb-dataContainer"><div class="lb-data"><div class="lb-details"><span class="lb-caption"></span><span class="lb-number"></span></div><div class="lb-closeContainer"><a href="#" onclick="" class="sharepopus">SHARE THIS PHOTO</a><a class="lb-close"></a></div></div></div><!--here--><div class="lb-container"><img class="lb-image" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" /><div class="lb-nav "><a class="lb-prev" href="" >Previous<span class="hidden-xs"> Photo</span></a><a class="click-here-to-download" href="#">DOWNLOAD HIGH-RES PHOTO</a><a class="lb-next" href="" >Next<span class="hidden-xs"> Photo</span></a></div><div class="lb-loader"><a class="lb-cancel"></a></div></div></div></div>').appendTo($('body')); 105 106 // Cache jQuery objects 107 this.$lightbox = $('#lightbox'); 108 this.$overlay = $('#lightboxOverlay'); 109 this.$outerContainer = this.$lightbox.find('.lb-outerContainer'); 110 this.$container = this.$lightbox.find('.lb-container'); 111 this.$image = this.$lightbox.find('.lb-image'); 112 this.$nav = this.$lightbox.find('.lb-nav'); 113 114 // Store css values for future lookup 115 this.containerPadding = { 116 top: parseInt(this.$container.css('padding-top'), 10), 117 right: parseInt(this.$container.css('padding-right'), 10), 118 bottom: parseInt(this.$container.css('padding-bottom'), 10), 119 left: parseInt(this.$container.css('padding-left'), 10) 120 }; 121 122 this.imageBorderWidth = { 123 top: parseInt(this.$image.css('border-top-width'), 10), 124 right: parseInt(this.$image.css('border-right-width'), 10), 125 bottom: parseInt(this.$image.css('border-bottom-width'), 10), 126 left: parseInt(this.$image.css('border-left-width'), 10) 127 }; 128 129 // Attach event handlers to the newly minted DOM elements 130 this.$overlay.hide().on('click', function() { 131 self.end(); 132 return false;
133 }); 134 135 this.$lightbox.hide().on('click', function(event) { 136 if ($(event.target).attr('id') === 'lightbox') { 137 self.end(); 138 } 139 return false; 140 }); 141 142 this.$outerContainer.on('click', function(event) { 143 if ($(event.target).attr('id') === 'lightbox') { 144 self.end(); 145 } 146 return false; 147 }); 148 149 this.$lightbox.find('.lb-prev').on('click', function() { 150 151 if (self.currentImageIndex === 0) { 152 self.changeImage(self.album.length - 1); 153 } else { 154 self.changeImage(self.currentImageIndex - 1); 155 } 156 157 return false; 158 }); 159 160 161 this.$lightbox.find('a.click-here-to-download').on('click', function() { 162 //window.open($(this).attr('href'), 'Share Facebook', config='height=300, width=500'); 163 window.open( $(this).attr('href') ); 164 165 }); 166 167 this.$lightbox.find('.lb-closeContainer a.fa-facebook').on('click', function() { 168 window.open($(this).attr('href'), 'Share Facebook', config='height=300, width=500'); 169 }); 170 171 this.$lightbox.find('.lb-closeContainer a.fa-twitter').on('click', function() { 172 window.open($(this).attr('href'), 'Share on Twitter', config='height=300, width=500'); 173 }); 174 175 this.$lightbox.find('.lb-closeContainer a.fa-google-plus').on('click', function() { 176 window.open($(this).attr('href'), 'Share on Google Plus', config='height=300, width=500'); 177 }); 178 179 180 181 182 this.$lightbox.find('.lb-next').on('click', function() { 183 184 if (self.currentImageIndex === self.album.length - 1) { 185 self.changeImage(0); 186 } else { 187 self.changeImage(self.currentImageIndex + 1); 188 } 189 190 return false; 191 }); 192 193 /* 194 Show context menu for image on right-click 195 196 There is a div containing the navigation that spans the entire image and lives above of it. If 197 you right-click, you are right clicking this div and not the image. This prevents users from 198 saving the image or using other context menu actions with the image. 199 200 To fix this, when we detect the right mouse button is pressed down, but not yet clicked, we 201 set pointer-events to none on the nav div. This is so that the upcoming right-click event on 202 the next mouseup will bubble down to the image. Once the right-click/contextmenu event occurs 203 we set the pointer events back to auto for the nav div so it can capture hover and left-click 204 events as usual. 205 */ 206 this.$nav.on('mousedown', function(event) { 207 if (event.which === 3) { 208 self.$nav.css('pointer-events', 'none'); 209 210 self.$lightbox.one('contextmenu', function() { 211 setTimeout(function() { 212 this.$nav.css('pointer-events', 'auto'); 213 }.bind(self), 0); 214 }); 215 } 216 }); 217 218 219 this.$lightbox.find('.lb-loader, .lb-close').on('click', function() { 220 self.end(); 221 return false; 222 }); 223 }; 224 225 // Show overlay and lightbox. If the image is part of a set, add siblings to album array. 226 Lightbox.prototype.start = function($link) { 227 var self = this; 228 var $window = $(window); 229 230 $window.on('resize', $.proxy(this.sizeOverlay, this)); 231 232 $('select, object, embed').css({ 233 visibility: 'hidden' 234 }); 235 236 this.sizeOverlay(); 237 238 this.album = []; 239 var imageNumber = 0; 240 241 function addToAlbum($link) { 242 self.album.push({ 243 link: $link.attr('href'), 244 title: $link.attr('data-title') || $link.attr('title'), 245 attach_id:$link.attr('data-attach-id'), 246 }); 247 } 248 249 // Support both data-lightbox attribute and rel attribute implementations 250 var dataLightboxValue = $link.attr('data-lightbox'); 251 var $links; 252 253 if (dataLightboxValue) { 254 $links = $($link.prop('tagName') + '[data-lightbox="' + dataLightboxValue + '"]'); 255 for (var i = 0; i < $links.length; i = ++i) { 256 addToAlbum($($links[i])); 257 if ($links[i] === $link[0]) { 258 imageNumber = i; 259 } 260 } 261 } else { 262 if ($link.attr('rel') === 'lightbox') { 263 // If image is not part of a set 264 addToAlbum($link); 265 } else { 266 // If image is part of a set 267 $links = $($link.prop('tagName') + '[rel="' + $link.attr('rel') + '"]'); 268 for (var j = 0; j < $links.length; j = ++j) { 269 addToAlbum($($links[j])); 270 if ($links[j] === $link[0]) { 271 imageNumber = j; 272 } 273 } 274 } 275 } 276 277 // Position Lightbox 278 var top = $window.scrollTop() + this.options.positionFromTop; 279 var left = $window.scrollLeft(); 280 this.$lightbox.css({ 281 top: top + 'px', 282 left: left + 'px' 283 }).fadeIn(this.options.fadeDuration); 284 285 // Disable scrolling of the page while open 286 if (this.options.disableScrolling) { 287 $('body').addClass('lb-disable-scrolling'); 288 } 289 290 this.changeImage(imageNumber); 291 }; 292 293 // Hide most UI elements in preparation for the animated resizing of the lightbox. 294 Lightbox.prototype.changeImage = function(imageNumber) { 295 var self = this; 296 297 this.disableKeyboardNav(); 298 var $image = this.$lightbox.find('.lb-image'); 299 300 this.$overlay.fadeIn(this.options.fadeDuration); 301 302 $('.lb-loader').fadeIn('slow'); 303 this.$lightbox.find('.lb-image, .lb-nav, .lb-prev, .lb-next, .lb-dataContainer, .lb-numbers, .lb-caption').hide(); 304 305 this.$outerContainer.addClass('animating'); 306 307 // When image to show is preloaded, we send the width and height to sizeContainer() 308 var preloader = new Image(); 309 preloader.onload = function() { 310 var $preloader; 311 var imageHeight; 312 var imageWidth; 313 var maxImageHeight; 314 var maxImageWidth; 315 var windowHeight; 316 var windowWidth; 317 318 $image.attr('src', self.album[imageNumber].link); 319 $image.attr('attachid',self.album[imageNumber].attach_id); 320 $preloader = $(preloader); 321 322 $image.width(preloader.width); 323 $image.height(preloader.height); 324 325 if (self.options.fitImagesInViewport) { 326 // Fit image inside the viewport. 327 // Take into account the border around the image and an additional 10px gutter on each side. 328 329 windowWidth = $(window).width(); 330 windowHeight = $(window).height(); 331 maxImageWidth = windowWidth - self.containerPadding.left - self.containerPadding.right - self.imageBorderWidth.left - self.imageBorderWidth.right - 20; 332 maxImageHeight = windowHeight - self.containerPadding.top - self.containerPadding.bottom - self.imageBorderWidth.top - self.imageBorderWidth.bottom - 120; 333 334 // Check if image size is larger then maxWidth|maxHeight in settings 335 if (self.options.maxWidth && self.options.maxWidth < maxImageWidth) { 336 maxImageWidth = self.options.maxWidth; 337 } 338 if (self.options.maxHeight && self.options.maxHeight < maxImageWidth) { 339 maxImageHeight = self.options.maxHeight; 340 } 341 342 // Is the current image's width or height is greater than the maxImageWidth or maxImageHeight 343 // option than we need to size down while maintaining the aspect ratio. 344 if ((preloader.width > maxImageWidth) || (preloader.height > maxImageHeight)) { 345 if ((preloader.width / maxImageWidth) > (preloader.height / maxImageHeight)) { 346 imageWidth = maxImageWidth; 347 imageHeight = parseInt(preloader.height / (preloader.width / imageWidth), 10); 348 $image.width(imageWidth); 349 $image.height(imageHeight); 350 } else { 351 imageHeight = maxImageHeight; 352 imageWidth = parseInt(preloader.width / (preloader.height / imageHeight), 10); 353 $image.width(imageWidth); 354 $image.height(imageHeight); 355 } 356 } 357 } 358 self.sizeContainer($image.width(), $image.height()); 359 }; 360 361 preloader.src = this.album[imageNumber].link; 362 this.currentImageIndex = imageNumber; 363 //$('.lb-container .lb-nav a.click-here-to-download').attr('href', $(".lb-container img.lb-image").attr('attachid') ); 364 //alert(this.album[imageNumber].attach_id); 365 $('.lb-container .lb-nav a.click-here-to-download').attr('href', this.album[imageNumber].attach_id ); 366 367 }; 368 369 // Stretch overlay to fit the viewport 370 Lightbox.prototype.sizeOverlay = function() { 371 this.$overlay 372 .width($(document).width()) 373 .height($(document).height()); 374 }; 375 376 // Animate the size of the lightbox to fit the image we are showing 377 Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight) { 378 var self = this; 379 380 var oldWidth = this.$outerContainer.outerWidth(); 381 var oldHeight = this.$outerContainer.outerHeight(); 382 var newWidth = imageWidth + this.containerPadding.left + this.containerPadding.right + this.imageBorderWidth.left + this.imageBorderWidth.right; 383 var newHeight = imageHeight + this.containerPadding.top + this.containerPadding.bottom + this.imageBorderWidth.top + this.imageBorderWidth.bottom; 384 385 function postResize() { 386 self.$lightbox.find('.lb-dataContainer').width(newWidth); 387 self.$lightbox.find('.lb-prevLink').height(newHeight); 388 self.$lightbox.find('.lb-nextLink').height(newHeight); 389 self.showImage(); 390 } 391 392 if (oldWidth !== newWidth || oldHeight !== newHeight) { 393 this.$outerContainer.animate({ 394 width: newWidth, 395 height: newHeight 396 }, this.options.resizeDuration, 'swing', function() { 397 postResize(); 398 }); 399 } else { 400 postResize(); 401 } 402 }; 403 404 // Display the image and its details and begin preload neighboring images. 405 Lightbox.prototype.showImage = function() { 406 this.$lightbox.find('.lb-loader').stop(true).hide(); 407 this.$lightbox.find('.lb-image').fadeIn(this.options.imageFadeDuration); 408 409 this.updateNav(); 410 this.updateDetails(); 411 this.preloadNeighboringImages(); 412 this.enableKeyboardNav(); 413 }; 414 415 // Display previous and next navigation if appropriate. 416 Lightbox.prototype.updateNav = function() { 417 // Check to see if the browser supports touch events. If so, we take the conservative approach 418 // and assume that mouse hover events are not supported and always show prev/next navigation 419 // arrows in image sets. 420 var alwaysShowNav = false;
421 try { 422 document.createEvent('TouchEvent'); 423 alwaysShowNav = (this.options.alwaysShowNavOnTouchDevices) ? true : false; 424 } catch (e) {} 425 426 this.$lightbox.find('.lb-nav').show(); 427 428 if (this.album.length > 1) { 429 if (this.options.wrapAround) { 430 if (alwaysShowNav) { 431 this.$lightbox.find('.lb-prev, .lb-next').css('opacity', '1'); 432 } 433 this.$lightbox.find('.lb-prev, .lb-next').show(); 434 } else { 435 if (this.currentImageIndex > 0) { 436 this.$lightbox.find('.lb-prev').show(); 437 if (alwaysShowNav) { 438 this.$lightbox.find('.lb-prev').css('opacity', '1'); 439 } 440 } 441 if (this.currentImageIndex < this.album.length - 1) { 442 this.$lightbox.find('.lb-next').show(); 443 if (alwaysShowNav) { 444 this.$lightbox.find('.lb-next').css('opacity', '1'); 445 } 446 } 447 } 448 } 449 }; 450 451 // Display caption, image number, and closing button. 452 Lightbox.prototype.updateDetails = function() { 453 var self = this; 454 455 // Enable anchor clicks in the injected caption html. 456 // Thanks Nate Wright for the fix. @https://github.com/NateWr 457 if (typeof this.album[this.currentImageIndex].title !== 'undefined' && 458 this.album[this.currentImageIndex].title !== '') { 459 var $caption = this.$lightbox.find('.lb-caption'); 460 if (this.options.sanitizeTitle) { 461 $caption.text(this.album[this.currentImageIndex].title); 462 } else { 463 $caption.html(this.album[this.currentImageIndex].title); 464 } 465 $caption.fadeIn('fast') 466 .find('a').on('click', function(event) { 467 if ($(this).attr('target') !== undefined) { 468 window.open($(this).attr('href'), $(this).attr('target')); 469 } else { 470 location.href = $(this).attr('href'); 471 } 472 }); 473 } 474 475 if (this.album.length > 1 && this.options.showImageNumberLabel) { 476 var labelText = this.imageCountLabel(this.currentImageIndex + 1, this.album.length); 477 this.$lightbox.find('.lb-number').text(labelText).fadeIn('fast'); 478 } else { 479 this.$lightbox.find('.lb-number').hide(); 480 } 481 482 this.$outerContainer.removeClass('animating'); 483 484 this.$lightbox.find('.lb-dataContainer').fadeIn(0, function() { 485 return self.sizeOverlay(); 486 }); 487 }; 488 489 // Preload previous and next images in set. 490 Lightbox.prototype.preloadNeighboringImages = function() { 491 if (this.album.length > this.currentImageIndex + 1) { 492 var preloadNext = new Image(); 493 preloadNext.src = this.album[this.currentImageIndex + 1].link; 494 } 495 if (this.currentImageIndex > 0) { 496 var preloadPrev = new Image(); 497 preloadPrev.src = this.album[this.currentImageIndex - 1].link; 498 } 499 }; 500 501 Lightbox.prototype.enableKeyboardNav = function() { 502 $(document).on('keyup.keyboard', $.proxy(this.keyboardAction, this)); 503 }; 504 505 Lightbox.prototype.disableKeyboardNav = function() { 506 $(document).off('.keyboard'); 507 }; 508 509 Lightbox.prototype.keyboardAction = function(event) { 510 var KEYCODE_ESC = 27; 511 var KEYCODE_LEFTARROW = 37; 512 var KEYCODE_RIGHTARROW = 39; 513 514 var keycode = event.keyCode; 515 var key = String.fromCharCode(keycode).toLowerCase(); 516 if (keycode === KEYCODE_ESC || key.match(/x|o|c/)) { 517 this.end(); 518 } else if (key === 'p' || keycode === KEYCODE_LEFTARROW) { 519 if (this.currentImageIndex !== 0) { 520 this.changeImage(this.currentImageIndex - 1); 521 } else if (this.options.wrapAround && this.album.length > 1) { 522 this.changeImage(this.album.length - 1); 523 } 524 } else if (key === 'n' || keycode === KEYCODE_RIGHTARROW) { 525 if (this.currentImageIndex !== this.album.length - 1) { 526 this.changeImage(this.currentImageIndex + 1); 527 } else if (this.options.wrapAround && this.album.length > 1) { 528 this.changeImage(0); 529 } 530 } 531 }; 532 533 // Closing time. :-( 534 Lightbox.prototype.end = function() { 535 this.disableKeyboardNav(); 536 $(window).off('resize', this.sizeOverlay); 537 this.$lightbox.fadeOut(this.options.fadeDuration); 538 this.$overlay.fadeOut(this.options.fadeDuration); 539 $('select, object, embed').css({ 540 visibility: 'visible' 541 }); 542 if (this.options.disableScrolling) { 543 $('body').removeClass('lb-disable-scrolling'); 544 } 545 }; 546 return new Lightbox(); 547}));
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.