1/* 2You can use this file with your scripts. 3It will not be overwritten when you upgrade solution. 4*/ 5 6(function () { 7 var HOVER_DELAY = 450; 8 var REQUEST_INTERVAL = 850; 9 var MAX_ACTIVE_REQUESTS = 1; 10 var BACKOFF_TIME = 8000; 11 12 var queue = []; 13 var activeRequests = 0; 14 var queueTimer = null; 15 var lastRequestStarted = 0; 16 var backoffUntil = 0; 17 var responseCache = {}; 18 19 function closestLazyCard(target) { 20 return target && target.closest ? target.closest('.catalog-block__wrapper[data-lazy-sku="Y"], .catalog-list__wrapper[data-lazy-sku="Y"]') : null; 21 } 22 23 function getTemplatePath() { 24 return window.arAsproOptions && window.arAsproOptions.SITE_TEMPLATE_PATH 25 ? window.arAsproOptions.SITE_TEMPLATE_PATH 26 : '/bitrix/templates/aspro-premier'; 27 } 28 29 function getCacheKey(card) { 30 return [ 31 card.dataset.lazySkuProductId || '', 32 card.dataset.lazySkuIblockId || '', 33 card.dataset.lazySkuSelectedOfferId || '', 34 card.dataset.lazySkuTreeProps || '', 35 card.dataset.lazySkuPriceCode || '', 36 card.dataset.lazySkuUseRegion || 'N', 37 card.dataset.lazySkuCurrencyId || 'RUB' 38 ].join('|'); 39 } 40 41 function buildRequestData(card) { 42 var data = new URLSearchParams(); 43 data.append('product_id', card.dataset.lazySkuProductId || ''); 44 data.append('iblock_id', card.dataset.lazySkuIblockId || ''); 45 data.append('selected_offer_id', card.dataset.lazySkuSelectedOfferId || ''); 46 data.append('sku_tree_props', card.dataset.lazySkuTreeProps || ''); 47 data.append('price_code', card.dataset.lazySkuPriceCode || ''); 48 data.append('show_gallery', card.dataset.lazySkuShowGallery || 'N'); 49 data.append('add_pict_prop', card.dataset.lazySkuAddPictProp || ''); 50 data.append('show_one_click_buy', card.dataset.lazySkuOneClickBuy || 'N'); 51 data.append('use_region', card.dataset.lazySkuUseRegion || 'N'); 52 data.append('display_compare', card.dataset.lazySkuDisplayCompare || 'N'); 53 data.append('show_favorite', card.dataset.lazySkuShowFavorite || 'N'); 54 data.append('use_price_count', card.dataset.lazySkuUsePriceCount || 'N'); 55 data.append('show_price_count', card.dataset.lazySkuShowPriceCount || '1'); 56 data.append('price_vat_include', card.dataset.lazySkuPriceVatInclude || 'Y'); 57 data.append('convert_currency', card.dataset.lazySkuConvertCurrency || 'Y'); 58 data.append('currency_id', card.dataset.lazySkuCurrencyId || 'RUB'); 59 return data; 60 } 61 62 function applyLazySkuHtml(card, html) { 63 var target = card.querySelector('.js-lazy-sku-container'); 64 if (!target || !html) { 65 return; 66 } 67 68 target.innerHTML = html; 69 card.dataset.lazySkuLoaded = 'Y'; 70 card.dataset.lazySkuLoading = 'N'; 71 card.dataset.lazySkuQueued = 'N'; 72 73 if (window.BX) { 74 window.BX.onCustomEvent('onAsproLazySkuLoaded', [{wrapper: card}]); 75 } 76 } 77 78 function loadLazySku(card) { 79 if (!card || card.dataset.lazySkuLoaded === 'Y') { 80 return Promise.resolve(); 81 } 82 83 var target = card.querySelector('.js-lazy-sku-container'); 84 if (!target) { 85 return Promise.resolve(); 86 } 87 88 var cacheKey = getCacheKey(card); 89 if (responseCache[cacheKey]) { 90 applyLazySkuHtml(card, responseCache[cacheKey]); 91 return Promise.resolve(); 92 } 93 94 card.dataset.lazySkuLoading = 'Y'; 95 96 return fetch(getTemplatePath() + '/ajax/lazy_sku_offers.php', { 97 method: 'POST', 98 credentials: 'same-origin', 99 headers: { 100 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 101 'X-Requested-With': 'XMLHttpRequest' 102 }, 103 body: buildRequestData(card).toString() 104 }) 105 .then(function (response) { 106 if (response.status === 429 || response.status === 503) { 107 backoffUntil = Date.now() + BACKOFF_TIME; 108 } 109 110 if (!response.ok) { 111 throw new Error('Lazy SKU request failed: ' + response.status); 112 } 113 114 return response.json(); 115 }) 116 .then(function (response) { 117 if (!response || !response.success || !response.html) { 118 throw new Error(response && response.error ? response.error : 'Empty lazy SKU response'); 119 } 120
121 responseCache[cacheKey] = response.html; 122 applyLazySkuHtml(card, response.html); 123 }) 124 .catch(function (error) { 125 card.dataset.lazySkuLoading = 'N'; 126 card.dataset.lazySkuQueued = 'N'; 127 128 if (window.console) { 129 console.warn('Lazy SKU load failed', error); 130 } 131 }); 132 } 133 134 function enqueueLazySku(card) { 135 if (!card || card.dataset.lazySkuLoaded === 'Y' || card.dataset.lazySkuLoading === 'Y' || card.dataset.lazySkuQueued === 'Y') { 136 return; 137 } 138 139 card.dataset.lazySkuCancelled = 'N'; 140 card.dataset.lazySkuQueued = 'Y'; 141 queue.push(card); 142 processQueue(); 143 } 144 145 function processQueue() { 146 if (queueTimer || activeRequests >= MAX_ACTIVE_REQUESTS) { 147 return; 148 } 149 150 var now = Date.now(); 151 var wait = Math.max(backoffUntil - now, REQUEST_INTERVAL - (now - lastRequestStarted), 0); 152 if (wait > 0) { 153 queueTimer = setTimeout(function () { 154 queueTimer = null; 155 processQueue(); 156 }, wait); 157 return; 158 } 159 160 var card = queue.shift(); 161 while (card && (card.dataset.lazySkuLoaded === 'Y' || card.dataset.lazySkuCancelled === 'Y')) { 162 card.dataset.lazySkuQueued = 'N'; 163 card = queue.shift(); 164 } 165 166 if (!card) { 167 return; 168 } 169 170 card.dataset.lazySkuQueued = 'N'; 171 activeRequests += 1; 172 lastRequestStarted = Date.now(); 173 174 loadLazySku(card).then(function () { 175 activeRequests -= 1; 176 processQueue(); 177 }); 178 } 179 180 function scheduleLazySku(card, delay) { 181 if (!card || card.dataset.lazySkuLoaded === 'Y' || card.dataset.lazySkuLoading === 'Y') { 182 return; 183 } 184 185 if (card.lazySkuTimer) { 186 clearTimeout(card.lazySkuTimer); 187 } 188 189 card.dataset.lazySkuCancelled = 'N'; 190 card.lazySkuTimer = setTimeout(function () { 191 card.lazySkuTimer = null; 192 enqueueLazySku(card); 193 }, delay); 194 } 195 196 function cancelScheduledLazySku(card) { 197 if (!card || card.dataset.lazySkuLoaded === 'Y' || card.dataset.lazySkuLoading === 'Y') { 198 return; 199 } 200 201 card.dataset.lazySkuCancelled = 'Y'; 202 if (card.lazySkuTimer) { 203 clearTimeout(card.lazySkuTimer); 204 card.lazySkuTimer = null; 205 } 206 } 207 208 document.addEventListener('mouseover', function (event) { 209 var card = closestLazyCard(event.target); 210 if (!card || (event.relatedTarget && card.contains(event.relatedTarget))) { 211 return; 212 } 213 214 scheduleLazySku(card, HOVER_DELAY); 215 }); 216 217 document.addEventListener('mouseout', function (event) { 218 var card = closestLazyCard(event.target); 219 if (!card || (event.relatedTarget && card.contains(event.relatedTarget))) { 220 return; 221 } 222 223 cancelScheduledLazySku(card); 224 }); 225 226 document.addEventListener('focusin', function (event) { 227 scheduleLazySku(closestLazyCard(event.target), 0); 228 }); 229 230 document.addEventListener('touchstart', function (event) { 231 scheduleLazySku(closestLazyCard(event.target), 0); 232 }, {passive: true}); 233})();
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.