1'use strict'; 2 3(function ($) { 4 $(function () { 5 // ready 6 wpcpo_init(); 7 8 // tooltips 9 if (wpcpo_vars.tooltip_library === 'tippy') { 10 tippy('.wpcpo-tippy-tooltip', { 11 allowHTML: true, interactive: true, 12 }); 13 } 14 }); 15 16 $(document).on('woosq_loaded', function () { 17 // quick view 18 wpcpo_init(); 19 }); 20 21 $(document).on('found_variation', function (e, t) { 22 if ($(e['target']).closest('.woosb-product').length || $(e['target']).closest('.wooco-product').length || $(e['target']).closest('.woobt-product').length || $(e['target']).closest('.woofs-product').length || $(e['target']).closest('.woosg-product').length) { 23 return; 24 } 25 26 let $total = $(e['target']).closest('form.cart').find('.wpcpo-total'); 27 28 $total.attr('data-price', t['display_price']); 29 30 wpcpo_update_total($total); 31 }); 32 33 $(document).on('reset_data', function (e) { 34 if ($(e['target']).closest('.woosb-product').length || $(e['target']).closest('.wooco-product').length || $(e['target']).closest('.woobt-product').length || $(e['target']).closest('.woofs-product').length || $(e['target']).closest('.woosg-product').length) { 35 return; 36 } 37 38 let $total = $(e['target']).closest('form.cart').find('.wpcpo-total'); 39 40 $total.attr('data-price', $total.attr('data-o_price')); 41 42 wpcpo_update_total($total); 43 }); 44 45 $(document).on('woovr_selected', function (e, selected, variations) { 46 if (variations.closest('.woosb-product').length || variations.closest('.wooco-product').length || variations.closest('.woobt-product').length || variations.closest('.woofs-product').length || variations.closest('.woosg-product').length) { 47 return; 48 } 49 50 let purchasable = selected.attr('data-purchasable'), 51 $total = variations.closest('form.cart').find('.wpcpo-total'); 52 53 if (purchasable === 'yes') { 54 $total.attr('data-price', selected.attr('data-price')); 55 } else { 56 $total.attr('data-price', $total.attr('data-o_price')); 57 } 58 59 wpcpo_update_total($total); 60 }); 61 62 /* WPC Product Bundles */ 63 $(document).on('woosb_calc_price', function (e, total_sale, total, total_html, price_suffix, $wrap) { 64 let wid = $wrap.attr('data-id'), $total = $('.wpcpo-total[data-product-id="' + wid + '"]'); 65 66 $total.attr('data-price', total_sale); 67 68 wpcpo_update_total($total); 69 }); 70 71 /* WPC Composite Products */ 72 $(document).on('wooco_calc_price', function (e, total, total_regular, total_html, $wrap) { 73 let wid = $wrap.attr('data-id'), $total = $('.wpcpo-total[data-product-id="' + wid + '"]'); 74 75 $total.attr('data-price', total); 76 77 wpcpo_update_total($total); 78 }); 79 80 $(document).on('change keyup', 'form.cart [name=quantity]', function () { 81 let $this = $(this); 82 83 if ($this.closest('.woosb-product').length || $this.closest('.wooco-product').length || $this.closest('.woobt-product').length || $this.closest('.woofs-product').length || $this.closest('.woosg-product').length) { 84 return; 85 } 86 87 wpcpo_update_total($this.closest('form.cart').find('.wpcpo-total')); 88 }); 89 90 $(document).on('change input', '.wpcpo-option-field', function () { 91 let $this = $(this), $options = $this.closest('.wpcpo-options'); 92 93 if ($this.hasClass('field-select')) { 94 let $wrapper = $this.closest('.form-row'), $option = $this.find(':selected'), label = $option.data('label'), 95 type = $option.data('price-type'), price = $option.data('price'), 96 custom_price = $option.data('price-custom'); 97 $wrapper.find('input[name$="label\]"]').attr('value', label); 98 $wrapper.find('input[name$="price_type\]"]').attr('value', type); 99 $wrapper.find('input[name$="price\]"]').attr('value', price); 100 $wrapper.find('input[name$="custom_price\]"]').attr('value', custom_price); 101 } else if ($this.hasClass('field-radio')) { 102 let $wrapper = $this.closest('.form-row'), $option = $wrapper.find(':checked'), 103 label = $option.data('label'), type = $option.data('price-type'), 104 custom_price = $option.data('price-custom'), price = $option.data('price'), 105 image = $option.data('image'); 106 $wrapper.find('input[name$="label\]"]').attr('value', label); 107 $wrapper.find('input[name$="image\]"]').attr('value', image); 108 $wrapper.find('input[name$="price_type\]"]').attr('value', t
108ype); 109 $wrapper.find('input[name$="price\]"]').attr('value', price); 110 $wrapper.find('input[name$="custom_price\]"]').attr('value', custom_price); 111 } else if ($this.hasClass('field-dimensions')) { 112 let $dimensions = $this.closest('.wpcpo-option-dimensions'), dimensions = []; 113 114 $dimensions.find('.wpcpo-dimension').each(function () { 115 if ($(this).find('input').val() !== '') { 116 let dimension = $(this).find('label').text() + ': ' + $(this).find('input').val(); 117 118 dimensions.push(dimension); 119 } 120 }); 121 122 if (dimensions.length) { 123 $this.val(dimensions.join('; ')); 124 } else { 125 $this.val(''); 126 } 127 } 128 129 wpcpo_validate($options); 130 wpcpo_update_total($this.closest('form.cart').find('.wpcpo-total')); 131 }); 132 133 $(document).on('blur', '.wpcpo-option-field', function () { 134 let $this = $(this), $options = $this.closest('.wpcpo-options'); 135 136 wpcpo_validate($options); 137 }); 138 139 $(document).on('change', '.wpcpo-option-field-dimension', function () { 140 let $this = $(this); 141 142 if (parseFloat($this.val()) < parseFloat($this.attr('min'))) { 143 $this.val($this.attr('min')); 144 } 145 146 $this.closest('.wpcpo-option-dimensions').find('.wpcpo-option-field').trigger('change'); 147 }); 148 149 $(document).on('keyup change', '.wpcpo-option-field', function () { 150 var $field = $(this); 151 152 if ($field.attr('maxlength') > 0) { 153 var value = $field.val(); 154 var remaining = $field.attr('maxlength') - value.length; 155 156 $field.next('.wpcpo-chars-remaining').find('span').text(remaining); 157 } 158 159 if (wpcpo_vars.change_url) { 160 // update URL 161 var $options = $field.closest('.wpcpo-options'); 162 var $form = $field.closest('form.cart'); 163 var link = new URL($form.attr('action')); 164 var search = new URLSearchParams(link.search); 165 var new_link = ''; 166 167 $options.find('.wpcpo-option').each(function () { 168 let $option = $(this), option_key = $option.data('key'), option_val = ''; 169 170 if ($option.hasClass('wpcpo-option-checkbox') || $option.hasClass('wpcpo-option-image-checkbox') || $option.hasClass('wpcpo-option-color-checkbox')) { 171 option_val = $.map($option.find(':checkbox:checked'), function (n, i) { 172 return n.value; 173 }).join(','); 174 } 175 176 if ($option.hasClass('wpcpo-option-select')) { 177 option_val = $option.find('select').val(); 178 } 179 180 if ($option.hasClass('wpcpo-option-radio') || $option.hasClass('wpcpo-option-image-radio') || $option.hasClass('wpcpo-option-color-radio')) { 181 option_val = $option.find('input[type="radio"]:checked').length ? $option.find('input[type="radio"]:checked').val() : ''; 182 } 183 184 if (option_val.length) { 185 search.set(option_key, option_val); 186 } else { 187 search.delete(option_key); 188 } 189 }); 190 191 $('input[name="wpcpo_url"]').val(search.toString()).trigger('change'); 192 193 if (search.toString() !== '') { 194 new_link = link + '?' + search.toString(); 195 } else { 196 new_link = link; 197 } 198 199 window.history.replaceState(null, null, new_link); 200 } 201 }); 202 203 $(document).on('click touch', '.wpcpo-clear-btn', function (e) { 204 e.preventDefault(); 205 206 $('.wpcpo-option-field').each(function () { 207 $(this).val('').prop('checked', false).prop('selected', false).trigger('blur'); 208 }); 209 210 wpcpo_init(); 211 }); 212})(jQuery); 213 214function wpcpo_round(value, decimals) { 215 return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals); 216} 217 218function wpcpo_format_money(number, places, symbol, thousand, decimal) { 219 number = number || 0; 220 places = !isNaN((places = Math.abs(places))) ? places : 2; 221 symbol = symbol !== undefined ? symbol : '$'; 222 thousand = thousand || ','; 223 decimal = decimal || '.'; 224 225 var negative = number < 0 ? '-' : '', 226 i = parseInt((number = wpcpo_round(Math.abs(+number || 0), places).toFixed(places)), 10) + '', j = 0; 227 228 if (i.length > 3) { 229 j = i.length % 3; 230 } 231 232 return (symbol + negative + (j ? i.substr(0, j) + thousand : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thousand) + (places ? decimal + wpcpo_round(Math.abs(number - i), places).toFixed(places).slice(2) : '')); 233} 234 235function wpcpo_format_price(price) { 236 var price_html = '<span class="woocommerce-Price-amount amount">'; 237 var price_formatted = wpcpo_format_money(price, wpcpo_vars.price_decimals, '', wpcpo_vars.price_thousand_separator, wpcpo_vars.price_decimal_separator); 238 239 switch (wpcpo_vars.price_format) { 240 case '%1$s%2$s': 241 //left 242 price_html += '<span class="woocommerce-Price-currencySymbol">' + wpcpo_vars.currency_symbol + '</span>' + price_formatted; 243 break; 244 case '%1$s %2$s': 245 //left with space 246 price_html += '<span class="woocommerce-Price-currencySymbol">' + wpcpo_vars.currency_symbol + '</span> ' + price_formatted; 247 break; 248 case '%2$s%1$s': 249 //right 250 price_html += price_formatted + '<span class="woocommerce-Price-currencySymbol">' + wpcpo_vars.currency_symbol + '</span>'; 251 break; 252 case '%2$s %1$s': 253 //right with space 254 price_html += price_formatted + ' <span class="woocommerce-Price-currencySymbol">' + wpcpo_vars.currency_symbol + '</span>'; 255 break; 256 default: 257 //default 258 price_html += '<span class="woocommerce-Price-currencySymbol">' + wpcpo_vars.currency_symbol + '</span> ' + price_formatted; 259 } 260 261 price_html += '</span>'; 262 263 return price_html; 264} 265 266function wpcpo_get_custom_price(custom_price, quantity, product_price, value, total = 0) { 267 let length = value.length; 268 let words = wpcpo_words_count(value); 269 270 value = parseFloat(value.replace(/[^\d.]/g, '')); 271 272 custom_price = custom_price.toLowerCase().replace(/([vpqlws])+/gi, function (match, tag, char) { 273 switch (tag) { 274 case 'q': 275 return quantity; 276 case 'p': 277 return product_price; 278 case 'l': 279 return length; 280 case 'w': 281 return words; 282 case 'v': 283 return value === '' ? 1 : value; 284 case 's': 285 return total; 286 } 287 }); 288 289 try {
290 custom_price = eval(custom_price.replace(/[^-()\d/*+.]/g, '')); 291 } catch (e) { 292 custom_price = 0; 293 } 294 295 if (isNaN(custom_price) || (custom_price === Infinity) || (custom_price === -Infinity)) { 296 custom_price = 0; 297 } 298 299 return custom_price; 300} 301 302function wpcpo_get_custom_dimensions_price($field, custom_price, quantity, product_price, value, total = 0) { 303 let $dimensions = $field.closest('.wpcpo-option-dimensions'); 304 305 custom_price = custom_price.toLowerCase().replace(/([vpqlws])+/gi, function (match, tag, char) { 306 switch (tag) { 307 case 'q': 308 return quantity; 309 case 'p': 310 return product_price; 311 case 's': 312 return total; 313 } 314 }); 315 316 custom_price = custom_price.toLowerCase().replace(/d(\d+)/gi, function (match, tag, char) { 317 if ($dimensions.find('.wpcpo-option-field-dimension-d' + tag).length && ($dimensions.find('.wpcpo-option-field-dimension-d' + tag).val() !== '')) { 318 return parseFloat($dimensions.find('.wpcpo-option-field-dimension-d' + tag).val()); 319 } else { 320 return 0; 321 } 322 }); 323 324 try { 325 custom_price = eval(custom_price.replace(/[^-()\d/*+.]/g, '')); 326 } catch (e) { 327 custom_price = 0; 328 } 329 330 if (isNaN(custom_price) || (custom_price === Infinity) || (custom_price === -Infinity)) { 331 custom_price = 0; 332 } 333 334 return custom_price; 335} 336 337function wpcpo_get_field_price($field, product_price, quantity = 1, total = 0) { 338 let field_price = 0, type = $field.data('price-type'), price = $field.data('price'), 339 custom_price = $field.data('price-custom'), value = $field.val(); 340 341 if ($field.hasClass('field-select')) { 342 let $option = $field.find(':selected'); 343 344 type = $option.data('price-type'); 345 price = $option.data('price'); 346 custom_price = $option.data('price-custom'); 347 } 348 349 switch (type) { 350 case 'flat': 351 if (isNaN(price)) { 352 field_price = parseFloat(product_price) * parseFloat(price) / 100; 353 } else { 354 field_price = parseFloat(price); 355 } 356 357 break; 358 case 'custom': 359 if ($field.hasClass('field-dimensions')) { 360 field_price = wpcpo_get_custom_dimensions_price($field, custom_price, quantity, product_price, value, total); 361 } else { 362 field_price = wpcpo_get_custom_price(custom_price, quantity, product_price, value, total); 363 } 364 365 break; 366 default: 367 // qty 368 if (isNaN(price)) { 369 field_price = parseFloat(product_price) * parseFloat(price) / 100 * quantity; 370 } else { 371 field_price = parseFloat(price) * quantity; 372 } 373 374 break; 375 } 376 377 return field_price; 378} 379 380function wpcpo_update_total($total) { 381 let qty = parseFloat($total.closest('form.cart').find('[name=quantity]').val()), 382 price = parseFloat($total.attr('data-price')), type = $total.data('type'), name = $total.data('product-name'), 383 total = 0, fields = $total.closest('.wpcpo-wrapper').find('.wpcpo-option-field').get(), html = '', 384 qty_string = wpcpo_vars.is_rtl ? wpcpo_vars.quantity_symbol + qty : qty + wpcpo_vars.quantity_symbol, 385 selected = 0; 386 387 if ($total.attr('data-total') !== undefined) { 388 // Compatible with WPC Price by Quantity 389 total = parseFloat($total.attr('data-total')); 390 } else { 391 total = price * qty; 392 } 393 394 html += '<ul>'; 395 html += `<li> 396<div class="wpcpo-col1"><span>${qty_string}</span> ${name}</div> 397<div class="wpcpo-col2"><strong><span class="amount">${wpcpo_format_price(total)}</span></strong></div> 398</li>`; 399 400 for (let field of fields) { 401 let $field = jQuery(field), enable_price = $field.data('enable-price'), 402 $price_label = $field.closest('.wpcpo-option').find('.label-price-' + $field.attr('id')), 403 value = $field.val(); 404 405 if ($field.is(':checkbox') || $field.is(':radio')) { 406 if ($field.prop('checked')) { 407 value = $field.data('label'); 408 } else { 409 value = ''; 410 } 411 } 412 413 if ($field.is('select')) { 414 value = $field.find('option:selected').data('label'); 415 } 416 417 $price_label.html(``); 418 419 if (value !== '' && value !== undefined) { 420 if (wpcpo_vars.summary_clear) { 421 selected++; 422 } 423 424 if (enable_price === 1 || wpcpo_vars.summary_free) { 425 let field_price = wpcpo_get_field_price($field, price, qty, total); 426 427 if (!isNaN(field_price)) { 428 total += parseFloat(field_price); 429 } 430 431 if (!isNaN(field_price) || wpcpo_vars.summary_free) { 432 if (isNaN(field_price)) { 433 html += `<li class="wpcpo-free"><div class="wpcpo-col1"><span>${$field.data('title')}:</span> ${value}</div><div class="wpcpo-col2"><strong><span class="amount">${wpcpo_format_price(field_price)}</span></strong></div></li>`; 434 } else { 435 if (parseFloat(field_price) > 0) { 436 $price_label.html(`(+${wpcpo_format_price(field_price)})`); 437 } else { 438 $price_label.html(`(${wpcpo_format_price(field_price)})`); 439 } 440 441 html += `<li><div class="wpcpo-col1"><span>${$field.data('title')}:</span> ${value}</div><div class="wpcpo-col2"><strong><span class="amount">${wpcpo_format_price(field_price)}</span></strong></div></li>`; 442 } 443 } 444 } 445 } 446 } 447 448 html += `<li class="wpcpo-subtotal wpcpo-subtotal-${selected}"><span class="wpcpo-clear"><a class="wpcpo-clear-btn" href="javascript:void(0);">${wpcpo_vars.i18n_clear}</a></span><span class="wpcpo-subtotal-amount">${wpcpo_vars.i18n_subtotal}<span class="amount">${wpcpo_format_price(total)}</span></span></li>`; 449 html += '</ul>'; 450 451 $total.html(html); 452 453 jQuery(document).trigger('wpcpo_update_total', [$total, total]); 454} 455 456function wpcpo_words_count(str) { 457 return str.split(' ').filter(function (n) { 458 return n != ''; 459 }).length; 460} 461 462function wpcpo_validate($options) { 463 let valid = true, $btn = $options.closest('form.cart').find('.single_add_to_cart_button'); 464 465 $options.find('.wpcpo-option-field').each(function () {
466 let $this = jQuery(this), $option = $this.closest('.wpcpo-option'); 467 468 // Limit Checkbox 469 if ($this.is(':checkbox')) { 470 let $inputsCheck = $option.find('input:checked'), countCheckbox = $inputsCheck.get(); 471 if (parseInt($option.data('limit')) > 0) { 472 if (countCheckbox.length >= parseInt($option.data('limit'))) { 473 $option.find('input:checkbox:not(:checked)').attr('disabled', true); 474 } else { 475 $option.find('input:checkbox').attr('disabled', false); 476 } 477 if (countCheckbox.length > parseInt($option.data('limit'))) { 478 $option.addClass('wpcpo-has-error'); 479 valid = false; 480 } else { 481 $option.removeClass('wpcpo-has-error'); 482 } 483 } 484 } 485 486 // Required Checkbox & Radio 487 if ($this.is(':checkbox') || $this.is(':radio')) { 488 let $inputsCheck = $option.find('input:checked'), countCheckbox = $inputsCheck.get(); 489 if ($option.hasClass('wpcpo-required')) { 490 if (countCheckbox.length > 0) { 491 $option.find('.wpcpo-option-field').removeAttr('required'); 492 $option.removeClass('wpcpo-has-error'); 493 } else { 494 $option.find('.wpcpo-option-field').attr('required', 'required'); 495 $option.addClass('wpcpo-has-error'); 496 valid = false; 497 } 498 } 499 } 500 501 // Required Input 502 if ($this.prop('required')) { 503 if ($this.val() === '') { 504 $option.addClass('wpcpo-has-error'); 505 valid = false; 506 } else { 507 $option.removeClass('wpcpo-has-error'); 508 } 509 } 510 }); 511 512 if (!valid) { 513 $btn.addClass('wpcpo-disabled'); 514 } else { 515 $btn.removeClass('wpcpo-disabled'); 516 } 517 518 jQuery(document).trigger('wpcpo_validate', [$options, valid]); 519} 520 521function wpcpo_init() { 522 if (jQuery('.wpcpo-color-picker').length) { 523 jQuery('.wpcpo-color-picker').wpColorPicker({ 524 change: function (e, ui) { 525 setTimeout(function () { 526 wpcpo_update_total(jQuery(e['target']).closest('.wpcpo-wrapper').find('.wpcpo-total')); 527 }, 100); 528 }, 529 }); 530 } 531 532 jQuery('.wpcpo-date-picker').each(function () { 533 var format = jQuery(this).attr('data-format'); 534 var block = jQuery(this).attr('data-block'); 535 var dpk_data = {dateFormat: format}; 536 537 if ((block !== undefined) && (block !== '')) { 538 var block_dates = block.split(','); 539 540 if (block_dates.includes('past')) { 541 dpk_data.minDate = new Date(); 542 } else { 543 if (block_dates.includes('future')) { 544 dpk_data.maxDate = new Date(); 545 } 546 } 547 548 dpk_data.onRenderCell = function onRenderCell(date, cellType) { 549 if (cellType === 'day') { 550 const weekday = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday']; 551 var day_w = weekday[date.getDay()]; 552 var day_f = (('0' + (date.getMonth() + 1)).slice(-2)) + '/' + (('0' + date.getDate()).slice(-2)) + '/' + date.getFullYear(); 553 var isDisabled = block_dates.includes(day_w) || block_dates.includes(day_f); 554 555 return { 556 disabled: isDisabled, 557 }; 558 } 559 }; 560 } 561 562 jQuery(this).wpcdpk(dpk_data); 563 }); 564 565 jQuery('.wpcpo-time-picker').each(function () { 566 var format = jQuery(this).attr('data-format'); 567 568 jQuery(this).wpcdpk({ 569 timeFormat: format, timepicker: true, onlyTimepicker: true, classes: 'only-time', 570 }); 571 }); 572 573 jQuery('.wpcpo-date-time-picker').each(function () { 574 var date_format = jQuery(this).attr('data-date_format'); 575 var time_format = jQuery(this).attr('data-time_format'); 576 577 jQuery(this).wpcdpk({ 578 dateFormat: date_format, timeFormat: time_format, timepicker: true, 579 }); 580 }); 581 582 jQuery('.wpcpo-date-range-picker').each(function () { 583 var format = jQuery(this).attr('data-format'); 584 585 jQuery(this).wpcdpk({range: true, dateFormat: format, multipleDatesSeparator: ' - '}); 586 }); 587 588 jQuery('.wpcpo-option-field').trigger('change'); 589 590 jQuery('.wpcpo-option-field').each(function () { 591 if (jQuery(this).attr('maxlength') > 0) { 592 jQuery(this).after('<small class="wpcpo-chars-remaining"><span>' + jQuery(this).attr('maxlength') + '</span> ' + wpcpo_vars.i18n_remaining + '</small>'); 593 } 594 }); 595 596 jQuery('.wpcpo-options').each(function () { 597 wpcpo_validate(jQuery(this)); 598 }); 599 600 jQuery('.wpcpo-total').each(function () { 601 wpcpo_update_total(jQuery(this)); 602 }); 603 604 jQuery(document).trigger('wpcpo_init'); 605}
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.