1(function ($) { 2 const debounce = function (callback, wait, immediate) { 3 let timeout; 4 return function () { 5 const context = this, 6 args = arguments; 7 const later = function () { 8 timeout = null; 9 if (!immediate) callback.apply(context, args); 10 }; 11 const callNow = immediate && !timeout; 12 clearTimeout(timeout); 13 timeout = setTimeout(later, wait); 14 if (callNow) callback.apply(context, args); 15 }; 16 }; 17 18 const updateCartItem = async (input) => { 19 const url = window.BreakdanceFrontend.data.ajaxUrl; 20 const hash = input.getAttribute("name").replace(/cart\[(\w+)]\[qty]/g, "$1"); 21 const newQty = parseFloat(input.value); 22 23 const data = new FormData(); 24 data.append("action", "breakdance_cart_update_qty"); 25 data.append("hash", hash); 26 data.append("quantity", newQty); 27 28 const payload = { 29 method: "POST", 30 credentials: "same-origin", 31 body: data 32 }; 33 34 const { makeAjaxRequest } = window.BreakdanceFrontend.utils; 35 await makeAjaxRequest(url, payload); 36 37 $(document.body).trigger("wc_fragment_refresh"); 38 $(document.body).trigger("wc_update_cart"); 39 }; 40 41 const delayedUpdateCartItem = debounce((input) => { 42 updateCartItem(input); 43 blockUI(input); 44 }, 300); 45 46 const afterInputChange = (input) => { 47 // Works for Mini Cart, Single Product Page, Shop and Cart Page. 48 if (isLoopProduct(input)) { 49 getAddToCartButton(input) 50 ?.setAttribute("data-quantity", input.value); 51 } else if (isSingleProduct(input)) { 52 // Do nothing. WooCommerce automatically picks up the input. 53 } else { 54 delayedUpdateCartItem(input); 55 } 56 }; 57 58 const isIncrement = (target) => { 59 return target.matches(".bde-quantity-button--inc"); 60 }; 61 62 const isSingleProduct = (input) => { 63 return !!input.closest("form.cart"); 64 }; 65 66 const isLoopProduct = (input) => { 67 return !!input.closest("li.product"); 68 }; 69 70 const blockUI = (input) => { 71 const row = input.closest(".woocommerce-mini-cart-item"); 72 73 $(row).block({ 74 message: null, 75 overlayCSS: { 76 opacity: 0.6 77 } 78 }); 79 }; 80 81 const getAddToCartButton = (input) => { 82 return input.closest("li.product").querySelector(".add_to_cart_button"); 83 }; 84 85 const getQuantityInput = (event) => { 86 return event.target.parentElement.querySelector(".qty"); 87 }; 88 89 const onMaybeButtonClick = (event) => { 90 const isButton = event.target.matches(".bde-quantity-button"); 91 92 if (!isButton) return; 93 94 event.preventDefault(); 95 96 const input = getQuantityInput(event); 97 const action = isIncrement(event.target) ? "stepUp" : "stepDown"; 98 99 input[action](); // Increment or decrement input 100 101 // Manually trigger change event. 102 const customEvent = new Event("change", { 103 bubbles: true, 104 cancelable: true 105 }); 106 107 input.dispatchEvent(customEvent); 108 }; 109 110 const onMaybeInputChange = (event) => { 111 const isInput = event.target.matches("input.qty"); 112 113 if (!isInput) return; 114 afterInputChange(event.target); 115 } 116 117 const maybeReloadCart = () => { 118 const containsEl = document.querySelector(".bde-cart-contents"); 119 if (containsEl) location.reload(); 120 } 121 122 addEventListener("DOMContentLoaded", () => { 123 addEventListener("change", onMaybeInputChange); 124 addEventListener("click", onMaybeButtonClick); 125 $(document.body).on("wc_cart_emptied", maybeReloadCart); 126 }); 127}(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.