PageSourceSearch

https://publisher.in.ua/wp-content/themes/fynode/assets/js/custom/…=1.0.0.pagespeed.ce.R0pLJ5-Y73.js

js publisher.in.ua collected 2026-10-02 05:00:29 UTC 30,078 bytes, 824 lines download raw bytes

1(function ($) {
2  "use strict";
3
4	$(document).on('fynodeSinglePageInit', function () {
5		fynodeThemeModule.variationform();
6	});
7
8	fynodeThemeModule.variationform = function() {
9		
10		var VariationForm = function( $form ) {
11			var self = this;
12
13			self.$form                = $form;
14			self.$attributeFields     = $form.find( '.variations select' );
15			self.$singleVariation     = $form.find( '.single_variation' );
16			self.$singleVariationWrap = $form.find( '.single_variation_wrap' );
17			self.$resetVariations     = $form.find( '.reset_variations' );
18			self.$product             = $form.closest( '.product' );
19			self.variationData        = $form.data( 'product_variations' );
20			self.useAjax              = false === self.variationData;
21			self.xhr                  = false;
22			self.loading              = true;
23
24			// Initial state.
25			self.$singleVariationWrap.show();
26			self.$form.off( '.wc-variation-form' );
27
28			// Methods.
29			self.getChosenAttributes    = self.getChosenAttributes.bind( self );
30			self.findMatchingVariations = self.findMatchingVariations.bind( self );
31			self.isMatch                = self.isMatch.bind( self );
32			self.toggleResetLink        = self.toggleResetLink.bind( self );
33
34			// Events.
35			$form.on( 'click.wc-variation-form', '.reset_variations', { variationForm: self }, self.onReset );
36			$form.on( 'reload_product_variations', { variationForm: self }, self.onReload );
37			$form.on( 'hide_variation', { variationForm: self }, self.onHide );
38			$form.on( 'show_variation', { variationForm: self }, self.onShow );
39			$form.on( 'click', '.single_add_to_cart_button', { variationForm: self }, self.onAddToCart );
40			$form.on( 'reset_data', { variationForm: self }, self.onResetDisplayedVariation );
41			$form.on( 'reset_image', { variationForm: self }, self.onResetImage );
42			$form.on( 'change.wc-variation-form', '.variations select', { variationForm: self }, self.onChange );
43			$form.on( 'found_variation.wc-variation-form', { variationForm: self }, self.onFoundVariation );
44			$form.on( 'check_variations.wc-variation-form', { variationForm: self }, self.onFindVariation );
45			$form.on( 'update_variation_values.wc-variation-form', { variationForm: self }, self.onUpdateAttributes );
46
47			// Init after gallery.
48			setTimeout( function() {
49				$form.trigger( 'check_variations' );
50				$form.trigger( 'wc_variation_form', self );
51				self.loading = false;
52			}, 100 );
53		};
54
55		/**
56		 * Reset all fields.
57		 */
58		VariationForm.prototype.onReset = function( event ) {
59			event.preventDefault();
60			event.data.variationForm.$attributeFields.val( '' ).trigger( 'change' );
61			event.data.variationForm.$form.trigger( 'reset_data' );
62		};
63
64		/**
65		 * Reload variation data from the DOM.
66		 */
67		VariationForm.prototype.onReload = function( event ) {
68			var form           = event.data.variationForm;
69			form.variationData = form.$form.data( 'product_variations' );
70			form.useAjax       = false === form.variationData;
71			form.$form.trigger( 'check_variations' );
72		};
73
74		/**
75		 * When a variation is hidden.
76		 */
77		VariationForm.prototype.onHide = function( event ) {
78			event.preventDefault();
79			event.data.variationForm.$form
80				.find( '.single_add_to_cart_button' )
81				.removeClass( 'wc-variation-is-unavailable' )
82				.addClass( 'disabled wc-variation-selection-needed' );
83			event.data.variationForm.$form
84				.find( '.woocommerce-variation-add-to-cart' )
85				.removeClass( 'woocommerce-variation-add-to-cart-enabled' )
86				.addClass( 'woocommerce-variation-add-to-cart-disabled' );
87		};
88
89		/**
90		 * When a variation is shown.
91		 */
92		VariationForm.prototype.onShow = function( event, variation, purchasable ) {
93			event.preventDefault();
94			if ( purchasable ) {
95				event.data.variationForm.$form
96					.find( '.single_add_to_cart_button' )
97					.removeClass( 'disabled wc-variation-selection-needed wc-variation-is-unavailable' );
98				event.data.variationForm.$form
99					.find( '.woocommerce-variation-add-to-cart' )
100					.removeClass( 'woocommerce-variation-add-to-cart-disabled' )
101					.addClass( 'woocommerce-variation-add-to-cart-enabled' );
102			} else {
103				event.data.variationForm.$form
104					.find( '.single_add_to_cart_button' )
105					.removeClass( 'wc-variation-selection-needed' )
106					.addClass( 'disabled wc-variation-is-unavailable' );
107				event.data.variationForm.$form
108					.find( '.woocommerce-variation-add-to-cart' )
109					.removeClass( 'woocommerce-variation-add-to-cart-enabled' )
110					.addClass( 'woocommerce-variation-add-to-cart-disabled' );
111			}
112
113			// If present, the media element library needs initialized on the variation description.
114			if ( wp.mediaelement ) {
115				event.data.variationForm.$form.find( '.wp-audio-shortcode, .wp-video-shortcode' )
116					.not( '.mejs-container' )
117					.filter(
118						function () {
119							return ! $( this ).parent().hasClass( 'mejs-mediaelement' );
120						}
121					)
122					.mediaelementplayer( wp.mediaelement.settings );
123			}
124		};
125
126		/**
127		 * When the cart button is pressed.
128		 */
129		VariationForm.prototype.onAddToCart = function( event ) {
130			if ( $( this ).is('.disabled') ) {
131				event.preventDefault();
132
133				if ( $( this ).is('.wc-variation-is-unavailable') ) {
134					window.alert( wc_add_to_cart_variation_params.i18n_unavailable_text );
135				} else if ( $( this ).is('.wc-variation-selection-needed') ) {
136					window.alert( wc_add_to_cart_variation_params.i18n_make_a_selection_text );
137				}
138			}
139		};
140
141		/**
142		 * When displayed variation data is reset.
143		 */
144		VariationForm.prototype.onResetDisplayedVariation = function( event ) {
145			var form = event.data.variationForm;
146			form.$product.find( '.product_meta' ).find( '.sku' ).wc_reset_content();
147			form.$product
148				.find( '.product_weight, .woocommerce-product-attributes-item--weight .woocommerce-product-attributes-item__value' )
149				.wc_reset_content();
150			form.$product
151				.find( '.product_dimensions, .woocommerce-product-attributes-item--dimensions .woocommerce-product-attributes-item__value' )
152				.wc_reset_content();
153			form.$form.trigger( 'reset_image' );
154			form.$singleVariation.slideUp( 200 ).trigger( 'hide_variation' );
155		};
156
157		/**
158		 * When the product image is reset.
159		 */
160		VariationForm.prototype.onResetImage = function( event ) {
161			event.data.variationForm.$form.wc_variations_image_update( false );
162		};
163
164		/**
165		 * Looks for matching variations for current selected attributes.
166		 */
167		VariationForm.prototype.onFindVariation = function( event, chosenAttributes ) {
168			var form              = event.data.variationForm,
169				attributes        = 'undefined' !== typeof chosenAttributes ? chosenAttributes : form.getChosenAttributes(),
170				currentAttributes = attributes.data;
171
172			if ( attributes.count && attributes.count === attributes.chosenCount ) {
173				if ( form.useAjax ) {
174					if ( form.xhr ) {
175						form.xhr.abort();
176					}
177					form.$form.block( { message: null, overlayCSS: { background: '#fff', opacity: 0.6 } } );
178					currentAttributes.product_id  = parseInt( form.$form.data( 'product_id' ), 10 );
179					currentAttributes.custom_data = form.$form.data( 'custom_data' );
180					form.xhr                      = $.ajax( {
181						url: wc_add_to_cart_variation_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'get_variation' ),
182						type: 'POST',
183						data: currentAttributes,
184						success: function( variation ) {
185							if ( variation ) {
186								form.$form.trigger( 'found_variation', [ variation ] );
187							} else {
188								form.$form.trigger( 'reset_data' );
189								attributes.chosenCount = 0;
190
191								if ( ! form.loading ) {
192									form.$form
193										.find( '.single_variation' )
194										.after(
195											'<p class="wc-no-matching-variations woocommerce-info">' +
196											wc_add_to_cart_variation_params.i18n_no_matching_variations_text +
197											'</p>'
198										);
199									form.$form.find( '.wc-no-matching-variations' ).slideDown( 200 );
200								}
201							}
202						},
203						complete: function() {
204							form.$form.unblock();
205						}
206					} );
207				} else {
208					form.$form.trigger( 'update_variation_values' );
209
210					var matching_variations = form.findMatchingVariations( form.variationData, currentAttributes ),
211						variation           = matching_variations.shift();
212
213					if ( variation ) {
214						form.$form.trigger( 'found_variation', [ variation ] );
215					} else {
216						form.$form.trigger( 'reset_data' );
217						attributes.chosenCount = 0;
218
219						if ( ! form.loading ) {
220							form.$form
221								.find( '.single_variation' )
222								.after(
223									'<p class="wc-no-matching-variations woocommerce-info">' +
224									wc_add_to_cart_variation_params.i18n_no_matching_variations_text +
225									'</p>'
226								);
227							form.$form.find( '.wc-no-matching-variations' ).slideDown( 200 );
228						}
229					}
230				}
231			} else {
232				form.$form.trigger( 'update_variation_values' );
233				form.$form.trigger( 'reset_data' );
234			}
235
236			// Show reset link.
237			form.toggleResetLink( attributes.chosenCount > 0 );
238		};
239
240		/**
241		 * Triggered when a variation has been found which matches all attributes.
242		 */
243		VariationForm.prototype.onFoundVariation = function( event, variation ) {
244			var form           = event.data.variationForm,
245				$sku           = form.$product.find( '.product_meta' ).find( '.sku' ),
246				$weight        = form.$product.find(
247					'.product_weight, .woocommerce-product-attributes-item--weight .woocommerce-product-attributes-item__value'
248				),
249				$dimensions    = form.$product.find(
250					'.product_dimensions, .woocommerce-product-attributes-item--dimensions .woocommerce-product-attributes-item__value'
251				),
252				$qty           = form.$singleVariationWrap.find( '.quantity' ),
253				purchasable    = true,
254				variation_id   = '',
255				template       = false,
256				$template_html = '';
257
258			if ( variation.sku ) {
259				$sku.wc_set_content( variation.sku );
260			} else {
261				$sku.wc_reset_content();
262			}
263
264			if ( variation.weight ) {
265				$weight.wc_set_content( variation.weight_html );
266			} else {
267				$weight.wc_reset_content();
268			}
269
270			if ( variation.dimensions ) {
271				// Decode HTML entities.
272				$dimensions.wc_set_content( $.parseHTML( variation.dimensions_html )[0].data );
273			} else {
274				$dimensions.wc_reset_content();
275			}
276
277			form.$form.wc_variations_image_update( variation );
278
279			if ( ! variation.variation_is_visible ) {
280				template = wp_template( 'unavailable-variation-template' );
281			} else {
282				template     = wp_template( 'variation-template' );
283				variation_id = variation.variation_id;
284			}
285
286			$template_html = template( {
287				variation: variation
288			} );
289			$template_html = $template_html.replace( '/*<![CDATA[*/', '' );
290			$template_html = $template_html.replace( '/*]]>*/', '' );
291
292			form.$singleVariation.html( $template_html );
293			form.$form.find( 'input[name="variation_id"], input.variation_id' ).val( variation.variation_id ).trigger( 'change' );
294
295			// Hide or show qty input
296			if ( variation.is_sold_individually === 'yes' ) {
297				$qty.find( 'input.qty' ).val( '1' ).attr( 'min', '1' ).attr( 'max', '' ).trigger( 'change' );
298				$qty.hide();
299			} else {
300
301				var $qty_input = $qty.find( 'input.qty' ),
302					qty_val    = parseFloat( $qty_input.val() );
303
304				if ( isNaN( qty_val ) ) {
305					qty_val = variation.min_qty;
306				} else {
307					qty_val = qty_val > parseFloat( variation.max_qty ) ? variation.max_qty : qty_val;
308					qty_val = qty_val < parseFloat( variation.min_qty ) ? variation.min_qty : qty_val;
309				}
310
311				$qty_input.attr( 'min', variation.min_qty ).attr( 'max', variation.max_qty ).val( qty_val ).trigger( 'change' );
312				$qty.show();
313			}
314
315			// Enable or disable the add to cart button
316			if ( ! variation.is_purchasable || ! variation.is_in_stock || ! variation.variation_is_visible ) {
317				purchasable = false;
318			}
319
320			// Reveal
321			if ( form.$singleVariation.text().trim() ) {
322				form.$singleVariation.slideDown( 200 ).trigger( 'show_variation', [ variation, purchasable ] );
323			} else {
324				form.$singleVariation.show().trigger( 'show_variation', [ variation, purchasable ] );
325			}
326		};
327
328		/**
329		 * Triggered when an attribute field changes.
330		 */
331		VariationForm.prototype.onChange = function( event ) {
332			var form = event.data.variationForm;
333
334			form.$form.find( 'input[name="variation_id"], input.variation_id' ).val( '' ).trigger( 'change' );
335			form.$form.find( '.wc-no-matching-variations' ).remove();
336
337			if ( form.useAjax ) {
338				form.$form.trigger( 'check_variations' );
339			} else {
340				form.$form.trigger( 'woocommerce_variation_select_change' );
341				form.$form.trigger( 'check_variations' );
342			}
343
344			// Custom event for when variation selection has been changed
345			form.$form.trigger( 'woocommerce_variation_has_changed' );
346		};
347
348		/**
349		 * Escape quotes in a string.
350		 * @param {string} string
351		 * @return {string}
352		 */
353		VariationForm.prototype.addSlashes = function( string ) {
354			string = string.replace( /'/g, '\\\'' );
355			string = string.replace( /"/g, '\\\"' );
356			return string;
357		};
358
359		/**
360		 * Updates attributes in the DOM to show valid values.
361		 */
362		VariationForm.prototype.onUpdateAttributes = function( event ) {
363			var form              = event.data.variationForm,
364				attributes        = form.getChosenAttributes(),
365				currentAttributes = attributes.data;
366
367			if ( form.useAjax ) {
368				return;
369			}
370
371			// Loop through selects and disable/enable options based on selections.
372			form.$attributeFields.each( function( index, el ) {
373				var current_attr_select     = $( el ),
374					current_attr_name       = current_attr_select.data( 'attribute_name' ) || current_attr_select.attr( 'name' ),
375					show_option_none        = $( el ).data( 'show_option_none' ),
376					option_gt_filter        = ':gt(0)',
377					attached_options_count  = 0,
378					new_attr_select         = $( '<select/>' ),
379					selected_attr_val       = current_attr_select.val() || '',
380					selected_attr_val_valid = true;
381
382				// Reference options set at first.
383				if ( ! current_attr_select.data( 'attribute_html' ) ) {
384					var refSelect = current_attr_select.clone();
385
386					refSelect.find( 'option' ).removeAttr( 'attached' ).prop( 'disabled', false ).prop( 'selected', false );
387
388					// Legacy data attribute.
389					current_attr_select.data(
390						'attribute_options',
391						refSelect.find( 'option' + option_gt_filter ).get()
392					);
393					current_attr_select.data( 'attribute_html', refSelect.html() );
394				}
395
396				new_attr_select.html( current_attr_select.data( 'attribute_html' ) );
397
398				// The attribute of this select field should not be taken into account when calculating its matching variations:
399				// The constraints of this attribute are shaped by the values of the other attributes.
400				var checkAttributes = $.extend( true, {}, currentAttributes );
401
402				checkAttributes[ current_attr_name ] = '';
403
404				var variations = form.findMatchingVariations( form.variationData, checkAttributes );
405
406				// Loop through variations.
407				for ( var num in variations ) {
408					if ( typeof( variations[ num ] ) !== 'undefined' ) {
409						var variationAttributes = variations[ num ].attributes;
410
411						for ( var attr_name in variationAttributes ) {
412							if ( variationAttributes.hasOwnProperty( attr_name ) ) {
413								var attr_val         = variationAttributes[ attr_name ],
414									variation_active = '';
415
416								if ( attr_name === current_attr_name ) {
417									if ( variations[ num ].variation_is_active ) {
418										variation_active = 'enabled';
419									}
420
421									if ( attr_val ) {
422										// Decode entities.
423										attr_val = $( '<div/>' ).html( attr_val ).text();
424
425										// Attach to matching options by value. This is done to compare
426										// TEXT values rather than any HTML entities.
427										var $option_elements = new_attr_select.find( 'option' );
428										if ( $option_elements.length ) {
429											for (var i = 0, len = $option_elements.length; i < len; i++) {
430												var $option_element = $( $option_elements[i] ),
431													option_value = $option_element.val();
432
433												if ( attr_val === option_value ) {
434													$option_element.addClass( 'attached ' + variation_active );
435													break;
436												}
437											}
438										}
439									} else {
440										// Attach all apart from placeholder.
441										new_attr_select.find( 'option:gt(0)' ).addClass( 'attached ' + variation_active );
442									}
443								}
444							}
445						}
446					}
447				}
448
449				// Count available options.
450				attached_options_count = new_attr_select.find( 'option.attached' ).length;
451
452				// Check if current selection is in attached options.
453				if ( selected_attr_val ) {
454					selected_attr_val_valid = false;
455
456					if ( 0 !== attached_options_count ) {
457						new_attr_select.find( 'option.attached.enabled' ).each( function() {
458							var option_value = $( this ).val();
459
460							if ( selected_attr_val === option_value ) {
461								selected_attr_val_valid = true;
462								return false; // break.
463							}
464						});
465					}
466				}
467
468				// Detach the placeholder if:
469				// - Valid options exist.
470				// - The current selection is non-empty.
471				// - The current selection is valid.
472				// - Placeholders are not set to be permanently visible.
473				if ( attached_options_count > 0 && selected_attr_val && selected_attr_val_valid && ( 'no' === show_option_none ) ) {
474					new_attr_select.find( 'option:first' ).remove();
475					option_gt_filter = '';
476				}
477
478				// Detach unattached.
479				new_attr_select.find( 'option' + option_gt_filter + ':not(.attached)' ).remove();
480
481				// Finally, copy to DOM and set value.
482				current_attr_select.html( new_attr_select.html() );
483				current_attr_select.find( 'option' + option_gt_filter + ':not(.enabled)' ).prop( 'disabled', true );
484
485				// Choose selected value.
486				if ( selected_attr_val ) {
487					// If the previously selected value is no longer available, fall back to the placeholder (it's going to be there).
488					if ( selected_attr_val_valid ) {
489						current_attr_select.val( selected_attr_val );
490					} else {
491						current_attr_select.val( '' ).trigger( 'change' );
492					}
493				} else {
494					current_attr_select.val( '' ); // No change event to prevent infinite loop.
495				}
496			});
497
498			// Custom event for when variations have been updated.
499			form.$form.trigger( 'woocommerce_update_variation_values' );
500		};
501
502		/**
503		 * Get chosen attributes from form.
504		 * @return array
505		 */
506		VariationForm.prototype.getChosenAttributes = function() {
507			var data   = {};
508			var count  = 0;
509			var chosen = 0;
510
511			this.$attributeFields.each( function() {
512				var attribute_name = $( this ).data( 'attribute_name' ) || $( this ).attr( 'name' );
513				var value          = $( this ).val() || '';
514
515				if ( value.length > 0 ) {
516					chosen ++;
517				}
518
519				count ++;
520				data[ attribute_name ] = value;
521			});
522
523			return {
524				'count'      : count,
525				'chosenCount': chosen,
526				'data'       : data
527			};
528		};
529
530		/**
531		 * Find matching variations for attributes.
532		 */
533		VariationForm.prototype.findMatchingVariations = function( variations, attributes ) {
534			var matching = [];
535			for ( var i = 0; i < variations.length; i++ ) {
536				var variation = variations[i];
537
538				if ( this.isMatch( variation.attributes, attributes ) ) {
539					matching.push( variation );
540				}
541			}
542			return matching;
543		};
544
545		/**
546		 * See if attributes match.
547		 * @return {Boolean}
548		 */
549		VariationForm.prototype.isMatch = function( variation_attributes, attributes ) {
550			var match = true;
551			for ( var attr_name in variation_attributes ) {
552				if ( variation_attributes.hasOwnProperty( attr_name ) ) {
553					var val1 = variation_attributes[ attr_name ];
554					var val2 = attributes[ attr_name ];
555					if ( val1 !== undefined && val2 !== undefined && val1.length !== 0 && val2.length !== 0 && val1 !== val2 ) {
556						match = false;
557					}
558				}
559			}
560			return match;
561		};
562
563		/**
564		 * Show or hide the reset link.
565		 */
566		VariationForm.prototype.toggleResetLink = function( on ) {
567			if ( on ) {
568				if ( this.$resetVariations.css( 'visibility' ) === 'hidden' ) {
569					this.$resetVariations.css( 'visibility', 'visible' ).hide().fadeIn();
570				}
571			} else {
572				this.$resetVariations.css( 'visibility', 'hidden' );
573			}
574		};
575
576		/**
577		 * Function to call wc_variation_form on jquery selector.
578		 */
579		$.fn.wc_variation_form = function() {
580			new VariationForm( this );
581			return this;
582		};
583
584		/**
585		 * Stores the default text for an element so it can be reset later
586		 */
587		$.fn.wc_set_content = function( content ) {
588			if ( undefined === this.attr( 'data-o_content' ) ) {
589				this.attr( 'data-o_content', this.text() );
590			}
591			this.text( content );
592		};
593
594		/**
595		 * Stores the default text for an element so it can be reset later
596		 */
597		$.fn.wc_reset_content = function() {
598			if ( undefined !== this.attr( 'data-o_content' ) ) {
599				this.text( this.attr( 'data-o_content' ) );
600			}
601		};
602
603		/**
604		 * Stores a default attribute for an element so it can be reset later
605		 */
606		$.fn.wc_set_variation_attr = function( attr, value ) {
607			if ( undefined === this.attr( 'data-o_' + attr ) ) {
608				this.attr( 'data-o_' + attr, ( ! this.attr( attr ) ) ? '' : this.attr( attr ) );
609			}
610			if ( false === value ) {
611				this.removeAttr( attr );
612			} else {
613				this.attr( attr, value );
614			}
615		};
616
617		/**
618		 * Reset a default attribute for an element so it can be reset later
619		 */
620		$.fn.wc_reset_variation_attr = function( attr ) {
621			if ( undefined !== this.attr( 'data-o_' + attr ) ) {
622				this.attr( attr, this.attr( 'data-o_' + attr ) );
623			}
624		};
625
626		/**
627		 * Reset the slide position if the variation has a different image than the current one
628		 */
629		$.fn.wc_maybe_trigger_slide_position_reset = function( variation ) {
630			var $form                = $( this ),
631				$product             = $form.closest( '.product' ),
632				$product_gallery     = $product.find( '.images' ),
633				reset_slide_position = false,
634				new_image_id         = ( variation && variation.image_id ) ? variation.image_id : '';
635
636			if ( $form.attr( 'current-image' ) !== new_image_id ) {
637				reset_slide_position = true;
638			}
639
640			$form.attr( 'current-image', new_image_id );
641
642			if ( reset_slide_position ) {
643				$product_gallery.trigger( 'woocommerce_gallery_reset_slide_position' );
644			}
645		};
646
647		/**
648		 * Sets product images for the chosen variation
649		 */
650		$.fn.wc_variations_image_update = function( variation ) {
651			var $form             = this,
652				$product          = $form.closest( '.product' ),
653				$product_gallery  = $product.find( '.images' ),
654				$gallery_nav      = $product.find( '.flex-control-nav' ),
655				$gallery_img      = $gallery_nav.find( 'li:eq(0) img' ),
656				$product_img_wrap = $product_gallery
657					.find( '.woocommerce-product-gallery__image, .woocommerce-product-gallery__image--placeholder' )
658					.eq( 0 ),
659				$product_img      = $product_img_wrap.find( '.wp-post-image' ),
660				$product_link     = $product_img_wrap.find( 'a' ).eq( 0 );
661
662			if ( variation && variation.image && variation.image.src && variation.image.src.length > 1 ) {
663				// See if the gallery has an image with the same original src as the image we want to switch to.
664				var galleryHasImage = $gallery_nav.find( 'li img[data-o_src="' + variation.image.gallery_thumbnail_src + '"]' ).length > 0;
665
666				// If the gallery has the image, reset the images. We'll scroll to the correct one.
667				if ( galleryHasImage ) {
668					$form.wc_variations_image_reset();
669				}
670
671				// See if gallery has a matching image we can slide to.
672				var slideToImage = $gallery_nav.find( 'li img[src="' + variation.image.gallery_thumbnail_src + '"]' );
673
674				if ( slideToImage.length > 0 ) {
675					slideToImage.trigger( 'click' );
676					$form.attr( 'current-image', variation.image_id );
677					window.setTimeout( function() {
678						$( window ).trigger( 'resize' );
679						$product_gallery.trigger( 'woocommerce_gallery_init_zoom' );
680					}, 20 );
681					return;
682				}
683
684				$product_img.wc_set_variation_attr( 'src', variation.image.src );
685				$product_img.wc_set_variation_attr( 'height', variation.image.src_h );
686				$product_img.wc_set_variation_attr( 'width', variation.image.src_w );
687				$product_img.wc_set_variation_attr( 'srcset', variation.image.srcset );
688				$product_img.wc_set_variation_attr( 'sizes', variation.image.sizes );
689				$product_img.wc_set_variation_attr( 'title', variation.image.title );
690				$product_img.wc_set_variation_attr( 'data-caption', variation.image.caption );
691				$product_img.wc_set_variation_attr( 'alt', variation.image.alt );
692				$product_img.wc_set_variation_attr( 'data-src', variation.image.full_src );
693				$product_img.wc_set_variation_attr( 'data-large_image', variation.image.full_src );
694				$product_img.wc_set_variation_attr( 'data-large_image_width', variation.image.full_src_w );
695				$product_img.wc_set_variation_attr( 'data-large_image_height', variation.image.full_src_h );
696				$product_img_wrap.wc_set_variation_attr( 'data-thumb', variation.image.src );
697				$gallery_img.wc_set_variation_attr( 'src', variation.image.gallery_thumbnail_src );
698				$product_link.wc_set_variation_attr( 'href', variation.image.full_src );
699			} else {
700				$form.wc_variations_image_reset();
701			}
702
703			window.setTimeout( function() {
704				$( window ).trigger( 'resize' );
705				$form.wc_maybe_trigger_slide_position_reset( variation );
706				$product_gallery.trigger( 'woocommerce_gallery_init_zoom' );
707			}, 20 );
708		};
709
710		/**
711		 * Reset main image to defaults.
712		 */
713		$.fn.wc_variations_image_reset = function() {
714			var $form             = this,
715				$product          = $form.closest( '.product' ),
716				$product_gallery  = $product.find( '.images' ),
717				$gallery_nav      = $product.find( '.flex-control-nav' ),
718				$gallery_img      = $gallery_nav.find( 'li:eq(0) img' ),
719				$product_img_wrap = $product_gallery
720					.find( '.woocommerce-product-gallery__image, .woocommerce-product-gallery__image--placeholder' )
721					.eq( 0 ),
722				$product_img      = $product_img_wrap.find( '.wp-post-image' ),
723				$product_link     = $product_img_wrap.find( 'a' ).eq( 0 );
724
725			$product_img.wc_reset_variation_attr( 'src' );
726			$product_img.wc_reset_variation_attr( 'width' );
727			$product_img.wc_reset_variation_attr( 'height' );
728			$product_img.wc_reset_variation_attr( 'srcset' );
729			$product_img.wc_reset_variation_attr( 'sizes' );
730			$product_img.wc_reset_variation_attr( 'title' );
731			$product_img.wc_reset_variation_attr( 'data-caption' );
732			$product_img.wc_reset_variation_attr( 'alt' );
733			$product_img.wc_reset_variation_attr( 'data-src' );
734			$product_img.wc_reset_variation_attr( 'data-large_image' );
735			$product_img.wc_reset_variation_attr( 'data-large_image_width' );
736			$product_img.wc_reset_variation_attr( 'data-large_image_height' );
737			$product_img_wrap.wc_reset_variation_attr( 'data-thumb' );
738			$gallery_img.wc_reset_variation_attr( 'src' );
739			$product_link.wc_reset_variation_attr( 'href' );
740		};
741
742		$(function() {
743			if ( typeof wc_add_to_cart_variation_params !== 'undefined' ) {
744				$( '.variations_form' ).each( function() {
745					$( this ).wc_variation_form();
746				});
747			}
748		});
749
750		/**
751		 * Matches inline variation objects to chosen attributes
752		 * @deprecated 2.6.9
753		 * @type {Object}
754		 */
755		var wc_variation_form_matcher = {
756			find_matching_variations: function( product_variations, settings ) {
757				var matching = [];
758				for ( var i = 0; i < product_variations.length; i++ ) {
759					var variation    = product_variations[i];
760
761					if ( wc_variation_form_matcher.variations_match( variation.attributes, settings ) ) {
762						matching.push( variation );
763					}
764				}
765				return matching;
766			},
767			variations_match: function( attrs1, attrs2 ) {
768				var match = true;
769				for ( var attr_name in attrs1 ) {
770					if ( attrs1.hasOwnProperty( attr_name ) ) {
771						var val1 = attrs1[ attr_name ];
772						var val2 = attrs2[ attr_name ];
773						if ( val1 !== undefined && val2 !== undefined && val1.length !== 0 && val2.length !== 0 && val1 !== val2 ) {
774							match = false;
775						}
776					}
777				}
778				return match;
779			}
780		};
781
782		/**
783		 * Avoids using wp.template where possible in order to be CSP compliant.
784		 * wp.template uses internally eval().
785		 * @param {string} templateId
786		 * @return {Function}
787		 */
788		var wp_template = function( templateId ) {
789			var html = document.getElementById( 'tmpl-' + templateId ).textContent;
790			var hard = false;
791			// any <# #> interpolate (evaluate).
792			hard = hard || /<#\s?data\./.test( html );
793			// any data that is NOT data.variation.
794			hard = hard || /{{{?\s?data\.(?!variation\.).+}}}?/.test( html );
795			// any data access deeper than 1 level e.g.
796			// data.variation.object.item
797			// data.variation.object['item']
798			// data.variation.array[0]
799			hard = hard || /{{{?\s?data\.variation\.[\w-]*[^\s}]/.test ( html );
800			if ( hard ) {
801				return wp.template( templateId );
802			}
803			return function template ( data ) {
804				var variation = data.variation || {};
805				return html.replace( /({{{?)\s?data\.variation\.([\w-]*)\s?(}}}?)/g, function( _, open, key, close ) {
806					// Error in the format, ignore.
807					if ( open.length !== close.length ) {
808						return '';
809					}
810					var replacement = variation[ key ] || '';
811					// {{{ }}} => interpolate (unescaped).
812					// {{  }}  => interpolate (escaped).
813					// https://codex.wordpress.org/Javascript_Reference/wp.template
814					if ( open.length === 2 ) {
815						return window.escape( replacement );
816					}
817					return replacement;
818				});
819			};
820		};
821
822	}
823
824})(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.