vendor: 4,563 bytes, lines 1-100
1/*! 2 * Lightbox v2.8.2 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 13// Uses Node, AMD or browser globals to create a module. 14(function (root, factory) { 15 if (typeof define === 'function' && define.amd) { 16 // AMD. Register as an anonymous module. 17 define(['jquery'], factory); 18 } else if (typeof exports === 'object') { 19 // Node. Does not work with strict CommonJS, but 20 // only CommonJS-like environments that support module.exports, 21 // like Node. 22 module.exports = factory(require('jquery')); 23 } else { 24 // Browser globals (root is window) 25 root.lightbox = factory(root.jQuery); 26 } 27}(this, function ($) { 28 29 function Lightbox(options) { 30 this.album = []; 31 this.currentImageIndex = void 0; 32 this.init(); 33 34 // options 35 this.options = $.extend({}, this.constructor.defaults); 36 this.option(options); 37 } 38 39 // Descriptions of all options available on the demo site: 40 // http://lokeshdhakar.com/projects/lightbox2/index.html#options 41 Lightbox.defaults = { 42 albumLabel: 'Image %1 of %2', 43 alwaysShowNavOnTouchDevices: false, 44 fadeDuration: 500, 45 fitImagesInViewport: true, 46 // maxWidth: 800, 47 // maxHeight: 600, 48 positionFromTop: 50, 49 resizeDuration: 700, 50 showImageNumberLabel: true, 51 wrapAround: false, 52 disableScrolling: false 53 }; 54 55 Lightbox.prototype.option = function(options) { 56 $.extend(this.options, options); 57 }; 58 59 Lightbox.prototype.imageCountLabel = function(currentImageNum, totalImages) { 60 return this.options.albumLabel.replace(/%1/g, currentImageNum).replace(/%2/g, totalImages); 61 }; 62 63 Lightbox.prototype.init = function() { 64 this.enable(); 65 this.build(); 66 }; 67 68 // Loop through anchors and areamaps looking for either data-lightbox attributes or rel attributes 69 // that contain 'lightbox'. When these are clicked, start lightbox. 70 Lightbox.prototype.enable = function() { 71 var self = this; 72 $('body').on('click', 'a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]', function(event) { 73 self.start($(event.currentTarget)); 74 return false; 75 }); 76 }; 77 78 // Build html for the lightbox and the overlay. 79 // Attach event handlers to the new DOM elements. click click click 80 Lightbox.prototype.build = function() { 81 var self = this; 82 $('<div id="lightboxOverlay" class="lightboxOverlay"></div><div id="lightbox" class="lightbox"><div class="lb-outerContainer"><div class="lb-container"><a href="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" download><img class="lb-image" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" /></a><div class="lb-loader"><a class="lb-cancel"></a></div></div></div><div class="lb-dataContainer"><div class="lb-data"><div class="row float-right"><div class="col d-flex" id="lb-socialContainer"><a id="lb-twitter" class="lb-icon" href="#"><i class="fa fa-twitter-square"></i></a><a id="lb-facebook" class="lb-icon" href="#"><i class="fa fa-facebook-square"></i></a><a id="lb-pinterest" class="lb-icon" href="#"><i class="fa fa-pinterest-square"></i></a><a id="lb-maps" class="lb-icon" href="#"><i class="fa fa-map"></i></a></div><div class="col" id="lb-delContainer"><a class="lb-delete" href="#"><i class="fa fa-trash" style="font-size: 40px;"></i></a></div><div class="col" id="lb-closeContainer"><a class="lb-close" href="#"></a></div></div></div></div></div>').appendTo($('body')); 83 84 // Cache jQuery objects 85 this.$lightbox = $('#lightbox'); 86 this.$overlay = $('#lightboxOverlay'); 87 this.$outerContainer = this.$lightbox.find('.lb-outerContainer'); 88 this.$container = this.$lightbox.find('.lb-container'); 89 90 // Store css values for future lookup 91 this.containerTopPadding = parseInt(this.$container.css('padding-top'), 10); 92 this.containerRightPadding = parseInt(this.$container.css('padding-right'), 10); 93 this.containerBottomPadding = parseInt(this.$container.css('padding-bottom'), 10); 94 this.containerLeftPadding = parseInt(this.$container.css('padding-left'), 10); 95 96 // Attach event handlers to the newly minted DOM elements 97 this.$overlay.hide().on('click', function() { 98 self.end(); 99 return false; 100 });
101 102 this.$lightbox.hide().on('click', function(event) { 103 if ($(event.target).attr('id') === 'lightbox') { 104 self.end(); 105 } 106 return false; 107 }); 108 109 this.$outerContainer.on('click', function(event) { 110 if ($(event.target).attr('id') === 'lightbox') { 111 self.end(); 112 } 113 return false; 114 }); 115 116 this.$lightbox.find('.lb-prev').on('click', function() { 117 if (self.currentImageIndex === 0) { 118 self.changeImage(self.album.length - 1); 119 } else { 120 self.changeImage(self.currentImageIndex - 1); 121 } 122 return false; 123 }); 124 125 this.$lightbox.find('.lb-next').on('click', function() { 126 if (self.currentImageIndex === self.album.length - 1) { 127 self.changeImage(0); 128 } else { 129 self.changeImage(self.currentImageIndex + 1); 130 } 131 return false; 132 }); 133 134 this.$lightbox.find('.lb-loader, .lb-close').on('click', function() { 135 self.end(); 136 return false; 137 }); 138 139 this.$lightbox.find('.lb-loader, .lb-delete').on('click', function() { 140 self.end(); 141 $('#delete-snapshot-confirm').modal(); 142 return false; 143 }); 144 145 this.$lightbox.find('.lb-loader, #lb-twitter').on('click', function() { 146 HandleTwitter(); 147 return false; 148 }); 149 this.$lightbox.find('.lb-loader, #lb-facebook').on('click', function() { 150 HandleFacebook(); 151 return false; 152 }); 153 this.$lightbox.find('.lb-loader, #lb-pinterest').on('click', function() { 154 HandlePinterest(); 155 return false; 156 }); 157 this.$lightbox.find('.lb-maps, #lb-maps').on('click', function() { 158 HandleStreetView(); 159 return false; 160 }); 161 this.$lightbox.find('.lb-loader, #lb-download').on('click', function() { 162 HandleDownload(); 163 return false; 164 }); }; 165 166 // Show overlay and lightbox. If the image is part of a set, add siblings to album array. 167 Lightbox.prototype.start = function($link) { 168 var self = this; 169 var $window = $(window); 170 171 var name = $link.attr('id'); 172 SetCurrentImageIndex(name); 173 174 $window.on('resize', $.proxy(this.sizeOverlay, this)); 175 176 $('select, object, embed').css({ 177 visibility: 'hidden' 178 }); 179 180 this.sizeOverlay(); 181 182 this.album = []; 183 var imageNumber = 0; 184 185 function addToAlbum($link) { 186 self.album.push({ 187 link: $link.attr('href'), 188 title: $link.attr('data-title') || $link.attr('title') 189 }); 190 } 191 192 // Support both data-lightbox attribute and rel attribute implementations 193 var dataLightboxValue = $link.attr('data-lightbox'); 194 var $links; 195 196 if (dataLightboxValue) { 197 $links = $($link.prop('tagName') + '[data-lightbox="' + dataLightboxValue + '"]'); 198 for (var i = 0; i < $links.length; i = ++i) { 199 addToAlbum($($links[i])); 200 if ($links[i] === $link[0]) { 201 imageNumber = i; 202 } 203 } 204 } else { 205 if ($link.attr('rel') === 'lightbox') { 206 // If image is not part of a set 207 addToAlbum($link); 208 } else { 209 // If image is part of a set 210 $links = $($link.prop('tagName') + '[rel="' + $link.attr('rel') + '"]'); 211 for (var j = 0; j < $links.length; j = ++j) { 212 addToAlbum($($links[j])); 213 if ($links[j] === $link[0]) { 214 imageNumber = j; 215 } 216 } 217 } 218 } 219 220 // Position Lightbox 221 var top = $window.scrollTop() + this.options.positionFromTop; 222 var left = $window.scrollLeft(); 223 this.$lightbox.css({ 224 top: top + 'px', 225 left: left + 'px' 226 }).fadeIn(this.options.fadeDuration); 227 228 // Disable scrolling of the page while open 229 if (this.options.disableScrolling) { 230 $('body').addClass('lb-disable-scrolling'); 231 } 232 233 this.changeImage(imageNumber); 234 }; 235 236 // Hide most UI elements in preparation for the animated resizing of the lightbox. 237 Lightbox.prototype.changeImage = function(imageNumber) { 238 var self = this; 239 240 this.disableKeyboardNav(); 241 var $image = this.$lightbox.find('.lb-image'); 242 243 this.$overlay.fadeIn(this.options.fadeDuration); 244 245 $('.lb-loader').fadeIn('slow'); 246 this.$lightbox.find('.lb-image, .lb-nav, .lb-prev, .lb-next, .lb-dataContainer, .lb-numbers, .lb-caption').hide(); 247 248 this.$outerContainer.addClass('animating'); 249 250 // When image to show is preloaded, we send the width and height to sizeContainer() 251 var preloader = new Image(); 252 preloader.onload = function() { 253 var $preloader; 254 var imageHeight; 255 var imageWidth; 256 var maxImageHeight; 257 var maxImageWidth; 258 var windowHeight; 259 var windowWidth; 260 261 $image.attr('src', self.album[imageNumber].link); 262 263 $preloader = $(preloader); 264 265 $image.width(preloader.width); 266 $image.height(preloader.height); 267 268 if (self.options.fitImagesInViewport) { 269 // Fit image inside the viewport. 270 // Take into account the border around the image and an additional 10px gutter on each side. 271 272 windowWidth = $(window).width(); 273 windowHeight = $(window).height(); 274 maxImageWidth = windowWidth - self.containerLeftPadding - self.containerRightPadding - 20; 275 maxImageHeight = windowHeight - self.containerTopPadding - self.containerBottomPadding - 120; 276 277 // Check if image size is larger then maxWidth|maxHeight in settings 278 if (self.options.maxWidth && self.options.maxWidth < maxImageWidth) { 279 maxImageWidth = self.options.maxWidth; 280 } 281 if (self.options.maxHeight && self.options.maxHeight < maxImageWidth) { 282 maxImageHeight = self.options.maxHeight; 283 } 284 285 // Is there a fitting issue? 286 if ((preloader.width > maxImageWidth) || (preloader.height > maxImageHeight)) { 287 if ((preloader.width / maxImageWidth) > (preloader.height / maxImageHeight)) { 288 imageWidth = maxImageWidth; 289 imageHeight = parseInt(preloader.height / (preloader.width / imageWidth), 10); 290 $image.width(imageWidth);
291 $image.height(imageHeight); 292 } else { 293 imageHeight = maxImageHeight; 294 imageWidth = parseInt(preloader.width / (preloader.height / imageHeight), 10); 295 $image.width(imageWidth); 296 $image.height(imageHeight); 297 } 298 } 299 } 300 self.sizeContainer($image.width(), $image.height()); 301 }; 302 303 preloader.src = this.album[imageNumber].link; 304 this.currentImageIndex = imageNumber; 305 }; 306 307 // Stretch overlay to fit the viewport 308 Lightbox.prototype.sizeOverlay = function() { 309 this.$overlay 310 .width($(document).width()) 311 .height($(document).height()); 312 }; 313 314 // Animate the size of the lightbox to fit the image we are showing 315 Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight) { 316 var self = this; 317 318 var oldWidth = this.$outerContainer.outerWidth(); 319 var oldHeight = this.$outerContainer.outerHeight(); 320 var newWidth = imageWidth + this.containerLeftPadding + this.containerRightPadding; 321 var newHeight = imageHeight + this.containerTopPadding + this.containerBottomPadding; 322 323 function postResize() { 324 self.$lightbox.find('.lb-dataContainer').width(newWidth); 325 self.$lightbox.find('.lb-prevLink').height(newHeight); 326 self.$lightbox.find('.lb-nextLink').height(newHeight); 327 self.showImage(); 328 } 329 330 if (oldWidth !== newWidth || oldHeight !== newHeight) { 331 this.$outerContainer.animate({ 332 width: newWidth, 333 height: newHeight 334 }, this.options.resizeDuration, 'swing', function() { 335 postResize(); 336 }); 337 } else { 338 postResize(); 339 } 340 }; 341 342 // Display the image and its details and begin preload neighboring images. 343 Lightbox.prototype.showImage = function() { 344 this.$lightbox.find('.lb-loader').stop(true).hide(); 345 this.$lightbox.find('.lb-image').fadeIn('slow'); 346 347 this.updateNav(); 348 this.updateDetails(); 349 this.preloadNeighboringImages(); 350 this.enableKeyboardNav(); 351 }; 352 353 // Display previous and next navigation if appropriate. 354 Lightbox.prototype.updateNav = function() { 355 // Check to see if the browser supports touch events. If so, we take the conservative approach 356 // and assume that mouse hover events are not supported and always show prev/next navigation 357 // arrows in image sets. 358 var alwaysShowNav = false; 359 try { 360 document.createEvent('TouchEvent'); 361 alwaysShowNav = (this.options.alwaysShowNavOnTouchDevices) ? true : false; 362 } catch (e) {} 363 364 this.$lightbox.find('.lb-nav').show(); 365 366 if (this.album.length > 1) { 367 if (this.options.wrapAround) { 368 if (alwaysShowNav) { 369 this.$lightbox.find('.lb-prev, .lb-next').css('opacity', '1'); 370 } 371 this.$lightbox.find('.lb-prev, .lb-next').show(); 372 } else { 373 if (this.currentImageIndex > 0) { 374 this.$lightbox.find('.lb-prev').show(); 375 if (alwaysShowNav) { 376 this.$lightbox.find('.lb-prev').css('opacity', '1'); 377 } 378 } 379 if (this.currentImageIndex < this.album.length - 1) { 380 this.$lightbox.find('.lb-next').show(); 381 if (alwaysShowNav) { 382 this.$lightbox.find('.lb-next').css('opacity', '1'); 383 } 384 } 385 } 386 } 387 }; 388 389 // Display caption, image number, and closing button. 390 Lightbox.prototype.updateDetails = function() { 391 var self = this; 392 393 // Enable anchor clicks in the injected caption html. 394 // Thanks Nate Wright for the fix. @https://github.com/NateWr 395 if (typeof this.album[this.currentImageIndex].title !== 'undefined' && 396 this.album[this.currentImageIndex].title !== '') { 397 this.$lightbox.find('.lb-caption') 398 .html(this.album[this.currentImageIndex].title) 399 .fadeIn('fast') 400 .find('a').on('click', function(event) { 401 if ($(this).attr('target') !== undefined) { 402 window.open($(this).attr('href'), $(this).attr('target')); 403 } else { 404 location.href = $(this).attr('href'); 405 } 406 }); 407 } 408 409 if (this.album.length > 1 && this.options.showImageNumberLabel) { 410 var labelText = this.imageCountLabel(this.currentImageIndex + 1, this.album.length); 411 this.$lightbox.find('.lb-number').text(labelText).fadeIn('fast'); 412 } else { 413 this.$lightbox.find('.lb-number').hide(); 414 } 415 416 this.$outerContainer.removeClass('animating'); 417 418 this.$lightbox.find('.lb-dataContainer').fadeIn(this.options.resizeDuration, function() { 419 return self.sizeOverlay(); 420 });
421 }; 422 423 // Preload previous and next images in set. 424 Lightbox.prototype.preloadNeighboringImages = function() { 425 if (this.album.length > this.currentImageIndex + 1) { 426 var preloadNext = new Image(); 427 preloadNext.src = this.album[this.currentImageIndex + 1].link; 428 } 429 if (this.currentImageIndex > 0) { 430 var preloadPrev = new Image(); 431 preloadPrev.src = this.album[this.currentImageIndex - 1].link; 432 } 433 }; 434 435 Lightbox.prototype.enableKeyboardNav = function() { 436 $(document).on('keyup.keyboard', $.proxy(this.keyboardAction, this)); 437 }; 438 439 Lightbox.prototype.disableKeyboardNav = function() { 440 $(document).off('.keyboard'); 441 }; 442 443 Lightbox.prototype.keyboardAction = function(event) { 444 var KEYCODE_ESC = 27; 445 var KEYCODE_LEFTARROW = 37; 446 var KEYCODE_RIGHTARROW = 39; 447 448 var keycode = event.keyCode; 449 var key = String.fromCharCode(keycode).toLowerCase(); 450 if (keycode === KEYCODE_ESC || key.match(/x|o|c/)) { 451 this.end(); 452 } else if (key === 'p' || keycode === KEYCODE_LEFTARROW) { 453 if (this.currentImageIndex !== 0) { 454 this.changeImage(this.currentImageIndex - 1); 455 } else if (this.options.wrapAround && this.album.length > 1) { 456 this.changeImage(this.album.length - 1); 457 } 458 } else if (key === 'n' || keycode === KEYCODE_RIGHTARROW) { 459 if (this.currentImageIndex !== this.album.length - 1) { 460 this.changeImage(this.currentImageIndex + 1); 461 } else if (this.options.wrapAround && this.album.length > 1) { 462 this.changeImage(0); 463 } 464 } 465 }; 466 467 // Closing time. :-( 468 Lightbox.prototype.end = function() { 469 this.disableKeyboardNav(); 470 $(window).off('resize', this.sizeOverlay); 471 this.$lightbox.fadeOut(this.options.fadeDuration); 472 this.$overlay.fadeOut(this.options.fadeDuration); 473 $('select, object, embed').css({ 474 visibility: 'visible' 475 }); 476 if (this.options.disableScrolling) { 477 $('body').removeClass('lb-disable-scrolling'); 478 } 479 }; 480 481 return new Lightbox(); 482}));
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.