PageSourceSearch

https://dinosaurstore.com/wp-content/themes/xtra/assets/js/woocommerce.js?ver=5.8

js dinosaurstore.com collected 2026-10-08 00:18:26 UTC 38,047 bytes, 1,191 lines download raw bytes

1! function( $ ) {
2	"use strict";
3
4	if ( typeof Codevz_Plus != 'object' ) {
5		var Codevz_Plus = {};
6	}
7
8	Codevz_Plus.woocommerce = function() {
9
10		var body 		= $( document.body ),
11			adminBar 	= document.getElementById('wpadminbar') ? 32 : 0;
12
13		// Fix WC message button.
14		document.querySelectorAll( '.button.wc-forward' ).forEach( function( el ) {
15			el.classList.remove( 'wc-forward' );
16		});
17
18		// AJAX Filters.
19		if ( document.querySelector( '.codevz-plus-shop-ajax-filters' ) ) {
20
21			function filterByPrice( page = 1 ) {
22				const filtersDiv = $('.codevz-plus-shop-ajax-filters');
23				const nonce = filtersDiv.data('nonce');
24				const [min, max] = [parseInt($('#min_price').val(), 10), parseInt($('#max_price').val(), 10)];
25				const rangeMin = $('.price_slider').slider('option', 'min');
26				const rangeMax = $('.price_slider').slider('option', 'max');
27
28				$('ul.products').addClass('codevz-plus-loading-products');
29
30				$.post(body.data('ajax'), { action: 'filter_products_by_price', min_price: min, max_price: max, page, nonce }, (res) => {
31					if (res.error) {
32						alert(res.data.message || 'Security check failed.');
33						return;
34					}
35
36					$('ul.products').removeClass('codevz-plus-loading-products').html(res.products);
37					$('.woocommerce-pagination').replaceWith(res.pagination);
38
39					// Show selected price filter if range changed
40					const filterHtml = (min > rangeMin || max < rangeMax) ? `
41						<div data-filter="price">
42							<span>Price: $${min} - $${max}</span>
43							<i class="fa czico-close-bold codevz-plus-shop-ajax-remove-filter"></i>
44						</div>` : '';
45					filtersDiv.find('> div').html(filterHtml);
46				});
47			}
48
49			// Debounce and optimize slider event
50			let debounceTimer;
51			body.on('slidechange', '.widget .price_slider', function() {
52				clearTimeout(debounceTimer);
53				debounceTimer = setTimeout(function() { filterByPrice() }, 200 );
54			});
55
56			// Remove filter
57			body.on('click', '.codevz-plus-shop-ajax-remove-filter', function() {
58				$(this).parent().remove();
59				$('.widget .price_slider').slider('values', [0, $('.price_slider').slider('option', 'max')]);
60				filterByPrice();
61			});
62
63			// Pagination
64			body.on('click', '.woocommerce-pagination a', function(e) {
65				e.preventDefault();
66				filterByPrice($(this).data('page') || 1);
67			});
68		}
69
70		// Product quantity field.
71		document.addEventListener( 'click', function (e) {
72
73			const btn = e.target.closest('.quantity-up, .quantity-down');
74			if (!btn) { return; }
75
76			const wrap = btn.closest('.quantity');
77			if (!wrap) { return; }
78
79			const i = wrap.querySelector('input.qty');
80			if (!i || i.disabled || i.readOnly) { return; }
81
82			const max = parseFloat(i.max) || Infinity;
83
84			let current = parseFloat(i.value);
85			if (isNaN(current)) { current = 0; }
86
87			const next = btn.classList.contains('quantity-up')
88				? Math.min(current + 1, max)
89				: Math.max(current - 1, 1);
90
91			if (next === current) { return; }
92
93			i.value = next;
94			i.dispatchEvent(new Event('change', { bubbles: true }));
95
96			if ( ! i.closest( '.product-type-grouped, .cz_popup_in, .woocommerce-cart-form' ) ) {
97				document.querySelectorAll('.page_content input.qty').forEach(function (other) {
98					if (
99						other === i ||
100						other.closest('.product-type-grouped') ||
101						parseFloat(other.value) === next
102					) {
103						return;
104					}
105
106					other.value = next;
107					other.dispatchEvent(new Event('change', { bubbles: true }));
108				});
109			}
110		});
111
112		// Cart page.
113		if ( document.querySelector( '.woocommerce-cart-form' ) ) {
114
115			// When cart page is empty, refresh
116			body.on( 'updated_wc_div', function() {
117				if ( ! document.querySelector( '.cart_item' ) ) {
118					window.location.reload();
119				}
120			});
121
122			// Auto update cart on quantity change
123			let timeout;
124			document.body.addEventListener( 'change', function(e) {
125				const input = e.target.closest( '.woocommerce-cart-form input.qty' );
126				if (!input) {return;}
127
128				clearTimeout(timeout);
129
130				timeout = setTimeout(function() {
131					const updateBtn = document.querySelector( '[name="update_cart"]' );
132					if (updateBtn) {updateBtn.click();}
133				}, 1000);
134			});
135
136		}
137
138		// Custom variations.
139		document.addEventListener('click', function(e) {
140		    const label = e.target.closest('.codevz-variations label');
141		    if (!label) {return;}
142
143		    const radio = label.previousElementSibling;
144		    if (radio && radio.type === 'radio') {
145		        radio.checked = true;
146
147		        const val = radio.value;
148		        const form = label.closest('.variations_form');
149		        const container = label.closest('.value');
150
151		        if (container) {
152		            const select = container.querySelector('select');
153		            if (select) {
154		                select.value = val;
155		                select.dispatchEvent(new Event('change', { bubbles: true }));
156
157		                if (form) {
158		                    const jqueryForm = window.jQuery && window.jQuery(form);
159		                    if (jqueryForm) {
160		                        jqueryForm.trigger('check_variations');
161		                    }
162		                }
163		            }
164		        }
165		    }
166		});
167
168		// Single add to cart fake loading.
169		let clickedButton = null;
170		body.on( 'click', '.single_add_to_cart_button', function() {
171		    clickedButton = $( this );
172		    sessionStorage.wooclicked = '1';
173		});
174		$(window).on( 'beforeunload', function() {
175		    if ( clickedButton && sessionStorage.wooclicked ) {
176		        clickedButton.addClass( 'loading' );
177		        sessionStorage.removeItem( 'wooclicked' );
178		    }
179		});
180
181		// Single AJAX add to cart.
182		document.addEventListener( 'submit', function(e) {
183		    const form = e.target.closest('form.cart');
184		    if (!form || form.closest('.product-type-external') || ! form.closest( '.codevz-woo-ajax-add-to-cart' ) ) {
185		    	return;
186		    }
187
188			if ( typeof wc_add_to_cart_params !== 'undefined' && wc_add_to_cart_params.cart_redirect_after_add === 'yes' ) {
189			    return;
190			}
191
192		    e.preventDefault();
193
194		    const button = form.querySelector('.single_add_to_cart_button');
195		    const qty = form.querySelector('input.qty');
196		    const formData = new FormData(form);
197
198		    if (!formData.has('product_id')) {
199		        const idInput = form.querySelector('input[name="add-to-cart"]') || form.querySelector('button[name="add-to-cart"]');
200		        if (idInput) formData.append('product_id', idInput.value);
201		    }
202		    
203		    formData.append('action', 'single_add_to_cart');
204		    formData.append('nonce', xtra_strings.nonce);
205
206		    button.classList.add('loading');
207		    if (qty) {
208		        qty.disabled = true;
209		        qty.parentNode.style.opacity = '0.3';
210		    }
211
212		    fetch(wc_add_to_cart_params.ajax_url, {
213		        method: 'POST',
214		        body: formData
215		    })
216		    .then(response => response.json())
217		    .then(data => {
218		        if (data.error) {
219		            window.location = data.product_url;
220		            return;
221		        }
222
223		        if (data.fragments) {
224		            Object.entries(data.fragments).forEach(([selector, html]) => {
225		                const target = document.querySelector(selector);
226		                if (target) {
227		                    if (selector === '.cz_cart_items' || target.classList.contains('cz_cart_items')) {
228		                        const temp = document.createElement('div');
229		                        temp.innerHTML = html;
230		                        const newContent = temp.querySelector(selector) ? temp.querySelector(selector).innerHTML : temp.innerHTML;
231		                        target.innerHTML = newContent;
232		                    } else {
233		                        target.outerHTML = html;
234		                    }
235		                }
236		            });
237		        }
238
239		        if (typeof jQuery !== 'undefined') {
240		            jQuery(document.body).trigger('added_to_cart', [data.fragments, data.cart_hash, jQuery(button)]);
241		        }
242
243		        button.classList.remove('loading');
244		        button.classList.add('added');
245
246		        // Show shopping mini cart after added.
247				setTimeout(() => {
248					const elmsCart = document.querySelector('.elms_shop_cart');
249					if ( elmsCart && ! form.closest( '.cz_popup_in' ) ) {
250					    document.querySelector('.elms_shop_cart').dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
251
252					    window.scrollTo({
253					        top: 0,
254					        behavior: 'smooth'
255					    });
256					}
257				}, 10);
258
259			    if (qty) {
260			        qty.disabled = true;
261			        qty.parentNode.style.opacity = '0.3';
262			    }
263		    })
264		    .catch(() => {
265		        button.classList.remove('loading');
266		        if (qty) {
267		            qty.disabled = false;
268		            qty.parentNode.style.opacity = '1';
269		        }
270		    });
271		});
272
273		// AJAX remove from mini cart.
274		document.addEventListener('click', function(e) {
275		    const removeLink = e.target.closest('a.remove');
276		    if (!removeLink) {return;}
277
278		    removeLink.classList.add( 'codevz-remove' );
279
280		    e.preventDefault();
281
282		    const cartContainer = removeLink.closest('.cz_cart_items');
283		    const itemRow = removeLink.closest('.item_small');
284		    const url = new URL(removeLink.getAttribute('href'));
285		    const removeKey = url.searchParams.get('remove_item');
286
287		    if (!removeKey) {return;}
288		    if (itemRow) {itemRow.style.opacity = '0.3';}
289
290		    function update_cart() {
291				const updateBtn = document.querySelector('[name="update_cart"]');
292				if (updateBtn) {
293				    updateBtn.disabled = false;
294				    updateBtn.click();
295				}
296			    setTimeout(() => document.querySelector( '.elms_shop_cart' ).dispatchEvent(new MouseEvent('mouseover', { bubbles: true })), 10 );
297		    }
298
299			fetch(wc_add_to_cart_params.ajax_url, {
300			    method: 'POST',
301			    body: new URLSearchParams({
302			        action: 'single_add_to_cart_remove', 
303			        remove_item: removeKey, 
304			        nonce: xtra_strings.nonce
305			    })
306			})
307			.then(response => response.json())
308			.then(data => {
309			    if (data.fragments) {
310			        Object.entries(data.fragments).forEach(([selector, html]) => {
311			            const target = document.querySelector(selector);
312			            if (!target) {return;}
313
314			            if (selector === '.cz_cart_items' || target.classList.contains('cz_cart_items')) {
315			                const temp = document.createElement('div');
316			                temp.innerHTML = html;
317			                const newContent = temp.querySelector(selector) ? temp.querySelector(selector).innerHTML : temp.innerHTML;
318			                target.innerHTML = newContent;
319			            } else {
320			                target.outerHTML = html;
321			            }
322			            update_cart();
323			        });
324			    }
325
326			    if (typeof jQuery !== 'undefined') {
327			        jQuery(document.body).trigger('removed_from_cart', [data.fragments, data.cart_hash, jQuery(removeLink)]);
328			    }
329			})
330			.catch(() => {
331			    if (itemRow) {itemRow.style.opacity = '1';}
332			    update_cart();
333			});
334		});
335
336		// Widgets accordion.
337		document.querySelectorAll( '.codevz-widgets-toggle .page_content .sidebar_inner' ).forEach( c => c.addEventListener( 'click', e => {
338			const t = e.target.closest('.codevz-widget-title');
339			if (!t) {return;}
340			const n = t.nextElementSibling;
341			if (!n) {return;}
342			n.hidden = !n.hidden;
343		}));
344
345		// Auto x-position shop cart in header.
346		if ( document.querySelector( '.elms_shop_cart' ) ) {
347
348			if ( document.querySelector( '.elms_shop_cart_offcanvas' ) ) {
349
350				// v6.0 - Custom cart offcanvas.
351				body.off( 'click.elms_shop_cart_offcanvas' ).on( 'click.elms_shop_cart_offcanvas', '.elms_shop_cart_offcanvas', function( e ) {
352
353					Codevz.offCanvas( $( this ).addClass( 'done' ), 1, $( '[data-offcanvas="cart"]' ) );
354					e.preventDefault();
355				});
356
357			} else {
358
359				const overlay = document.querySelector('.codevz-plus-dropdown-overlay .inner_layout > .cz_overlay');
360				let hoverTimeout;
361				let isCartActive = false;
362
363				document.body.addEventListener('click', (e) => {
364				    const dropdown = document.querySelector('.cz_cart_items');
365				    
366				    if (dropdown && !dropdown.contains(e.target) && !e.target.closest('.elms_shop_cart') && !e.target.closest('.cz')) {
367				        dropdown.style.opacity = '0';
368				        dropdown.style.visibility = 'hidden';
369				        dropdown.style.pointerEvents = 'none';
370				        if (overlay) {
371				            overlay.style.display = 'none';
372				        }
373				        isCartActive = false;
374				    }
375				});
376
377				document.body.addEventListener('mouseover', (e) => {
378				    const cartX = e.target.closest('.elms_shop_cart');
379				    if (!cartX) {
380				        return;
381				    }
382
383				    isCartActive = true;
384				    clearTimeout(hoverTimeout);
385
386				    const dropdown = cartX.querySelector('.cz_cart_items');
387				    const icon = cartX.querySelector('.shop_icon i');
388				    const isRtl = document.body.classList.contains('rtl');
389
390				    if (!dropdown) {
391				        return;
392				    }
393
394				    dropdown.style.pointerEvents = 'auto';
395
396				    if ((window.innerWidth / 2) > (cartX.getBoundingClientRect().left + window.scrollX + 300)) {
397				        cartX.classList.add('inview_right');
398				        const iconMl = parseFloat(getComputedStyle(icon).marginLeft) || 0;
399				        const leftVal = (icon.offsetWidth / 2) + (isRtl ? -38 : 36) + iconMl;
400				        dropdown.style.left = isRtl ? `${leftVal}px` : `-${leftVal}px`;
401				    } else {
402				        const iconMr = parseFloat(getComputedStyle(icon).marginRight) || 0;
403				        dropdown.style.right = `${(icon.offsetWidth / 2) - 36 + iconMr}px`;
404				    }
405
406				    setTimeout(() => {
407				        dropdown.style.opacity = '1';
408				        dropdown.style.visibility = 'visible';
409				        if (overlay) {
410				            overlay.style.zIndex = '99';
411				            overlay.style.display = 'block';
412				        }
413				    }, 100);
414				});
415
416				document.body.addEventListener('mouseout', (e) => {
417				    if (!isCartActive) {
418				        return;
419				    }
420
421				    const cartX = e.target.closest('.elms_shop_cart');
422				    if (!cartX) {
423				        return;
424				    }
425
426				    const dropdown = cartX.querySelector('.cz_cart_items');
427				    const relatedTarget = e.relatedTarget;
428
429				    if (!dropdown) {
430				        return;
431				    }
432
433				    if (relatedTarget && cartX.contains(relatedTarget)) {
434				        return;
435				    }
436
437				    isCartActive = false;
438
439				    hoverTimeout = setTimeout(() => {
440				        dropdown.style.opacity = '0';
441				        dropdown.style.visibility = 'hidden';
442				        dropdown.style.pointerEvents = 'none';
443				        if (overlay) {
444				            overlay.style.display = 'none';
445				        }
446				    }, 250);
447				});
448
449			}
450
451		}
452
453		// Move cart count to icon data.
454		const cartBox = document.querySelector( '.elms_shop_cart' );
455		if ( cartBox ) {
456			let mutationTimeout;
457			const observer = new MutationObserver(() => {
458				clearTimeout(mutationTimeout);
459				mutationTimeout = setTimeout(() => {
460					cartBox.querySelector( '.shop_icon > i' ).setAttribute( 'data-count', cartBox.querySelector( '.cz_cart_count' ).innerHTML );
461				}, 100 );
462			});
463			observer.observe( cartBox, { childList: true, subtree: true });
464		}
465
466		// Wishlist & Compare popup.
467		var wishComPopup = $( '#xtra_wish_compare' );
468		wishComPopup.appendTo( 'body' );
469
470		// Fix wishComPopup link issue.
471		wishComPopup.on( 'click', 'a', function() {
472			window.location = $( this ).attr( 'href' );
473		});
474
475		// Current wishlist items
476		if ( document.querySelector( '.xtra-add-to-wishlist, .xtra-wishlist, .wishlist_icon' ) ) {
477
478			var wishlist = localStorage.getItem( 'xtraWishlist' ),
479				wishlistDiv = $( '.xtra-wishlist' ),
480				noWishlist = '<h2 class="xtra-wish-compare-empty xtra-wishlist-empty tac"><i class="fa fa-heart-o"></i>' + wishlistDiv.attr( 'data-empty' ) + '<small>' + xtra_strings.wishlist_desc + '</small></h2><a href="' + xtra_strings.shop_url + '" class="button" style="margin:40px auto;display:table;"><span><strong>' + xtra_strings.back_to_shop + '</strong></span></a>';
481
482			// Wishlist shortcode
483			wishlistDiv.length && wishlistDiv.each( function() {
484
485				var en 		= $( this ),
486					nonce 	= en.data( 'nonce' ),
487					col 	= en.data( 'col' );
488
489				if ( wishlist ) {
490
491					// Check ID's.
492					$.post( body.data( 'ajax' ), 'action=xtra_wishlist_content&check=1&ids=' + wishlist + '&nonce=' + nonce, function( msg ) {
493
494						localStorage.setItem( 'xtraWishlist', msg );
495
496						wishlist = msg;
497
498						// Get wishlist products.
499						$.post( body.data( 'ajax' ), 'action=xtra_wishlist_content&ids=' + wishlist + '&nonce=' + nonce + '&
499col=' + col, function( msg ) {
500
501							en.removeClass( 'xtra-icon-loading' ).html( msg );
502
503							$( '.woocommerce-loop-product__link' ).prepend( '<i class="xtra-remove-from-wishlist fas fa-times"></i>' );
504
505							var count = localStorage.getItem( 'xtraWishlist' ).replace( /\d+/g,'' ).length;
506
507							$( '.wishlist_icon > i' ).attr( 'data-count', count || 0 );
508
509							if ( ! count ) {
510								en.removeClass( 'xtra-icon-loading' ).html( noWishlist );
511							}
512
513							if ( ! en.find( 'li' ).length ) {
514								en.removeClass( 'xtra-icon-loading' ).html( noWishlist );
515							}
516
517						});
518
519					});
520
521				} else {
522
523					en.removeClass( 'xtra-icon-loading' ).html( noWishlist );
524
525				}
526
527			});
528
529			// Set wishlist products
530			if ( wishlist ) {
531				wishlist = wishlist.split( ',' );
532
533				$.each( wishlist, function( index, id ) {
534					var product = $( '[data-id="' + id + '"] .xtra-add-to-wishlist' );
535
536					if ( product.length ) {
537						product.removeClass( 'fa-heart-o' ).addClass( 'fa-heart' ).attr( 'data-title', xtra_strings.added_wishlist );
538					}
539				});
540
541				var count = localStorage.getItem( 'xtraWishlist' ).replace( /\d+/g,'' ).length;
542
543				$( '.wishlist_icon > i' ).attr( 'data-count', count || 0 );
544
545				if ( ! count ) {
546					wishlistDiv.removeClass( 'xtra-icon-loading' ).html( noWishlist );
547				}
548			}
549
550			// Wishlist icon.
551			body.on( 'click', '.xtra-add-to-wishlist,.xtra-remove-from-wishlist', function(e) {
552
553				var en = $( this ),
554					id = en.closest( '.product' ).find( '[data-id]' ).data( 'id' ) + ',',
555					ls = localStorage.getItem( 'xtraWishlist' ) || '',
556					tt = en.attr( 'data-title' );
557
558				if ( en.hasClass( 'fa-heart' ) && ! en.closest( '.xtra-wishlist' ).length ) {
559
560					window.location.replace( xtra_strings.wishlist_url );
561
562				} else {
563
564					en.addClass( 'xtra-icon-loading' ).removeAttr( 'data-title' );
565
566					setTimeout(function() {
567
568						if ( en.hasClass( 'fa-heart' ) || en.hasClass( 'fa-times' ) ) {
569
570							ls = ls.replace( id, '' );
571
572							localStorage.setItem( 'xtraWishlist', ls );
573
574							tt = xtra_strings.add_wishlist;
575
576							en.removeClass( 'fa-heart' ).addClass( 'fa-heart-o' );
577
578						} else if ( ls.indexOf( id ) < 0 ) {
579
580							localStorage.setItem( 'xtraWishlist', ls + id );
581
582							tt = xtra_strings.added_wishlist;
583
584							setTimeout( function() {
585
586								$( '[data-id="' + id.replace( ',', '' ) + '"] .xtra-add-to-wishlist' ).removeClass( 'fa-heart-o' ).addClass( 'fa-heart' ).attr( 'data-title', xtra_strings.added_wishlist );
587
588							}, 500 );
589
590							$( '.cz_close_popup' ).trigger( 'click' );
591
592							setTimeout( function() {
593
594								wishComPopup.find( 'h3' ).html( en.closest( '.product' ).find( '.woocommerce-loop-product__title, .product_title' ).html() );
595								wishComPopup.find( 'a' ).attr( 'href', xtra_strings.wishlist_url ).find( 'strong' ).html( xtra_strings.view_wishlist );
596								wishComPopup.fadeIn( 'fast' ).delay( 1000 ).addClass( 'cz_show_popup' );
597
598							}, $( '.cz_popup_modal' ).is( ':visible' ) ? 50 : 0 );
599						}
600
601						en.removeClass( 'xtra-icon-loading' );
602
603						setTimeout( function() {
604
605							en.attr( 'data-title', tt );
606
607						}, 250 );
608
609						// Wishlist page.
610						if ( en.closest( '.xtra-wishlist' ).length ) {
611
612							en.closest( 'li' ).fadeOut(function() {
613
614								$( this ).remove();
615
616								if ( ! wishlistDiv.find( 'li' ).length ) {
617									wishlistDiv.removeClass( 'xtra-icon-loading' ).html( noWishlist );
618								}
619
620							});
621
622						}
623
624						var count = localStorage.getItem( 'xtraWishlist' ).replace( /\d+/g,'' ).length;
625
626						$( '.wishlist_icon > i' ).attr( 'data-count', count || 0 );
627
628						if ( ! count ) {
629							wishlistDiv.removeClass( 'xtra-icon-loading' ).html( noWishlist );
630						}
631
632					}, 1000 );
633
634				}
635
636				e.preventDefault();
637			});
638
639		}
640
641		// Current compare items
642		if ( document.querySelector( '.xtra-add-to-compare, .xtra-compare, .compare_icon' ) ) {
643
644			// Compare icon.
645			body.on( 'click', '.xtra-add-to-compare,.xtra-remove-from-compare', function(e) {
646
647				var en = $( this ),
648					id = en.closest( '.product' ).find( '[data-id]' ).data( 'id' ) + ',',
649					ls = localStorage.getItem( 'xtraCompare' ) || '',
650					tt = en.attr( 'data-title' );
651
652				// Remove from compare.
653				if ( en.attr( 'class' ).indexOf( 'remove' ) > 0 ) {
654
655					id = en.closest( 'td' ).find( '[data-id]' ).data( 'id' ) + ',';
656
657					en.addClass( 'xtra-icon-loading' );
658
659					ls = ls.replace( id, '' );
660
661					localStorage.setItem( 'xtraCompare', ls );
662
663					window.location.replace( xtra_strings.compare_url );
664
665					e.preventDefault();
666
667					return false;
668
669				}
670
671				// ...
672				if ( en.hasClass( 'fa-check' ) && ! en.closest( '.xtra-compare' ).length ) {
673
674					window.location.replace( xtra_strings.compare_url );
675
676				} else {
677
678					en.addClass( 'xtra-icon-loading' ).removeAttr( 'data-title' );
679
680					setTimeout( function() {
681
682						if ( en.hasClass( 'fa-check' ) || en.hasClass( 'fa-times' ) ) {
683
684							ls = ls.replace( id, '' );
685
686							localStorage.setItem( 'xtraCompare', ls );
687
688							tt = xtra_strings.add_compare;
689
690							en.removeClass( 'fa-check' ).addClass( 'czico-shuffle' ).attr( 'data-title', xtra_strings.add_compare );
691
692						} else if ( ls.indexOf( id ) < 0 ) {
693
694							localStorage.setItem( 'xtraCompare', ls + id );
695
696							tt = xtra_strings.added_compare;
697
698							setTimeout( function() {
699
700								$( '[data-id="' + id.replace( ',', '' ) + '"] .xtra-add-to-compare' ).removeClass( 'czico-shuffle' ).addClass( 'fa-check' ).attr( 'data-title', xtra_strings.added_compare );
701
702							}, 500 );
703
704							$( '.cz_close_popup' ).trigger( 'click' );
705
706							setTimeout( function() {
707
708								wishComPopup.find( 'h3' ).html( en.closest( '.product' ).find( '.woocommerce-loop-product__title, .product_title' ).html() );
709								wishComPopup.find( 'a' ).attr( 'href', xtra_strings.compare_url ).find( 'strong' ).html( xtra_strings.view_compare );
710								wishComPopup.fadeIn( 'fast' ).delay( 1000 ).addClass( 'cz_show_popup' );
711
712							}, $( '.cz_popup_modal' ).is( ':visible' ) ? 50 : 0 );
713
714						}
715
716						en.removeClass( 'xtra-icon-loading' );
717
718						setTimeout( function() {
719
720							en.attr( 'data-title', tt );
721
722						}, 250 );
723
724						var compareDiv = null;
725
726						// Compare page.
727						if ( en.closest( '.xtra-compare' ).length ) {
728
729							en.closest( 'li' ).fadeOut(function() {
730
731								$( this ).remove();
732
733								if ( ! compareDiv.find( 'li' ).length ) {
734									compareDiv.removeClass( 'xtra-icon-loading' ).html( noCompare );
735								}
736
737							});
738
739						}
740
741						var count = localStorage.getItem( 'xtraCompare' ).replace( /\d+/g,'' ).length;
742
743						$( '.compare_icon > i' ).attr( 'data-count', count || 0 );
744
745						if ( ! count ) {
746							compareDiv.removeClass( 'xtra-icon-loading' ).html( noCompare );
747						}
748
749					}, 1000 );
750
751				}
752
753				e.preventDefault();
754			});
755
756			var compare = localStorage.getItem( 'xtraCompare' ),
757				compareDiv = $( '.xtra-compare' ),
758				noCompare = '<h2 class="xtra-wish-compare-empty xtra-compare-empty tac"><i class="fa-solid fa-list-check"></i>' + compareDiv.attr( 'data-empty' ) + '<small>' + xtra_strings.wishlist_desc + '</small></h2><a href="' + xtra_strings.shop_url + '" class="button" style="margin:40px auto;display:table;"><span><strong>' + xtra_strings.back_to_shop + '</strong></span></a>';
759
760			// Compare shortcode
761			compareDiv.length && compareDiv.each( function() {
762
763				var en = $( this ),
764					nonce = en.data( 'nonce' );
765
766				if ( compare ) {
767
768					// Check ID's.
769					$.post( body.data( 'ajax' ), 'action=xtra_compare_content&check=1&ids=' + compare + '&nonce=' + nonce, function( msg ) {
770
771						localStorage.setItem( 'xtraCompare', msg );
772
773						compare = msg;
774
775						// Get compare products.
776						$.post( body.data( 'ajax' ), 'action=xtra_compare_content&ids=' + compare + '&nonce=' + nonce, function( msg ) {
777
778							en.removeClass( 'xtra-icon-loading' ).html( msg );
779
780							$( '.cz-compare-tr-general td' ).prepend( '<i class="xtra-remove-from-compare fas fa-times"></i>' );
781
782							var count = localStorage.getItem( 'xtraCompare' ).replace( /\d+/g,'' ).length;
783
784							$( '.compare_icon > i' ).attr( 'data-count', count || 0 );
785
786							if ( ! count ) {
787								en.removeClass( 'xtra-icon-loading' ).html( noCompare );
788							}
789
790							if ( ! en.find( 'li' ).length ) {
791								en.removeClass( 'xtra-icon-loading' ).html( noCompare );
792							}
793
794						});
795
796					});
797
798				} else {
799
800					en.removeClass( 'xtra-icon-loading' ).html( noCompare );
801
802				}
803
804			});
805
806			// Set compare products
807			if ( compare ) {
808				compare = compare.split( ',' );
809
810				$.each( compare, function( index, id ) {
811					var product = id ? $( '[data-id="' + id + '"] .xtra-add-to-compare' ) : 0;
812
813					if ( product.length ) {
814						product.removeClass( 'czico-shuffle' ).addClass( 'fa-check' ).attr( 'data-title', xtra_strings.added_compare );
815					}
816				});
817
818				var count = localStorage.getItem( 'xtraCompare' ).replace( /\d+/g,'' ).length;
819
820				$( '.compare_icon > i' ).attr( 'data-count', count || 0 );
821
822				if ( ! count ) {
823					compareDiv.removeClass( 'xtra-icon-loading' ).html( noCompare );
824				}
825			}
826
827		}
828
829		// Product quick view.
830		if ( document.querySelector( '.xtra-product-quick-view' ) ) {
831
832			body.on( 'click', '.xtra-product-quick-view', function( e ) {
833
834				e.preventDefault();
835
836				var x 		= $( this ),
837					id 		= x.parent().data( 'id' ),
838					nonce 	= x.data( 'nonce' ),
839					link  	= x.closest( 'a' ).attr( 'href' ),
840					popup 	= $( '#xtra_quick_view' ),
841					content = popup.find( '.cz_popup_in > div' ),
842					tt 		= x.attr( 'data-title' );
843
844				popup.appendTo( 'body' );
845
846				x.addClass( 'xtra-icon-loading' ).removeAttr( 'data-title' );
847
848				content.html( '' );
849				content.addClass( 'xtra-qv-loading' );
850
851				popup.fadeIn( 'fast' ).delay( 1000 ).addClass( 'cz_show_popup' );
852
853				$( 'html, body' ).addClass( 'no-scroll' );
854
855				$.post( body.data( 'ajax' ), 'action=xtra_quick_view&id=' + id + '&nonce=' + nonce, function( msg ) {
856
857					x.removeClass( 'xtra-icon-loading' ).attr( 'data-title', tt );
858					content.removeClass().html( msg );
859
860					// Add link to full product view.
861					content.find( '.product_title' ).append( '<a href="' + link + '"><small>' + xtra_strings.quick_view_full + '</small></a>' );
862
863					// Set wishlist in quickview.
864					if ( localStorage.getItem( 'xtraWishlist' ) && localStorage.getItem( 'xtraWishlist' ).indexOf( id ) >= 0 ) {
865						$( '[data-id="' + id + '"] .xtra-add-to-wishlist' ).removeClass( 'fa-heart-o' ).addClass( 'fa-heart' ).attr( 'data-title', xtra_strings.added_wishlist );
866					}
867
868					// Set compare in quickview.
869					if ( localStorage.getItem( 'xtraCompare' ) && localStorage.getItem( 'xtraCompare' ).indexOf( id ) >= 0 ) {
870						$( '[data-id="' + id + '"] .xtra-add-to-compare' ).removeClass( 'czico-shuffle' ).addClass( 'fa-check' ).attr( 'data-title', xtra_strings.added_compare );
871					}
872
873					// Fix flex slider.
874					setTimeout( function() {
875
876						// Init variations
877						content.find('.variations_form').each(function () {
878							var $form = $( this );
879							$form.wc_variation_form();
880							$form.trigger('wc_variation_form'); 
881							$form.find('.variations select').trigger('change');
882						});
883
884						content.find( '.woocommerce-product-gallery' ).each( function() {
885							$( this ).wc_product_gallery();
886						} );
887
888						$( window ).trigger( 'resize' );
889
890					}, 500 );
891
892					// Fix onsale position.
893					content.find( 'div.product, .xtra-single-product' ).find( '> .onsale' ).prependTo( $( '.woocommerce-product-gallery' ) );
894
895					// Add to cart redirect to cart on quick view popup. 
896					content.find( '[name="add-to-cart"]' ).closest( 'form' ).attr( 'action', xtra_strings.cart_url );
897
898				});
899
900				return false;
901
902			});
903
904		}
905
906		// Append onsale badge to parent in archive.
907		document.querySelectorAll('ul.products .onsale').forEach(badge => {
908		    const parentLink = badge.closest('a');
909		    if (parentLink) {
910		        parentLink.appendChild(badge);
911		    }
912		});
913
914		// Checkout page functions.
915		if ( document.querySelector( '.woocommerce-checkout' ) ) {
916
917			// Fix checkout section title!
918			$( 'wc-order-attribution-inputs' ).each( function() {
919
920				var $this = $( this );
921
922				$this.appendTo( $this.parent() );
923
924			});
925
926			// Fix City and state in RTL.
927			if ( body.hasClass( 'rtl' ) ) {
928
929				setTimeout( function() {
930
931					$( '#billing_state_field' ).insertBefore( '#billing_city_field' );
932
933				}, 500 );
934
935			}
936
937		}
938
939		// Add button class to restore-item link in message box.
940		$( '.woocommerce-message .restore-item' ).addClass( 'button' );
941
942		// Added to cart notification.
943		body.on( 'added_to_cart', function( e, fragments, cart_hash, $button ) {
944
945			// Show view cart btn.
946			setTimeout( function() {
947				$button.hide().next().addClass( 'button product_type_codevz' ).fadeIn();
948			}, 100 );
949
950			// Notification.
951			var notif = $( '.codevz-added-to-cart-notif' ),
952				width = notif.find( 'span' ).outerWidth();
953
954			// Check if its on single page with sticky mode.
955			notif[ $( '.cz-sticky-add-to-cart-show' ).length ? 'addClass' : 'removeClass' ]( 'codevz-added-to-cart-notif-above-sticky' );
956
957			setTimeout( function() {
958
959				var parent = $button.closest( 'li.product' ).length ? $button.closest( 'li.product' ) : $button.closest( '.summary' ),
960					title  = parent.find( '.woocommerce-loop-product__title' ).html(),
961					title  = title ? title : $( '.cz-sticky-add-to-cart' ).attr( 'data-title' ) || '-';
962
963				// Show the notification.
964				notif.addClass( 'codevz-added-to-cart-notif-show' ).find( 'strong' ).text( title.replace( /<[^>]*>.*?<\/[^>]*>/g, '' ) );
965
966				setTimeout( function() {
967
968					// Show the added details span.
969					notif.addClass( 'codevz-added-to-cart-notif-show-span' );
970
971				}, 1200 );
972
973				setTimeout( function() {
974
975					// Hide the notification after a delay.
976					notif.removeClass( 'codevz-added-to-cart-notif-show-span' );
977
978					setTimeout( function() {
979
980						// Hide the span.
981						notif.removeClass( 'codevz-added-to-cart-notif-show' );
982
983					}, 500 );
984
985				}, 6000 );
986
987			}, 100 );
988
989		});
990
991		// Single product page.
992		if ( body.hasClass( 'single-product' ) ) {
993
994			setTimeout( function() {
995
996				// Sticky product tabs row.
997				var woot 	= $( '.codevz-sticky-product-tabs .woocommerce-tabs' ),
998					tabs 	= woot.find( 'ul.tabs' ),
999					panels 	= woot.find( '.panel' ),
1000					lastTab = panels.last(),
1001					scrollTop, isFixed, activeTabId;
1002
1003				if ( tabs.length ) {
1004
1005					var tabsOffset  = tabs.offset().top,
1006						placeholder = $( '<div>' ).css({
1007							'height': tabs.outerHeight(),
1008							'margin': tabs.css( 'margin' )
1009						}).insertBefore( tabs );
1010
1011					$( window ).on( 'scroll', function() {
1012
1013						if ( Codevz.inview( woot, 100 ) ) {
1014
1015							requestAnimationFrame(function() {
1016
1017								scrollTop 	= $(window).scrollTop() + adminBar;
1018								isFixed 	= scrollTop > tabsOffset;
1019
1020								tabs.toggleClass( 'fixed-tabs', isFixed );
1021								placeholder[ isFixed ? 'show' : 'hide' ]();
1022
1023								// Determine which tab content is currently in view
1024								panels.each( function() {
1025									var tabContent 		= $(this);
1026									var topOffset 		= tabContent.offset().top - 150;
1027									var bottomOffset 	= topOffset + tabContent.outerHeight();
1028
1029									// Check if the tab content is within the viewport
1030									if ( topOffset <= ( scrollTop + tabs.outerHeight()) && bottomOffset >= scrollTop ) {
1031										activeTabId = tabContent.attr('id');
1032										return false;
1033									}
1034								});
1035
1036								// Set active class on corresponding tab link
1037								tabs.find('li').removeClass('active');
1038								if ( activeTabId ) {
1039									tabs.find('a[href="#' + activeTabId + '"]').closest('li').addClass('active');
1040								} else if ( scrollTop <= tabsOffset ) { // If at top of page, set first tab as active
1041									tabs.find('li:first').addClass('active');
1042								}
1043
1044								// Last tab out of viewport, hide sticky.
1045								tabs.toggle( ( lastTab.offset().top + lastTab.outerHeight() - tabs.outerHeight() ) >= scrollTop );
1046
1047							});
1048
1049						}
1050
1051					});
1052
1053				}
1054
1055				// Tabs scroll to.
1056				body.on( 'click', '.wc-tabs a', function() {
1057
1058					var $page 		= $( 'html, body' ),
1059						tabs 		= $( 'body:not(.woo-product-tabs-vertical) .wc-tabs' ),
1060						tab 		= $( this ).attr( 'href' ).replace( '#', '' ),
1061						sticky 		= $( '.header_is_sticky' ).not( '.smart_sticky,.header_4' );
1062
1063					tab && $page.stop( true, true ).animate({
1064
1065						scrollTop: $( '#' + tab ).offset().top - ( tabs.outerHeight() || 0 ) - ( sticky.outerHeight() || 0 ) - adminBar - ( $( '.xtra-preview-header' ).outerHeight() || 0 ) - 50
1066
1067					}, 1000, 'easeInOutCodevz', function() {
1068
1069						$page.stop( true, true );
1070
1071					});
1072
1073				}).on( 'click', '.codevz-woo-rating-count', function(e) {
1074
1075					$( '.reviews_tab a' ).trigger( 'click' );
1076					e.preventDefault();
1077
1078				});
1079
1080			}, 1000 );
1081
1082			// Disable product page lightbox
1083			$( '.woo-disable-lightbox .woocommerce-product-gallery__wrapper > div:first-child a' ).removeAttr( 'href' ).css( 'cursor', 'default' );
1084
1085			// Move single onSale badge to sticky.
1086			$( 'div.product, .xtra-single-product' ).find( '> .onsale' ).prependTo( $( '.woocommerce-product-gallery' ) );
1087
1088			// Woo sticky column.
1089			$( '.woocommerce-product-gallery' ).addClass( 'cz_sticky_col' );
1090
1091			// Edit reviews count in tab and add span.
1092			$( '.wc-tabs [href="#tab-reviews"]' ).html( function( i, html ) {
1093				return html.replace( '(', '<span>' ).replace( ')', '</span>' );
1094			});
1095
1096			// Out of stock message.
1097			var outofstock_p = $( 'p.stock.out-of-stock' );
1098
1099			// Add error class to outofstock p tag.
1100			outofstock_p.addClass( 'woocommerce-error' );
1101
1102			// Sticky add to cart.
1103			if ( $( '.cz-sticky-add-to-cart' ).length && ! outofstock_p.length ) {
1104
1105				var sticky 	= $( '.cz-sticky-add-to-cart .row' ),
1106					product = $( '.xtra-single-product' ),
1107					cart 	= product.find( '.cart' ),
1108					footer  = $( '.layout_1,.layout_2' ).length ? $( '.layout_1,.layout_2' ) : $( '#site_footer' );
1109
1110				// Set product details in sticky bar.
1111				sticky.append( '<h3>' + sticky.parent().attr( 'data-title' ) + '</h3>' );
1112				sticky.append( product.find( '.cart' ).clone() );
1113				sticky.find( 'h3' ).append( product.find( '.price' ).clone() );
1114
1115				// Change add to cart to select options for variation products.
1116				if ( sticky.find( '.variations_form' ).length && ! $( '.codevz-select-options' ).length ) {
1117
1118					sticky.find( '.single_add_to_cart_button' ).hide().after( '<a href="#" class="codevz-select-options button alt">' + xtra_strings.select_options + '</a>' );
1119
1120					body.on( 'click', '.codevz-select-options', function() {
1121
1122						var targetOffsetTop = $( '.summary .variations_form' ).offset().top - 800;
1123
1124						$( 'html, body' ).animate( { scrollTop: targetOffsetTop }, 1200, 'easeInOutCodevz' );
1125
1126						return false;
1127
1128					});
1129
1130				}
1131
1132				// Product image.
1133				var image = product.find( '.woocommerce-product-gallery__image a > img' ).attr( 'src' ),
1134					offset;
1135
1136				if ( image ) {
1137					sticky.prepend( '<img src="' + image + '" />' );
1138				}
1139
1140				// Show/hide sticky on scroll.
1141				let timeout;
1142				$( window ).on( 'scroll.sticky_add_to_cart', function() {
1143
1144					clearTimeout( timeout );
1145
1146					timeout = setTimeout( function() {
1147
1148						offset = $( window ).scrollTop() > cart.offset().top + cart.outerHeight();
1149
1150						// Show/Hide sticky row.
1151						sticky.parent()[ offset ? 'addClass' : 'removeClass' ]( 'cz-sticky-add-to-cart-show' );
1152
1153						// Fix footer margin.
1154						footer.css( 'margin-bottom', sticky.parent().outerHeight() );
1155
1156						// Fixed icons.
1157						$( 'i.backtotop,i.fixed_contact' ).css( 'bottom', ( offset ? ( $( window ).width() > 769 ? $( '.cz-sticky-add-to-cart' ).outerHeight() + 20 : '' ) : '' ) );
1158
1159					}, 100 );
1160
1161				});
1162
1163			} // Sticky add to cart.
1164
1165			// Add title to product image zoom + new icon.
1166			Codevz.heightChanged( $( '.woocommerce-product-gallery' ), function() {
1167
1168				setTimeout( function() {
1169
1170					const trigger = $( '.woocommerce-product-gallery__trigger' );
1171					const thumbs  = $( '.flex-control-thumbs' );
1172
1173					if ( ! $( '.codevz-woo-zoom' ).length ) {
1174						trigger.html( '<i class="fa czico-010-expand"></i><span class="codevz-woo-zoom">' + xtra_strings.zoom_text + '</span>' );
1175					}
1176
1177					if ( thumbs.length ) {
1178						trigger.css( 'bottom', thumbs.outerHeight() + 30 );
1179					}
1180
1181				}, 500 );
1182
1183			});
1184
1185		} // Single product page.
1186
1187	};
1188
1189	Codevz_Plus.woocommerce();
1190
1191}( jQuery );

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.