1let isServiceListExpanded = false; 2let isMenuExpanded = false; 3const hiddenServices = document.getElementsByClassName('cs-header__serviceHidden'); 4const hiddenServicesToggler = document.getElementsByClassName('cs-header__servicesToggleInner')[0]; 5const servicesContainer = document.getElementsByClassName('cs-header__services')[0]; 6const serviceContainerHeight = 205; 7const serviceWrapperHeight = 47; 8 9const menuToggler = document.getElementsByClassName('cs-header__menuIconWrapper'); 10const menuMobileContent = document.getElementsByClassName('cs-header__content'); 11 12const serviceUserArea = document.getElementsByClassName('cs-header__serviceUserArea')[0]; 13 14const searchEndpoint = window.location.origin + '/wp-json/cs-rest-api/v1/header'; 15 16if(document.getElementsByClassName('cs-header__servicesToggle')[0]){ 17 document.getElementsByClassName('cs-header__servicesToggle')[0].addEventListener("click", function(){ 18 if(isServiceListExpanded){ 19 hiddenServicesToggler.style.transform = 'rotate(135deg)'; 20 hiddenServicesToggler.style.bottom = 'unset'; 21 hiddenServicesToggler.style.transition = '0.5s ease-in-out'; 22 servicesContainer.style.height = '205px'; 23 servicesContainer.style.transition = '0.5s ease-in-out'; 24 isServiceListExpanded = false; 25 } else { 26 hiddenServicesToggler.style.transform = 'rotate(-45deg)'; 27 hiddenServicesToggler.style.bottom = '5px'; 28 hiddenServicesToggler.style.transition = '0.5s ease-in-out'; 29 isServiceListExpanded = true; 30 servicesContainer.style.height = (serviceContainerHeight + (Math.ceil(hiddenServices.length/2) * serviceWrapperHeight )) + 'px'; 31 servicesContainer.style.transition = '0.5s ease-in-out'; 32 } 33 }); 34} 35 36 37menuToggler[0].addEventListener("click", function (){ 38 menuMobileContent[0].classList.add('cs-header__contentActive'); 39}); 40 41document.getElementsByClassName('cs-header__closeIcon')[0].addEventListener("click", function (){ 42 menuMobileContent[0].classList.remove('cs-header__contentActive'); 43}); 44 45 46//debounce implementation 47let timerId; 48 49//search service implementation 50 51function getResultElementsHTML(resultElements){ 52 let resultElementsHTML = ''; 53 const apiPath = "https://api.comprasocial.me/"; 54 resultElements.forEach(resultElement => { 55 resultElementsHTML += `<a href="${resultElement.service.pageUrl}" class="cs-header__searchResultElement"> 56 <span class="cs-header__searchResultElementIcons"> 57 <img class="cs-header__searchResultElementIcon" src="${apiPath}${resultElement.service.category.icon.path}"> 58 <img class="cs-header__searchResultElementIcon" src="${apiPath}${resultElement.service.imagePath.path}"> 59 </span> 60 <span class="cs-header__searchResultElementTitle">${resultElement.service.displayName}</span> 61 </a>`; 62 }) 63 return resultElementsHTML; 64} 65 66function animateResultElements(){ 67 const results = document.getElementsByClassName('cs-header__searchResultElement'); 68 let time = 0 69 for(let result of results) { 70 setTimeout(() => { 71 result.style.opacity = '1'; 72 result.style.transition = 'opacity 0.25s ease-in-out'; 73 },time); 74 time += 250 75 } 76} 77const searchBoxDom = document.getElementsByClassName('cs-header__searchInput')[0]; 78const searchBoxContainerDom = document.getElementsByClassName('cs-header__search')[0]; 79const cancelSearchButtonDom = document.getElementsByClassName('cs-header__searchCancelButton')[0]; 80const contentMobileHeaderDom = document.getElementsByClassName('cs-header__contentMobileHeader')[0]; 81 82function generateHTMLForServicesMenu(servicesMenu){ 83 finalHTML = ''; 84 servicesMenu.forEach((service, index) => { 85 if(index < 8){ 86 finalHTML += generateHTMLForService(service); 87 } else { 88 finalHTML += generateHTMLForService(service, true); 89 } 90 }); 91 finalHTML += "</div>"; 92 return finalHTML; 93} 94 95function generateHTMLForService(service, isHidden = false){ 96 if(isHidden){ 97 return `<a href="${service.url}" class="cs-header__service cs-header__serviceHidden"> 98 <img class="cs-header__serviceIcon" src="https://api.comprasocial.me/${service.icon.path}"> 99 <div class="cs-header__serviceName">${service.displayName}</div> </a>`; 100 } else { 101 return `<a href="${service.url}" class="cs-header__service"> 102 <img class="cs-header__serviceIcon" src="https://api.comprasocial.me/${service.icon.path}"> 103 <div class="cs-header__serviceName">${service.displayName}</div> </a>`; 104 } 105} 106//DA INSERIRE BOTTONE PER ESPANDERE 107async function setServices(){ 108 const data = { 109 "lang": currentLanguage 110 }; 111 if(sessionStorage.getItem("servicesMenuItem-" + currentLanguage) != "undefined" && sessionStorage.hasOwnProperty("serviceMenuItem-" + currentLanguage)){ 112 const servicesMenu = JSON.parse(sessionStorage.getItem("servicesMenuItem-" + currentLanguage)); 113 servicesMenuHTML = generateHTMLForServicesMenu(servicesMenu);
114 const elementServices = document.querySelector('.cs-header__services').innerHTML = servicesMenuHTML; 115 116 } else { 117 await fetch('https://api.comprasocial.me/api/collections/get/MenuServices?token=31a788dd979e8eacf6e1cdf7774ffa',{ 118 method: 'POST', 119 headers: { 120 'Content-Type': 'application/json' 121 }, 122 body: JSON.stringify(data) 123 }).then(async function(response){ 124 await response.json().then(function(servicesData){ 125 sessionStorage.setItem("servicesMenuItem-" + currentLanguage, JSON.stringify(servicesData.entries)); 126 servicesMenuHTML = generateHTMLForServicesMenu(servicesData.entries); 127 document.querySelector('.cs-header__services').innerHTML = servicesMenuHTML; 128 }) 129 }); 130 } 131} 132 133setServices(); 134 135async function setServicesSearchList(){ 136 const data = { 137 "lang": currentLanguage, 138 "populate": 1 139 }; 140 if(!sessionStorage.getItem("servicesSearchList-" + currentLanguage) || sessionStorage.getItem("servicesSearchList-" + currentLanguage) == "undefined"){ 141 await fetch('https://api.comprasocial.me/api/collections/get/servicesSearchList?token=31a788dd979e8eacf6e1cdf7774ffa',{ 142 method: 'POST', 143 headers: { 144 'Content-Type': 'application/json' 145 }, 146 body: JSON.stringify(data) 147 }).then(async function(response){ 148 await response.json().then(function(servicesList){ 149 sessionStorage.setItem("servicesSearchList-" + currentLanguage, JSON.stringify(servicesList.entries)); 150 }) 151 }); 152 } 153} 154 155setServicesSearchList(); 156// This represents a very heavy method. Which takes a lot of time to execute 157function makeAPICall() { 158 const searchTerm = searchBoxDom.value.trim(); 159 const resultContainer = document.getElementById('cs-header__resultsContainer'); 160 if(searchTerm){ 161 if(searchTerm.length > 2){ 162 console.log(getServicesSearchResultToShow(searchBoxDom.value)); 163 const searchResult = getServicesSearchResultToShow(searchBoxDom.value); 164 resultContainer.innerHTML = getResultElementsHTML(searchResult); 165 animateResultElements(); 166// then(function(response) { 167// response.json().then(function(data) { 168// resultContainer.innerHTML = getResultElementsHTML(data); 169// animateResultElements(); 170// } 171// ) 172// }) 173 } else if (searchTerm.length === 0 ){ 174 resultContainer.innerHTML = ''; 175 } 176 } else { 177 resultContainer.innerHTML = ''; 178 } 179} 180 181function getServicesSearchResultToShow(searchServicesQuery){ 182 const servicesSearchList = JSON.parse(sessionStorage.getItem("servicesSearchList-" + currentLanguage)); 183 let result = []; 184 for( let service of servicesSearchList){ 185 const searchTerms = service.searchTerms.split(','); 186 let addService = false; 187 let accuracyScore = 0; 188 searchTerms.forEach((searchTerm,indexSearchTerm) => { 189 if(searchTerm.toLowerCase().includes(searchServicesQuery.toLowerCase()) && !addService){ 190 addService = true; 191 accuracyScore = indexSearchTerm 192 } 193 }); 194 if(addService){ 195 result.push({ 196 "service": service, 197 "score": accuracyScore 198 }) 199 } 200 } 201 result = result.sort((a,b) => a.score - b.score); 202 return result; 203} 204 205// Debounce function: Input as function which needs to be debounced and delay is the debounced time in milliseconds 206const debounceFunction = function (func, delay) { 207 // Cancels the setTimeout method execution 208 clearTimeout(timerId) 209 210 // Executes the func after delay time. 211 timerId = setTimeout(func, delay) 212} 213 214// Event listener on the input box 215searchBoxDom.addEventListener('input', function () { 216 debounceFunction(makeAPICall, 500) 217}); 218 219searchBoxDom.addEventListener('focus', function (){ 220 serviceUserArea.style.opacity = '0'; 221 serviceUserArea.style.transition = 'opacity 0.25s ease-in-out'; 222 searchBoxContainerDom.style.width = '75%'; 223 searchBoxContainerDom.style.marginRight = '10px'; 224 searchBoxContainerDom.style.transition = 'all 0.25s ease-in-out'; 225 cancelSearchButtonDom.style.height = '30px'; 226 cancelSearchButtonDom.style.fontSize = '14px'; 227 cancelSearchButtonDom.style.padding = '0 10px'; 228 cancelSearchButtonDom.style.transition = 'all 0.25s ease-in-out'; 229 if(window.screen.width < 1024) { 230 contentMobileHeaderDom.style.opacity = '0'; 231 contentMobileHeaderDom.style.transition = 'all 0.5s ease-in-out'; 232 setTimeout(()=> { 233 contentMobileHeaderDom.style.height = '0'; 234 },250); 235 setTimeout(() => { 236 contentMobileHeaderDom.style.visibility = 'hidden'; 237 },500); 238 } 239 setTimeout(() => { 240 serviceUserArea.style.height = '0'; 241 },250) 242}); 243 244const resultContainer = document.getElementById('cs-header__resultsContainer'); 245 246searchBoxDom.addEventListener('blur', function (){ 247 if(resultContainer.innerHTML === '' && searchBoxDom.value === ''){ 248 showMenuAndUserAreaAfterSearch(); 249 } 250}); 251 252function showMenuAndUserAreaAfterSearch(){ 253 serviceUserArea.style.opacity = '1'; 254 serviceUserArea.style.transition = 'opacity 0.25s ease-in-out'; 255 serviceUserArea.style.removeProperty('height'); 256 searchBoxContainerDom.style.removeProperty('width'); 257 searchBoxContainerDom.style.removeProperty('margin-right'); 258 cancelSearchButtonDom.style.removeProperty('height'); 259 cancelSearchButtonDom.style.removeProperty('font-size'); 260 cancelSearchButtonDom.style.removeProperty('padding'); 261 contentMobileHeaderDom.style.removeProperty('height'); 262 263 if(window.screen.width < 1024) { 264 setTimeout(() => { 265 contentMobileHeaderDom.style.opacity = '1'; 266 contentMobileHeaderDom.style.removeProperty('visibility'); 267 },300); 268 } else { 269 contentMobileHeaderDom.style.opacity = '1'; 270 } 271} 272 273cancelSearchButtonDom.addEventListener('click', function (){ 274 searchBoxDom.value = ''; 275 resultContainer.innerHTML = ''; 276 showMenuAndUserAreaAfterSearch(); 277}) 278
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.