1jQuery(function ($) { 2 // Remove any delegated click handlers from other scripts 3 $(document).off("click", ".zap-competition-qty-plus, .zap-competition-qty-minus"); 4 5 // Inject styles for quantity buttons 6 $("<style>") 7 .text( 8 ` 9 .zap-competition-qty > .zap-competition-qty-plus, 10 .zap-competition-qty > .zap-competition-qty-minus { 11 -webkit-touch-callout: none; 12 -webkit-user-select: none; 13 user-select: none; 14 -webkit-tap-highlight-color: transparent; 15 } 16 `, 17 ) 18 .appendTo("head"); 19 20 let interval = null; 21 let timeout = null; 22 let $activeInput = null; 23 let stepDirection = 0; 24 let startTime = 0; 25 let holdTriggered = false; 26 27 function getAcceleratedStep(ms) { 28 if (ms > 3000) return 20; 29 if (ms > 2000) return 10; 30 if (ms > 1200) return 5; 31 if (ms > 600) return 2; 32 return 1; 33 } 34 35 function updateValue($input, step) { 36 const min = Number($input.attr("min")) || 0; 37 const max = Number($input.attr("max")) || Infinity; 38 const current = Number($input.val()) || 0; 39 const next = Math.max(min, Math.min(current + step, max)); 40 41 $input.val(next); 42 syncRange($input, next); 43 } 44 45 function syncRange($input, value) { 46 const $wrapper = $input.closest(".zap-competition-qty").parent(); 47 const $range = $wrapper.find('input[type="range"]'); 48 49 if ($range.length) { 50 $range.val(value).trigger("input").trigger("change"); 51 } 52 } 53 54 function onPointerDown(e) { 55 const $btn = $(e.target).closest(".zap-competition-qty-plus, .zap-competition-qty-minus"); 56 if (!$btn.length) return; 57 58 if (e.pointerType === "touch") e.preventDefault(); 59 60 const $container = $btn.closest(".zap-competition-qty"); 61 const $input = $container.find('input[type="number"]'); 62 if (!$input.length) return; 63 64 stepDirection = $btn.hasClass("zap-competition-qty-plus") ? 1 : -1; 65 $activeInput = $input; 66 startTime = Date.now(); 67 holdTriggered = false; 68 69 timeout = setTimeout(() => { 70 if ($activeInput) startHoldLoop(); 71 }, 300); 72 } 73 74 function startHoldLoop() { 75 holdTriggered = true; 76 77 interval = setInterval(() => { 78 const heldFor = Date.now() - startTime; 79 const step = getAcceleratedStep(heldFor); 80 updateValue($activeInput, stepDirection * step); 81 }, 100); 82 } 83 84 function stopPointer() { 85 clearInterval(interval); 86 clearTimeout(timeout); 87 88 interval = null; 89 timeout = null; 90 91 if ($activeInput) { 92 if (!holdTriggered) { 93 updateValue($activeInput, stepDirection); 94 } 95 96 syncRange($activeInput, $activeInput.val()); 97 } 98 99 $activeInput = null; 100 } 101 102 // Bind pointer events 103 $(document).on("pointerdown", onPointerDown).on("pointerup pointercancel pointerleave", stopPointer); 104 105 // â FIX: Only disable right-click on the buttons (not the whole container) 106 $(document).on("contextmenu", ".zap-competition-qty-plus, .zap-competition-qty-minus", function (e) { 107 e.preventDefault(); 108 }); 109});
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.