/******/ (() => { // webpackBootstrap
let __webpack_exports__ = {};
/*global wc_gzd_unit_price_observer_params, accounting */
;
(function ($, window, document, undefined) {
var GermanizedUnitPriceObserver = function ($wrapper) {
var self = this;
self.params = wc_gzd_unit_price_observer_params;
self.$wrapper = $wrapper.closest(self.params.wrapper);
self.$form = self.$wrapper.find('.variations_form, .cart').length > 0 ? self.$wrapper.find('.variations_form, .cart') : false;
self.isVar = self.$form ? self.$form.hasClass('variations_form') : false;
self.$product = self.$wrapper.closest('.product');
self.requests = [];
self.observer = {};
self.timeout = false;
self.priceData = false;
self.productId = 0;
if (self.$wrapper.length <= 0) {
self.$wrapper = self.$product;
}
self.replacePrice = self.$wrapper.hasClass('bundled_product') ? false : self.params.replace_price;
if ("MutationObserver" in window || "WebKitMutationObserver" in window || "MozMutationObserver" in window) {
self.$wrapper.addClass('has-unit-price-observer');
self.initObservers(self);
if (self.isVar && self.$form) {
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'));
self.variationId = parseInt(self.$form.find('input[name=variation_id]').length > 0 ? self.$form.find('input[name=variation_id]').val() : 0);
if (self.$form.find('input[name=variation_id]').length <= 0) {
self.variationId = parseInt(self.$form.find('input.variation_id').length > 0 ? self.$form.find('input.variation_id').val() : 0);
}
self.$form.on('reset_data.unit-price-observer', {
GermanizedUnitPriceObserver: self
}, self.onResetVariation);
self.$form.on('found_variation.unit-price-observer', {
GermanizedUnitPriceObserver: self
}, self.onFoundVariation);
} else {
if (self.$form && self.$form.find('*[name=add-to-cart][type=submit]').length > 0) {
self.productId = parseInt(self.$form.find('*[name=add-to-cart][type=submit]').val());
} else if (self.$form && self.$form.data('product_id')) {
self.productId = parseInt(self.$form.data('product_id'));
} else {
var classList = self.$product.attr('class').split(/\s+/);
/**
* Check whether we may find the post/product by a class added by Woo, e.g. post-64
*/
$.each(classList, function (index, item) {
if ('post-' === item.substring(0, 5)) {
var postId = parseInt(item.substring(5).replace(/[^0-9]/g, ''));
if (postId > 0) {
self.productId = postId;
return true;
}
}
});
/**
* Do only use the add to cart button attribute as fallback as there might be a lot of
* other product/add to cart buttons within a single product main product wrap (e.g. related products).
*/
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) {
self.productId = parseInt(self.$product.find('a.ajax_add_to_cart, a.add_to_cart_button').data('product_id'));
}
}
}
if (self.productId <= 0) {
self.destroy(self);
return false;
}
if (self.params.refresh_on_load) {
/**
* Do not refresh variable products on single product pages
* as that leads to race conditions with the Woo Core.
*/
if (self.isVar && self.$form) {
self.$form.on('show_variation.unit-price-observer', {
GermanizedUnitPriceObserver: self
}, function (event) {
var self = event.data.GermanizedUnitPriceObserver;
self.forceRefresh(self);
});
self.$form.on('reset_data.unit-price-observer', {
GermanizedUnitPriceObserver: self
}, function (event) {
var self = event.data.GermanizedUnitPriceObserver;
self.forceRefresh(self);
});
} else {
self.forceRefresh(self);
}
}
}
$wrapper.data('unitPriceObserver', self);
};
GermanizedUnitPriceObserver.prototype.destroy = function (self) {
self = self || this;
self.cancelObservers(self);
if (self.$form) {
self.$form.off('.unit-price-observer');
}
self.$wrapper.removeClass('has-unit-price-observer');
};
GermanizedUnitPriceObserver.prototype.getTextWidth = function ($element) {
var htmlOrg = $element.html();
var html_calc = '' + htmlOrg + '';
$element.html(html_calc);
var textWidth = $element.find('span:first').width();
$element.html(htmlOrg);
return textWidth;
};
GermanizedUnitPriceObserver.prototype.getPriceNode = function (self, priceSelector, isPrimarySelector, visibleOnly) {
isPrimarySelector = typeof isPrimarySelector === 'undefined' ? false : isPrimarySelector;
visibleOnly = typeof visibleOnly === 'undefined' ? true : visibleOnly;
let visibleSelector = visibleOnly ? ':visible' : '';
var $node = self.$wrapper.find(priceSelector + ':not(.price-unit)' + visibleSelector).not('.variations_form .single_variation .price').first();
if (isPrimarySelector && self.isVar && ($node.length <= 0 || !self.replacePrice)) {
$node = self.$wrapper.find('.woocommerce-variation-price span.price:not(.price-unit):last' + visibleSelector);
} else if (isPrimarySelector && $node.length <= 0) {
$node = self.$wrapper.find('.price:not(.price-unit):last' + visibleSelector);
}
if ($node.length <= 0 && self.$wrapper.hasClass('wc-block-product')) {
$node = self.$wrapper.find('.wc-block-grid__product-price');
}
return $node;
};
GermanizedUnitPriceObserver.prototype.getObserverNode = function (self, priceSelector, isPrimarySelector) {
var $node = self.getPriceNode(self, priceSelector, isPrimarySelector, false);
if (isPrimarySelector && self.isVar && !self.replacePrice) {
$node = self.$wrapper.find('.single_variation:last');
}
return $node;
};
GermanizedUnitPriceObserver.prototype.getUnitPriceNode = function (self, $price) {
if ($price.length <= 0) {
return [];
}
var $element = [];
var isSingleProductBlock = $price.parents('.wp-block-woocommerce-product-price[data-is-descendent-of-single-product-template]').length > 0;
var isProductGridBlock = self.$wrapper.hasClass('wc-block-product');
if ('SPAN' === $price[0].tagName) {
$element = self.$wrapper.find('.price-unit');
} else {
if (isSingleProductBlock) {
$element = self.$wrapper.find('.wp-block-woocommerce-gzd-product-unit-price[data-is-descendent-of-single-product-template] .price-unit');
} else if (isProductGridBlock) {
$element = self.$wrapper.find('.price-unit:not(.wc-gzd-additional-info-placeholder)');
} else {
$element = self.$wrapper.find('.price-unit:not(.wc-gzd-additional-info-placeholder, .wc-gzd-additional-info-loop)');
}
}
/**
* Check whether the unit price is empty - prevent refreshing empty prices.
*/
if ($element.length > 0) {
if ($element.is(':empty') || $element.find('.wc-gzd-additional-info-placeholder').is(':empty')) {
$element = [];
}
}
return $element;
};
GermanizedUnitPriceObserver.prototype.stopObserver = function (self, priceSelector) {
var observer = self.getObserver(self, priceSelector);
if (observer) {
observer.disconnect();
}
};
GermanizedUnitPriceObserver.prototype.startObserver = function (self, priceSelector, isPrimary) {
var observer = self.getObserver(self, priceSelector),
$node = self.getObserverNode(self, priceSelector, isPrimary);
if (observer) {
self.stopObserver(self, priceSelector);
if ($node.length > 0) {
observer.observe($node[0], {
attributes: true,
childList: true,
subtree: true,
characterData: true,
attributeFilter: ['style', 'data-force-refresh']
});
}
return true;
}
return false;
};
GermanizedUnitPriceObserver.prototype.initObservers = function (self) {
if (Object.keys(self.observer).length !== 0) {
return;
}
$.each(self.params.price_selector, function (priceSelector, priceArgs) {
var isPrimary = priceArgs.hasOwnProperty('is_primary_selector') ? priceArgs['is_primary_selector'] : false,
$observerNode = self.getObserverNode(self, priceSelector, isPrimary),
currentObserver = false;
if ($observerNode.length > 0 && $observerNode.is(':visible')) {
// Callback function to execute when mutations are observed
var callback = function (mutationsList, observer) {
var $priceNode = self.getPriceNode(self, priceSelector, isPrimary);
for (let mutation of mutationsList) {
let $element = $(mutation.target);
if ($element.length > 0) {
let $priceElement;
if ($element.is(priceSelector)) {
$priceElement = $element;
} else {
$priceElement = $element.parents(priceSelector);
}
if ($priceElement.length > 0) {
$priceNode = $priceElement;
}
}
}
/**
* Clear the timeout and abort open AJAX requests as
* a new mutation has been observed
*/
if (self.timeout) {
clearTimeout(self.timeout);
}
var $unitPrice = self.getUnitPriceNode(self, $priceNode),
hasRefreshed = false;
if ($priceNode.length <= 0) {
return false;
}
self.stopObserver(self, priceSelector);
if ($unitPrice.length > 0) {
self.setUnitPriceLoading(self, $unitPrice);
/**
* Need to use a tweak here to make sure our variation listener
* has already adjusted the variationId (in case necessary).
*/
self.timeout = setTimeout(function () {
self.stopObserver(self, priceSelector);
$priceNode = self.getPriceNode(self, priceSelector, isPrimary); // Refresh dom instance as the price element may change during timeout
if ($priceNode.length > 0) {
var priceData = self.getCurrentPriceData(self, $priceNode, priceArgs['is_total_price'], isPrimary, priceArgs['quantity_selector']);
var isVisible = $priceNode.is(':visible');
if (priceData) {
if (self.isRefreshingUnitPrice(self.getCurrentProductId(self))) {
self.abortRefreshUnitPrice(self.getCurrentProductId(self));
}
hasRefreshed = true;
self.refreshUnitPrice(self, priceData, priceSelector, isPrimary);
}
if (!hasRefreshed && $unitPrice.length > 0) {
self.unsetUnitPriceLoading(self, $unitPrice);
if (!isVisible && isPrimary) {
$unitPrice.hide();
}
}
}
self.startObserver(self, priceSelector, isPrimary);
}, 500);
}
};
if ("MutationObserver" in window) {
currentObserver = new window.MutationObserver(callback);
} else if ("WebKitMutationObserver" in window) {
currentObserver = new window.WebKitMutationObserver(callback);
} else if ("MozMutationObserver" in window) {
currentObserver = new window.MozMutationObserver(callback);
}
if (currentObserver) {
self.observer[priceSelector] = currentObserver;
self.startObserver(self, priceSelector, isPrimary);
}
}
});
};
GermanizedUnitPriceObserver.prototype.getObserver = function (self, priceSelector) {
if (self.observer.hasOwnProperty(priceSelector)) {
return self.observer[priceSelector];
}
return false;
};
GermanizedUnitPriceObserver.prototype.cancelObservers = function (self) {
for (var key in self.observer) {
if (self.observer.hasOwnProperty(key)) {
self.observer[key].disconnect();
delete self.observer[key];
}
}
};
/**
* Reset all fields.
*/
GermanizedUnitPriceObserver.prototype.onResetVariation = function (event) {
var self = event.data.GermanizedUnitPriceObserver;
self.variationId = 0;
};
GermanizedUnitPriceObserver.prototype.forceRefresh = function (self) {
$.each(self.params.price_selector, function (priceSelector, priceArgs) {
var isPrimary = priceArgs.hasOwnProperty('is_primary_selector') ? priceArgs['is_primary_selector'] : false,
$price = self.getPriceNode(self, priceSelector, isPrimary),
$unitPrice = self.getUnitPriceNode(self, $price);
/**
* Do only refresh primary price nodes on load.
*/
if (!isPrimary) {
return;
}
if ($unitPrice.length > 0) {
$price[0].setAttribute('data-force-refresh', 'yes');
}
});
};
GermanizedUnitPriceObserver.prototype.onFoundVariation = function (event, variation) {
var self = event.data.GermanizedUnitPriceObserver;
if (variation.hasOwnProperty('variation_id')) {
self.variationId = parseInt(variation.variation_id);
}
self.initObservers(self);
};
GermanizedUnitPriceObserver.prototype.getCurrentPriceData = function (self, priceSelector, isTotalPrice, isPrimary, quantitySelector) {
quantitySelector = quantitySelector && '' !== quantitySelector ? quantitySelector : self.params.qty_selector;
var $price = typeof priceSelector === 'string' || priceSelector instanceof String ? self.getPriceNode(self, priceSelector, isPrimary) : priceSelector;
if ($price.length > 0) {
// Add a tmp hidden class to detect hidden elements in cloned obj
$price.find(':hidden').addClass('wc-gzd-is-hidden');
var $unit_price = self.getUnitPriceNode(self, $price),
$priceCloned = $price.clone();
// Remove price suffix from cloned DOM element to prevent finding the wrong (sale) price
$priceCloned.find('.woocommerce-price-suffix').remove();
$priceCloned.find('.wc-gzd-is-hidden').remove();
var sale_price = '',
$priceInner = $priceCloned.find('.amount:first'),
$qty = $(self.params.wrapper + ' ' + quantitySelector + ':first'),
qty = 1,
is_range = false;
if ($qty.length > 0) {
qty = parseFloat($qty.val());
}
/**
* In case the price element does not contain the default Woo price structure
* search the whole element.
*/
if ($priceInner.length <= 0) {
if ($priceCloned.find('.price').length > 0) {
$priceInner = $priceCloned.find('.price');
} else {
$priceInner = $priceCloned;
}
}
var price = self.getRawPrice($priceInner, self.params.price_decimal_sep);
/**
* Is sale?
*/
if ($priceCloned.find('.amount').length > 1) {
// The second .amount element is the sale price
var $sale_price = $($priceCloned.find('.amount')[1]);
sale_price = self.getRawPrice($sale_price, self.params.price_decimal_sep);
}
/**
* Is price range, e.g. variable products
*/
if (sale_price && $priceCloned.find('del').length <= 0) {
is_range = true;
}
$price.find('.wc-gzd-is-hidden').removeClass('wc-gzd-is-hidden');
if ($unit_price.length > 0 && price) {
if (isTotalPrice) {
price = parseFloat(price) / qty;
if (sale_price) {
sale_price = parseFloat(sale_price) / qty;
}
}
return {
'price': price,
'unit_price': $unit_price,
'sale_price': sale_price,
'quantity': qty,
'is_range': is_range
};
}
}
return false;
};
GermanizedUnitPriceObserver.prototype.getCurrentProductId = function (self) {
var productId = self.productId;
if (self.variationId > 0) {
productId = self.variationId;
}
return parseInt(productId);
};
GermanizedUnitPriceObserver.prototype.getRawPrice = function ($el, decimal_sep) {
var price_raw = $el.length > 0 ? $el.text() : '',
price = false;
try {
price = accounting.unformat(price_raw, decimal_sep);
} catch (e) {
price = false;
}
return price;
};
GermanizedUnitPriceObserver.prototype.setUnitPriceLoading = function (self, $unit_price) {
var unitPriceOrg = $unit_price.html();
if (!$unit_price.hasClass('wc-gzd-loading')) {
if ($unit_price.find('.wc-gzd-placeholder-loading').length <= 0) {
var textWidth = self.getTextWidth($unit_price),
textHeight = $unit_price.find('span').length > 0 ? $unit_price.find('span').innerHeight() : $unit_price.height();
/**
* @see https://github.com/zalog/placeholder-loading
*/
$unit_price.html('');
}
$unit_price.addClass('wc-gzd-loading');
}
$unit_price.data('org-html', unitPriceOrg);
return unitPriceOrg;
};
GermanizedUnitPriceObserver.prototype.unsetUnitPriceLoading = function (self, $unit_price, newHtml) {
newHtml = newHtml || $unit_price.data('org-html');
$unit_price.html(newHtml);
if ($unit_price.hasClass('wc-gzd-loading')) {
$unit_price.removeClass('wc-gzd-loading');
}
if (typeof newHtml === "string" && newHtml.length > 0) {
$unit_price.show();
}
};
GermanizedUnitPriceObserver.prototype.isRefreshingUnitPrice = function (currentProductId) {
return germanized.unit_price_observer_queue.exists(currentProductId);
};
GermanizedUnitPriceObserver.prototype.abortRefreshUnitPrice = function (currentProductId) {
return germanized.unit_price_observer_queue.abort(currentProductId);
};
GermanizedUnitPriceObserver.prototype.refreshUnitPrice = function (self, priceData, priceSelector, isPrimary) {
germanized.unit_price_observer_queue.add(self, self.getCurrentProductId(self), priceData, priceSelector, isPrimary);
};
/**
* Function to call wc_gzd_variation_form on jquery selector.
*/
$.fn.wc_germanized_unit_price_observer = function () {
if ($(this).data('unitPriceObserver')) {
$(this).data('unitPriceObserver').destroy();
}
new GermanizedUnitPriceObserver(this);
return this;
};
$(function () {
if (typeof wc_gzd_unit_price_observer_params !== 'undefined') {
const initObservations = function () {
$(wc_gzd_unit_price_observer_params.wrapper).each(function () {
if ($(this).is('body')) {
return;
}
$(this).wc_germanized_unit_price_observer();
});
};
initObservations();
/**
* Support (async) navigation for product collection block
*/
if ($('.wp-block-woocommerce-product-collection').length > 0) {
let currentObserver = false;
const maybeInitObserver = function (mutationsList, observer) {
let needsInit = false;
for (let mutation of mutationsList) {
let $element = $(mutation.target);
if ($element.length > 0 && 'woocommerce/product-template' === $element.data('block-name')) {
needsInit = true;
break;
}
}
if (needsInit) {
initObservations();
}
};
if ("MutationObserver" in window) {
currentObserver = new window.MutationObserver(maybeInitObserver);
} else if ("WebKitMutationObserver" in window) {
currentObserver = new window.WebKitMutationObserver(maybeInitObserver);
} else if ("MozMutationObserver" in window) {
currentObserver = new window.MozMutationObserver(maybeInitObserver);
}
if (currentObserver) {
$('.wp-block-woocommerce-product-collection').each(function () {
let $node = $(this);
currentObserver.observe($node[0], {
childList: true,
subtree: true
});
});
}
}
}
});
})(jQuery, window, document);
window.germanized = window.germanized || {};
((window.germanized = window.germanized || {})["static"] = window.germanized["static"] || {})["unit-price-observer"] = __webpack_exports__;
/******/ })()
;