1if (getVar('ps') && Number(getVar('ps')) > 1 && DYNAMIC_LOADING_SHOW_BUTTON == 1) { 2 if (history.scrollRestoration) history.scrollRestoration = 'manual'; 3} 4 5window.pushstateloaded = false; 6 7function paginationPushState(key, title, url) { 8 window.pushstateloaded = true; 9 if (window.history && window.history.pushState) window.history.replaceState(key, title, url); 10} 11 12function ProductLoader(opt) { 13 let downLoaded = true; 14 let upLoaded = true; 15 let scrollY; 16 17 const defaults = { 18 pageNo: '', 19 //baseUrl: '.BASE_URL:last', 20 equalParent: '#katalog', 21 parentDiv: '.catalogWrapper', 22 productDiv: '.productItem', 23 loadMoreButton: '.LoadMoreButton', 24 heightEqualDiv: '.productItem:first', 25 loadMoreStatus: true, 26 scrollLoadStatus: true, 27 loadingStatus: false, 28 up: false, 29 }; 30 31 const options = { ...defaults, ...opt }; 32 options.parentDiv = options.equalParent + ' ' + options.parentDiv; 33 options.pageNo = Number(getVar('ps') || 1); 34 35 const addClassProduct = async function(products) { 36 products[0].dataset.page = options.pageNo; 37 products[products.length - 1].dataset.page = options.pageNo; 38 39 Array.from(products).forEach((product, index) => { 40 product.dataset.index = `${options.pageNo}-${index}`; 41 product.classList.remove('ease'); 42 product.addEventListener('click', e => { 43 let setProduct = { 44 category: window.location.pathname, 45 product: product.dataset.index, 46 }; 47 if (setProduct.product) setCookie('productIndex', JSON.stringify(setProduct)); 48 }); 49 }); 50 }; 51 52 const appendProduct = async function(result, prepend = false) { 53 const domParser = new DOMParser(); 54 const resultElm = domParser.parseFromString(result, "text/html"); 55 const products = resultElm.documentElement.querySelectorAll(options.productDiv); 56 57 if (products.length == 0) return; 58 59 for(let i=0; i<products.length; i++) { 60 if (prepend == false) { 61 document.querySelector(options.parentDiv).append(products[i]); 62 } else { 63 document.querySelector(options.parentDiv).prepend(products[(products.length - 1) - i]); 64 } 65 } 66 67 if (prepend != false) { 68 scrollY = products[products.length - 1].offsetTop + products[products.length - 1].offsetHeight; 69 window.scrollTo(0, scrollY); 70 window.onscroll = function() { window.scrollTo(0, scrollY); }; 71 } 72 73 $(options.equalParent).equalizer(); 74 $(document).ready(function() { 75 FavouriteApi.setButtons(); 76 }); 77 78 if (typeof loaderCallback == 'function' && loaderCallback != 'undefined') { 79 loaderCallback(products); 80 } 81 82 for(let i=0; i < TSOFT_APPS.product.dynamicLoader.length; i++){ 83 if(typeof TSOFT_APPS.product.dynamicLoader[i] === 'function'){ 84 try { 85 const regex = /PRODUCT_DATA\.push\(JSON\.parse\('([^']+)'\)\);/g; 86 const matches = []; 87 88 for (const match of result.matchAll(regex)) { 89 let jsonData = eval("'" + match[1] + "'"); 90 matches.push(JSON.parse(jsonData)); 91 } 92 TSOFT_APPS.product.dynamicLoader[i]?.(matches); 93 } catch (error) { console.log('Product dynamicLoader Callback Error =>' + error); } 94 } 95 } 96 97 addClassProduct(products); 98 99 window.onscroll = null; 100 101 setTimeout(() => { 102 prepend == false ? downLoaded = true : upLoaded = true; 103 }, 300); 104 }; 105 106 const getProduct = async function(page, prepend = false) { 107 options.pageNo = prepend == false ? Number(page) + 1 : Number(page) - 1; 108 if (options.pageNo < 1) return; 109 110 const products = document.querySelectorAll(`${options.parentDiv} ${options.productDiv}[data-page="${options.pageNo}"]`); 111 if (products.length > 0) return; 112 113 document.body.classList.add('is-loading-products'); 114 prepend == false ? downLoaded = false : upLoaded = false;
115 116 let params = getLink('link', window.location.pathname.replaceAll(/^\//ig, '')); 117 params = getLink('ps', '', params); 118 params = getLink('pg', options.pageNo, params); 119 params = params.replaceAll(/^[^?]*\//g, ''); 120 params = params.replace('?', '&'); 121 122 await $.ajax({ 123 url: '/srv/service/product/loader?' + params, 124 success: async function (result) { 125 if (result) await appendProduct(result, prepend); 126 } 127 }); 128 129 document.body.classList.remove('is-loading-products'); 130 }; 131 132 let lastScrollTop = 0; 133 const runScroll = async function() { 134 const { clientHeight } = document.documentElement, 135 pageProducts = document.querySelectorAll(`${options.parentDiv} ${options.productDiv}[data-page]`); 136 if (pageProducts.length == 0) return; 137 138 pageProducts.forEach(async (product) => { 139 const productRect = product.getBoundingClientRect(); 140 const productGap = productRect.height > window.innerHeight ? productRect.height / 2 : 0; 141 if (productRect.top >= 0 && (productRect.bottom - productGap <= window.innerHeight) && getVar('ps') != product.dataset.page) { 142 if (product.dataset.page == 1) { 143 paginationPushState('pagination', `Page ${product.dataset.page}`, getLink('ps', '')); 144 } else { 145 paginationPushState('pagination', `Page ${product.dataset.page}`, getLink('ps', product.dataset.page)); 146 } 147 } 148 }); 149 150 const products = document.querySelectorAll(`${options.parentDiv} ${options.productDiv}[data-page="${getVar('ps') || 1}"]`), 151 firstProduct = products[0].getBoundingClientRect(), 152 lastProduct = products[1] ? products[1].getBoundingClientRect() : products[0].getBoundingClientRect(); 153 154 let currentScrollTop = window.scrollY || document.documentElement.scrollTop; 155 if (currentScrollTop > lastScrollTop) { 156 if (((lastProduct.height / 2) + lastProduct.top) < clientHeight && downLoaded == true) getProduct(getVar('ps') || 1); 157 } else if (currentScrollTop < lastScrollTop) { 158 if (firstProduct.top > 0 && (firstProduct.bottom / 2) < clientHeight && options.up == true && upLoaded == true) getProduct(getVar('ps') || 1, true); 159 } 160 lastScrollTop = currentScrollTop; 161 }; 162 163 $(window).load(function() { 164 window.addEventListener('scroll', runScroll); 165 document.body.addEventListener('touchend', runScroll, false); 166 167 if (getVar('ps') && Number(getVar('ps')) > 1 && DYNAMIC_LOADING_SHOW_BUTTON == 1) { 168 if (history.scrollRestoration) history.scrollRestoration = 'manual'; 169 170 const getProductIdCookie = getCookie('productIndex'); 171 setCookie('productIndex', ''); 172 if (getProductIdCookie) { 173 const getProductId = JSON.parse(getProductIdCookie); 174 if (getProductId?.category == window.location.pathname && getProductId?.product) { 175 const product = document.querySelector(`${options.parentDiv} ${options.productDiv}[data-index="${getProductId.product}"]`); 176 const otherProduct = document.querySelector(`${options.parentDiv} ${options.productDiv}`); 177 178 let scrollY = 0; 179 if (product) { 180 scrollY = product.offsetTop - 100; 181 } else if (otherProduct) { 182 scrollY = otherProduct.offsetTop - 100; 183 } 184 185 window.scrollTo(0, scrollY); 186 } 187 } 188 } 189 }); 190 191 this.run = function() { 192 const products = document.querySelectorAll(`${options.parentDiv} ${options.productDiv}`); 193 if (products.length > 0) addClassProduct(products); 194 } 195 196 if (getVar('ps') && Number(getVar('ps')) > 1 && DYNAMIC_LOADING_SHOW_BUTTON == 1) { 197 const loadBtn = document.createElement('div'); 198 loadBtn.className = 'col col-12 mb product-loader-btn'; 199 loadBtn.style = 'display: flex; justify-content: center'; 200 loadBtn.innerHTML = `<button id="product-loader-btn" class="btn btn-warning">
200${LANG.get('show_more_products')}</button>`; 201 document.querySelector(options.parentDiv).before(loadBtn); 202 loadBtn.querySelector('#product-loader-btn').addEventListener('click', () => { 203 loadBtn.remove(); 204 options.up = true; 205 getProduct(getVar('ps'), true); 206 }); 207 } 208};
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.