https://publisher.in.ua/wp-content/themes/fynode/assets/js/custom/…=1.0.0.pagespeed.ce.R0pLJ5-Y73.js
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.