jquery.lightbox.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. /**
  2. * WP jQuery Lightbox
  3. * Version 1.4.8.2 - 2021-01-23
  4. *
  5. * @author Ulf Benjaminsson (http://www.ulfbenjaminsson.com)
  6. *
  7. * This is a modified version of Warren Krevenkis Lightbox-port (see notice below) for use in the WP jQuery Lightbox-
  8. * plugin (http://wordpress.org/extend/plugins/wp-jquery-lightbox/)
  9. * Modifications include:
  10. * . migrated to modern jQuery (Thanks: [Joseph Rézeau aka papijo](https://www.rezeau.org/)!)
  11. * . improved support of Gutenberg editor's image captions (Thanks: [Joseph Rézeau aka papijo](https://www.rezeau.org/)!)
  12. * . added slideshow
  13. * . added swipe-support
  14. * . added "support" for WordPress admin bar.
  15. * . improved the resizing code to respect aspect ratio
  16. * . improved scaling routines to maximize images while taking captions into account
  17. * . added support for browser resizing and orientation changes
  18. * . grabs image caption from WordPress [gallery] or media library output
  19. * . using WordPress API to localize script (with safe fallbacks)
  20. * . grabs image title if the link lacks one
  21. * . using rel attribute instead of class
  22. * . auto-lightboxing all links after page load
  23. * . replaced explicit IMG-urls with divs, styled through the CSS.
  24. * . honors empty captions / titles
  25. * . use only title if captions is identical
  26. * . added support for disabling all animations
  27. * . using no-conflict mode (for good measure)
  28. **/
  29. /**
  30. * jQuery Lightbox
  31. * Version 0.5 - 11/29/2007
  32. * @author Warren Krewenki
  33. *
  34. * This package is distributed under the BSD license.
  35. * For full license information, see LICENSE.TXT
  36. *
  37. * Based on Lightbox 2 by Lokesh Dhakar (http://www.huddletogether.com/projects/lightbox2/)
  38. * Originally written to make use of the Prototype framework, and Script.acalo.us, now altered to use jQuery.
  39. **/
  40. (function($){
  41. //http://stackoverflow.com/a/16187766/347764
  42. function versionCompare(a, b){
  43. var i, l, d;
  44. a = a.split('.');
  45. b = b.split('.');
  46. l = Math.min(a.length, b.length);
  47. for (i=0; i<l; i++) {
  48. d = parseInt(a[i], 10) - parseInt(b[i], 10);
  49. if (d !== 0) {
  50. return d;
  51. }
  52. }
  53. return a.length - b.length;
  54. }
  55. $.fn.lightbox = function(options) {
  56. var opts = $.extend({}, $.fn.lightbox.defaults, options);
  57. if($("#overlay").is(':visible')){//to resize the overlay whenever doLightbox is invoked
  58. $(window).trigger('resize'); //we need this to deal with InfiniteScroll and similar.
  59. }
  60. function onClick() {
  61. initialize();
  62. start(this);
  63. return false;
  64. }
  65. if(versionCompare($.fn.jquery, '1.7') > 0){
  66. return $(this).on("click", onClick);
  67. }else{
  68. return $(this).live("click", onClick); //deprecated since 1.7
  69. }
  70. function initialize() {
  71. $(window).on('orientationchange', resizeListener);
  72. $(window).on('resize', resizeListener);
  73. $('#overlay').remove();
  74. $('#lightbox').remove();
  75. opts.inprogress = false;
  76. opts.auto = -1;
  77. var txt = opts.strings;
  78. var arrowLeft = '<svg id="prevArrow" width="60px" height="60px" viewBox="-5.5 0 26 26" xmlns="http://www.w3.org/2000/svg"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-423.000000, -1196.000000)" fill="currentColor"><path d="M428.115,1209 L437.371,1200.6 C438.202,1199.77 438.202,1198.43 437.371,1197.6 C436.541,1196.76 435.194,1196.76 434.363,1197.6 L423.596,1207.36 C423.146,1207.81 422.948,1208.41 422.985,1209 C422.948,1209.59 423.146,1210.19 423.596,1210.64 L434.363,1220.4 C435.194,1221.24 436.541,1221.24 437.371,1220.4 C438.202,1219.57 438.202,1218.23 437.371,1217.4 L428.115,1209" id="chevron-left"></path></g></g></svg>';
  79. var arrowRight = '<svg id="nextArrow" width="60px" height="60px" viewBox="-5.5 0 26 26" xmlns="http://www.w3.org/2000/svg"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-474.000000, -1196.000000)" fill="currentColor"><path d="M488.404,1207.36 L477.637,1197.6 C476.806,1196.76 475.459,1196.76 474.629,1197.6 C473.798,1198.43 473.798,1199.77 474.629,1200.6 L483.885,1209 L474.629,1217.4 C473.798,1218.23 473.798,1219.57 474.629,1220.4 C475.459,1221.24 476.806,1221.24 477.637,1220.4 L488.404,1210.64 C488.854,1210.19 489.052,1209.59 489.015,1209 C489.052,1208.41 488.854,1207.81 488.404,1207.36"></path></g></g></svg>';
  80. var navigation = opts.newNavStyle
  81. ? '<div id="newHoverNav">' + arrowLeft + arrowRight + '</div>'
  82. : '<div id="hoverNav"><a href="javascript://" title="' + txt.prevLinkTitle + '" id="prevLink"></a><a href="javascript://" id="nextLink" title="' + txt.nextLinkTitle + '"></a></div>';
  83. var swipeNavigation = opts.newNavStyle
  84. ? arrowLeft + arrowRight
  85. : '<a href="javascript://" title="' + txt.prevLinkTitle + '" id="prevLink" class="touch-device"></a><a href="javascript://" id="nextLink" class="touch-device" title="' + txt.nextLinkTitle + '"></a>';
  86. var outerImage = '<div id="outerImageContainer"><div id="imageContainer"><img id="lightboxImage">' + navigation + '<div id="jqlb_loading"><a href="javascript://" id="loadingLink"><div id="jqlb_spinner"></div></a></div></div></div>';
  87. if ( jqlbIsTouchDevice() ) {
  88. outerImage = '<div id="outerImageContainer"><div id="imageContainer"><img id="lightboxImage">' + swipeNavigation + '<div id="jqlb_loading"><a href="javascript://" id="loadingLink"><div id="jqlb_spinner"></div></a></div></div></div>';
  89. }
  90. var imageData = '<div id="imageDataContainer" class="clearfix"><div id="imageData"><div id="imageDetails"><span id="titleAndCaption"></span><div id="controls"><span id="numberDisplay"></span> <a id="playPause" href="#"></a> <span id="downloadLink"></span></div></div><div id="bottomNav">';
  91. imageData += '<a href="javascript://" id="bottomNavClose" title="' + txt.closeTitle + '"><div id="jqlb_closelabel"></div></a></div></div></div>';
  92. var string;
  93. if ( opts.navbarOnTop ) {
  94. string = '<div id="overlay"></div><div id="lightbox">' + imageData + outerImage + '</div>';
  95. $("body").append(string);
  96. $("#imageDataContainer").addClass('ontop');
  97. } else {
  98. string = '<div id="overlay"></div><div id="lightbox">' + outerImage + imageData + '</div>';
  99. $("body").append(string);
  100. }
  101. $("#overlay").on("click", function () { end(); }).hide();
  102. $("#lightbox").on("click", function () { end(); }).hide();
  103. $("#loadingLink").on("click", function () { end(); return false; });
  104. $("#bottomNavClose").on("click", function () { end(); return false; });
  105. $('#outerImageContainer').width(opts.widthCurrent).height(opts.heightCurrent);
  106. $('#imageDataContainer').width(opts.widthCurrent);
  107. if (!opts.imageClickClose) {
  108. $("#lightboxImage").on("click", function () { return false; });
  109. $("#hoverNav").on("click", function () { return false; });
  110. }
  111. // Apply color options
  112. $("#outerImageContainer").css({ "background-color": opts.borderColor });
  113. $("#overlay").css({
  114. "background-color": opts.overlayColor ?? '#000',
  115. "opacity": opts.overlayOpacity ?? '.6',
  116. "font-style": "italic"
  117. });
  118. // Hide/show infobar
  119. if ( ! opts.showInfoBar ) {
  120. $('#imageDataContainer').addClass('hide');
  121. }
  122. // Fixed nav postion infobar
  123. if ( opts.fixedNav ) {
  124. $('#prevArrow').addClass('fixed');
  125. $('#nextArrow').addClass('fixed');
  126. }
  127. };
  128. //allow image to reposition & scale if orientation change or resize occurs.
  129. function resizeListener(e) {
  130. if (opts.resizeTimeout) {
  131. clearTimeout(opts.resizeTimeout);
  132. opts.resizeTimeout = false;
  133. }
  134. opts.resizeTimeout = setTimeout(function () { doScale(); }, 50); //a delay to avoid duplicate event calls.
  135. }
  136. function getPageSize(){
  137. return {
  138. pageWidth:$(document).width(), //returns width of HTML document
  139. pageHeight:$(document).height(),
  140. viewportWidth:$(window).width(), //width of browser viewport, minus scrollbars
  141. viewportHeight:$(window).height()-opts.adminBarHeight,
  142. };
  143. };
  144. function getPageScroll() {
  145. var yScroll = $(document).scrollTop();
  146. if(opts.adminBarHeight && parseInt($('#wpadminbar').css('top'), 10) === 0){
  147. yScroll += opts.adminBarHeight;
  148. }
  149. return {x:$(document).scrollLeft(), y:yScroll};
  150. };
  151. function start(imageLink) {
  152. var pageSize = getPageSize();
  153. var newTop = 0;
  154. $("#overlay").hide().css({width: pageSize.pageWidth + 'px', height: pageSize.pageHeight + 'px', opacity: opts.overlayOpacity*100 + '%'}).fadeIn(400);
  155. var imageNum = 0;
  156. var images = [];
  157. opts.downloads = {}; //to keep track of any custom download links
  158. $("a").each(function(){
  159. if(!this.href || (this.rel != imageLink.rel)) {
  160. return;
  161. }
  162. var jqThis = $(this);
  163. var title = opts.showTitle ? getTitle(jqThis) : '';
  164. var caption = {html:'',text:''};
  165. if (opts.showCaption) {
  166. // Case if Gutenberg blocks : the caption now resides inside the <figcaption> tag.
  167. var figureCaption = jqThis.parent().children('figcaption')[0];
  168. if (figureCaption !== undefined) { // Case Gutenberg blocks
  169. caption.html = figureCaption.innerHTML;
  170. } else { // Case Classic blocks
  171. var caption = getCaption(jqThis);
  172. }
  173. }
  174. if (opts.showTitle && title.toLowerCase() == caption.text.toLowerCase()) {
  175. title = caption.html; //to keep linked captions
  176. caption.html = ''; //but not duplicate the text
  177. }
  178. var s = (title != '') ? '<span id="titleText">' + title + '</span>' : '';
  179. s += (title != '' && caption.html)? '<br />' : '';
  180. s += (caption.html != '') ? '<span id="captionText">' + caption.html +'</span>' : '';
  181. if(opts.showDownload || jqThis.attr("data-download")){
  182. opts.downloads[images.length] = jqThis.attr("data-download"); //use length as an index. convenient since it will always be unique
  183. }
  184. images.push(new Array(this.href, s, images.length));
  185. });
  186. if (images.length > 1) {
  187. for (i = 0; i < images.length; i++) {
  188. for (j = images.length - 1; j > i; j--) {
  189. if (images[i][0] == images[j][0]) {
  190. images.splice(j, 1);
  191. }
  192. }
  193. }
  194. while (images[imageNum][0] != imageLink.href) { imageNum++; }
  195. }
  196. opts.imageArray = images;
  197. var scroll = getPageScroll();
  198. setLightBoxPos(scroll.y, scroll.x).show();// calculate top and left offset for the lightbox
  199. changeImage(imageNum);
  200. // Set panzoom on initial image
  201. if ( jqlbIsZoomEnabled() ) {
  202. var lightboxImage = document.getElementById( 'lightboxImage' );
  203. panzoom = Panzoom( lightboxImage, { maxScale: 5, minScale: 1, panOnlyWhenZoomed: true } );
  204. }
  205. setNav();
  206. };
  207. function getTitle(jqLink){
  208. var title = jqLink.attr("title") || '';
  209. var jqImg = jqLink.children('img:first-child');
  210. if ( opts.useAltForTitle && ( jqLink.attr('alt') || jqImg.attr('alt') ) ) {
  211. title = jqLink.attr('alt') ? jqLink.attr('alt') : jqImg.attr('alt');
  212. }
  213. if(!title){
  214. var jqImg = jqLink.children('img:first-child');
  215. if (jqImg.attr('title')) {
  216. title = jqImg.attr('title'); //grab the title from the image if the link lacks one
  217. } else if(jqImg.attr('alt')){
  218. title = jqImg.attr('alt'); //if neither link nor image have a title attribute
  219. }
  220. }
  221. return DOMPurify.sanitize(title);
  222. }
  223. function getCaption(jqLink){
  224. var caption = {html:'',text:''};
  225. if (jqLink.parent().next('.gallery-caption').html()) {
  226. var jq = jqLink.parent().next('.gallery-caption');
  227. caption.html = jq.html(); //holds html, links etc
  228. caption.text = jq.text(); //plain-text
  229. } else if (jqLink.next('.wp-caption-text').html()) {
  230. caption.html = jqLink.next('.wp-caption-text').html();
  231. caption.text = jqLink.next('.wp-caption-text').text();
  232. }
  233. caption.text = caption.text.trim().replace('&#8217;', '&#039;').replace('’', '\'').replace('…', '...');//http://nickjohnson.com/b/wordpress-apostrophe-vs-right-single-quote
  234. return caption;
  235. }
  236. function setLightBoxPos(newTop, newLeft) {
  237. if (opts.resizeSpeed > 0) {
  238. return $('#lightbox').animate({ top: newTop+ 'px', left: newLeft+ 'px' }, opts.resizeSpeed, 'linear');
  239. }
  240. return $('#lightbox').css({ top: newTop + 'px', left: newLeft + 'px' });
  241. };
  242. function changeImage(imageNum) {
  243. if (opts.inprogress != false) {
  244. return;
  245. }
  246. opts.inprogress = true;
  247. opts.activeImage = imageNum;
  248. // hide elements during transition
  249. $('#jqlb_loading').show();
  250. $('#lightboxImage').hide();
  251. $('#hoverNav').hide();
  252. $('#prevLink').hide();
  253. $('#nextLink').hide();
  254. $('#prevArrow').hide();
  255. $('#nextArrow').hide();
  256. doChangeImage();
  257. };
  258. function doChangeImage() {
  259. opts.imgPreloader = new Image();
  260. opts.imgPreloader.onload = function () {
  261. $('#lightboxImage').attr('src', opts.imageArray[opts.activeImage][0]);
  262. updateDetails();
  263. doScale(); // once image is preloaded, resize image container
  264. preloadNeighborImages();
  265. };
  266. opts.imgPreloader.src = opts.imageArray[opts.activeImage][0];
  267. };
  268. function doScale() {
  269. if (!opts.imgPreloader) {
  270. return;
  271. }
  272. var newWidth = opts.imgPreloader.width;
  273. var newHeight = opts.imgPreloader.height;
  274. var pageSize = getPageSize();
  275. var noScrollWidth = (pageSize.viewportWidth < pageSize.pageWidth) ? pageSize.pageWidth : pageSize.viewportWidth; //if viewport is smaller than page, use page width.
  276. $("#overlay").css({ width: noScrollWidth + 'px', height: pageSize.pageHeight + 'px' });
  277. var maxHeight = (pageSize.viewportHeight) - ($("#imageDataContainer").outerHeight(true) + (2 * opts.borderSize));
  278. var maxWidth = (pageSize.viewportWidth) - (2*opts.borderSize);
  279. if(opts.fitToScreen){
  280. var displayHeight = maxHeight-opts.marginSize;
  281. var displayWidth = maxWidth-opts.marginSize;
  282. var ratio = 1;
  283. if (newHeight > displayHeight) {
  284. ratio = displayHeight / newHeight; //ex. 600/1024 = 0.58
  285. }
  286. newWidth = newWidth * ratio;
  287. newHeight = newHeight * ratio;
  288. ratio = 1;
  289. if (newWidth > displayWidth) {
  290. ratio = displayWidth / newWidth; //ex. 800/1280 == 0.62
  291. }
  292. newWidth = Math.round(newWidth * ratio);
  293. newHeight = Math.round(newHeight * ratio);
  294. }
  295. var scroll = getPageScroll();
  296. var centerY = scroll.y + (maxHeight * 0.5);
  297. var newTop = centerY - (newHeight * 0.5);
  298. var newLeft = scroll.x;
  299. $('#lightboxImage').width(newWidth).height(newHeight);
  300. resizeImageContainer(newWidth, newHeight, newTop, newLeft);
  301. }
  302. function resizeImageContainer(imgWidth, imgHeight, lightboxTop, lightboxLeft) {
  303. opts.widthCurrent = $("#outerImageContainer").outerWidth();
  304. opts.heightCurrent = $("#outerImageContainer").outerHeight();
  305. var widthNew = Math.max(300, imgWidth + (opts.borderSize * 2)); //300 = iphone. http://wordpress.org/support/topic/image-not-resized-correctly-with-wptouch?replies=6#post-4205735
  306. var heightNew = (imgHeight + (opts.borderSize * 2));
  307. setLightBoxPos(lightboxTop, lightboxLeft);
  308. $('#imageDataContainer').animate({width:widthNew}, opts.resizeSpeed, 'linear');
  309. $('#outerImageContainer').animate({width:widthNew,height:heightNew}, opts.resizeSpeed, 'linear', function () {
  310. showImage();
  311. });
  312. if (opts.imageArray.length > 1) {
  313. $('#hoverNav').show();
  314. $('#prevLink').show();
  315. $('#nextLink').show();
  316. $('#prevArrow').show();
  317. $('#nextArrow').show();
  318. }
  319. $('#prevLink,#nextLink').height(imgHeight);
  320. };
  321. function showImage(){
  322. $('#jqlb_loading').hide();
  323. showDetails();
  324. if(opts.resizeSpeed > 0){
  325. $('#lightboxImage').fadeIn("fast", function(){
  326. onImageVisible();
  327. });
  328. }else{
  329. $('#lightboxImage').show();
  330. onImageVisible();
  331. }
  332. opts.inprogress = false;
  333. };
  334. function showDetails(){
  335. $('#titleAndCaption').css("opacity", '100%');
  336. if(opts.showDownload){
  337. $('#downloadLink').css('opacity', '100%');
  338. }
  339. if(opts.showNumbers){
  340. $('#numberDisplay').css('opacity', '100%');
  341. }
  342. if(opts.slidehowSpeed){
  343. $('#playPause').css('opacity', '100%');
  344. }
  345. if(opts.resizeSpeed > 0){
  346. $("#imageDetails").animate({opacity: '100%'}, 'fast');
  347. }else{
  348. $("#imageDetails").css('opacity', '100%');
  349. }
  350. }
  351. function onImageVisible(){
  352. if(opts.auto != -1){
  353. clearTimeout(opts.auto); //in case we came here after mouse/keyboard interaction
  354. opts.auto = setTimeout(function(){changeImage((opts.activeImage == (opts.imageArray.length - 1)) ? 0 : opts.activeImage + 1);}, opts.slidehowSpeed);
  355. }
  356. enableKeyboardNav();
  357. // Re-attach panzoom to current image
  358. if ( jqlbIsZoomEnabled() ) {
  359. panzoom?.destroy();
  360. var lightboxImage = document.getElementById( 'lightboxImage' );
  361. panzoom = Panzoom( lightboxImage, { maxScale: 5, minScale: 1, panOnlyWhenZoomed: true } );
  362. }
  363. }
  364. function preloadNeighborImages() {
  365. if (opts.imageArray.length > 1) {
  366. preloadNextImage = new Image();
  367. preloadNextImage.src = opts.imageArray[(opts.activeImage == (opts.imageArray.length - 1)) ? 0 : opts.activeImage + 1][0]
  368. preloadPrevImage = new Image();
  369. preloadPrevImage.src = opts.imageArray[(opts.activeImage == 0) ? (opts.imageArray.length - 1) : opts.activeImage - 1][0]
  370. } else {
  371. if ((opts.imageArray.length - 1) > opts.activeImage) {
  372. preloadNextImage = new Image();
  373. preloadNextImage.src = opts.imageArray[opts.activeImage + 1][0];
  374. }
  375. if (opts.activeImage > 0) {
  376. preloadPrevImage = new Image();
  377. preloadPrevImage.src = opts.imageArray[opts.activeImage - 1][0];
  378. }
  379. }
  380. };
  381. function updateDetails(){ //update caption, title and control, and makes them invisible while we animate into position.
  382. var images = opts.imageArray;
  383. var txt = opts.strings;
  384. var i = opts.activeImage;
  385. var downloadIndex = images[i][2];
  386. var pos = (opts.showNumbers && images.length > 1) ? txt.image + (i + 1) + txt.of + images.length : '';
  387. $("#imageDetails").css("opacity", '100%');
  388. if(images[i][1] != ''){
  389. $('#titleAndCaption').css('opacity', '100%').html(images[i][1]);
  390. }else{
  391. $('#titleAndCaption').empty();
  392. }
  393. if(opts.showNumbers){
  394. $('#numberDisplay').css('opacity', '100%').html(pos);
  395. }else{
  396. $('#numberDisplay').empty();
  397. }
  398. if(opts.slidehowSpeed && images.length > 1){
  399. var pp = (opts.auto === -1) ? txt.play : txt.pause;
  400. $('#playPause').css('opacity', '100%').attr('href', '#').text(pp);
  401. }else{
  402. $('#playPause').empty();
  403. }
  404. if(opts.showDownload || opts.downloads[downloadIndex]){
  405. var url = opts.downloads[downloadIndex] ? opts.downloads[downloadIndex] : images[i][0];
  406. url = DOMPurify.sanitize(url);
  407. if (url.startsWith('http://') || url.startsWith('https://')){
  408. $('#downloadLink').css('opacity', '100%').html($('<a>').attr('href', url).attr('target', '_blank').attr('download', '').text(txt.download));
  409. }
  410. }else{
  411. $('#downloadLink').empty();
  412. }
  413. var position = $('#downloadLink').position();
  414. };
  415. function setNav() {
  416. if (opts.imageArray.length > 1) {
  417. $('#prevLink').on("click", function () {
  418. changeImage((opts.activeImage == 0) ? (opts.imageArray.length - 1) : opts.activeImage - 1);
  419. return false;
  420. });
  421. $('#nextLink').on("click", function () {
  422. changeImage((opts.activeImage == (opts.imageArray.length - 1)) ? 0 : opts.activeImage + 1);
  423. return false;
  424. });
  425. $('#prevArrow').on("click", function () {
  426. changeImage((opts.activeImage == 0) ? (opts.imageArray.length - 1) : opts.activeImage - 1);
  427. return false;
  428. });
  429. $('#nextArrow').on("click", function () {
  430. changeImage((opts.activeImage == (opts.imageArray.length - 1)) ? 0 : opts.activeImage + 1);
  431. return false;
  432. });
  433. if($.fn.touchwipe){
  434. $('#imageContainer').touchwipe({
  435. wipeLeft: function() {
  436. if ( ! isImageZoomed() ) {
  437. changeImage((opts.activeImage == (opts.imageArray.length - 1)) ? 0 : opts.activeImage + 1);
  438. }
  439. },
  440. wipeRight: function() {
  441. if ( ! isImageZoomed() ) {
  442. changeImage((opts.activeImage == 0) ? (opts.imageArray.length - 1) : opts.activeImage - 1);
  443. }
  444. },
  445. min_move_x: 20,
  446. preventDefaultEvents: true
  447. });
  448. }
  449. if(opts.slidehowSpeed){
  450. $('#playPause').off('click').on("click", function() {
  451. if(opts.auto != -1){
  452. $(this).text(opts.strings.play);
  453. clearTimeout(opts.auto);
  454. opts.auto = -1;
  455. }else{
  456. $(this).text(opts.strings.pause);
  457. opts.auto = setTimeout(function(){changeImage((opts.activeImage == (opts.imageArray.length - 1)) ? 0 : opts.activeImage + 1);}, opts.slidehowSpeed);
  458. }
  459. return false;
  460. });
  461. }
  462. enableKeyboardNav();
  463. }
  464. };
  465. function end() {
  466. disableKeyboardNav();
  467. clearTimeout(opts.auto);
  468. opts.auto = -1;
  469. $('#lightbox').hide();
  470. $('#overlay').fadeOut();
  471. };
  472. function keyboardAction(e) {
  473. var o = e.data.opts;
  474. var keycode = e.keyCode;
  475. var escapeKey = 27;
  476. var key = String.fromCharCode(keycode).toLowerCase();
  477. if ((key == 'x') || (key == 'o') || (key == 'c') || (keycode == escapeKey)) { // close lightbox
  478. end();
  479. } else if ((key == 'p') || (keycode == 37)) { // display previous image
  480. disableKeyboardNav();
  481. changeImage((o.activeImage == 0) ? (o.imageArray.length - 1) : o.activeImage - 1);
  482. } else if ((key == 'n') || (keycode == 39)) { // display next image
  483. disableKeyboardNav();
  484. changeImage((o.activeImage == (o.imageArray.length - 1)) ? 0 : o.activeImage + 1);
  485. }
  486. return false;
  487. };
  488. function enableKeyboardNav() {
  489. $(document).off('keydown').on('keydown', {opts: opts}, keyboardAction);
  490. };
  491. function disableKeyboardNav() {
  492. $(document).off('keydown');
  493. };
  494. function isImageZoomed() {
  495. if ( jqlbIsZoomEnabled() && panzoom?.getScale() > 1 ) {
  496. return true;
  497. }
  498. return false;
  499. }
  500. };
  501. $.fn.lightbox.defaults = {
  502. showCaption:false,
  503. showNumbers:true,
  504. adminBarHeight:0, //28
  505. overlayOpacity: '80%',
  506. borderSize: 10,
  507. imageArray: new Array,
  508. activeImage: null,
  509. inprogress: false, //this is an internal state variable. don't touch.
  510. widthCurrent: 300,
  511. heightCurrent: 300,
  512. showTitle: true,
  513. imageClickClose: true
  514. };
  515. $(document).ready(doLightBox);
  516. })(jQuery);
  517. var panzoom = {};
  518. function jqlbIsTouchDevice() {
  519. return (('ontouchstart' in window) ||
  520. (navigator.maxTouchPoints > 0) ||
  521. (navigator.msMaxTouchPoints > 0));
  522. }
  523. function jqlbIsZoomEnabled() {
  524. return JQLBSettings.allowPinchZoom === '1'
  525. }
  526. //you can call doLightBox() manually at any time to activate the lightboxing. Useful for AJAX-loaded content.
  527. function doLightBox(){
  528. var haveConf = (typeof JQLBSettings == 'object');
  529. var ss, rs, ms = 0;
  530. if(haveConf && JQLBSettings.slideshowSpeed) {
  531. ss = parseInt(JQLBSettings.slideshowSpeed);
  532. }
  533. if(haveConf && JQLBSettings.resizeSpeed) {
  534. rs = parseInt(JQLBSettings.resizeSpeed);
  535. }
  536. if(haveConf && JQLBSettings.marginSize){
  537. ms = parseInt(JQLBSettings.marginSize);
  538. }
  539. if(haveConf && jqlbIsTouchDevice() && JQLBSettings.mobileMarginSize){
  540. ms = parseInt(JQLBSettings.mobileMarginSize)
  541. }
  542. var default_strings = {
  543. prevLinkTitle: 'previous image',
  544. nextLinkTitle: 'next image',
  545. closeTitle: 'close image gallery',
  546. image: 'Image ',
  547. of: ' of ',
  548. download: 'Download',
  549. pause: '(pause slideshow)',
  550. play: '(play slideshow)'
  551. };
  552. jQuery('a[rel^="lightbox"]').lightbox({
  553. adminBarHeight: jQuery('#wpadminbar').height() || 0,
  554. showNumbers: (haveConf && JQLBSettings.showNumbers == '1') ? true : false,
  555. showCaption: (haveConf && JQLBSettings.showCaption == '1') ? true : false,
  556. showTitle: (haveConf && JQLBSettings.showTitle == '1') ? true : false,
  557. useAltForTitle: (haveConf && JQLBSettings.useAltForTitle == '1') ? true : false,
  558. marginSize: (haveConf && ms) ? ms : 0,
  559. fitToScreen: (haveConf && JQLBSettings.fitToScreen == '1') ? true : false,
  560. resizeSpeed: (haveConf && rs >= 0) ? rs : 400,
  561. slidehowSpeed: (haveConf && ss >= 0) ? ss : 4000,
  562. showDownload: (haveConf && JQLBSettings.showDownload == '1') ? true : false,
  563. navbarOnTop: (haveConf && JQLBSettings.navbarOnTop == '1') ? true : false,
  564. strings: (haveConf && typeof JQLBSettings.prevLinkTitle == 'string') ? JQLBSettings : default_strings,
  565. borderSize: (haveConf && JQLBSettings?.borderSize ? JQLBSettings?.borderSize : 10),
  566. borderColor: (haveConf && JQLBSettings?.borderColor ),
  567. overlayColor: (haveConf && JQLBSettings?.overlayColor ),
  568. overlayOpacity: (haveConf && JQLBSettings?.overlayOpacity ),
  569. newNavStyle: (haveConf && JQLBSettings?.newNavStyle == '1' ? true : false ),
  570. fixedNav: (haveConf && JQLBSettings?.fixedNav == '1' ? true : false ),
  571. navArrowColor: (haveConf && JQLBSettings?.navArrowColor ),
  572. navBackgroundColor: (haveConf && JQLBSettings?.navBackgroundColor ),
  573. showInfoBar: (haveConf && JQLBSettings?.showInfoBar == '1' ? true : false )
  574. });
  575. }