1'use strict'; 2 3document.addEventListener('DOMContentLoaded', function () { 4 const body = document.body; 5 body.classList.add('red-is-active'); 6 // Selectors definition 7 const SELECTORS = { 8 chatbotBtn: '.chatbotbutton', 9 chatbotRender: '#chatbot-render', 10 chatbotMainContent: '#main-content', 11 ctaPanelBtn: '.cta-panel-button', 12 ctaPanel: '.cta-panel', 13 ctaPanelHeader: '.cta-panel-header', 14 ctaList: '.cta-list', 15 ctaClosePanel: '.cta-close-panel', 16 chatbotPanel: '.ai-panel', 17 actionButtons: '.action-buttons', 18 powerfrontEntryPoint: '#powerfront-entry-point', 19 redIframe: '#red-iframe', 20 pdpProductContainer: '.pdp-product-container', 21 denimGuideAccordionBtn: '.fpls-wall-diesel-denimguide-sticky__mobile-menu__title.fpls-box-accordion', 22 denimGuideInnerLabel: '.fpls-wall-diesel-denimguide-sticky__mobile-menu__label.fpls-label' 23 }; 24 25 const element = document.getElementById('entry-point-component'); 26 27 if (!element) { 28 console.error('No entry point component found!'); 29 return; 30 } 31 32 let chatLoaded = false; 33 let chatRequested = false; 34 let timeInactivity; 35 let boolInactivity = false; 36 37 function initSelectors() { 38 return { 39 ctaPanelBtnEl: element.querySelector(SELECTORS.ctaPanelBtn), 40 ctaPanelEl: element.querySelector(SELECTORS.ctaPanel), 41 buttonBotEl: element.querySelectorAll(SELECTORS.chatbotBtn), 42 ctaListEl: element.querySelector(SELECTORS.ctaList), 43 ctaClosePanelEl: element.querySelectorAll(SELECTORS.ctaClosePanel), 44 chatbotPanelEl: element.querySelector(SELECTORS.chatbotPanel), 45 ctaPanelHeaderEl: element.querySelector(SELECTORS.ctaPanelHeader), 46 actionButtonsEl: element.querySelector(SELECTORS.actionButtons), 47 powerfrontEntryPointEl: element.querySelector(SELECTORS.powerfrontEntryPoint), 48 redIframeEl: element.querySelector(SELECTORS.redIframe), 49 chatbotRenderEl: element.querySelector(SELECTORS.chatbotRender), 50 pdpProductContainerEl: document.querySelector(SELECTORS.pdpProductContainer), 51 denimGuideAccordionBtnEl: document.querySelector(SELECTORS.denimGuideAccordionBtn), 52 denimGuideInnerLabelEls: document.querySelectorAll(SELECTORS.denimGuideInnerLabel) 53 }; 54 } 55 56 function initWidget(selectors) { 57 const { ctaPanelBtnEl, ctaPanelEl, ctaClosePanelEl, actionButtonsEl, chatbotPanelEl, ctaListEl, ctaPanelHeaderEl, pdpProductContainerEl } = selectors; 58 59 if (pdpProductContainerEl) { 60 document.body.classList.add('pdp-page'); 61 } 62 63 if (ctaPanelBtnEl) { 64 ctaPanelBtnEl.addEventListener('click', (e) => { 65 e.preventDefault(); 66 ctaPanelEl.classList.toggle('d-none'); 67 ctaPanelBtnEl.classList.toggle('selected'); 68 }); 69 } 70 71 if (ctaClosePanelEl.length) { 72 ctaClosePanelEl.forEach((btn) => { 73 btn.addEventListener('click', (e) => { 74 e.preventDefault(); 75 closePanels(ctaPanelEl, ctaListEl, actionButtonsEl, ctaPanelHeaderEl, ctaPanelBtnEl, chatbotPanelEl) 76 }); 77 }); 78 } 79 80 document.addEventListener('algolia-search:open', () => { 81 console.log('event received::algolia-search:open'); 82 if (!ctaPanelEl.classList.contains('d-none')) { 83 closePanels(ctaPanelEl, ctaListEl, actionButtonsEl, ctaPanelHeaderEl, ctaPanelBtnEl, chatbotPanelEl) 84 } 85 }) 86 87 initChatbotBtn(selectors); 88 initPFBtn(selectors); 89 90 if (element.classList.contains('d-none')) { 91 element.classList.remove('d-none'); 92 element.classList.add('loaded'); 93 } 94 } 95 96 function initChatbotBtn(selectors) { 97 const { buttonBotEl, ctaPanelEl, ctaListEl, ctaPanelHeaderEl, chatbotPanelEl, actionButtonsEl } = selectors; 98 99 if (buttonBotEl.length) { 100 buttonBotEl.forEach((btn) => { 101 btn.addEventListener('click', async (e) => { 102 var viewport = document.querySelector("meta[name=viewport]"); 103 if (viewport) { 104 viewport.setAttribute("content", "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes"); 105 } 106 e.preventDefault(); 107 document.dispatchEvent(new CustomEvent('loaderRED:start', {detail: {element: ctaPanelEl }})); 108 ctaListEl.classList.add('d-none'); 109 ctaPanelHeaderEl.classList.add('d-none'); 110 111 if (ctaPanelEl.classList.contains('d-none')) { 112 ctaPanelEl.classList.remove('d-none'); 113 } 114 115 actionButtonsEl.classList.add('d-none'); 116 actionButtonsEl.classList.remove('d-flex'); 117 118 ctaPanelEl.classList.add('ai-panel-open'); 119 document.dispatchEvent(new CustomEvent('loaderRED:end', {detail: {element: ctaPanelEl }})); 120 chatbotPanelEl.classList.remove('d-none'); 121
122 if (isMobileDevice()) { 123 document.dispatchEvent(new CustomEvent('bodyRED:lock', {detail: {lock: true }})); 124 } 125 126 const eventBody = { 127 userId: selectors.chatbotRenderEl.getAttribute('data-user-id'), 128 chatId: getCookie('chatThreadUserId') ? getCookie('chatThreadUserId') : null, 129 baseUrl: selectors.chatbotRenderEl.getAttribute('data-base-url'), 130 imgBaseUrl: selectors.chatbotRenderEl.getAttribute('data-images-url'), 131 quickViewUrlBase: selectors.chatbotRenderEl.getAttribute('data-quick-view-url') 132 }; 133 134 if(selectors.chatbotRenderEl.getAttribute('data-init')==='false'){ 135 initInactivityListener(); 136 const eventOrigin = selectors.chatbotRenderEl.getAttribute('data-red-app-url'); 137 postMessage(selectors.redIframeEl, 'init', eventBody, eventOrigin); 138 selectors.chatbotRenderEl.setAttribute('data-init','true'); 139 } 140 }); 141 }); 142 } 143 } 144 145 function closePanels(ctaPanelEl, ctaListEl, actionButtonsEl, ctaPanelHeaderEl, ctaPanelBtnEl, chatbotPanelEl) { 146 var viewport = document.querySelector("meta[name=viewport]"); 147 if (viewport) { 148 viewport.setAttribute("content", "width=device-width, initial-scale=1"); 149 } 150 ctaPanelEl.classList.toggle('d-none'); 151 actionButtonsEl.classList.remove('d-none'); 152 actionButtonsEl.classList.add('d-flex'); 153 if (ctaPanelEl.classList.contains('ai-panel-open')) { 154 ctaPanelEl.classList.remove('ai-panel-open'); 155 ctaListEl.classList.remove('d-none'); 156 ctaPanelHeaderEl.classList.remove('d-none'); 157 } 158 159 if (!chatbotPanelEl.classList.contains('d-none')) { 160 chatbotPanelEl.classList.add('d-none'); 161 } 162 ctaPanelBtnEl.classList.remove('selected'); 163 164 if (isMobileDevice()) { 165 document.dispatchEvent(new CustomEvent('bodyRED:lock', {detail: {lock: false }})); 166 } 167 } 168 169 function isMobileDevice() { 170 // Definisci una regex per rilevare dispositivi mobili Apple o Android 171 const mobileRegex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i; 172 173 // Testa la stringa dell'User-Agent contro la regex 174 return mobileRegex.test(navigator.userAgent); 175 } 176 177 function postMessage(element, eventName, body, origin) { 178 element.contentWindow.postMessage({ 179 name: eventName, 180 body: body 181 }, origin); 182 183 console.log('event sent::'+ eventName, body); 184 } 185 186 function initPFBtn(selectors) { 187 const { powerfrontEntryPointEl, ctaPanelEl } = selectors; 188 189 if (powerfrontEntryPointEl) { 190 powerfrontEntryPointEl.addEventListener('click', (e) => { 191 e.preventDefault(); 192 ctaPanelEl.classList.toggle('d-none'); 193 openChatButtonClick(); 194 }); 195 } 196 } 197 198 function checkPowerfront() { 199 const { powerfrontEntryPointEl, ctaListEl } = selectors; 200 201 window._inside = window._inside || []; 202 chatLoaded = false; 203 chatRequested = false; 204 window._inside.push({ 205 action: 'bind', 206 name: 'chatavailable', 207 callback: (available) => { 208 chatLoaded = true; 209 210 if (available) { 211 ctaListEl.classList.add('powerfront-available'); 212 ctaListEl.classList.remove('powerfront-not-available'); 213 powerfrontEntryPointEl.classList.remove('d-none'); 214 console.log('Powerfront is available'); 215 216 if (chatRequested) { 217 insideFrontInterface.openChatPane(); 218 } 219 } else { 220 ctaListEl.classList.add('powerfront-not-available'); 221 ctaListEl.classList.remove('powerfront-available'); 222 powerfrontEntryPointEl.classList.add('d-none'); 223 console.log('Powerfront is unavailable'); 224 } 225 chatRequested = false; 226 } 227 }); 228 } 229 230 function openChatButtonClick() { 231 if (chatLoaded) { 232 insideFrontInterface.openChatPane(); 233 } else { 234 chatRequested = true; 235 } 236 return false; 237 } 238 239 function setCookie(cName, cValue, expireTimestamp) { 240 const expires = "expires=" + new Date(expireTimestamp).toUTCString(); 241 document.cookie = cName + "=" + cValue + "; " + expires + "; path=/"; 242 } 243 244 function getCookie(cName) { 245 const name = cName + "="; 246 const cDecoded = decodeURIComponent(document.cookie); 247 const cArr = cDecoded .split('; '); 248 let res; 249 cArr.forEach(val => { 250 if (val.indexOf(name) === 0) res = val.substring(name.length); 251 }) 252 return res; 253 } 254 255 function initInactivityListener(){ 256 window.addEventListener('load', resetTimerInactivity, true); 257 var events = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart', 'click'];
258 events.forEach(function(name) { 259 document.addEventListener(name, resetTimerInactivity, true); 260 }); 261 } 262 263 function resetTimerInactivity(){ 264 clearTimeout(timeInactivity); 265 boolInactivity = false; 266 timeInactivity = setTimeout(sendInactivityStatus, 300000); // 300000 = 5 min --- 10000 = 10sec 267 } 268 269 function sendInactivityStatus(){ 270 boolInactivity = true; 271 postMessage(selectors.redIframeEl, 'parentInactivity', {}, selectors.chatbotRenderEl.getAttribute('data-red-app-url')); 272 } 273 274 275 async function fetchProductsData(renderUrl, productIds) { 276 var resp; 277 let data = await fetch(renderUrl + '?pids=' + productIds + '&extend=price,images') 278 .then((response) => { 279 if (!response.ok) { 280 throw new Error('Network response was not ok ' + response.statusText); 281 } 282 return response.json(); 283 }).then(data => { 284 resp = data; 285 }) 286 .catch(function (error) { 287 console.error('There has been a problem with your fetch operation:', error); 288 return null; 289 }); 290 return resp; 291 } 292 293 // Entry point initialize 294 const selectors = initSelectors(); 295 checkPowerfront(); 296 initWidget(selectors); 297 298 window.addEventListener('message', (event) => { 299 if (event && event.origin.indexOf(new URL(selectors.redIframeEl.getAttribute('src')).origin) > -1) { 300 if(event.data) { 301 switch(event.data.name) { 302 case 'startChat': { 303 if (utag && utag.data && utag.data.page_type) { 304 if(!window.ChatbotAI_track) { 305 console.error('ERROR: ChatbotAI_track function does not exists | EVENTS TRACKING IS NOT INITIALIZED'); 306 return; 307 } 308 309 window.ChatbotAI_track(event.data.name, { 310 page_type: utag.data.page_type, 311 conversationID: event.data.body.chatId 312 }); 313 } 314 break; 315 } 316 317 case 'chatbotAppMounted': { 318 console.log('Chatbot App Mounted', event.data.body); 319 break; 320 } 321 case 'updateChatId': { 322 setCookie('chatThreadUserId', event.data.body.chatId, event.data.body.expire); 323 break; 324 } 325 case 'getProductsData': { 326 fetchProductsData(selectors.chatbotRenderEl.getAttribute('data-product-url'), event.data.body.productIDs).then(data => { 327 if (data && data.productsData) { 328 postMessage(selectors.redIframeEl, 'getProductsDataResult', { productsData: data.productsData }, selectors.chatbotRenderEl.getAttribute('data-red-app-url')); 329 } 330 }); 331 break; 332 } 333 334 case 'checkInactivityStatus': { 335 postMessage(selectors.redIframeEl, 'parentInactivityStatus', {inactive: boolInactivity}, selectors.chatbotRenderEl.getAttribute('data-red-app-url')); 336 break; 337 } 338 default: 339 console.log('Sorry, event not recognized!'); 340 } 341 } 342 } 343 } 344 ); 345 346 const addToCartWrapper = document.querySelector('.add-to-cart-wrapper'); 347 const mainHeader = document.getElementById('main-header'); 348 window.addEventListener('scroll', (event) => { 349 if (body.classList.contains('pdp-page')) { 350 if (!selectors.actionButtonsEl.classList.contains('pdp-mobile')) { 351 selectors.actionButtonsEl.classList.add('pdp-mobile') 352 } 353 354 if (mainHeader.classList.contains('header-sticky')) { 355 // selectors.actionButtonsEl.classList.add('sticky'); 356 357 if (addToCartWrapper && addToCartWrapper.style.display === 'none'){ 358 selectors.actionButtonsEl.classList.remove('pdp-mobile') 359 selectors.actionButtonsEl.classList.remove('sticky'); 360 } 361 } else { 362 selectors.actionButtonsEl.classList.remove('sticky'); 363 } 364 } 365 }) 366 367 if (selectors.denimGuideAccordionBtnEl) { 368 if (selectors.actionButtonsEl) { 369 selectors.denimGuideAccordionBtnEl.addEventListener('click', function() { 370 selectors.actionButtonsEl.classList.toggle('d-flex'); 371 selectors.actionButtonsEl.classList.toggle('d-none'); 372 }) 373
374 selectors.denimGuideInnerLabelEls.forEach(label => { 375 label.addEventListener('click', function() { 376 selectors.actionButtonsEl.classList.toggle('d-flex'); 377 selectors.actionButtonsEl.classList.toggle('d-none'); 378 }); 379 }) 380 } 381 } 382});
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.