1// various functions for basket, shop informers, etc 2 3// common params 4function setCommonParams() { 5 if (self.commonParamsLoaded) return 6 if (!self.alertParams) self.alertParams = { tm:10000, align:'left', icon:'/.s/img/icon/warning.png', pad:10 }; 7 if (!self.alertWarnParams) self.alertWarnParams = { tm:8000, align:'center', icon:'/.s/img/icon/warning.png' }; 8 if (!self.alertErrorParams) self.alertErrorParams = { tm:8000, align:'center', icon:'/.s/img/icon/error.png' }; 9 if (!self.alertInfoParams) self.alertInfoParams = { tm:10000, align:'center' }; 10 self.commonParamsLoaded = true; 11} 12 13function str_repeat(i, m) { 14 for (var o = []; m > 0; o[--m] = i); 15 return o.join(''); 16} 17 18function sprintf() { 19 var i = 0, a, f = arguments[i++], o = [], m, p, c, x, s = ''; 20 while (f) { 21 if (m = /^[^\x25]+/.exec(f)) { 22 o.push(m[0]); 23 } 24 else if (m = /^\x25{2}/.exec(f)) { 25 o.push('%'); 26 } 27 else if (m = /^\x25(?:(\d+)\$)?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+)?)?([b-fosuxX])/.exec(f)) { 28 if (((a = arguments[m[1] || i++]) == null) || (a == undefined)) { 29 throw('Too few arguments.'); 30 } 31 if (/[^s]/.test(m[7]) && (typeof(a) != 'number')) { 32 throw('Expecting number but found ' + typeof(a)); 33 } 34 switch (m[7]) { 35 case 'b': a = a.toString(2); break; 36 case 'c': a = String.fromCharCode(a); break; 37 case 'd': a = parseInt(a); break; 38 case 'e': a = m[6] ? a.toExponential(m[6]) : a.toExponential(); break; 39 case 'f': a = parseFloat(a).toFixed(m[6] ? m[6] : 0); break; 40 case 'o': a = a.toString(8); break; 41 case 's': a = ((a = String(a)) && m[6] ? a.substring(0, m[6]) : a); break; 42 case 'u': a = Math.abs(a); break; 43 case 'x': a = a.toString(16); break; 44 case 'X': a = a.toString(16).toUpperCase(); break; 45 } 46 a = (/[def]/.test(m[7]) && m[2] && a >= 0 ? '+'+ a : a); 47 c = m[3] ? m[3] == '0' ? '0' : m[3].charAt(1) : ' '; 48 x = m[5] - String(a).length - s.length; 49 p = m[5] ? str_repeat(c, x) : ''; 50 o.push(s + (m[4] ? a + p : p + a)); 51 } 52 else { 53 throw('Huh ?!'); 54 } 55 f = f.substring(m[0].length); 56 } 57 return o.join(''); 58} 59 60function price_to_format(price, separator, decpoint){ 61 rr = /(\d*)\.?(\d*)/.exec(price); 62 if(typeof(rr[1]) != 'undefined'){ 63 b = rr[1].replace(/(\d{1,3}(?=(\d{3})+(?:\.\d|\b)))/g, "\$1"+separator); 64 } 65 return (rr[2] ? b + decpoint + rr[2] : b); 66} 67 68function getCookie(c_name){ 69 var i,x,y,ARRcookies=document.cookie.split(";"); 70 for (i=0;i<ARRcookies.length;i++){ 71 x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("=")); 72 y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1); 73 x=x.replace(/^\s+|\s+$/g,""); 74 if (x==c_name){ 75 return unescape(y); 76 } 77 } 78} 79 80function formatPrice(price, currObj){ 81 var data = price*currObj.rate; 82 var znak = ''; 83 if(data<0){ 84 data*=-1; 85 znak = '-'; 86 } 87 88 data = price_to_format(sprintf(uCoz.shop_price_f[0], data), uCoz.shop_price_separator, (uCoz.shop_price_f[1] != '' ? uCoz.shop_price_f[1] : '.')); 89
90 return currObj.dpos ? znak+""+currObj.disp+""+data : znak+""+data+""+currObj.disp; 91} 92 93function optChangePrice(obj, event){ 94 var obj_id = $(obj).attr('id').split('-'); 95 var id = obj_id[1]; 96 97 if( uCoz==undefined || uCoz.sh_goods[id] == undefined ){ return; } 98 99 var pref = obj_id[0]; 100 if(obj.nodeName=='INPUT'){ 101 pref = pref.replace(/^q/, ''); 102 } 103 104 var pos = undefined; 105 var over = 0; 106 var old_sum = 0; 107 $.each($("[id^="+pref+"-"+id+"-oval-]"), function(){ 108 var o_val = '0'; 109 110 if(this.tagName == 'INPUT' && this.checked){ 111 var opt_over = $(this).attr('class').match(/(-?\d+(?:\.\d+)?)/); 112 if( opt_over && opt_over[1] ){ 113 over += parseFloat(opt_over[1]); 114 } 115 o_val = ( $(this).attr('data-o-val') || '0' ); 116 } 117 118 if(this.tagName == 'SELECT'){ 119 var opt_over = $(this).children(":selected").attr('class').match(/(-?\d+(?:\.\d+)?)/); 120 if( opt_over && opt_over[1] ){ 121 over += parseFloat(opt_over[1]); 122 } 123 o_val = ( $(this).children(":selected").attr('data-o-val') || '0' ); 124 } 125 126 if( o_val.search('%') != -1 ){ 127 o_val = uCoz.sh_goods[id].old_price * parseFloat(o_val) / 100; 128 } 129 130 old_sum += parseFloat(o_val); 131 var match = $(this).attr('class').match(/pos(\d+)/); 132 if(match && (parseInt(match[1])<pos || pos == undefined)) pos = parseInt(match[1]); 133 }); 134 135 if($(obj).hasClass("pos"+pos) && uCoz.sh_goods[id].imgs != undefined && uCoz.sh_goods[id].imgs.length>1 && uCoz.sh_goods[id].imgs[obj.options.selectedIndex] != undefined){ 136 // var selector = pref != 'id' ? 'ipreview' : pref+'-gphoto-'+id; 137 var selector = pref+'-gphoto-'+id; 138 if(pref == 'id' && $('img#ipreview').length) selector='ipreview'; 139 $('img#'+selector).attr('src', uCoz.sh_goods[id].imgs[obj.options.selectedIndex]).attr('idx', obj.options.selectedIndex); 140 } 141 142 var cnt = $('#q'+pref+'-'+id+'-basket').val(); 143 if(cnt=='' || cnt==undefined) cnt=1; 144 var curr = getCookie(uCoz.mf+'uShopCu') ? getCookie(uCoz.mf+'uShopCu') : uCoz.sh_curr_def; 145 var price = formatPrice((over + parseFloat(uCoz.sh_goods[id].price)) * cnt, uCoz.sh_curr[curr]); 146 $("."+pref+"-good-"+id+"-price").html(price); 147 148 if(uCoz.sh_goods[id].old_price != '0.00'){ 149 $("."+pref+"-good-"+id+"-oldprice").html(formatPrice((old_sum + parseFloat(uCoz.sh_goods[id].old_price)) * cnt, uCoz.sh_curr[curr])); 150 } 151} 152 153function checkNumber(obj, event, changePrice) { 154 var err_msg = ''; 155 var obj_id = $(obj).attr('id').split('-'); 156 var pref = obj_id[0].replace(/^q/, ''); 157 var id = obj_id[1]; 158 159 $('#'+pref+'-'+id+'-options-selectors').find('input:checked, select').each(function(){ 160 if($(this).val() === ''){ 161 err_msg += '<li>'+$(this).parent().parent().find('span.opt').html().replace(':', '')+'</li>'; 162 } 163 }); 164 165 if(err_msg !== ''){ 166 err_msg = checkNumber_err.replace('%err_msg%', err_msg); 167 shop_alert('<div class="MyWinError">'+err_msg+'<div>', checkNumber_header, 'warning', 350, 100, {tm:8000, align:'left', icon:'/.s/img/icon/warning.png'}); 168 }else{ 169 if(/[^0-9\.\,\%\-]/.test(obj.value) == false){ 170 if(parseInt(changePrice)) setTimeout(function(){optChangePrice(obj)}, 100); 171 return true; 172 } 173 } 174 175 return false 176} 177 178 179function subscribeNotifyStock(id, opt_sel, var_sel){ 180 if( lock_buttons ) return false; 181 return new _uWnd('confirm_subscribe_stock', 182 ' ', 183 500, 308, 184 { 185 align: 'left', 186 modal: 0, 187 closeonesc: 0, 188 nomove: 1, 189 autosize: 1, 190 resize: 0, 191 192 }, 193 { type: 'POST', url: '/shop/subscribe_notify_stock', data: {ssid: uCoz.ssid, id: id, opt_sel: opt_sel, var_sel: var_sel} } 194 ); 195} 196 197 198function subscribeNotifyStockConf(id){ 199 _uPostForm('subscribe_stock_'+id, {type:'POST', url:'/shop/subscribe_notify_stock'}); 200 _uWnd.close('shop_opt_form'); 201} 202 203function invoiceCancel(order_hash, tg_shop) { 204 _uPostForm('', 205 { type:'POST', 206 url:'/shop/order/'+order_hash, 207 data:{ 208 'mode':'invoice_cancel', 209 'ssid':uCoz.ssid, 210 'tg_shop': tg_shop 211 } 212 } 213 ); 214 return false; 215} 216 217function wishlist(obj) { 218 if( lock_buttons ) return false; 219 lock_buttons = 1; 220 var tmp = obj.id.split('-'); 221 var pref = tmp[0]; 222 var id = tmp[1]; 223 $(obj).removeClass().addClass('wish').addClass('wait'); 224 _uPostForm('', { 225 type:"POST", 226 url:"/shop/wishlisth", 227 data:{ 228 "goods_id":id, 229 "pref":pref 230 } 231 }); 232 return false;
233} 234 235function clearWishlist(){ 236 if( lock_buttons ) return false; 237 238 lock_buttons = 1; 239 $.ajax({ 240 url: "/shop/wishlisth", 241 type: "POST", 242 async: true, 243 data: { 244 "clear": 1, 245 } 246 }).always(function( data ) { 247 document.location.href='/shop'; 248 }); 249 250 return false; 251} 252 253function shopChangeGoodsOpt(url, pref, goods_id, obj) { 254 var wrapObj; 255 if(pref == 'id'){ 256 wrapObj = $('#id-'+goods_id+'-options-selectors').parents('div.list-item').length ? 257 $('#id-'+goods_id+'-options-selectors').parents('div.list-item') : 258 $('#id-'+goods_id+'-options-selectors').parents('table:eq(1)'); 259 }else if((pref == 'last_view') || (pref == 'top_view') || (pref == 'last_add')){ 260 wrapObj = $('#'+pref+'-'+goods_id+'-options-selectors').parents('table:first'); 261 }else if(pref.search('inf') == 0){ 262 wrapObj = $('#'+pref+'-'+goods_id+'-options-selectors').parents('div.goods-list'); 263 }else { 264 try{ 265 wrapObj = uCoz.shop_goods_wrappers(pref, goods_id); 266 }catch(e){ 267 } 268 } 269 270 _shopFadeControl(pref+'-'+goods_id+'-options-selectors', 1, wrapObj); 271 var opt = new Array(); 272 var opt_id = $(obj).attr('id').split('-')[3]; 273 $('#'+pref+'-'+goods_id+'-options-selectors').find('input:checked, select').each(function(){ 274 if(this.value !== ''){ 275 opt.push(this.id.split('-')[3]+(parseInt(this.value) ? '-'+this.value :'')); 276 } 277 }); 278 279 // get productVariations 280 const variationsStr = getVariationsStr(goods_id, pref); 281 282 _uPostForm('', { 283 url:url, 284 data:{ 285 mode:'opt-sel', 286 pref:pref, 287 opt:opt.join(':'), 288 opt_id:opt_id, 289 cnt:( $('#q'+pref+'-'+goods_id+'-basket').val() || 1 ), 290 ...(variationsStr && {variations:variationsStr}), 291 }, 292 type:'POST'} 293 ); 294} 295 296function _shopFadeControl(id, pos, obj){ 297 var el = (typeof(obj) == 'object') ? obj : $('#'+id); 298 var top = 0; 299 var left = 0; 300 if(pos && el.length){ 301 top = el.position().top; 302 left = el.position().left; 303 } 304 if(el.length){ 305 var g=document.createElement("div"); 306 var height = $(el).height(); 307 var scrollHeight = $(el)[0].scrollHeight; 308 if(height < scrollHeight){ 309 height = scrollHeight; 310 } 311 $(g).addClass('myWinGrid').addClass('shop-fade').attr("id",id+'-fade').css({"left":left,"top":top,"position":"absolute","border":"#CCCCCC 1px solid","width":$(el).width()+'px',"height":height+'px',"z-index":11}).hide().on('mousedown', function(e){e.stopPropagation();e.preventDefault();_uWnd.globalmousedown();}).html('<div class="myWinLoad" style="margin:5px;"></div>'); 312 $(el).append(g); 313 $(g).show(); 314 } 315} 316 317function ga_event(event_name) { 318 var events = { 319 basket_add : '/shop/basket/add_ushop_', 320 basket_buynow : '/shop/basket/quick_ushop_', 321 basket_clear : '/shop/basket/clear_ushop_', 322 checkout_done : '/shop/checkout/done_ushop_', 323 checkout : '/shop/checkout_ushop_', 324 shop_autoreg : '/shop/user/autoreg_ushop_' 325 }; 326 327 if (window._gaq !== undefined) _gaq.push([ '_trackPageview', events[ event_name ] ]) 328} 329 330/** 331 * Apply option images on [product page]/[Item appearance in the catalog] 332 * @param prefix - block prefix 333 * @param productId - product id 334 * @param {Array.<Object>} imageList - option value images. 335 * @param {string} imageList[].origin - link for image original. 336 * @param {string} imageList[].big - link for image big. 337 * @param {string} imageList[].middle - link for image thumbnail. 338 * @param {string} imageList[].small - link for image icon. 339 */ 340function applyOptionImagesToPage(prefix, productId, imageList = []) { 341 if (!imageList.length || !prefix || !productId) { 342 return console.warn('Insufficient arguments. Please provide all required arguments.'); 343 } 344 345 const containerEl = document.querySelector('.shop-itempage-images'); 346 const isProductPage = prefix === 'id' && containerEl; 347 const mainImageEl = isProductPage ? containerEl.querySelector('#ipreview') : document.querySelector(`#${prefix}-gphoto-${productId}`); 348 349 const setOptionImagesList = (list) => { 350 window.uCoz ??= {}; 351 window.uCoz.sh_goods ??= {}; 352 window.uCoz.sh_goods[productId] = { 353 ...window.uCoz.sh_goods[productId], 354 optionImagesList: list.map(({origin}) => [origin]), 355 }; 356 }; 357 358 const setMainImage = () => { 359 const {middle} = imageList[0]; 360 361 if (isProductPage) { 362 setOptionImagesList(imageList); 363 364 mainImageEl.setAttribute('idx', '0'); 365 mainImageEl.setAttribute('src', middle); 366 mainImageEl.removeAttribute('onClick'); 367 368 if (!window.uCoz.sh_goods[productId].isPreviewListenerSet) { 369 window.uCoz.sh_goods[productId].isPreviewListenerSet = true; 370 mainImageEl.addEventListener('click', function () { 371 _bldCont1(productId, this.getAttribute('idx'), window.uCoz.sh_goods[productId].optionImagesList); 372 }); 373 } 374 } else { // else is "Item appearance in the catalog" 375 mainImageEl.setAttribute('idx', '0'); 376 mainImageEl.setAttribute('src', middle); 377 } 378 }; 379 380 const setSmallImages = () => { 381 containerEl.querySelectorAll('img:not(#ipreview)').forEach(img => img.remove()); 382 383 const smallsTemplate = new DocumentFragment(); 384 385 imageList.map(({small, middle}, index) => { 386 const imgEl = document.createElement('img'); 387 const space = document.createTextNode(' '); 388 389 imgEl.classList.add('gphoto'); 390 imgEl.src = small; 391 imgEl.addEventListener('click', () => { 392 if (index === +mainImageEl.getAttribute('idx')) return; 393 394 mainImageEl.src = middle; 395 mainImageEl.setAttribute('idx', `${index}`); 396 }); 397 398 smallsTemplate.appendChild(imgEl); 399 smallsTemplate.appendChild(space); 400 }); 401 402 containerEl.appendChild(smallsTemplate); 403 }; 404 405 mainImageEl && setMainImage(); 406 isProductPage && containerEl && setSmallImages(); 407} 408 409 410/** 411 * Gets all selected variation values and returns them as a string separated by a delimiter. 412 * 413 * @param {string} productId - The product ID to identify the variation elements. 414 * @param {string} prefix - The prefix used in the CSS classes for the variation elements. 415 * @returns {string} A string of selected variation values separated by the "|". Returns an empty string if no values are found or an error occurs. 416 */ 417function getVariationsStr(productId, prefix) { 418 if (!productId || !prefix) { 419 console.error("Invalid product: Id or prefix."); 420 return ''; 421 } 422 423 try { 424 const selectedElements = document.querySelectorAll(`.js-uv-block-${productId}-${prefix} input:checked`); 425 426 if (!selectedElements.length) {
427 console.warn("No selected variations found."); 428 return ''; 429 } 430 431 const values = [...selectedElements].map(({dataset: {vVal}}) => vVal || ''); 432 return values.filter(Boolean).join('|'); 433 434 } catch (error) { 435 console.error("Error in getSelectedVariationsString:", error); 436 return ''; 437 } 438} 439 440/** 441 * Changes the product variation based on the given prefix and product ID. 442 * 443 * @param {string} prefix - The prefix to be used for the product variation. 444 * @param {number|string} productId - The ID of the product whose variation is to be changed. 445 */ 446function changeVariation(prefix, productId) { 447 if (_shopLockButtons()) return; 448 449 document.body.classList.add('uv-reloading'); 450 451 const sel = getVariationsStr(productId, prefix); 452 const cnt = document.getElementById(`q${prefix}-${productId}-basket`)?.value; 453 454 _uPostForm('', { 455 url: '/shop/variations', 456 type: 'POST', 457 data: { 458 id: productId, 459 pref: prefix, 460 sel: sel, 461 cnt: isNaN(cnt) ? 1 : cnt, 462 } 463 }); 464} 465 466window.applyVariationToPage = changeVariation; 467 468 469// run some 470setCommonParams()
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.