PageSourceSearch

https://sofloebikeshop.com/wp-content/plugins/variation-swatches-woo/assets/js/swatches.js?ver=1.0.6

js sofloebikeshop.com collected 2026-10-06 04:12:18 UTC 16,195 bytes, 584 lines download raw bytes

1( function ( $ ) {
2	const removeAttrClass = cfvsw_swatches_settings.remove_attr_class;
3	const addRemoveWithCommonClass = `${ removeAttrClass } cfvsw-swatches-out-of-stock`;
4	const addRemoveDisableClass = removeAttrClass + '-disable';
5	const addRemoveDisableClassCommon = `${ addRemoveDisableClass } cfvsw-swatches-disabled`;
6
7	// Disable out of stock attr.
8	const SW = {
9		init: () => {
10			if ( cfvsw_swatches_settings.disable_out_of_stock ) {
11				SW.firstTime();
12				SW.Events();
13			}
14		},
15		firstTime: () => {
16			const getVariationTable = $( 'table.variations' ).not(
17				'.cfvsw-variation-disable-logic'
18			);
19			getVariationTable.addClass( 'cfvsw-variation-disable-logic' );
20			getVariationTable.each( function () {
21				const table = $( this );
22				const getForm = table.closest(
23					'[data-product_id][data-product_variations]'
24				);
25				const getFormData = getForm.data( 'product_variations' );
26				SW.swatchesOptions( getForm, getFormData );
27			} );
28		},
29		chooseOption() {
30			const option = $( this );
31			const getForm = option.closest(
32				'[data-product_id][data-product_variations]'
33			);
34			getForm
35				.find( '.disable-to-select' )
36				.removeClass( 'disable-to-select' );
37			const td = option.closest( 'td' );
38			const checkTdSelected = td
39				.find( '.cfvsw-hidden-select select' )
40				.val();
41			if ( '' !== checkTdSelected ) {
42				td.addClass( 'disable-to-select' );
43			}
44			const getFormData = getForm.data( 'product_variations' );
45			SW.swatchesOptions( getForm, getFormData );
46		},
47		getSelectedOptions: ( getForm ) => {
48			const getSelectedSwatches = getForm.find(
49				'.cfvsw-hidden-select select'
50			);
51			const selected = {};
52			getSelectedSwatches.each( function () {
53				const select = $( this );
54				const getValue = select.val();
55				const getAttrName = select.attr( 'data-attribute_name' );
56				if ( '' !== getValue && '' !== getAttrName ) {
57					selected[ getAttrName ] = getValue;
58				}
59			} );
60			return selected;
61		},
62		swatchesOptions: ( getForm, getFormData ) => {
63			const getTdAvoidCurrent = getForm
64				.find( 'td' )
65				.not( '.disable-to-select' );
66			const getAllSelect = getTdAvoidCurrent.find(
67				'.cfvsw-swatches-container[swatches-attr]'
68			);
69			if ( ! getAllSelect.length ) {
70				return;
71			}
72			const getSelectedOptions = SW.getSelectedOptions( getForm );
73			const findToRemoveClass = getTdAvoidCurrent.find(
74				`.${ addRemoveDisableClass }`
75			);
76			if ( findToRemoveClass.length ) {
77				findToRemoveClass.removeClass( addRemoveDisableClassCommon );
78			}
79			getAllSelect.each( function () {
80				const select = $( this );
81				const getAttrName = select.attr( 'swatches-attr' );
82				if ( '' !== getAttrName ) {
83					const findOptions = select.find( '.cfvsw-swatches-option' );
84					findOptions.each( function () {
85						const optValue = $( this );
86						const currentTermSlug = optValue.attr( 'data-slug' );
87
88						if ( currentTermSlug && '' !== currentTermSlug ) {
89							const hasStock = SW.checkOptionAvail(
90								getAttrName,
91								currentTermSlug,
92								getSelectedOptions,
93								getFormData
94							);
95							if ( ! hasStock ) {
96								optValue.addClass(
97									addRemoveDisableClassCommon
98								);
99							}
100						}
101					} );
102				}
103			} );
104		},
105		checkOptionAvail: (
106			getAttrName,
107			currentTermSlug,
108			getSelectedOptions,
109			getFormData
110		) => {
111			let hasThisSwatch;
112			for ( let index = 0; index < getFormData.length; index++ ) {
113				const productVariations = getFormData[ index ];
114				const { attributes, is_in_stock } = productVariations;
115				const passedInRaw = SW.checkInPreRawData(
116					getSelectedOptions,
117					attributes,
118					getAttrName,
119					currentTermSlug,
120					is_in_stock
121				);
122				if ( passedInRaw ) {
123					hasThisSwatch = is_in_stock;
124					break;
125				}
126			}
127			return hasThisSwatch;
128		},
129		checkInPreRawData: (
130			getSelectedOptions,
131			attributes,
132			getAttrName,
133			currentTermSlug,
134			is_in_stock
135		) => {
136			let hasThisSwatch = false;
137			// If getSelectedOptions values have.
138			const copySelected = { ...getSelectedOptions };
139			const selectedKeys = Object.keys( getSelectedOptions );
140			const getCurrentIndex = selectedKeys.indexOf( getAttrName );
141			const currentObj = {};
142			currentObj[ getAttrName ] = currentTermSlug;
143			if ( getCurrentIndex >= 0 ) {
144				selectedKeys.splice( getCurrentIndex, 1 );
145				delete copySelected[ getAttrName ];
146			}
147			hasThisSwatch = SW.checkInRawData(
148				attributes,
149				copySelected,
150				currentObj,
151				is_in_stock
152			);
153			return hasThisSwatch;
154		},
155		checkInRawData: ( attribute, selected, currentObj, is_in_stock ) => {
156			const cloneAttr = { ...attribute };
157			const selectedCurrent = { ...selected, ...currentObj };
158			let checkAndAvail = true;
159			for ( const checkIsAvail in selectedCurrent ) {
160				const value = selectedCurrent[ checkIsAvail ];
161				const attrValue = attribute[ checkIsAvail ];
162				if ( '' === attrValue ) {
163					delete cloneAttr[ checkIsAvail ];
164					continue;
165				}
166				if ( value === attrValue ) {
167					delete cloneAttr[ checkIsAvail ];
168					continue;
169				}
170				checkAndAvail = false;
171			}
172
173			if ( is_in_stock ) {
174				return checkAndAvail;
175			}
176			// Check when out of stock
177			for ( const cloneKey in cloneAttr ) {
178				const cloneValue = cloneAttr[ cloneKey ];
179				if ( '' !== cloneValue ) {
180					checkAndAvail = false;
181				}
182			}
183			return checkAndAvail;
184		},
185		Events: () => {
186			$( document ).on(
187				'click',
188				'.cfvsw-swatches-container .cfvsw-swatches-option[data-slug]',
189				SW.chooseOption
190			);
191		},
192	};
193
194	$( document ).on( 'click', '.cfvsw-swatches-option', function () {
195		const swatchesOption = $( this );
196		if (
197			swatchesOption.hasClass( 'cfvsw-swatches-disabled' ) ||
198			swatchesOption.hasClass( 'cfvsw-swatches-out-of-stock' )
199		) {
200			return;
201		}
202		onClickSwatchesOption( swatchesOption );
203	} );
204
205	$( 'body' ).on(
206		'click',
207		'.cfvsw_ajax_add_to_cart.cfvsw_variation_found',
208		function ( e ) {
209			e.preventDefault();
210			triggerAddToCart( $( this ) );
211		}
212	);
213
214	function onClickSwatchesOption( swatch ) {
215		if ( swatch.hasClass( 'cfvsw-selected-swatch' ) ) {
216			swatch.removeClass( 'cfvsw-selected-swatch' );
217			resetPrice( swatch );
218			resetThumbnail( swatch );
219			resetButtonData( swatch );
220		} else {
221			const parent = swatch.parent();
222			parent.find( '.cfvsw-swatches-option' ).each( function () {
223				$( this ).removeClass( 'cfvsw-selected-swatch' );
224			} );
225
226			swatch.addClass( 'cfvsw-selected-swatch' );
227		}
228
229		updateSelectOption( swatch );
230		if ( cfvsw_swatches_settings.html_design !== 'inline' ) {
231			updateTitle( swatch );
232		}
233	}
234
235	function updateSelectOption( swatch ) {
236		const value = swatch.hasClass( 'cfvsw-selected-swatch' )
237			? swatch.data( 'slug' )
238			: '';
239		const select = swatch
240			.closest( '.cfvsw-swatches-container' )
241			.prev()
242			.find( 'select' );
243		select.val( value ).change();
244	}
245
246	function updateTitle( swatch ) {
247		const label = swatch.closest( 'tr' ).children( '.label' );
248		label.find( '.cfvsw-selected-label' ).remove();
249
250		if ( ! swatch.hasClass( 'cfvsw-selected-swatch' ) ) {
251			return;
252		}
253
254		label
255			.children( 'label' )
256			.append( '<span class="cfvsw-selected-label"></span>' );
257		label
258			.children( 'label' )
259			.children( '.cfvsw-selected-label' )
260			.html( swatch.data( 'title' ) );
261	}
262
263	function triggerAddToCart( variant ) {
264		if ( variant.is( '.wc-variation-is-unavailable' ) ) {
265			return window.alert( cfvsw_swatches_settings.unavailable_text );
266		}
267		const productId = variant.data( 'product_id' );
268		let variationId = variant.attr( 'data-variation_id' );
269		variationId = parseInt( variationId );
270		if (
271			isNaN( productId ) ||
272			productId === 0 ||
273			isNaN( variationId ) ||
274			variationId === 0
275		) {
276			return true;
277		}
278		let variation = variant.attr( 'data-selected_variant' );
279		variation = JSON.parse( variation );
280		const data = {
281			action: 'cfvsw_ajax_add_to_cart',
282			security: cfvsw_swatches_settings.ajax_add_to_cart_nonce,
283			product_id: productId,
284			variation_id: variationId,
285			variation,
286		};
287		$( document.body ).trigger( 'adding_to_cart', [ variant, data ] );
288		variant.removeClass( 'added' ).addClass( 'loading' );
289		// Ajax add to cart request
290		$.ajax( {
291			type: 'POST',
292			url: cfvsw_swatches_settings.ajax_url,
293			data,
294			dataType: 'json',
295			success( response ) {
296				if ( ! response ) {
297					return;
298				}
299
300				if ( response.error && response.product_url ) {
301					window.location = response.product_url;
302					return;
303				}
304
305				// Trigger event so themes can refresh other areas.
306				$( document.body ).trigger( 'added_to_cart', [
307					response.fragments,
308					response.cart_hash,
309					variant,
310				] );
311				$( document.body ).trigger( 'update_checkout' );
312
313				variant.removeClass( 'loading' ).addClass( 'added' );
314			},
315			error( errorThrown ) {
316				variant.removeClass( 'loading' );
317				console.log( errorThrown );
318			},
319		} );
320	}
321
322	$( document ).on( 'change', '.cfvsw-hidden-select select', function () {
323		setTimeout( () => {
324			updateSwatchesAvailability();
325		}, 1 );
326	} );
327
328	$( '.reset_variations' ).on( 'click', function () {
329		resetSwatches( $( this ) );
330	} );
331
332	// Tooltip.
333	$( document ).on(
334		{
335			mouseenter() {
336				const addToTooltip = $( this );
337				const tooltip = addToTooltip.data( 'tooltip' );
338				if (
339					'' === tooltip ||
340					'undefined' === typeof tooltip ||
341					addToTooltip.hasClass( 'cfvsw-label-option' )
342				) {
343					return;
344				}
345
346				if ( addToTooltip.children( '.cfvsw-tooltip' ).length === 0 ) {
347					addToTooltip.prepend(
348						`<div class="cfvsw-tooltip"><span class="cfvsw-tooltip-label">${ tooltip }</span></div>`
349					);
350					$( '.cfvsw-tooltip' ).fadeIn( 500 );
351					const swatchHeight = addToTooltip
352						.children( '.cfvsw-swatch-inner' )
353						.innerHeight();
354					$( '.cfvsw-tooltip' ).css( {
355						bottom: swatchHeight,
356					} );
357					if (
358						cfvsw_swatches_settings.tooltip_image &&
359						addToTooltip.hasClass( 'cfvsw-image-option' )
360					) {
361						$( '.cfvsw-tooltip' ).prepend(
362							"<span class='cfvsw-tooltip-preview'></span>"
363						);
364						const preview = addToTooltip
365							.children( '.cfvsw-swatch-inner' )
366							.css( 'backgroundImage' );
367						$( '.cfvsw-tooltip' ).css( {
368							bottom: swatchHeight - 30,
369							padding: '2px',
370						} );
371						$( '.cfvsw-tooltip-preview' ).css( {
372							backgroundImage: preview,
373							backgroundSize: 'cover',
374						} );
375					}
376				}
377			},
378			mouseleave() {
379				$( '.cfvsw-tooltip' ).remove();
380			},
381		},
382		'.cfvsw-swatches-option'
383	);
384
385	$( document ).on( 'ready', function () {
386		setTimeout( () => {
387			setSwatchesSelection();
388		}, 1 );
389		$( '.woocommerce-widget-layered-nav-list' ).each( function () {
390			if ( $( this ).find( '.cfvsw-swatches-container' ).length ) {
391				$( this ).addClass( 'cfvsw-filters' );
392			}
393		} );
394	} );
395
396	$( '.cfvsw-shop-variations' ).on( 'click', function ( e ) {
397		e.preventDefault();
398	} );
399
400	$( '.cfvsw-shop-variations .cfvsw-more-link' ).on( 'click', function ( e ) {
401		window.location = e.target.href;
402	} );
403
404	function updateSwatchesAvailability() {
405		$( '.cfvsw-hidden-select select' ).each( function () {
406			const availableOptions = [];
407			$( this )
408				.children( 'option' )
409				.each( function () {
410					if ( '' !== $( this ).val() ) {
411						availableOptions.push( $( this ).val() );
412					}
413				} );
414			$( this )
415				.parent()
416				.next()
417				.find( '.cfvsw-swatches-option' )
418				.each( function () {
419					if (
420						-1 ===
421						$.inArray(
422							$( this ).attr( 'data-slug' ),
423							availableOptions
424						)
425					) {
426						$( this ).addClass( addRemoveWithCommonClass );
427					} else {
428						$( this ).removeClass( addRemoveWithCommonClass );
429					}
430				} );
431		} );
432	}
433
434	function setSwatchesSelection() {
435		$( '.cfvsw-hidden-select select' ).each( function () {
436			const selected = $( this ).val();
437			$( this )
438				.parent()
439				.next()
440				.find( `[data-slug='${ selected }']` )
441				.trigger( 'click' );
442		} );
443	}
444
445	function resetSwatches( resetButton ) {
446		$( '.cfvsw-swatches-option' ).each( function () {
447			$( this ).removeClass( 'cfvsw-selected-swatch' );
448		} );
449		$( '.cfvsw-selected-label' ).remove();
450
451		if ( cfvsw_swatches_settings.disable_out_of_stock ) {
452			const table = resetButton.closest( 'table' );
453			const findDisabledAttr = table.find(
454				`.${ addRemoveDisableClass }`
455			);
456			const findDisableSelect = table.find( '.disable-to-select' );
457			if ( findDisableSelect.length ) {
458				findDisableSelect.removeClass( 'disable-to-select' );
459			}
460			if ( findDisabledAttr ) {
461				findDisabledAttr.removeClass( addRemoveDisableClassCommon );
462			}
463			setTimeout( () => {
464				SW.firstTime();
465			}, 20 );
466		}
467	}
468
469	function addVariationFunctionality() {
470		$( '.cfvsw_variations_form:not(.variation-function-added)' ).each(
471			function () {
472				const thisForm = $( this );
473				thisForm.addClass( 'variation-function-added' );
474				thisForm.wc_variation_form();
475				thisForm.on( 'found_variation', function ( e, variation ) {
476					updateThumbnail( thisForm, variation.image );
477					if ( thisForm.attr( 'data-cfvsw-catalog' ) ) {
478						return;
479					}
480					updatePrice( thisForm, variation );
481					updatebuttonData( thisForm, variation );
482				} );
483			}
484		);
485	}
486
487	$( window ).load( function () {
488		addVariationFunctionality();
489	} );
490
491	function updateThumbnail( swatch, imageData ) {
492		const listItem = swatch.closest( 'li' );
493		const thumbnail = listItem.find( 'img:first' );
494		if ( 0 === listItem.find( '.cfvsw-original-thumbnail' ).length ) {
495			const originalThumbnail = thumbnail.clone();
496			thumbnail.after( '<span class="cfvsw-original-thumbnail"></span>' );
497			listItem
498				.find( '.cfvsw-original-thumbnail' )
499				.html( originalThumbnail );
500		}
501		thumbnail.attr( 'src', imageData.thumb_src );
502		thumbnail.attr( 'srcset', '' );
503	}
504
505	function resetThumbnail( swatch ) {
506		const listItem = swatch.closest( 'li' );
507		if ( listItem.find( '.cfvsw-original-thumbnail' ).length ) {
508			const thumbnail = listItem.find( 'img:first' );
509			thumbnail.replaceWith(
510				listItem.find( '.cfvsw-original-thumbnail' ).html()
511			);
512			listItem.find( '.cfvsw-original-thumbnail' ).remove();
513		}
514	}
515
516	function updatePrice( swatch, variation ) {
517		if ( 0 === variation.price_html.length ) {
518			return;
519		}
520		if ( swatch.parents( 'li' ).find( '.cfvsw-original-price' ).length ) {
521			const price = swatch.parents( 'li' ).find( '.price' );
522			price.replaceWith( variation.price_html );
523		} else {
524			const price = swatch.parents( 'li' ).find( '.price' );
525			price.after( variation.price_html );
526			price.removeClass( 'price' ).addClass( 'cfvsw-original-price' );
527		}
528	}
529
530	function resetPrice( swatch ) {
531		if ( swatch.parents( 'li' ).find( '.cfvsw-original-price' ).length ) {
532			swatch.parents( 'li' ).find( '.price' ).remove();
533			swatch
534				.parents( 'li' )
535				.find( '.cfvsw-original-price' )
536				.removeClass( 'cfvsw-original-price' )
537				.addClass( 'price' );
538		}
539	}
540
541	function updatebuttonData( variant, variation ) {
542		const select = variant.find( '.variations select' );
543		const data = {};
544		const button = variant
545			.parents( 'li' )
546			.find( '.cfvsw_ajax_add_to_cart' );
547
548		select.each( function () {
549			const attributeName =
550				$( this ).data( 'attribute_name' ) || $( this ).attr( 'name' );
551			const value = $( this ).val() || '';
552			data[ attributeName ] = value;
553		} );
554
555		button.html( button.data( 'add_to_cart_text' ) );
556		button.addClass( 'cfvsw_variation_found' );
557		button.attr( 'data-variation_id', variation.variation_id );
558		button.attr( 'data-selected_variant', JSON.stringify( data ) );
559	}
560
561	function resetButtonData( variant ) {
562		const button = variant
563			.parents( 'li' )
564			.find( '.cfvsw_ajax_add_to_cart' );
565		button.html( button.data( 'select_options_text' ) );
566		button.removeClass( 'cfvsw_variation_found' );
567		button.attr( 'data-variation_id', '' );
568		button.attr( 'data-selected_variant', '' );
569	}
570
571	SW.init();
572	document.addEventListener( 'astraInfinitePaginationLoaded', function () {
573		SW.firstTime();
574		addVariationFunctionality();
575	} );
576
577	// Add custom trigger to load swatches.
578
579	// document.dispatchEvent( new CustomEvent("cfvswVariationLoad", { detail: {} }) ); To load variation trigger we need to trigger this.
580	document.addEventListener( 'cfvswVariationLoad', function () {
581		SW.firstTime();
582		addVariationFunctionality();
583	} );
584} )( 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.