PageSourceSearch

https://www.woodenhottubsale.co.uk/wp-content/plugins/timberin-pro…/assets/professional-cart.js?ver=1787659037

js woodenhottubsale.co.uk collected 2026-10-04 22:08:51 UTC 4,453 bytes, 156 lines download raw bytes

1(function () {
2	'use strict';
3
4	var labels = window.timberinProfessionalCart || {
5		decrease: 'Decrease quantity',
6		increase: 'Increase quantity'
7	};
8
9	function setMissingCellLabels(form) {
10		var names = ['product-price', 'product-quantity', 'product-subtotal'];
11
12		names.forEach(function (className) {
13			var heading = form.querySelector('thead th.' + className);
14			var text = heading ? heading.textContent.replace(/\s+/g, ' ').trim() : '';
15
16			if (!text) {
17				return;
18			}
19
20			form.querySelectorAll('tr.cart_item td.' + className).forEach(function (cell) {
21				if (!cell.getAttribute('data-title')) {
22					cell.setAttribute('data-title', text);
23				}
24			});
25		});
26	}
27
28	function createButton(direction) {
29		var button = document.createElement('button');
30		button.type = 'button';
31		button.className = direction + ' timberin-cart-quantity__button';
32		button.setAttribute('data-timberin-quantity', direction);
33		button.setAttribute('aria-label', direction === 'minus' ? labels.decrease : labels.increase);
34		button.textContent = direction === 'minus' ? '−' : '+';
35		return button;
36	}
37
38	function preferNativeControl(quantity, direction) {
39		var controls = Array.prototype.slice.call(quantity.querySelectorAll('.' + direction));
40		var nativeControl = controls.find(function (control) {
41			return !control.hasAttribute('data-timberin-quantity');
42		});
43
44		if (nativeControl) {
45			controls.forEach(function (control) {
46				if (control !== nativeControl && control.hasAttribute('data-timberin-quantity')) {
47					control.remove();
48				}
49			});
50			return nativeControl;
51		}
52
53		return controls[0] || null;
54	}
55
56	function enhanceQuantity(quantity) {
57		var input = quantity.querySelector('input.qty');
58
59		if (!input) {
60			return;
61		}
62
63		var minus = preferNativeControl(quantity, 'minus');
64		var plus = preferNativeControl(quantity, 'plus');
65
66		if (!minus) {
67			minus = createButton('minus');
68			quantity.insertBefore(minus, input);
69		} else if (!minus.getAttribute('aria-label')) {
70			minus.setAttribute('aria-label', labels.decrease);
71		}
72
73		if (!plus) {
74			plus = createButton('plus');
75			input.insertAdjacentElement('afterend', plus);
76		} else if (!plus.getAttribute('aria-label')) {
77			plus.setAttribute('aria-label', labels.increase);
78		}
79
80		quantity.setAttribute('data-timberin-quantity-ready', 'true');
81	}
82
83	function mount() {
84		document.querySelectorAll('form.woocommerce-cart-form').forEach(function (form) {
85			setMissingCellLabels(form);
86			form.querySelectorAll('.quantity').forEach(enhanceQuantity);
87		});
88	}
89
90	function updateAddedControl(button) {
91		var quantity = button.closest('.quantity');
92		var input = quantity ? quantity.querySelector('input.qty') : null;
93
94		if (!input || input.disabled || input.readOnly) {
95			return;
96		}
97
98		var direction = button.getAttribute('data-timberin-quantity');
99		var min = input.min === '' ? 0 : parseFloat(input.min);
100		var max = input.max === '' ? Infinity : parseFloat(input.max);
101		var step = input.step === '' || input.step === 'any' ? 1 : parseFloat(input.step);
102		var value = input.value === '' ? min : parseFloat(input.value);
103
104		if (!Number.isFinite(min)) {
105			min = 0;
106		}
107		if (!Number.isFinite(step) || step <= 0) {
108			step = 1;
109		}
110		if (!Number.isFinite(value)) {
111			value = min;
112		}
113
114		value += direction === 'minus' ? -step : step;
115		value = Math.max(min, Math.min(max, value));
116
117		var decimals = (String(step).split('.')[1] || '').length;
118		input.value = decimals ? value.toFixed(decimals) : String(Math.round(value));
119		input.dispatchEvent(new Event('input', { bubbles: true }));
120		input.dispatchEvent(new Event('change', { bubbles: true }));
121	}
122
123	document.addEventListener('click', function (event) {
124		var button = event.target.closest('[data-timberin-quantity]');
125
126		if (!button) {
127			return;
128		}
129
130		event.preventDefault();
131		updateAddedControl(button);
132	});
133
134	if (document.readyState === 'loading') {
135		document.addEventListener('DOMContentLoaded', mount, { once: true });
136	} else {
137		mount();
138	}
139
140	window.addEventListener('pageshow', mount);
141
142	if (window.jQuery) {
143		window.jQuery(document.body).on('updated_wc_div updated_cart_totals', function () {
144			window.setTimeout(mount, 0);
145		});
146	}
147
148	var root = document.querySelector('.woocommerce') || document.body;
149	if (window.MutationObserver && root) {
150		var timer;
151		new MutationObserver(function () {
152			window.clearTimeout(timer);
153			timer = window.setTimeout(mount, 0);
154		}).observe(root, { childList: true, subtree: true });
155	}
156}());

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.