diff --git a/script/lightbox.js b/script/lightbox.js index bce8efc..b60402e 100644 --- a/script/lightbox.js +++ b/script/lightbox.js @@ -1,11 +1,11 @@ /*! - * Lightbox v2.11.0 + * Lightbox v2.11.1 * by Lokesh Dhakar * * More info: * http://lokeshdhakar.com/projects/lightbox2/ * - * Copyright 2007, 2018, 2019 Lokesh Dhakar + * Copyright Lokesh Dhakar * Released under the MIT license * https://github.com/lokesh/lightbox2/blob/master/LICENSE * @@ -102,7 +102,19 @@ } var self = this; - $('
').appendTo($('body')); + + // The two root notes generated, #lightboxOverlay and #lightbox are given + // tabindex attrs so they are focusable. We attach our keyboard event + // listeners to these two elements, and not the document. Clicking anywhere + // while Lightbox is opened will keep the focus on or inside one of these + // two elements. + // + // We do this so we can prevent propogation of the Esc keypress when + // Lightbox is open. This prevents it from intefering with other components + // on the page below. + // + // Github issue: https://github.com/lokesh/lightbox2/issues/663 + $('
').appendTo($('body')); // Cache jQuery objects this.$lightbox = $('#lightbox'); @@ -150,7 +162,6 @@ if ($(event.target).attr('id') === 'lightbox') { self.end(); } - return false; }); this.$outerContainer.on('click', function(event) { @@ -217,10 +228,6 @@ $window.on('resize', $.proxy(this.sizeOverlay, this)); - $('select, object, embed').css({ - visibility: 'hidden' - }); - this.sizeOverlay(); this.album = []; @@ -265,7 +272,8 @@ } } } - + + // Position Lightbox var top = $window.scrollTop() + this.options.positionFromTop; var left = $window.scrollLeft(); @@ -276,7 +284,7 @@ // Disable scrolling of the page while open if (this.options.disableScrolling) { - $('html').addClass('lb-disable-scrolling'); + $('body').addClass('lb-disable-scrolling'); } this.changeImage(imageNumber); @@ -285,12 +293,15 @@ // Hide most UI elements in preparation for the animated resizing of the lightbox. Lightbox.prototype.changeImage = function(imageNumber) { var self = this; - - this.disableKeyboardNav(); + var filename = this.album[imageNumber].link; + var filetype = filename.split('.').slice(-1)[0]; var $image = this.$lightbox.find('.lb-image'); - this.$overlay.fadeIn(this.options.fadeDuration); + // Disable keyboard nav during transitions + this.disableKeyboardNav(); + // Show loading state + this.$overlay.fadeIn(this.options.fadeDuration); $('.lb-loader').fadeIn('slow'); //ADDED-START //this.$lightbox.find('.lb-image, .lb-nav, .lb-prev, .lb-next, .lb-dataContainer, .lb-numbers, .lb-caption').hide(); @@ -314,9 +325,9 @@ windowWidth = $(window).width(); windowHeight = $(window).height(); maxVideoWidth = windowWidth - self.containerPadding.left - self.containerPadding.right - self.videoBorderWidth.left - self.videoBorderWidth.right - 20; - maxVideoHeight = windowHeight - self.containerPadding.top - self.containerPadding.bottom - self.videoBorderWidth.top - self.videoBorderWidth.bottom - 120; + maxVideoHeight = windowHeight - self.containerPadding.top - self.containerPadding.bottom - self.videoBorderWidth.top - self.videoBorderWidth.bottom - 70; - //Check if image size is larger then maxWidth|maxHeight in settings + //Check if image size is larger than maxWidth|maxHeight in settings if(self.options.maxWidth && self.options.maxWidth < maxVideoWidth) maxVideoWidth = self.options.maxWidth; if(self.options.maxHeight && self.options.maxHeight < maxVideoWidth) maxVideoHeight = self.options.maxHeight; @@ -367,7 +378,7 @@ $image.attr({ 'alt': self.album[imageNumber].alt, - 'src': self.album[imageNumber].link + 'src': filename }); $preloader = $(preloader); @@ -382,38 +393,58 @@ $image.width(preloader.width); $image.height(preloader.height); + windowWidth = $(window).width(); + windowHeight = $(window).height(); + // Calculate the max image dimensions for the current viewport. + // Take into account the border around the image and an additional 10px gutter on each side. + maxImageWidth = windowWidth - self.containerPadding.left - self.containerPadding.right - self.imageBorderWidth.left - self.imageBorderWidth.right - 20; + maxImageHeight = windowHeight - self.containerPadding.top - self.containerPadding.bottom - self.imageBorderWidth.top - self.imageBorderWidth.bottom - self.options.positionFromTop - 70; + + /* + SVGs that don't have width and height attributes specified are reporting width and height + values of 0 in Firefox 47 and IE11 on Windows. To fix, we set the width and height to the max + dimensions for the viewport rather than 0 x 0. + + https://github.com/lokesh/lightbox2/issues/552 + */ + + if (filetype === 'svg') { + if ((preloader.width === 0) || preloader.height === 0) { + $image.width(maxImageWidth); + $image.height(maxImageHeight); + } + } + + // Fit image inside the viewport. if (self.options.fitImagesInViewport) { - // Fit image inside the viewport. - // Take into account the border around the image and an additional 10px gutter on each side. - - windowWidth = $(window).width(); - windowHeight = $(window).height(); - maxImageWidth = windowWidth - self.containerPadding.left - self.containerPadding.right - self.imageBorderWidth.left - self.imageBorderWidth.right - 20; - maxImageHeight = windowHeight - self.containerPadding.top - self.containerPadding.bottom - self.imageBorderWidth.top - self.imageBorderWidth.bottom - 120; // Check if image size is larger then maxWidth|maxHeight in settings if (self.options.maxWidth && self.options.maxWidth < maxImageWidth) { maxImageWidth = self.options.maxWidth; } - if (self.options.maxHeight && self.options.maxHeight < maxImageWidth) { + if (self.options.maxHeight && self.options.maxHeight < maxImageHeight) { maxImageHeight = self.options.maxHeight; } - // Is the current image's width or height is greater than the maxImageWidth or maxImageHeight - // option than we need to size down while maintaining the aspect ratio. - if ((preloader.width > maxImageWidth) || (preloader.height > maxImageHeight)) { - if ((preloader.width / maxImageWidth) > (preloader.height / maxImageHeight)) { - imageWidth = maxImageWidth; - imageHeight = parseInt(preloader.height / (preloader.width / imageWidth), 10); - $image.width(imageWidth); - $image.height(imageHeight); - } else { - imageHeight = maxImageHeight; - imageWidth = parseInt(preloader.width / (preloader.height / imageHeight), 10); - $image.width(imageWidth); - $image.height(imageHeight); - } + } else { + maxImageWidth = self.options.maxWidth || preloader.width || maxImageWidth; + maxImageHeight = self.options.maxHeight || preloader.height || maxImageHeight; + } + + // Is the current image's width or height is greater than the maxImageWidth or maxImageHeight + // option than we need to size down while maintaining the aspect ratio. + if ((preloader.width > maxImageWidth) || (preloader.height > maxImageHeight)) { + if ((preloader.width / maxImageWidth) > (preloader.height / maxImageHeight)) { + imageWidth = maxImageWidth; + imageHeight = parseInt(preloader.height / (preloader.width / imageWidth), 10); + $image.width(imageWidth); + $image.height(imageHeight); + } else { + imageHeight = maxImageHeight; + imageWidth = parseInt(preloader.width / (preloader.height / imageHeight), 10); + $image.width(imageWidth); + $image.height(imageHeight); } } //ADDED-START @@ -422,24 +453,37 @@ //ADDED-END }; - preloader.src = this.album[imageNumber].link; + // Preload image before showing + preloader.src = this.album[imageNumber].link; this.currentImageIndex = imageNumber; }; // Stretch overlay to fit the viewport Lightbox.prototype.sizeOverlay = function() { - this.$overlay - .width($(document).width()) - .height($(document).height()); + var self = this; + /* + We use a setTimeout 0 to pause JS execution and let the rendering catch-up. + Why do this? If the `disableScrolling` option is set to true, a class is added to the body + tag that disables scrolling and hides the scrollbar. We want to make sure the scrollbar is + hidden before we measure the document width, as the presence of the scrollbar will affect the + number. + */ + setTimeout(function() { + self.$overlay + .width($(document).width()) + .height($(document).height()); + + }, 0); }; // Animate the size of the lightbox to fit the image we are showing + // This method also shows the the image. //ADDED-START //Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight) { Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight, media) { media = media || 'image'; //ADDED-END - var self = this; + var self = this; var oldWidth = this.$outerContainer.outerWidth(); var oldHeight = this.$outerContainer.outerHeight(); @@ -455,6 +499,10 @@ self.$lightbox.find('.lb-dataContainer').width(newWidth); self.$lightbox.find('.lb-prevLink').height(newHeight); self.$lightbox.find('.lb-nextLink').height(newHeight); + + // Set focus on one of the two root nodes so keyboard events are captured. + self.$overlay.focus(); + self.showImage(); } @@ -525,7 +573,7 @@ // Display caption, image number, and closing button. Lightbox.prototype.updateDetails = function() { var self = this; - + // Enable anchor clicks in the injected caption html. // Thanks Nate Wright for the fix. @https://github.com/NateWr if (typeof this.album[this.currentImageIndex].title !== 'undefined' && @@ -536,14 +584,7 @@ } else { $caption.html(this.album[this.currentImageIndex].title); } - $caption.fadeIn('fast') - .find('a').on('click', function(event) { - if ($(this).attr('target') !== undefined) { - window.open($(this).attr('href'), $(this).attr('target')); - } else { - location.href = $(this).attr('href'); - } - }); + $caption.fadeIn('fast'); } if (this.album.length > 1 && this.options.showImageNumberLabel) { @@ -573,11 +614,13 @@ }; Lightbox.prototype.enableKeyboardNav = function() { - $(document).on('keyup.keyboard', $.proxy(this.keyboardAction, this)); + this.$lightbox.on('keyup.keyboard', $.proxy(this.keyboardAction, this)); + this.$overlay.on('keyup.keyboard', $.proxy(this.keyboardAction, this)); }; Lightbox.prototype.disableKeyboardNav = function() { - $(document).off('.keyboard'); + this.$lightbox.off('.keyboard'); + this.$overlay.off('.keyboard'); }; Lightbox.prototype.keyboardAction = function(event) { @@ -586,16 +629,18 @@ var KEYCODE_RIGHTARROW = 39; var keycode = event.keyCode; - var key = String.fromCharCode(keycode).toLowerCase(); - if (keycode === KEYCODE_ESC || key.match(/x|o|c/)) { + + if (keycode === KEYCODE_ESC) { + // Prevent bubbling so as to not affect other components on the page. + event.stopPropagation(); this.end(); - } else if (key === 'p' || keycode === KEYCODE_LEFTARROW) { + } else if (keycode === KEYCODE_LEFTARROW) { if (this.currentImageIndex !== 0) { this.changeImage(this.currentImageIndex - 1); } else if (this.options.wrapAround && this.album.length > 1) { this.changeImage(this.album.length - 1); } - } else if (key === 'n' || keycode === KEYCODE_RIGHTARROW) { + } else if (keycode === KEYCODE_RIGHTARROW) { if (this.currentImageIndex !== this.album.length - 1) { this.changeImage(this.currentImageIndex + 1); } else if (this.options.wrapAround && this.album.length > 1) { @@ -622,11 +667,9 @@ $(window).off('resize', this.sizeOverlay); this.$lightbox.fadeOut(this.options.fadeDuration); this.$overlay.fadeOut(this.options.fadeDuration); - $('select, object, embed').css({ - visibility: 'visible' - }); + if (this.options.disableScrolling) { - $('html').removeClass('lb-disable-scrolling'); + $('body').removeClass('lb-disable-scrolling'); } };