PageSourceSearch

https://sitecrafter.uk/wp-content/plugins/ultimate-addons-for-gutenberg/assets/js/image-gallery.js?ver=2.20.5

js sitecrafter.uk collected 2026-10-10 01:22:02 UTC 20,695 bytes, 589 lines download raw bytes

1let spectraImageGalleryLoadStatus = true;
2let clickedImageId = null;
3
4const UAGBImageGalleryMasonry = {
5	initByOffset( $selector, instance ){
6		// Verify $selector and instance.
7		if ( ! $selector || ! instance ) {
8			return;
9		}
10
11		// Add class for scroll not init.
12		$selector.classList.add( 'scroll-not-init' );
13
14		// Add class for last image not loaded.
15		$selector.classList.add( 'last-image-not-loaded' );
16
17		const getAllImages = $selector.querySelectorAll( 'img' );
18		if( getAllImages.length ){
19			// Get last image.
20			const getLastImage = getAllImages[ getAllImages.length - 1 ];
21			// Add event listener for last image.
22			getLastImage.addEventListener( 'load', () => {
23					// You can perform additional actions here once the image has loaded.
24					// Remove class for last image not loaded.
25					$selector.classList.remove( 'last-image-not-loaded' );
26					setTimeout( function() {
27						instance.layout();
28					}, 100 );
29				}
30			);
31		}
32
33		let timeOutInstance = null;
34		// Get scroll position dynamically.
35		window.addEventListener( 'scroll', function() {
36			if ( ! $selector.classList.contains( 'scroll-not-init' ) ) {
37				return;
38			}
39			// Clear timeout instance.
40			clearTimeout( timeOutInstance );
41
42			if ( UAGBImageGalleryMasonry.presentInViewport( $selector ) ) {
43				// If $selector comes in view port then init masonry.
44				$selector.classList.remove( 'scroll-not-init' );
45				// Init masonry.
46				timeOutInstance = setTimeout( function() {
47					instance.layout();
48				}, 100 );
49			}
50		} );
51	},
52	init( $attr, $selector, lightboxSettings, thumbnailSettings ) {
53		let count = 2;
54		const windowHeight50 = window.innerHeight / 1.25;
55		const $scope = document.querySelector( $selector );
56		let thumbnailSwiper = null;
57		if ( $attr.lightboxThumbnails ) {
58			thumbnailSwiper = new Swiper( `${$selector}+.spectra-image-gallery__control-lightbox .spectra-image-gallery__control-lightbox--thumbnails`,
59				thumbnailSettings
60			);
61			lightboxSettings = {
62				...lightboxSettings,
63				thumbs: {
64					swiper: thumbnailSwiper,
65				},
66			}
67		}
68		const lightboxSwiper = new Swiper( `${$selector}+.spectra-image-gallery__control-lightbox .spectra-image-gallery__control-lightbox--main`,
69			lightboxSettings
70		)
71		lightboxSwiper.lazy.load();
72		loadLightBoxImages( $scope, lightboxSwiper, null, $attr, thumbnailSwiper );
73		const loader = $scope?.querySelector( '.spectra-image-gallery__control-loader' );
74		const loadButton = $scope?.querySelector( '.spectra-image-gallery__control-button' );
75		if ( $attr.feedPagination && $attr.paginateUseLoader ) {
76			window.addEventListener( 'scroll', function () {
77				let mediaItem = $scope?.querySelector( '.spectra-image-gallery__media-wrapper' );
78				if ( ! mediaItem ) {
79					mediaItem = $scope;
80				}
81				const boundingClientRect = mediaItem.lastElementChild.getBoundingClientRect();
82				const offsetTop = boundingClientRect.top + window.scrollY;
83				if ( window.pageYOffset + windowHeight50 >= offsetTop ) {
84					const $args = {
85						page_number: count,
86					};
87					const total = $attr.gridPages;
88					if ( spectraImageGalleryLoadStatus ) {
89						if ( count > total ) {
90							loader.style.display = 'none';
91						}
92						if ( count <= total ) {
93							UAGBImageGalleryMasonry.callAjax( $scope, $args, $attr, false, count, $selector, lightboxSwiper, thumbnailSwiper );
94							count++;
95							spectraImageGalleryLoadStatus = false;
96						}
97					}
98				}
99			} );
100		} else if ( $attr.feedPagination && ! $attr.paginateUseLoader ) {
101			loadButton.onclick = function () {
102				const total = $attr.gridPages;
103				const $args = {
104					total,
105					page_number: count,
106				};
107				loadButton.classList.add( 'disabled' );
108				if ( spectraImageGalleryLoadStatus ) {
109					if ( count <= total ) {
110						UAGBImageGalleryMasonry.callAjax( $scope, $args, $attr, false, count, $selector, lightboxSwiper, thumbnailSwiper );
111						count++;
112						spectraImageGalleryLoadStatus = false;
113					}
114				}
115			};
116		}
117	},
118
119	createElementFromHTML( htmlString ) {
120		const htmlElement = document.createElement( 'div' );
121		const htmlCleanString = htmlString.replace( /\s+/gm, ' ' ).replace( /( )+/gm, ' ' ).trim();
122		htmlElement.innerHTML = htmlCleanString;
123		return htmlElement;
124	},
125
126	getCustomURL( image, $attr ) {
127		const urlValidRegex = new RegExp(
128			'^((http|https)://)(www.)?[a-zA-Z0-9@:%._\\+~#?&//=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%._\\+~#?&//=]*)$'
129		);
130		const imageID = parseInt( image.getAttribute( 'data-spectra-gallery-image-id' ) );
131		return urlValidRegex.test( $attr?.customLinks[ imageID ] ) ? $attr.customLinks[ imageID ] : undefined;
132	},
133
134	openCustomURL( customURL ) {
135		window.open( customURL, '_blank' );
136	},
137
138	addClickEvents( element, $attr ) {
139		const imageElements = element?.querySelectorAll( '.spectra-image-gallery__media-wrapper' );
140		imageElements.forEach( ( image ) => {
141			const imageURL = UAGBImageGalleryMasonry.getCustomURL( image, $attr );
142			if ( imageURL ) {
143				image.style.cursor = 'pointer';
144				image.addEventListener( 'click', () => UAGBImageGalleryMasonry.openCustomURL( imageURL ) );
145				image.addEventListener( 'keydown', ( event ) => {
146					if ( 13 === event.keyCode || 32 === event.keyCode ) {
147						event.preventDefault();
148						UAGBImageGalleryMasonry.openCustomURL( imageURL );
149					}
150				} );
151			}
152		} );
153	},
154
155	callAjax( $scope, $obj, $attr, append = false, count, $selector, lightboxSwiper, thumbnailSwiper ) {
156		const mediaData = new FormData();
157		mediaData.append( 'action', 'uag_load_image_gallery_masonry' );
158		mediaData.append( 'nonce', uagb_image_gallery.uagb_image_gallery_masonry_ajax_nonce );
159		mediaData.append( 'page_number', $obj.page_number );
160		mediaData.append( 'attr', JSON.stringify( $attr ) );
161		fetch( uagb_image_gallery.ajax_url, {
162			method: 'POST',
163			credentials: 'same-origin',
164			body: mediaData,
165		} )
166			.then( ( resp ) => resp.json() )
167			.then( function ( data ) {
168				let element = $scope?.querySelector( '.spectra-image-gallery__layout--masonry' );
169				if ( ! element ) {
170					element = $scope;
171				}
172
173				setTimeout( function () {
174					const isotope = new Isotope( element, {
175						itemSelector: '.spectra-image-gallery__media-wrapper--isotope',
176						stagger: 10,
177					} );
178					isotope.insert( UAGBImageGalleryMasonry.createElementFromHTML( data.data ) );
179					imagesLoaded( element ).on( 'progress', function () {
180						isotope.layout();
181					} );
182					imagesLoaded( element ).on( 'always', function () {
183						const currentScope = document.querySelector( $selector );
184						const loadButton = currentScope?.querySelector( '.spectra-image-gallery__control-button' )
185							loadButton?.classList?.remove( 'disabled' );
186							loadLightBoxImages( currentScope, lightboxSwiper, null, $attr, thumbnailSwiper );
187						} );
188					if ( 'url' === $attr.imageClickEvent && $attr.customLinks ) {
189						UAGBImageGalleryMasonry.addClickEvents( element, $attr );
190					}
191					spectraImageGalleryLoadStatus = true;
192					if ( true === append ) {
193						$scope?.querySelector( '.spectra-image-gallery__control-button' ).classList.toggle( 'disabled' );
194					}
195					if ( count === parseInt( $obj.total ) ) {
196						$scope.querySelector( '.spectra-image-gallery__control-button' ).style.opacity = 0;
197						setTimeout( () => {
198							$scope.querySelector( '.spectra-image-gallery__control-button' ).parentElement.style.display =
199								'none';
200						}, 2000 );
201					}
202				}, 500 );
203			} );
204	},
205	presentInViewport( element ) {
206		const rect = element.getBoundingClientRect();
207		return (
208			rect.top >= 0 &&
209			rect.left >= 0 &&
210			rect.bottom <= ( window.innerHeight || document.documentElement.clientHeight ) &&
211			rect.right <= ( window.innerWidth || document.documentElement.clientWidth )
212		);
213	},
214};
215
216const UAGBImageGalleryPagedGrid = {
217	init( $attr, $selector, lightboxSettings, thumbnailSettings ) {
218		let count = 1;
219		const $scope = document.querySelector( $selector );
220		let thumbnailSwiper = null;
221		if ( $attr.lightboxThumbnails ){
222			thumbnailSwiper = new Swiper( `${$selector}+.spectra-image-gallery__control-lightbox .spectra-image-gallery__control-lightbox--thumbnails`,
223			thumbnailSettings
224			);
225			lightboxSettings = {
226				...lightboxSettings,
227				thumbs: {
228					swiper: thumbnailSwiper,
229				},
230			}
231		}
232		const lightboxSwiper = new Swiper( `${$selector}+.spectra-image-gallery__control-lightbox .spectra-image-gallery__control-lightbox--main`,
233			lightboxSettings
234		)
235		lightboxSwiper.lazy.load();
236		loadLightBoxImages( $scope, lightboxSwiper, count, $attr, thumbnailSwiper );
237		const arrows = $scope?.querySelectorAll( '.spectra-image-gallery__control-arrows--grid' );
238		const dots = $scope?.querySelectorAll( '.spectra-image-gallery__control-dot' );
239		for ( let i = 0; i < arrows.length; i++ ) {
240			arrows[ i ].addEventListener( 'click', ( event ) => {
241				const thisArrow = event.currentTarget;
242				let page = count;
243				switch ( thisArrow.getAttribute( 'data-direction' ) ) {
244					case 'Prev':
245						--page;
246						break;
247					case 'Next':
248						++page;
249						break;
250				}
251				let mediaItem = $scope?.querySelector( '.spectra-image-gallery__media-wrapper' );
252				if ( ! mediaItem ) {
253					mediaItem = $scope;
254				}
255				const total = $attr.gridPages;
256				const $args = {
257					page_number: page,
258					total,
259				};
260				if ( page === total || page === 1 ) {
261					thisArrow.disabled = true;
262				} else {
263					arrows.forEach( ( ele ) => {
264						ele.disabled = false;
265					} );
266				}
267				if ( page <= total && page >= 1 ) {
268					UAGBImageGalleryPagedGrid.callAjax( $scope, $args, $attr, arrows, $selector, lightboxSwiper, thumbnailSwiper );
269					count = page;
270				}
271			} );
272		}
273		for ( let i = 0; i < dots.length; i++ ) {
274			dots[ i ].addEventListener( 'click', ( event ) => {
275				const thisDot = event.currentTarget;
276				const page = thisDot.getAttribute( 'data-go-to' );
277				let mediaItem = $scope?.querySelector( '.spectra-image-gallery__media-wrapper' );
278				if ( ! mediaItem ) {
279					mediaItem = $scope;
280				}
281				const $args = {
282					page_number: page,
283					total: $attr.gridPages,
284				};
285				UAGBImageGalleryPagedGrid.callAjax( $scope, $args, $attr, arrows, $selector, lightboxSwiper, thumbnailSwiper );
286				count = page;
287			} );
288		}
289	},
290
291	createElementFromHTML( htmlString ) {
292		const htmlElement = document.createElement( 'div' );
293		const htmlCleanString = htmlString.replace( /\s+/gm, ' ' ).replace( /( )+/gm, ' ' ).trim();
294		htmlElement.innerHTML = htmlCleanString;
295		return htmlElement;
296	},
297
298	getCustomURL( image, $attr ) {
299		const urlValidRegex = new RegExp(
300			'^((http|https)://)(www.)?[a-zA-Z0-9@:%._\\+~#?&//=\\-]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%._\\+~#?&//=]*)$'
301		);
302		const imageID = parseInt( image.getAttribute( 'data-spectra-gallery-image-id' ) );
303		return urlValidRegex.test( $attr?.customLinks[ imageID ] ) ? $attr.customLinks[ imageID ] : undefined;
304	},
305
306	openCustomURL( customURL ) {
307		window.open( customURL, '_blank' );
308	},
309
310	addClickEvents( element, $attr ) {
311		const imageElements = element?.querySelectorAll( '.spectra-image-gallery__media-wrapper' );
312		imageElements.forEach( ( image ) => {
313			const imageURL = UAGBImageGalleryPagedGrid.getCustomURL( image, $attr );
314			if ( imageURL ) {
315				image.style.cursor = 'pointer';
316				image.setAttribute( 'tabindex', '0' );
317				image.addEventListener( 'click', () => UAGBImageGalleryPagedGrid.openCustomURL( imageURL ) );
318				image.addEventListener( 'keydown', ( event ) => {
319					if ( 13 === event.keyCode || 32 === event.keyCode ) {
320						UAGBImageGalleryPagedGrid.openCustomURL( imageURL );
321					}
322				} );
323			}
324		} );
325	},
326
327	callAjax( $scope, $obj, $attr, arrows, $selector, lightboxSwiper, thumbnailSwiper ) {
328		const mediaData = new FormData();
329		mediaData.append( 'action', 'uag_load_image_gallery_grid_pagination' );
330		mediaData.append( 'nonce', uagb_image_gallery.uagb_image_gallery_grid_pagination_ajax_nonce );
331		mediaData.append( 'page_number', $obj.page_number );
332		mediaData.append( 'attr', JSON.stringify( $attr ) );
333		fetch( uagb_image_gallery.ajax_url, {
334			method: 'POST',
335			credentials: 'same-origin',
336			body: mediaData,
337		} )
338			.then( ( resp ) => resp.json() )
339			.then( function ( data ) {
340				if ( data.success === false ) {
341					return;
342				}
343				setTimeout( function () {
344					let element = $scope?.querySelector( '.spectra-image-gallery__layout--isogrid' );
345					if ( ! element ) {
346						element = $scope;
347					}
348					const mediaElements = element.querySelectorAll( '.spectra-image-gallery__media-wrapper--isotope' );
349					const isotope = new Isotope( element, {
350						itemSelector: '.spectra-image-gallery__media-wrapper--isotope',
351						layoutMode: 'fitRows',
352					} );
353					mediaElements.forEach( ( mediaEle ) => {
354						isotope.remove( mediaEle );
355						isotope.layout();
356					} );
357					isotope.insert( UAGBImageGalleryPagedGrid.createElementFromHTML( data.data ) );
358					imagesLoaded( element ).on( 'progress', function () {
359						isotope.layout();
360					} );
361					imagesLoaded( element ).on( 'always', function () {
362						const currentScope = document.querySelector( $selector );
363						loadLightBoxImages( currentScope, lightboxSwiper, parseInt( $obj.page_number ), $attr, thumbnailSwiper );
364					} );
365					if ( $attr.customLinks ) {
366						UAGBImageGalleryPagedGrid.addClickEvents( element, $attr );
367					}
368					if ( parseInt( $obj.page_number ) === 1 ) {
369						arrows.forEach( ( arrow ) => {
370							arrow.disabled = arrow.getAttribute( 'data-direction' ) === 'Prev';
371						} );
372					} else if ( parseInt( $obj.page_number ) === parseInt( $obj.total ) ) {
373						arrows.forEach( ( arrow ) => {
374							arrow.disabled = arrow.getAttribute( 'data-direction' ) === 'Next';
375						} );
376					} else {
377						arrows.forEach( ( arrow ) => {
378							arrow.disabled = false;
379						} );
380					}
381					$scope
382						?.querySelector( '.spectra-image-gallery__control-dot--active' )
383						.classList.toggle( 'spectra-image-gallery__control-dot--active' );
384					const $activeDot = $scope?.querySelectorAll( '.spectra-image-gallery__control-dot' );
385					$activeDot[ parseInt( $obj.page_number ) - 1 ].classList.toggle(
386						'spectra-image-gallery__control-dot--active'
387					);
388				}, 500 );
389			} );
390	},
391};
392
393const cycleInLightbox = ( selector, e ) => {
394	// Check if Tab key was pressed
395	if ( e.key === 'Tab' ) {
396		const focusableElements = selector.querySelectorAll( 'button, div[data-role="button"], [href], [tabindex]:not([tabindex="-1"])' );
397		const firstFocusableElement = focusableElements[0];
398		const lastFocusableElement = focusableElements[focusableElements.length - 1];
399		
400		// Get the active element using ownerDocument
401		const activeElement = e.target.ownerDocument.activeElement;
402
403		// Check if Shift + Tab was pressed and if the current active element is the first one
404		if ( e.shiftKey && activeElement === firstFocusableElement ) {
405			e.preventDefault();
406			lastFocusableElement.focus();
407		}
408		// Check if Tab was pressed and if the current active element is the last one
409		else if ( !e.shiftKey && activeElement === lastFocusableElement ) {
410			e.preventDefault();
411			firstFocusableElement.focus();
412		}
413	}
414}
415
416
417const loadLightBoxImages = ( blockScope, lightboxSwiper, pageNum, attr, thumbnailSwiper ) => {
418	if ( ! blockScope ) {
419		return;
420	}
421	const pageLimit = attr.paginateLimit;
422	
423	const theBody = document.querySelector( 'body' );
424	const updateCounter = ( curPage ) => {
425		const lightbox = blockScope?.nextElementSibling;
426		const counter = lightbox.querySelector( '.spectra-image-gallery__control-lightbox--count-page' );
427		if ( counter ) {
428			counter.innerHTML = parseInt( curPage ) + 1;
429		}
430	};
431	lightboxSwiper.on( 'activeIndexChange', ( swiperInstance ) => {
432		if ( attr.lightboxThumbnails ) {
433			thumbnailSwiper.slideTo( swiperInstance.activeIndex );
434		}
435		if ( attr.lightboxDisplayCount ) {
436			updateCounter( swiperInstance.activeIndex );
437		}
438		lightboxSwiper.lazy.load();
439	} )
440	if ( attr.lightboxThumbnails ) {
441		thumbnailSwiper.on( 'activeIndexChange', ( swiperInstance ) => {
442			lightboxSwiper.slideTo( swiperInstance.activeIndex );
443		} );
444
445	}
446	const lightbox = blockScope?.nextElementSibling;
447	let lightboxHandlers = {};
448	if ( lightbox && lightbox?.classList.contains( 'spectra-image-gallery__control-lightbox' ) ) {
449		// create a lightbox cycle listeners.
450        const createListeners = () => {
451			const cycleInLightboxWithID = cycleInLightbox.bind( null, lightbox );
452
453			// Function to add the event listener
454			function addEventListener() {
455			  lightbox.addEventListener( 'keydown', cycleInLightboxWithID );
456			}
457
458			// Function to remove the event listener
459			function removeEventListener() {
460			  lightbox.removeEventListener( 'keydown', cycleInLightboxWithID );
461			}
462
463			return { addEventListener, removeEventListener };
464		};
465
466		lightboxHandlers = createListeners();
467
468		lightbox.addEventListener( 'keydown', ( event ) => {
469			if ( 27 === event.keyCode ) {
470				theBody.style.overflow = '';
471				lightbox.style.opacity = 0;
472				setTimeout( () => {
473					lightbox.style.display = 'none';
474					lightboxHandlers.removeEventListener();
475					if ( clickedImageId ) {
476						const clickedImage = document.querySelector( `[data-spectra-gallery-image-id="${clickedImageId}"]` );
477						clickedImage?.focus();  
478						clickedImageId = null;
479					}
480				}, 250 );
481			}
482		} );
483		lightbox.style.display = 'none';
484		if ( attr.lightboxCloseIcon ) {
485			const closeButton = lightbox.querySelector( '.spectra-image-gallery__control-lightbox--close' );
486			if ( closeButton ) {
487				closeButton.addEventListener( 'click', () => {
488					theBody.style.overflow = '';
489					lightbox.style.opacity = 0;
490					setTimeout( () => {
491						lightbox.style.display = 'none';
492						if ( clickedImageId ) {
493							const clickedImage = document.querySelector( `[data-spectra-gallery-image-id="${clickedImageId}"]` );
494							clickedImage?.focus();  
495							clickedImageId = null;
496						}
497						lightboxHandlers.removeEventListener();
498					}, 250 );
499				} );
500			}
501		}
502		if ( attr.lightboxDisplayCount ) {
503			const lightboxTotal = lightbox.querySelector( '.spectra-image-gallery__control-lightbox--count-total' );
504			lightboxTotal.innerHTML = attr.mediaGallery.length;
505		}
506	}
507	const enableLightbox = ( goTo, clickedImage ) => {
508		if ( ! lightboxSwiper || !lightbox ) {
509			return;
510		}
511		clickedImageId = clickedImage.getAttribute( 'data-spectra-gallery-image-id' );
512		lightbox.style.display = '';
513		lightbox.focus();
514		setTimeout( () => {
515			lightboxSwiper.slideTo( goTo );
516		}, 100 );
517		setTimeout( () => {
518			lightbox.style.opacity = 1;
519			if ( lightbox?.classList.contains( 'spectra-image-gallery__control-lightbox' ) ) {
520				theBody.style.overflow = 'hidden';
521			}
522
523			lightboxHandlers.addEventListener();
524
525		}, 250 );
526	}
527
528	if ( pageNum !== null ) {
529		setTimeout( () => {
530			addClickListeners( blockScope, pageNum, enableLightbox, pageLimit, attr );
531		}, 1000 );
532	} else {
533		addClickListeners( blockScope, null, enableLightbox, null, attr );
534	}
535};
536
537const generateUniqueId = ( index ) => `image-${index}-${Date.now()}`;
538
539const addClickListeners = ( $scope, pageNum, enableLightbox, pageLimit, attr )  => {
540	const images = $scope.querySelectorAll( '.spectra-image-gallery__media-wrapper' );
541	const imageUrls = {};
542	if ( 'image' === attr.imageClickEvent ) {
543		const mediaGallery = attr.mediaGallery;
544		mediaGallery.forEach( media => {
545			imageUrls[ media.id ] = media.url;
546		} );
547	}
548
549	images.forEach( ( image, index ) => {
550		image.style.cursor = 'pointer';
551		const uniqueId = generateUniqueId( index );
552		if( 'lightbox' === attr.imageClickEvent ) {
553            image.setAttribute( 'data-spectra-gallery-image-id', uniqueId );
554		};
555        if ( 'image' === attr.imageClickEvent ) { 
556			const imgId = image.getAttribute( 'data-spectra-gallery-image-id' );
557			const imgURL = imageUrls[ imgId ];
558			image.addEventListener( 'click', () => {
559				openImageInWindow( imgURL ); // To avoid opening multiple tab at same when Popup and redirect is enabled.
560			} );
561			image.addEventListener( 'keydown', ( event ) => {
562				if ( 13 === event.keyCode || 32 === event.keyCode ) {
563					openImageInWindow( imgURL );
564				}
565			} );
566		} else {
567			const nextImg = pageNum !== null ? index + ( pageNum - 1 ) * pageLimit : index;
568		    image.addEventListener( 'click', () => enableLightbox( nextImg, image ) );
569		    image.addEventListener( 'keydown', ( event ) => {
570			if ( 13 === event.keyCode || 32 === event.keyCode ) {
571				event.preventDefault();
572				enableLightbox( nextImg, image );
573			}
574		} );
575		}
576	} );
577}
578
579let imageWindow = null;
580const openImageInWindow = ( imageUrl ) => {
581	// Check if the window is already open
582	if ( imageWindow && !imageWindow.closed ) {
583		// If open, focus on the existing window
584		imageWindow.focus();
585	} else {
586		// If not open or closed, open a new window
587		imageWindow = window.open( imageUrl, '_blank' );
588	}
589}

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.