PageSourceSearch

https://sabineweiskopf.com/wp-content/plugins/woocommerce-germaniz…/static/unit-price-observer.js?ver=3.20.7

js sabineweiskopf.com collected 2026-10-08 08:04:38 UTC 19,251 bytes, 451 lines download raw bytes

1/******/ (function() { // webpackBootstrap
2var __webpack_exports__ = {};
3/*global wc_gzd_unit_price_observer_params, accounting */
4;
5(function ($, window, document, undefined) {
6  var GermanizedUnitPriceObserver = function ($wrapper) {
7    var self = this;
8    self.params = wc_gzd_unit_price_observer_params;
9    self.$wrapper = $wrapper.closest(self.params.wrapper);
10    self.$form = self.$wrapper.find('.variations_form, .cart').length > 0 ? self.$wrapper.find('.variations_form, .cart') : false;
11    self.isVar = self.$form ? self.$form.hasClass('variations_form') : false;
12    self.$product = self.$wrapper.closest('.product');
13    self.requests = [];
14    self.observer = {};
15    self.timeout = false;
16    self.priceData = false;
17    self.productId = 0;
18    if (self.$wrapper.length <= 0) {
19      self.$wrapper = self.$product;
20    }
21    self.replacePrice = self.$wrapper.hasClass('bundled_product') ? false : self.params.replace_price;
22    if ("MutationObserver" in window || "WebKitMutationObserver" in window || "MozMutationObserver" in window) {
23      self.$wrapper.addClass('has-unit-price-observer');
24      self.initObservers(self);
25      if (self.isVar && self.$form) {
26        self.productId = parseInt(self.$form.find('input[name=product_id]').length > 0 ? self.$form.find('input[name=product_id]').val() : self.$form.data('product_id'));
27        self.variationId = parseInt(self.$form.find('input[name=variation_id]').length > 0 ? self.$form.find('input[name=variation_id]').val() : 0);
28        if (self.$form.find('input[name=variation_id]').length <= 0) {
29          self.variationId = parseInt(self.$form.find('input.variation_id').length > 0 ? self.$form.find('input.variation_id').val() : 0);
30        }
31        self.$form.on('reset_data.unit-price-observer', {
32          GermanizedUnitPriceObserver: self
33        }, self.onResetVariation);
34        self.$form.on('found_variation.unit-price-observer', {
35          GermanizedUnitPriceObserver: self
36        }, self.onFoundVariation);
37      } else {
38        if (self.$form && self.$form.find('*[name=add-to-cart][type=submit]').length > 0) {
39          self.productId = parseInt(self.$form.find('*[name=add-to-cart][type=submit]').val());
40        } else if (self.$form && self.$form.data('product_id')) {
41          self.productId = parseInt(self.$form.data('product_id'));
42        } else {
43          var classList = self.$product.attr('class').split(/\s+/);
44
45          /**
46           * Check whether we may find the post/product by a class added by Woo, e.g. post-64
47           */
48          $.each(classList, function (index, item) {
49            if ('post-' === item.substring(0, 5)) {
50              var postId = parseInt(item.substring(5).replace(/[^0-9]/g, ''));
51              if (postId > 0) {
52                self.productId = postId;
53                return true;
54              }
55            }
56          });
57
58          /**
59           * Do only use the add to cart button attribute as fallback as there might be a lot of
60           * other product/add to cart buttons within a single product main product wrap (e.g. related products).
61           */
62          if (self.productId <= 0 && 1 === self.$product.find('a.ajax_add_to_cart[data-product_id], a.add_to_cart_button[data-product_id]').length) {
63            self.productId = parseInt(self.$product.find('a.ajax_add_to_cart, a.add_to_cart_button').data('product_id'));
64          }
65        }
66      }
67      if (self.productId <= 0) {
68        self.destroy(self);
69        return false;
70      }
71      if (self.params.refresh_on_load) {
72        $.each(self.params.price_selector, function (priceSelector, priceArgs) {
73          var isPrimary = priceArgs.hasOwnProperty('is_primary_selector') ? priceArgs['is_primary_selector'] : false,
74            $price = self.getPriceNode(self, priceSelector, isPrimary),
75            $unitPrice = self.getUnitPriceNode(self, $price);
76
77          /**
78           * Do only refresh primary price nodes on load.
79           */
80          if (!isPrimary) {
81            return;
82          }
83          if ($unitPrice.length > 0) {
84            self.stopObserver(self, priceSelector);
85            self.setUnitPriceLoading(self, $unitPrice);
86            setTimeout(function () {
87              self.stopObserver(self, priceSelector);
88              var priceData = self.getCurrentPriceData(self, $price, priceArgs['is_total_price'], isPrimary, priceArgs['quantity_selector']);
89              if (priceData) {
90                self.refreshUnitPrice(self, priceData, priceSelector, isPrimary);
91              } else if ($unitPrice.length > 0) {
92                self.unsetUnitPriceLoading(self, $unitPrice);
93              }
94              self.startObserver(self, priceSelector, isPrimary);
95            }, 250);
96          }
97        });
98      }
99    }
100    $wrapper.data('unitPriceObserver', self);
101  };
102  GermanizedUnitPriceObserver.prototype.destroy = function (self) {
103    self = self || this;
104    self.cancelObservers(self);
105    if (self.$form) {
106      self.$form.off('.unit-price-observer');
107    }
108    self.$wrapper.removeClass('has-unit-price-observer');
109  };
110  GermanizedUnitPriceObserver.prototype.getTextWidth = function ($element) {
111    var htmlOrg = $element.html();
112    var html_calc = '<span>' + htmlOrg + '</span>';
113    $element.html(html_calc);
114    var textWidth = $element.find('span:first').width();
115    $element.html(htmlOrg);
116    return textWidth;
117  };
118  GermanizedUnitPriceObserver.prototype.getPriceNode = function (self, priceSelector, isPrimarySelector, visibleOnly) {
119    isPrimarySelector = typeof isPrimarySelector === 'undefined' ? false : isPrimarySelector;
120    visibleOnly = typeof visibleOnly === 'undefined' ? true : visibleOnly;
121    let visibleSelector = visibleOnly ? ':visible' : '';
122    var $node = self.$wrapper.find(priceSelector + ':not(.price-unit)' + visibleSelector).not('.variations_form .single_variation .price').first();
123    if (isPrimarySelector && self.isVar && ($node.length <= 0 || !self.replacePrice)) {
124      $node = self.$wrapper.find('.woocommerce-variation-price span.price:not(.price-unit):last' + visibleSelector);
125    } else if (isPrimarySelector && $node.length <= 0) {
126      $node = self.$wrapper.find('.price:not(.price-unit):last' + visibleSelector);
127    }
128    if ($node.length <= 0 && self.$wrapper.hasClass('wc-block-product')) {
129      $node = self.$wrapper.find('.wc-block-grid__product-price');
130    }
131    return $node;
132  };
133  GermanizedUnitPriceObserver.prototype.getObserverNode = function (self, priceSelector, isPrimarySelector) {
134    var $node = self.getPriceNode(self, priceSelector, isPrimarySelector, false);
135    if (isPrimarySelector && self.isVar && !self.replacePrice) {
136      $node = self.$wrapper.find('.single_variation:last');
137    }
138    return $node;
139  };
140  GermanizedUnitPriceObserver.prototype.getUnitPriceNode = function (self, $price) {
141    if ($price.length <= 0) {
142      return [];
143    }
144    var $element = [];
145    var isSingleProductBlock = $price.parents('.wp-block-woocommerce-product-price[data-is-descendent-of-single-product-template]').length > 0;
146    var isProductGridBlock = self.$wrapper.hasClass('wc-block-product');
147    if ('SPAN' === $price[0].tagName) {
148      $element = self.$wrapper.find('.price-unit');
149    } else {
150      if (isSingleProductBlock) {
151        $element = self.$wrapper.find('.wp-block-woocommerce-gzd-product-unit-price[data-is-descendent-of-single-product-template] .price-unit');
152      } else if (isProductGridBlock) {
153        $element = self.$wrapper.find('.price-unit:not(.wc-gzd-additional-info-placeholder)');
154      } else {
155        $element = self.$wrapper.find('.price-unit:not(.wc-gzd-additional-info-placeholder, .wc-gzd-additional-info-loop)');
156      }
157    }
158
159    /**
160     * Check whether the unit price is empty - prevent refreshing empty prices.
161     */
162    if ($element.length > 0) {
163      if ($element.is(':empty') || $element.find('.wc-gzd-additional-info-placeholder').is(':empty')) {
164        $element = [];
165      }
166    }
167    return $element;
168  };
169  GermanizedUnitPriceObserver.prototype.stopObserver = function (self, priceSelector) {
170    var observer = self.getObserver(self, priceSelector);
171    if (observer) {
172      observer.disconnect();
173    }
174  };
175  GermanizedUnitPriceObserver.prototype.startObserver = function (self, priceSelector, isPrimary) {
176    var observer = self.getObserver(self, priceSelector),
177      $node = self.getObserverNode(self, priceSelector, isPrimary);
178    if (observer) {
179      self.stopObserver(self, priceSelector);
180      if ($node.length > 0) {
181        observer.observe($node[0], {
182          attributes: true,
183          childList: true,
184          subtree: true,
185          characterData: true,
186          attributeFilter: ['style']
187        });
188      }
189      return true;
190    }
191    return false;
192  };
193  GermanizedUnitPriceObserver.prototype.initObservers = function (self) {
194    if (Object.keys(self.observer).length !== 0) {
195      return;
196    }
197    $.each(self.params.price_selector, function (priceSelector, priceArgs) {
198      var isPrimary = priceArgs.hasOwnProperty('is_primary_selector') ? priceArgs['is_primary_selector'] : false,
199        $observerNode = self.getObserverNode(self, priceSelector, isPrimary),
200        currentObserver = false;
201      if ($observerNode.length > 0 && $observerNode.is(':visible')) {
202        // Callback function to execute when mutations are observed
203        var callback = function (mutationsList, observer) {
204          var $priceNode = self.getPriceNode(self, priceSelector, isPrimary);
205          for (let mutation of mutationsList) {
206            let $element = $(mutation.target);
207            if ($element.length > 0) {
208              let $priceElement;
209              if ($element.is(priceSelector)) {
210                $priceElement = $element;
211              } else {
212                $priceElement = $element.parents(priceSelector);
213              }
214              if ($priceElement.length > 0) {
215                $priceNode = $priceElement;
216              }
217            }
218          }
219
220          /**
221           * Clear the timeout and abort open AJAX requests as
222           * a new mutation has been observed
223           */
224          if (self.timeout) {
225            clearTimeout(self.timeout);
226          }
227          var $unitPrice = self.getUnitPriceNode(self, $priceNode),
228            hasRefreshed = false;
229          if ($priceNode.length <= 0) {
230            return false;
231          }
232          self.stopObserver(self, priceSelector);
233          if ($unitPrice.length > 0) {
234            self.setUnitPriceLoading(self, $unitPrice);
235
236            /**
237             * Need to use a tweak here to make sure our variation listener
238             * has already adjusted the variationId (in case necessary).
239             */
240            self.timeout = setTimeout(function () {
241              self.stopObserver(self, priceSelector);
242              $priceNode = self.getPriceNode(self, priceSelector, isPrimary); // Refresh dom instance as the price element may change during timeout
243
244              if ($priceNode.length > 0) {
245                var priceData = self.getCurrentPriceData(self, $priceNode, priceArgs['is_total_price'], isPrimary, priceArgs['quantity_selector']);
246                var isVisible = $priceNode.is(':visible');
247                if (priceData) {
248                  if (self.isRefreshingUnitPrice(self.getCurrentProductId(self))) {
249                    self.abortRefreshUnitPrice(self.getCurrentProductId(self));
250                  }
251                  hasRefreshed = true;
252                  self.refreshUnitPrice(self, priceData, priceSelector, isPrimary);
253                }
254                if (!hasRefreshed && $unitPrice.length > 0) {
255                  self.unsetUnitPriceLoading(self, $unitPrice);
256                  if (!isVisible && isPrimary) {
257                    $unitPrice.hide();
258                  }
259                }
260              }
261              self.startObserver(self, priceSelector, isPrimary);
262            }, 500);
263          }
264        };
265        if ("MutationObserver" in window) {
266          currentObserver = new window.MutationObserver(callback);
267        } else if ("WebKitMutationObserver" in window) {
268          currentObserver = new window.WebKitMutationObserver(callback);
269        } else if ("MozMutationObserver" in window) {
270          currentObserver = new window.MozMutationObserver(callback);
271        }
272        if (currentObserver) {
273          self.observer[priceSelector] = currentObserver;
274          self.startObserver(self, priceSelector, isPrimary);
275        }
276      }
277    });
278  };
279  GermanizedUnitPriceObserver.prototype.getObserver = function (self, priceSelector) {
280    if (self.observer.hasOwnProperty(priceSelector)) {
281      return self.observer[priceSelector];
282    }
283    return false;
284  };
285  GermanizedUnitPriceObserver.prototype.cancelObservers = function (self) {
286    for (var key in self.observer) {
287      if (self.observer.hasOwnProperty(key)) {
288        self.observer[key].disconnect();
289        delete self.observer[key];
290      }
291    }
292  };
293
294  /**
295   * Reset all fields.
296   */
297  GermanizedUnitPriceObserver.prototype.onResetVariation = function (event) {
298    var self = event.data.GermanizedUnitPriceObserver;
299    self.variationId = 0;
300  };
301  GermanizedUnitPriceObserver.prototype.onFoundVariation = function (event, variation) {
302    var self = event.data.GermanizedUnitPriceObserver;
303    if (variation.hasOwnProperty('variation_id')) {
304      self.variationId = parseInt(variation.variation_id);
305    }
306    self.initObservers(self);
307  };
308  GermanizedUnitPriceObserver.prototype.getCurrentPriceData = function (self, priceSelector, isTotalPrice, isPrimary, quantitySelector) {
309    quantitySelector = quantitySelector && '' !== quantitySelector ? quantitySelector : self.params.qty_selector;
310    var $price = typeof priceSelector === 'string' || priceSelector instanceof String ? self.getPriceNode(self, priceSelector, isPrimary) : priceSelector;
311    if ($price.length > 0) {
312      // Add a tmp hidden class to detect hidden elements in cloned obj
313      $price.find(':hidden').addClass('wc-gzd-is-hidden');
314      var $unit_price = self.getUnitPriceNode(self, $price),
315        $priceCloned = $price.clone();
316
317      // Remove price suffix from cloned DOM element to prevent finding the wrong (sale) price
318      $priceCloned.find('.woocommerce-price-suffix').remove();
319      $priceCloned.find('.wc-gzd-is-hidden').remove();
320      var sale_price = '',
321        $priceInner = $priceCloned.find('.amount:first'),
322        $qty = $(self.params.wrapper + ' ' + quantitySelector + ':first'),
323        qty = 1,
324        is_range = false;
325      if ($qty.length > 0) {
326        qty = parseFloat($qty.val());
327      }
328
329      /**
330       * In case the price element does not contain the default Woo price structure
331       * search the whole element.
332       */
333      if ($priceInner.length <= 0) {
334        if ($priceCloned.find('.price').length > 0) {
335          $priceInner = $priceCloned.find('.price');
336        } else {
337          $priceInner = $priceCloned;
338        }
339      }
340      var price = self.getRawPrice($priceInner, self.params.price_decimal_sep);
341
342      /**
343       * Is sale?
344       */
345      if ($priceCloned.find('.amount').length > 1) {
346        // The second .amount element is the sale price
347        var $sale_price = $($priceCloned.find('.amount')[1]);
348        sale_price = self.getRawPrice($sale_price, self.params.price_decimal_sep);
349      }
350
351      /**
352       * Is price range, e.g. variable products
353       */
354      if (sale_price && $priceCloned.find('del').length <= 0) {
355        is_range = true;
356      }
357      $price.find('.wc-gzd-is-hidden').removeClass('wc-gzd-is-hidden');
358      if ($unit_price.length > 0 && price) {
359        if (isTotalPrice) {
360          price = parseFloat(price) / qty;
361          if (sale_price) {
362            sale_price = parseFloat(sale_price) / qty;
363          }
364        }
365        return {
366          'price': price,
367          'unit_price': $unit_price,
368          'sale_price': sale_price,
369          'quantity': qty,
370          'is_range': is_range
371        };
372      }
373    }
374    return false;
375  };
376  GermanizedUnitPriceObserver.prototype.getCurrentProductId = function (self) {
377    var productId = self.productId;
378    if (self.variationId > 0) {
379      productId = self.variationId;
380    }
381    return parseInt(productId);
382  };
383  GermanizedUnitPriceObserver.prototype.getRawPrice = function ($el, decimal_sep) {
384    var price_raw = $el.length > 0 ? $el.text() : '',
385      price = false;
386    try {
387      price = accounting.unformat(price_raw, decimal_sep);
388    } catch (e) {
389      price = false;
390    }
391    return price;
392  };
393  GermanizedUnitPriceObserver.prototype.setUnitPriceLoading = function (self, $unit_price) {
394    var unitPriceOrg = $unit_price.html();
395    if (!$unit_price.hasClass('wc-gzd-loading')) {
396      var textWidth = self.getTextWidth($unit_price),
397        textHeight = $unit_price.find('span').length > 0 ? $unit_price.find('span').innerHeight() : $unit_price.height();
398      /**
399       * @see https://github.com/zalog/placeholder-loading
400       */
401      $unit_price.html('<span class="wc-gzd-placeholder-loading"><span class="wc-gzd-placeholder-row" style="height: ' + $unit_price.height() + 'px;"><span class="wc-gzd-placeholder-row-col-4" style="width: ' + textWidth + 'px; height: ' + textHeight + 'px;"></span></span></span>');
402      $unit_price.addClass('wc-gzd-loading');
403    }
404    $unit_price.data('org-html', unitPriceOrg);
405    return unitPriceOrg;
406  };
407  GermanizedUnitPriceObserver.prototype.unsetUnitPriceLoading = function (self, $unit_price, newHtml) {
408    newHtml = newHtml || $unit_price.data('org-html');
409    $unit_price.html(newHtml);
410    if ($unit_price.hasClass('wc-gzd-loading')) {
411      $unit_price.removeClass('wc-gzd-loading');
412    }
413    if (typeof newHtml === "string" && newHtml.length > 0) {
414      $unit_price.show();
415    }
416  };
417  GermanizedUnitPriceObserver.prototype.isRefreshingUnitPrice = function (currentProductId) {
418    return germanized.unit_price_observer_queue.exists(currentProductId);
419  };
420  GermanizedUnitPriceObserver.prototype.abortRefreshUnitPrice = function (currentProductId) {
421    return germanized.unit_price_observer_queue.abort(currentProductId);
422  };
423  GermanizedUnitPriceObserver.prototype.refreshUnitPrice = function (self, priceData, priceSelector, isPrimary) {
424    germanized.unit_price_observer_queue.add(self, self.getCurrentProductId(self), priceData, priceSelector, isPrimary);
425  };
426
427  /**
428   * Function to call wc_gzd_variation_form on jquery selector.
429   */
430  $.fn.wc_germanized_unit_price_observer = function () {
431    if ($(this).data('unitPriceObserver')) {
432      $(this).data('unitPriceObserver').destroy();
433    }
434    new GermanizedUnitPriceObserver(this);
435    return this;
436  };
437  $(function () {
438    if (typeof wc_gzd_unit_price_observer_params !== 'undefined') {
439      $(wc_gzd_unit_price_observer_params.wrapper).each(function () {
440        if ($(this).is('body')) {
441          return;
442        }
443        $(this).wc_germanized_unit_price_observer();
444      });
445    }
446  });
447})(jQuery, window, document);
448window.germanized = window.germanized || {};
449((window.germanized = window.germanized || {})["static"] = window.germanized["static"] || {})["unit-price-observer"] = __webpack_exports__;
450/******/ })()
451;

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.