1(function ($) { 2 'use strict'; 3 4 var autoUpdateTimer = null; 5 var cartLightboxInitialized = false; 6 7 function isMobileCartViewport() { 8 return window.matchMedia('(max-width: 767px)').matches; 9 } 10 11 function getBestImageSource(img) { 12 if (!img) { 13 return ''; 14 } 15 16 if (img.currentSrc) { 17 return img.currentSrc; 18 } 19 20 var srcset = img.getAttribute('srcset') || ''; 21 if (srcset) { 22 var candidates = srcset.split(',').map(function (entry) { 23 var parts = entry.trim().split(/\s+/); 24 return parts[0] || ''; 25 }).filter(Boolean); 26 27 if (candidates.length) { 28 return candidates[candidates.length - 1]; 29 } 30 } 31 32 return img.getAttribute('src') || ''; 33 } 34 35 function ensureCartLightbox() { 36 if (!document.body || document.querySelector('.gpph-cart-lightbox')) { 37 return; 38 } 39 40 document.body.insertAdjacentHTML( 41 'beforeend', 42 '' + 43 '<div class="gpph-cart-lightbox" aria-hidden="true">' + 44 '<div class="gpph-cart-lightbox__dialog" role="dialog" aria-modal="true" aria-label="Podglad produktu">' + 45 '<button type="button" class="gpph-cart-lightbox__close" aria-label="Zamknij podglad">×</button>' + 46 '<div class="gpph-cart-lightbox__media">' + 47 '<img class="gpph-cart-lightbox__image" alt="">' + 48 '</div>' + 49 '</div>' + 50 '</div>' 51 ); 52 } 53 54 function setCartLightboxState(isOpen, imageSrc, imageAlt) { 55 var lightbox = document.querySelector('.gpph-cart-lightbox'); 56 if (!lightbox) { 57 return; 58 } 59 60 var image = lightbox.querySelector('.gpph-cart-lightbox__image'); 61 if (!image) { 62 return; 63 } 64 65 if (isOpen) { 66 image.src = imageSrc || ''; 67 image.alt = imageAlt || ''; 68 lightbox.classList.add('is-open'); 69 lightbox.setAttribute('aria-hidden', 'false'); 70 document.body.classList.add('gpph-cart-lightbox-open'); 71 return; 72 } 73 74 lightbox.classList.remove('is-open'); 75 lightbox.setAttribute('aria-hidden', 'true'); 76 document.body.classList.remove('gpph-cart-lightbox-open'); 77 image.removeAttribute('src'); 78 image.alt = ''; 79 } 80 81 function bindCartLightboxEvents() { 82 if (cartLightboxInitialized) { 83 return; 84 } 85 86 ensureCartLightbox(); 87 cartLightboxInitialized = true; 88 89 $(document).on('click.gpphCartLightbox', '.woocommerce-cart-form table.cart td.product-thumbnail a', function (event) { 90 if (!isMobileCartViewport()) { 91 return; 92 } 93 94 var img = this.querySelector('img'); 95 var imageSrc = getBestImageSource(img); 96 if (!imageSrc) { 97 return; 98 } 99 100 event.preventDefault(); 101 setCartLightboxState(true, imageSrc, (img && img.getAttribute('alt')) || ''); 102 }); 103 104 $(document).on('click.gpphCartLightbox', '.gpph-cart-lightbox, .gpph-cart-lightbox__close', function (event) { 105 if ( 106 event.target.classList.contains('gpph-cart-lightbox') || 107 event.target.classList.contains('gpph-cart-lightbox__close') 108 ) { 109 setCartLightboxState(false); 110 } 111 }); 112 113 $(document).on('keydown.gpphCartLightbox', function (event) { 114 if (event.key === 'Escape') { 115 setCartLightboxState(false); 116 } 117 }); 118 } 119 120 function parseNumber(value, fallbackValue) { 121 var parsed = parseFloat(value); 122 return Number.isFinite(parsed) ? parsed : fallbackValue; 123 } 124 125 function getQuantityMeta($input) { 126 var stepRaw = String($input.attr('step') || '1'); 127 var step = parseNumber(stepRaw, 1); 128 var min = parseNumber($input.attr('min'), 0); 129 var max = parseNumber($input.attr('max'), Number.POSITIVE_INFINITY); 130 131 if (!Number.isFinite(step) || step <= 0) { 132 step = 1; 133 stepRaw = '1'; 134 } 135 136 if (!Number.isFinite(min)) { 137 min = 0; 138 } 139 140 if (!Number.isFinite(max) || max <= 0) { 141 max = Number.POSITIVE_INFINITY; 142 } 143 144 var precision = 0; 145 if (stepRaw.indexOf('.') !== -1) { 146 precision = stepRaw.split('.')[1].length; 147 } 148 149 return { 150 min: min, 151 max: max, 152 step: step, 153 precision: precision 154 }; 155 } 156 157 function normalizeValue(value, precision) { 158 var factor = Math.pow(10, precision); 159 return Math.round(value * factor) / factor; 160 } 161 162 function formatValue(value, precision) { 163 if (precision > 0) { 164 return normalizeValue(value, precision).toFixed(precision).replace(/\.?0+$/, ''); 165 } 166 167 return String(Math.round(value)); 168 } 169 170 function refreshStepperState($quantity) { 171 var $input = $quantity.find('input.qty').first(); 172 if (!$input.length) { 173 return; 174 } 175 176 var meta = getQuantityMeta($input); 177 var current = parseNumber($input.val(), meta.min); 178 var epsilon = Math.pow(10, -(meta.precision + 2)); 179 var $minus = $quantity.find('.gpph-cart-qty-btn--minus'); 180 var $plus = $quantity.find('.gpph-cart-qty-btn--plus'); 181 182 if ($minus.length) {
183 $minus.prop('disabled', current <= (meta.min + epsilon)); 184 } 185 186 if ($plus.length) { 187 if (meta.max === Number.POSITIVE_INFINITY) { 188 $plus.prop('disabled', false); 189 } else { 190 $plus.prop('disabled', current >= (meta.max - epsilon)); 191 } 192 } 193 } 194 195 function syncQuantitySteppers() { 196 if (!$('body').hasClass('woocommerce-cart')) { 197 return; 198 } 199 200 $('.woocommerce-cart-form .quantity').each(function () { 201 var $quantity = $(this); 202 var $input = $quantity.find('input.qty').first(); 203 204 if (!$input.length) { 205 return; 206 } 207 208 if (!$quantity.find('.gpph-cart-qty-stepper').length) { 209 var $stepper = $('<div class="gpph-cart-qty-stepper" data-gpph-qty-stepper="1"></div>'); 210 var $minus = $('<button type="button" class="gpph-cart-qty-btn gpph-cart-qty-btn--minus" aria-label="Zmniejsz ilosc">-</button>'); 211 var $plus = $('<button type="button" class="gpph-cart-qty-btn gpph-cart-qty-btn--plus" aria-label="Zwieksz ilosc">+</button>'); 212 213 $input.attr('inputmode', 'numeric'); 214 215 $input.after($stepper); 216 $stepper.append($minus); 217 $stepper.append($input); 218 $stepper.append($plus); 219 } 220 221 refreshStepperState($quantity); 222 }); 223 } 224 225 function bindQuantityStepperEvents() { 226 $(document).off('click.gpphCartQty', '.gpph-cart-qty-btn'); 227 $(document).off('input.gpphCartQty change.gpphCartQty', '.woocommerce-cart-form .quantity input.qty'); 228 229 function queueCartUpdate() { 230 clearTimeout(autoUpdateTimer); 231 232 autoUpdateTimer = setTimeout(function () { 233 var form = document.querySelector('form.woocommerce-cart-form'); 234 var updateButton = form ? form.querySelector('[name="update_cart"]') : null; 235 236 if (!form || !updateButton) { 237 return; 238 } 239 240 if (updateButton.classList.contains('loading')) { 241 return; 242 } 243 244 updateButton.disabled = false; 245 updateButton.removeAttribute('disabled'); 246 247 if (typeof form.requestSubmit === 'function') { 248 form.requestSubmit(updateButton); 249 return; 250 } 251 252 if (typeof updateButton.click === 'function') { 253 updateButton.click(); 254 return; 255 } 256 257 form.submit(); 258 }, 420); 259 } 260 261 $(document).on('click.gpphCartQty', '.gpph-cart-qty-btn', function (event) { 262 event.preventDefault(); 263 264 var $button = $(this); 265 if ($button.prop('disabled')) { 266 return; 267 } 268 269 var $quantity = $button.closest('.quantity'); 270 var $input = $quantity.find('input.qty').first(); 271 if (!$input.length) { 272 return; 273 } 274 275 var meta = getQuantityMeta($input); 276 var current = parseNumber($input.val(), meta.min); 277 var direction = $button.hasClass('gpph-cart-qty-btn--plus') ? 1 : -1; 278 var next = current + (direction * meta.step); 279 280 if (next < meta.min) { 281 next = meta.min; 282 } 283 if (next > meta.max) { 284 next = meta.max; 285 } 286 287 next = normalizeValue(next, meta.precision); 288 if (next === current) { 289 refreshStepperState($quantity); 290 return; 291 } 292 293 $input.val(formatValue(next, meta.precision)).trigger('input').trigger('change'); 294 $('button[name="update_cart"], input[name="update_cart"]').prop('disabled', false).removeAttr('disabled'); 295 296 refreshStepperState($quantity); 297 }); 298 299 $(document).on('input.gpphCartQty change.gpphCartQty', '.woocommerce-cart-form .quantity input.qty', function () { 300 refreshStepperState($(this).closest('.quantity')); 301 queueCartUpdate(); 302 }); 303 } 304 305 function initCartLoader() { 306 if (!$('body').hasClass('woocommerce-cart')) { 307 return; 308 } 309 310 var $root = $('.gpph-cart-native').first(); 311 if (!$root.length || $root.data('gpphCartLoaderReady')) { 312 return; 313 } 314 315 $root.data('gpphCartLoaderReady', true); 316 317 if (!$root.find('.gpph-cart-native__loader').length) { 318 $root.append( 319 '<div class="gpph-cart-native__loader" aria-hidden="true">' + 320 '<div class="gpph-cart-native__loader-card" role="status" aria-l
320ive="polite">' + 321 '<span class="gpph-cart-native__loader-spinner" aria-hidden="true"></span>' + 322 '<span class="gpph-cart-native__loader-text">Aktualizacja koszyka...</span>' + 323 '</div>' + 324 '</div>' 325 ); 326 } 327 328 var minVisibleMs = 320; 329 var safetyMs = 15000; 330 var startedAt = 0; 331 var safetyTimer = null; 332 var hideTimer = null; 333 334 function forceOff() { 335 clearTimeout(autoUpdateTimer); 336 clearTimeout(safetyTimer); 337 clearTimeout(hideTimer); 338 $root.removeClass('gpph-cart-native--is-loading').removeAttr('aria-busy'); 339 } 340 341 function setOn() { 342 clearTimeout(hideTimer); 343 344 if ($root.hasClass('gpph-cart-native--is-loading')) { 345 return; 346 } 347 348 startedAt = Date.now(); 349 $root.addClass('gpph-cart-native--is-loading').attr('aria-busy', 'true'); 350 351 clearTimeout(safetyTimer); 352 safetyTimer = setTimeout(forceOff, safetyMs); 353 } 354 355 function setOff() { 356 if (!$root.hasClass('gpph-cart-native--is-loading')) { 357 return; 358 } 359 360 var elapsed = Date.now() - startedAt; 361 var delay = Math.max(0, minVisibleMs - elapsed); 362 363 clearTimeout(safetyTimer); 364 clearTimeout(hideTimer); 365 366 hideTimer = setTimeout(function () { 367 $root.removeClass('gpph-cart-native--is-loading').removeAttr('aria-busy'); 368 }, delay); 369 } 370 371 function isCartAjax(url) { 372 if (!url) { 373 return false; 374 } 375 376 return ( 377 url.indexOf('wc-ajax=update_shipping_method') !== -1 || 378 url.indexOf('wc-ajax=update_cart') !== -1 || 379 url.indexOf('wc-ajax=apply_coupon') !== -1 || 380 url.indexOf('wc-ajax=remove_coupon') !== -1 || 381 url.indexOf('wc-ajax=get_refreshed_fragments') !== -1 382 ); 383 } 384 385 $(document).on('change', 'input[name^="shipping_method"]', setOn); 386 $(document).on('click', 'button[name="update_cart"], button[name="apply_coupon"], a.remove', setOn); 387 $(document).on('submit', 'form.woocommerce-cart-form', setOn); 388 $(document).ajaxSend(function (_event, _jqXHR, settings) { 389 if (isCartAjax(settings && settings.url)) { 390 setOn(); 391 } 392 }); 393 394 $(document).ajaxComplete(function (_event, _jqXHR, settings) { 395 if (isCartAjax(settings && settings.url)) { 396 setOff(); 397 } 398 }); 399 400 $(document.body).on( 401 'updated_wc_div updated_cart_totals applied_coupon removed_coupon wc_fragments_refreshed wc_fragment_refresh', 402 function () { 403 clearTimeout(autoUpdateTimer); 404 setOff(); 405 } 406 ); 407 408 $(window).on('pageshow', forceOff); 409 } 410 411 function initCartInteractions() { 412 initCartLoader(); 413 bindQuantityStepperEvents(); 414 syncQuantitySteppers(); 415 bindCartLightboxEvents(); 416 } 417 418 $(initCartInteractions); 419 $(document.body).on( 420 'updated_wc_div updated_cart_totals applied_coupon removed_coupon wc_fragments_refreshed wc_fragment_refresh', 421 initCartInteractions 422 ); 423})(jQuery);
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.