1/** 2 * @property {object} wdp_script_data_pro 3 * @property {string} wdp_script_data_pro.ajaxurl 4 * @property {string} wdp_script_data_pro.update_price_with_qty 5 * @property {string} wdp_script_data_pro.js_init_trigger 6 * @property {boolean} wdp_script_data_pro.replace_variable_price 7 * @property {string} wdp_script_data_pro.variable_price_selector 8 * @property {object} wdp_script_data_pro.page_data 9 * @property {boolean} wdp_script_data_pro.create_on_load 10 * @property {boolean} wdp_script_data_pro.show_spinner 11 * @property {string} wdp_script_data_pro.security 12 * @property {string} wdp_script_data_pro.security_param 13 */ 14 15/** 16 * @class 17 */ 18var DynamicPrice = (function () { 19 /** 20 * @constructs DynamicPrice 21 * @param {jQuery} $form 22 * @param {object} $opts 23 */ 24 function DynamicPrice($form, $opts) { 25 /** 26 * @type {Boolean} 27 * @private 28 */ 29 this.__isEnable = false; 30 31 /** 32 * @type {Object} 33 * @private 34 */ 35 this.__pageData = {}; 36 37 /** 38 * @type {String} 39 * @private 40 */ 41 this.__ajaxUrl = ""; 42 43 /** 44 * @name DynamicPrice#form 45 * @type {jQuery} 46 */ 47 this.form = null; 48 49 /** 50 * @type {number} 51 * @private 52 */ 53 this.__inputTimerId = null; 54 55 /** 56 * @type {Array} 57 * @private 58 */ 59 this.__price_destinations = []; 60 61 /** 62 * @type {Array} 63 * @private 64 */ 65 this.__subtotal_destinations = []; 66 67 /** 68 * @type {Array} 69 * @private 70 */ 71 this.__total_price_destinations = []; 72 73 this.__priceHtmlTemplate = "{{price_html}}"; 74 75 this.__priceSuffix = ""; 76 77 // for input observing 78 this.__lastChange = null;
79 this.__lastValue = null; 80 81 /** 82 * @type {Boolean} 83 * @private 84 */ 85 this.__show_spinner = true; 86 87 if (typeof $opts === 'undefined') { 88 $opts = wdp_script_data_pro; 89 } 90 91 if (typeof $opts.price_html_template !== 'undefined') { 92 this.__priceHtmlTemplate = $opts.price_html_template; 93 } 94 95 if (typeof $opts.dynamic_price_enable !== 'undefined') { 96 this.__isEnable = !!$opts.dynamic_price_enable; 97 } else if (typeof $opts.update_price_with_qty !== 'undefined') { 98 this.__isEnable = $opts.update_price_with_qty === "1"; 99 } 100 if (typeof $opts.page_data !== 'undefined') { 101 this.__pageData = $opts.page_data; 102 } 103 104 if (typeof $opts.price_suffix !== 'undefined') { 105 this.__priceSuffix = $opts.price_suffix; 106 } 107 108 if (typeof $opts.ajaxurl !== 'undefined') { 109 this.__ajaxUrl = $opts.ajaxurl; 110 } else { 111 logError("Empty ajaxurl"); 112 return; 113 } 114 115 if (typeof $form !== 'undefined' && $form.is('form')) { 116 this.form = $form 117 } else { 118 logError("Incorrect form provided"); 119 } 120 121 if (typeof $opts.show_spinner !== 'undefined') { 122 this.__show_spinner = !! $opts.show_spinner; 123 } 124 125 /** 126 * 127 * @returns {function(): {price: number, value: string}[]} 128 * @private 129 */ 130 this.__addons_supplier = function () { 131 return [] 132 }; 133 } 134 135 function getTimestamp() { 136 return Math.floor(Date.now() / 1000); 137 } 138 139 DynamicPrice.prototype.stopObserve = function () { 140 if (this.__inputTimerId) { 141 clearInterval(this.__inputTimerId); 142 } 143 }; 144 145 DynamicPrice.prototype.__getQty = function () { 146 var $input = this.form.find('input[name="quantity"]'); 147 if ($input.length === 0) { 148 $input = this.form.find('select[name="quantity"]'); 149 if ($input.length === 0) { 150 return 0; 151 } 152 } 153 154 return $input.val(); 155 }; 156 157 DynamicPrice.prototype.observe = function () { 158 this.stopObserve(); 159 160 this.__lastChange = null;
161 this.__lastValue = this.__getQty(); 162 163 this.__inputTimerId = setInterval(this.__watch.bind(this), 300); 164 }; 165 166 DynamicPrice.prototype.__watch = function () { 167 var $qty = this.__getQty(); 168 169 if ($qty && this.__lastValue !== $qty) { 170 this.__lastValue = $qty; 171 this.__lastChange = getTimestamp(); 172 } else if (this.__lastValue && this.__lastValue === $qty && this.__lastChange) { 173 this.__lastChange = null; 174 this.__update(this.__lastValue); 175 } 176 }; 177 178 DynamicPrice.prototype.__getProductId = function () { 179 var variationIdEl = this.form.find('[name="variation_id"]'); 180 var productIdEl = this.form.find('[name="add-to-cart"]'); 181 182 if (variationIdEl.length) { 183 return parseInt(variationIdEl.val()); 184 } else if (productIdEl.length) { 185 return parseInt(productIdEl.val()); 186 } 187 188 return false; 189 }; 190 191 DynamicPrice.prototype.__getVariationAttributes = function () { 192 let attributes = {}; 193 194 this.form.find('select').each(function (index, item) { 195 if (jQuery(item).attr("data-attribute_name")) { 196 attributes[jQuery(item).attr("data-attribute_name")] = jQuery(this).val(); 197 } 198 }); 199 200 return attributes; 201 }; 202 203 /** 204 * 205 * @param {string} $qty 206 * @param {string|undefined} $customPrice 207 * @returns {jQuery|null} 208 * @private 209 */ 210 DynamicPrice.prototype.__update = function ($qty, $customPrice = undefined) { 211 if (!this.__isEnable) { 212 return null; 213 } 214 215 if (typeof $qty === 'undefined' || !$qty) { 216 logError("Empty qty"); 217 return null; 218 } else { 219 $qty = parseFloat($qty); 220 } 221 222 if (typeof $customPrice === 'undefined') { 223 $customPrice = null; 224 } 225 226 var $existTotalPriceDestinations = []; 227 jQuery.each(this.__total_price_destinations, function (_, $selector) { 228 var $el = jQuery($selector).first(); 229 if ($el.length !== 0) { 230 $existTotalPriceDestinations.push($el); 231 } 232 }); 233 234 235 var $productId = this.__getProductId(); 236 if (!$productId) { 237 replaceDestinations($existTotalPriceDestinations, ''); 238 239 logError("Empty product ID"); 240 return null; 241 } 242 243 var $existPriceDestinations = []; 244 jQuery.each(this.__price_destinations, function (_, $selector) { 245 var $el = jQuery($selector).first(); 246 if ($el.length !== 0) { 247 $existPriceDestinations.push($el); 248 } 249 }); 250 251 var $existSubtotalDestinations = []; 252 jQuery.each(this.__subtotal_destinations, function (_, $selector) { 253 var $el = jQuery($selector).first(); 254 if ($el.length !== 0) { 255 $existSubtotalDestinations.push($el); 256 } 257 }); 258 259 260 if ($existPriceDestinations.length === 0 && $existSubtotalDestinations.length === 0 && $existTotalPriceDestinations.length === 0) { 261 return null; 262 } 263 264 var data = { 265 action: 'get_price_product_with_bulk_table', 266 product_id: $productId, 267 attributes: this.__getVariationAttributes(), 268 qty: $qty, 269 page_data: this.__pageData, 270 ...jQuery('form.cart').triggerHandler('wdp_get_custom_data') 271 }; 272 273 data[wdp_script_data_pro.security_param] = wdp_script_data_pro.security; 274 275 var $spinner_price = "<div id=\"spinner_price\"><img class=\"spinner_img\"></div>"; 276 var pricePreloaded = false; 277 278 if ($customPrice !== null) { 279 data.custom_price = $customPrice; 280 } else { 281 var $price_html = this.__tryToGetPreLoadedPrice($productId, $qty); 282 if ($price_html) { 283 replaceDestinations($existPriceDestinations, $price_html); 284 285 if ($existSubtotalDestinations.length === 0 && $existTotalPriceDestinations.length === 0) { 286 return; 287 } 288 289 pricePreloaded = true; 290 } 291 } 292 293 if ( this.__show_spinner ) { 294 if (!pricePreloaded) { 295 replaceDestinations($existPriceDestinations, $spinner_price); 296 } 297 replaceDestinations($existSubtotalDestinations, $spinner_price); 298 replaceDestinations($existTotalPriceDestinations, $spinner_price); 299 } 300 301 data.addons = this.__addons_supplier(); 302 303 return jQuery.ajax({ 304 url: this.__ajaxUrl, 305 data: data, 306 dataType: 'json', 307 type: 'POST', 308 success: function (response) { 309 if (response.success) { 310 if ( !pricePreloaded ) { 311 replaceDestinations($existPriceDestinations, response.data.price_html); 312 } 313 replaceDestinations($existSubtotalDestinations, response.data.subtotal_html); 314 replaceDestinations($existTotalPriceDestinations, response.data.total_price_html); 315 } else { 316 if ( !pricePreloaded ) { 317 clearDestinations($existPriceDestinations); 318 } 319 clearDestinations($existSubtotalDestinations); 320 clearDestinations($existTotalPriceDestinations); 321 } 322 }, 323 error: function (response) { 324 if ( !pricePreloaded ) { 325 clearDestinations($existPriceDestinations); 326 } 327 clearDestinations($existSubtotalDestinations); 328 clearDestinations($existTotalPriceDestinations); 329 } 330 }); 331 }; 332 333 DynamicPrice.prototype.__clearTotalPrice = function() { 334 var $existTotalPriceDestinations = []; 335 jQuery.each(this.__total_price_destinations, function (_, $selector) { 336 var $el = jQuery($selector).first(); 337 if ($el.length !== 0) { 338 $existTotalPriceDestinations.push($el); 339 } 340 }); 341 342 var $productId = this.__getProductId(); 343 344 if (!$productId) { 345 replaceDestinations($existTotalPriceDestinations, ''); 346 } 347 }; 348 349 DynamicPrice.prototype.__tryToGetPreLoadedPrice = function ($productId, $qty) { 350 if ( typeof wdp_script_data_pro.preLoaded === 'undefined' ) { 351 return null; 352 } 353 354 var $preLoaded = wdp_script_data_pro.preLoaded; 355 356 $qty = parseFloat($qty); 357 if ( ! $qty ) { 358 return null; 359 } 360 361 $productId = $productId.toString(); 362 363 var _this = this; 364 365 var $html = null;
366 jQuery.each($preLoaded, function ($preLoadedProductId, $data) { 367 if ( typeof $data.ranges === 'undefined' || typeof $data.price_html === 'undefined' || typeof $data.price_html_view === 'undefined' || typeof $data.index_number === 'undefined' ) { 368 return; // continue 369 } 370 var $ranges = $data.ranges; 371 var $price_html = $data.price_html; 372 var $current_qty = $data.index_number + $qty; 373 var $qty_already_in_cart = $data.qty_already_in_cart; 374 375 if ( $preLoadedProductId === $productId ) { 376 jQuery.each($ranges, function (_, $range) { 377 if (compareFloats($range['from'], '<=', $current_qty) && compareFloats($current_qty, '<=', $range['to']) 378 || (compareFloats($range['from'], '<=', $current_qty) && $range['to'] === "") 379 || ($range['from'] === "" && compareFloats($current_qty, '<=', $range['to'])) 380 ) { 381 $html = _this.__formatPriceHtml($range['striked_price_html'], $current_qty, $qty_already_in_cart, $range['regular_price_striked']); 382 return false; 383 } 384 }); 385 386 if ( ! $html ) { 387 if ( $current_qty === 1 ) { 388 $html = $data.price_html_view; 389 } else{ 390 $html = _this.__formatPriceHtml($price_html, $current_qty, $qty_already_in_cart, ""); 391 } 392 } 393 } 394 if ( $html ) { 395 return false; 396 } 397 }); 398 399 return $html; 400 }; 401 402 function compareFloats($a, $op, $b) { 403 $a = Math.floor(parseFloat($a) * 100); 404 $b = Math.floor(parseFloat($b) * 100); 405 406 switch ($op) { 407 case "=": 408 return $a === $b; 409 case ">": 410 return $a > $b; 411 case ">=": 412 return $a >= $b; 413 case "<": 414 return $a < $b; 415 case "<=": 416 return $a <= $b; 417 } 418 419 return null; 420 } 421 422 function replaceDestinations($targets, $priceHtml) { 423 jQuery.each($targets, function (_, $target) { 424 $target.html($priceHtml); 425 jQuery(document).trigger('wdp_price_product_updated', $priceHtml); 426 }) 427 } 428 429 function clearDestinations($targets) { 430 jQuery.each($targets, function (_, $target) { 431 $target.html(""); 432 jQuery(document).trigger('wdp_price_product_updated', ""); 433 }) 434 } 435 436 DynamicPrice.prototype.addPriceDestination = function ($dest) { 437 if (typeof $dest === 'string') { 438 this.__price_destinations.push($dest); 439 } else if (Array.isArray($dest)) { 440 Array.prototype.push.apply(this.__price_destinations, $dest); 441 } 442 }; 443 444 DynamicPrice.prototype.addSubtotalDestination = function ($dest) { 445 if (typeof $dest === 'string') { 446 this.__subtotal_destinations.push($dest); 447 } else if (Array.isArray($dest)) { 448 Array.prototype.push.apply(this.__subtotal_destinations, $dest); 449 } 450 }; 451 452 DynamicPrice.prototype.addTotalPriceDestination = function ($dest) { 453 if (typeof $dest === 'string') { 454 this.__total_price_destinations.push($dest); 455 } else if (Array.isArray($dest)) { 456 Array.prototype.push.apply(this.__total_price_destinations, $dest); 457 } 458 }; 459 460 /** 461 * 462 * @param {function(): {price: number, value: string}[]} callback 463 */ 464 DynamicPrice.prototype.withAddonsSupplier = function (callback) { 465 this.__addons_supplier = callback; 466 }; 467 468 DynamicPrice.prototype.update = function ($args) { 469 var $qty = null; 470 var $customPrice = null; 471 472 if (typeof $args !== 'undefined') { 473 if (typeof $args.qty !== 'undefined') { 474 $qty = parseFloat($args.qty); 475 } else { 476 $qty = this.__getQty(); 477 } 478 479 if (typeof $args.custom_price !== 'undefined') { 480 $customPrice = $args.custom_price; 481 } 482 } 483 484 return this.__update($qty, $customPrice); 485 }; 486 487 488 DynamicPrice.prototype.disable = function () { 489 this.__isEnable = false;
490 }; 491 492 DynamicPrice.prototype.enable = function () { 493 this.__isEnable = true; 494 }; 495 496 DynamicPrice.prototype.__formatPriceHtml = function ($priceHtml, $indexNumber, $qtyAlreadyInCart, regularPriceStriked) { 497 return this.__priceHtmlTemplate 498 .replace("{{price_html}}", $priceHtml) 499 .replace("{{Nth_item}}", addSuffixOf($indexNumber)) 500 .replace("{{qty_already_in_cart}}", $qtyAlreadyInCart) 501 .replace("{{price_suffix}}", this.__priceSuffix) 502 .replace("{{regular_price_striked}}", regularPriceStriked); 503 }; 504 505 function addSuffixOf($value) { 506 var mod10 = $value % 10, 507 mod100 = $value % 100; 508 509 if (mod10 === 1 && mod100 !== 11) { 510 return $value + "st"; 511 } 512 if (mod10 === 2 && mod100 !== 12) { 513 return $value + "nd"; 514 } 515 if (mod10 === 3 && mod100 !== 13) { 516 return $value + "rd"; 517 } 518 return $value + "th"; 519 } 520 521 function logError($text) { 522 console.error("DynamicPrice error: %s", $text); 523 } 524 525 return DynamicPrice; 526})(); 527 528var dynamicPrices = []; 529 530function createDynamicPrice() { 531 var dynamicPrices = []; 532 533 jQuery('form.cart').each(function () { 534 var $form = jQuery(this); 535 var isVariation = $form.hasClass("variations_form"); 536 var $targets = []; 537 var $productId = $form.find('[name="add-to-cart"]').val(); 538 539 if (!$productId) { 540 return false; 541 } 542 543 if (isVariation) { 544 $targets.push('.product.post-' + $productId + ' .woocommerce-variation-price .price'); 545 546 if (wdp_script_data_pro.replace_variable_price) { 547 $targets.push('.product.post-' + $productId + ' ' + wdp_script_data_pro.variable_price_selector); 548 } 549 } else { 550 $targets.push('.product.post-' + $productId + ' .price'); 551 } 552 553 var optFirst = Object.assign({}, wdp_script_data_pro); 554 optFirst.dynamic_price_enable = true; 555 var dynamicPrice = new DynamicPrice($form, optFirst); 556 557 if ( optFirst.update_price_with_qty === "1" ) { 558 dynamicPrice.addPriceDestination($targets); 559 } 560 561 dynamicPrice.addTotalPriceDestination(["div.adp-total-price"]); 562 563 dynamicPrice.observe(); 564 dynamicPrices.push(dynamicPrice); 565 }); 566 567 return dynamicPrices; 568} 569 570if (wdp_script_data_pro.js_init_trigger) { 571 jQuery(document).on(wdp_script_data_pro.js_init_trigger, function () { 572 dynamicPrices = createDynamicPrice(); 573 }); 574} 575 576if (wdp_script_data_pro.create_on_load) { 577 jQuery(document).ready(function () { 578 dynamicPrices = createDynamicPrice(); 579 580 jQuery('.variations_form').on('found_variation', {variationForm: this}, 581 function (event, variation) { 582 if (typeof variation !== 'undefined') { 583 setTimeout(function () { 584 dynamicPrices.forEach(function (dynamicPrice) { 585 if (dynamicPrice.form[0] !== undefined && dynamicPrice.form[0] === event.target) { 586 dynamicPrice.__update(dynamicPrice.__getQty()) 587 } 588 }); 589 }, 0); 590 } 591 592 return true; 593 }); 594 595 jQuery('form.cart').on('adp_found_variation', function () { 596 setTimeout(function () { 597 dynamicPrices.forEach(function (dynamicPrice) { 598 if (dynamicPrice.form[0] !== undefined) { 599 dynamicPrice.__update(dynamicPrice.__getQty()) 600 } 601 }); 602 }, 0); 603 return true; 604 }); 605 606 jQuery('.variations_form').on('reset_data', {variationForm: this}, 607 function (event) { 608 setTimeout(function () { 609 dynamicPrices.forEach(function (dynamicPrice) { 610 if (dynamicPrice.form[0] !== undefined && dynamicPrice.form[0] === event.target) { 611 dynamicPrice.__clearTotalPrice(); 612 } 613 }); 614 615 }, 0); 616 617 return true; 618 }); 619 }); 620}
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.