1(function (document, Granite) { 2 "use strict"; 3 function decodeHtml(html) { 4 const doc = new DOMParser().parseFromString(html, "text/html"); 5 return doc.documentElement.textContent; 6 } 7 function decodeTagLabel(tag) { 8 try { 9 return decodeHtml(decodeURIComponent(tag)); 10 } catch (e) { 11 return decodeHtml(tag); 12 } 13 } 14 function notifyContentFragmentListReady() { 15 const list = document.querySelector('.cmp-contentfragmentlist'); 16 if (!list) { 17 return; 18 } 19 const fragments = list.querySelectorAll('.cmp-contentfragment'); 20 const processed = list.querySelectorAll('.cmp-contentfragment.processed'); 21 // Do not advertise readiness while the list is still empty or only partially processed. 22 // An early ready event is what lets the grid filter lock in a stale display:none state. 23 if (fragments.length === 0 || processed.length !== fragments.length) { 24 return; 25 } 26 document.dispatchEvent(new CustomEvent('contentfragmentlist:ready', { bubbles: true })); 27 } 28 29 function processArticles() { 30 const articles = document.querySelectorAll('.cmp-contentfragment:not(.processed)'); 31 32 articles.forEach((article, index) => { 33 try{ 34 35 article.classList.add('processed'); 36 37 const authoredProperties = article.closest('.contentfragmentlist') 38 ?.querySelector('.authoredProperties'); 39 40 const enableRatings = authoredProperties?.querySelector('.enableRatings')?.value === 'true'; 41 const enableWheretoBuy = authoredProperties?.querySelector('.enableWheretoBuy')?.value === 'true'; 42 const ctaLabel = authoredProperties?.querySelector('.ctaLabel')?.value; 43 const clickAction = authoredProperties?.querySelector('.clickAction')?.value || "whole"; // Default to whole card 44 const bvRatingsCFProperty = authoredProperties?.querySelector('.bvRatingsCFProperty')?.value; 45 // const absoultePath = authoredProperties?.querySelector('.absoultePath')?.value; 46 47 var ctaLinkExternalUrl = article.querySelector('.cmp-contentfragment__element--ctalinkExternalUrl .cmp-contentfragment__element-value')?.textContent.trim(); 48 const productName = article.querySelector('.cmp-contentfragment__element--productCardShortName .cmp-contentfragment__element-value')?.textContent.trim(); 49 const imageAltText = article.querySelector('.cmp-contentfragment__element--productAsset1AltText .cmp-contentfragment__element-value')?.textContent.trim(); 50 const isDispatcher = !window.location.hostname.includes("localhost") && !window.location.hostname.includes("author") && !window.location.hostname.includes("publish"); 51 const mutliLangSite = {"/elmex/de_ch": "de-ch","/elmex/fr_be": "fr-be","/elmex/nl_be": "nl-be","/elmex/fr_ch/": "fr-ch","/tu-hogar/es_co": "es-co","/tu-hogar/es_gt": "es-gt","/tu-hogar/es_do": "es-do","/tu-hogar/es_ve": "es-ve","/tu-hogar/en_jm": "en-jm","/tu-hogar/es_pr": "es-pr","/tu-hogar/es_pe": "es-pe","/tu-hogar/es_ec": "es-ec","/tu-hogar/es_uy": "es-uy","/palmolive-eu/fr_ch":"fr-ch","/palmolive-eu/de_ch":"de-ch","/mens-speed-stick/es_mx": "es-mx","/mens-speed-stick/es_ec": "es-ec","/mens-speed-stick/es_gt": "es-gt","/mens-speed-stick/es_co": "es-co","/mens-speed-stick/es_do": "es-do","/mens-speed-stick/es_ve": "es-ve","/mens-speed-stick/es_uy": "es-uy","/mens-speed-stick/es_py": "es-py","/mens-speed-stick/es_pe": "es-pe","/mens-speed-stick/es_cl": "es-cl","/meridol/fr_be": "fr-be","/meridol/nl_be": "nl-be","/meridol/en_sa": "en-sa","/meridol/ar_sa": "ar-sa","/meridol/de_ch": "de-ch","/meridol/fr_ch": "fr-ch","/hills-vet/de_ch": "de-ch","/hills-vet/fr_ch": "fr-ch","/hills-vet/fr_be": "fr-be","/hills-vet/nl_be": "nl-be","/hills-vet/fr_ca": "fr-ca","/hills-vet/en_ca": "en-ca","/ladies-speed-stick/es_mx": "es-mx","/ladies-speed-stick/es_ec": "es-ec","/ladies-speed-stick/es_gt": "es-gt","/ladies-speed-stick/es_co": "es-co","/ladies-speed-stick/es_do": "es-do","/ladies-speed-stick/es_ve": "es-ve","/ladies-speed-stick/es_py": "es-py","/ladies-speed-stick/es_pe": "es-pe","/ladies-speed-stick/es_cl": "es-cl","/protex/es_ar": "es_ar","/protex/es_cl": "es_cl","/protex/es_ve": "es_ve","/protex/es_ec": "es_ec","/protex/es_py": "es_py","/protex/es_pe": "es_pe","/protex/es_pr": "es-pr","/protex/es_do": "es_do","/protex/es_uy": "es_uy","/protex/es_gt": "es_gt","/protex/es_co": "es_co","/sanex/fr_be": "fr
51-be","/sanex/nl_be": "nl-be","/velopvask/da_dk": "da-dk"}; 52 53 54 // if(isDispatcher){ 55 // let isUrlShortend = false; 56 // if(absoultePath && absoultePath.indexOf(ctaLinkExternalUrl)){ 57 // for (const key in mutliLangSite) { 58 // if (ctaLinkExternalUrl.includes(key)) { 59 // ctaLinkExternalUrl = ctaLinkExternalUrl.replace(absoultePath, "/"+mutliLangSite[key]).replace(".html", ""); 60 // isUrlShortend = true; 61 // break; 62 // } 63 // } 64 // if(!isUrlShortend) { 65 // ctaLinkExternalUrl = ctaLinkExternalUrl.replace(absoultePath, "").replace(".html", ""); 66 // } 67 // } else { 68 // article.classList.remove('processed'); 69 // return; 70 // } 71 // } 72 73 if (clickAction === "whole" && ctaLinkExternalUrl) { 74 const wrapperLink = document.createElement('a'); 75 wrapperLink.href = ctaLinkExternalUrl; 76 wrapperLink.ariaLabel = productName; 77 wrapperLink.classList.add('article-card'); 78 wrapperLink.style.display = 'block'; 79 wrapperLink.style.textDecoration = 'none'; 80 81 wrapperLink.appendChild(article.cloneNode(true)); 82 article.replaceWith(wrapperLink); 83 84 const clonedArticle = wrapperLink.querySelector('.cmp-contentfragment'); 85 processContentFragmentElements(clonedArticle, true, ctaLinkExternalUrl, productName, imageAltText,enableRatings,enableWheretoBuy,ctaLabel,clickAction, bvRatingsCFProperty); 86 } 87 else if(clickAction === "individual" && ctaLinkExternalUrl){ 88 const wrapperLink = document.createElement('div'); 89 wrapperLink.classList.add('article-card'); 90 wrapperLink.appendChild(article.cloneNode(true)); 91 article.replaceWith(wrapperLink); 92 const clonedArticle = wrapperLink.querySelector('.cmp-contentfragment'); 93 processContentFragmentElements(clonedArticle, true, ctaLinkExternalUrl, productName, imageAltText,enableRatings,enableWheretoBuy,ctaLabel,clickAction, bvRatingsCFProperty); 94 } 95 else { 96 processContentFragmentElements(article, false); 97 } 98 if (index == (articles.length - 1) && enableRatings) { 99 fragmentListDataPrivacyConsentCheck('contentfragmentlist-ratings-reviews', 'data-privacy-script-src'); 100 } 101 } catch (error) { 102 // Every remaining card still needs its product markup, otherwise the grid filter has 103 // nothing to match against and reports a partial or zero count. 104 console.error('contentfragmentlist: card failed to process', error); 105 } 106 }); 107 notifyContentFragmentListReady(); 108 } 109 110 111 112 // Function to process content fragment elements 113 function processContentFragmentElements(article, isLinkPresent, ctaLinkExternalUrl = '', productName = '', imageAltText = '',enableRatings,enableWheretoBuy,ctaLabel,clickAction, bvRatingsCFProperty) { 114 const contentFragmentElements = article.querySelectorAll('.cmp-contentfragment__element'); 115 const frontPackShotAlttextEle = article.querySelector('.cmp-contentfragment__element--name .cmp-contentfragment__element-value'); 116 const frontPackShotAlttextEleValue = frontPackShotAlttextEle?.textContent.trim(); 117 contentFragmentElements.forEach(element => { 118 try { 119 const contentValue = element.querySelector('.cmp-contentfragment__element-value')?.textContent.trim(); 120 121 const newDiv = document.createElement('dd'); 122 123 if (isLinkPresent && clickAction === "whole") { 124 125 const divElement = document.createElement('div'); 126 divElement.className = 'element-content'; 127 128 if (element.classList.contains('cmp-contentfragment__element--productAsset1')) { 129 const imgTag = document.createElement('img'); 130 imgTag.src = contentValue; 131 imgTag.alt = imageAltText; 132 divElement.appendChild(imgTag); 133 newDiv.className = 'product-image'; 134 newDiv.appendChild(divElement); 135 136 } else if (element.classList.contains('cmp-contentfragment__element--frontPackShot')) { 137 const imgTag = document.createElement('img'); 138 imgTag.src = contentValue; 139 imgTag.alt = frontPackShotAlttextEleValue ? frontPackShotAlttextEleValue : "Alt Text"; 140 divElement.appendChild(imgTag); 141 newDiv.className = 'product-image'; 142 newDiv.appendChild(divElement); 143 } 144 else if (element.classList.contains('cmp-contentfragment__element--brand')) { 145 const pTag = document.createElement('p'); 146 pTag.textContent = contentValue; 147 divElement.appendChild(pTag); 148 newDiv.className = 'product-brand'; 149 newDiv.appendChild(divElement); 150 } 151 else if (element.classList.contains('cmp-contentfragment__element--name')) { 152 const pTag = document.createElement('p'); 153 pTag.textContent = contentValue; 154 divElement.appendChild(pTag); 155 newDiv.className = 'product-name'; 156 newDiv.appendChild(divElement); 157 158 }else if (element.classList.contains('cmp-contentfragment__element--productCardShortName')) { 159 const pTag = document.createElement('p'); 160 pTag.textContent = contentValue; 161 divElement.appendChild(pTag); 162 newDiv.className = 'product-card-short-name'; 163 newDiv.appendChild(divElement); 164 165 }else if (element.classList.contains('cmp-contentfragment__element--productCardShortDescription')) { 166 const pTag = document.createElement('p'); 167 pTag.textContent = contentValue; 168 divElement.appendChild(pTag); 169 newDiv.className = 'product-card-short-description'; 170 newDiv.appendChild(divElement); 171 172 } else if (element.classList.contains('cmp-contentfragment__element--description')) { 173 const pTag = document.createElement('p'); 174 pTag.textContent = contentValue; 175 newDiv.appendChild(pTag); 176 newDiv.className = 'product-description'; 177 178 } else if (bvRatingsCFProperty && element.classList.contains('cmp-contentfragment__element--'+bvRatingsCFProperty)) { 179 if (enableRatings) { 180 const customDiv = document.createElement('div'); 181 customDiv.setAttribute('data-bv-show', 'inline_rating'); 182 customDiv.setAttribute('data-bv-product-id', contentValue); 183 customDiv.setAttribute('data-bv-redirect-url', ctaLinkExternalUrl); 184 divElement.appendChild(customDiv); 185 newDiv.className = 'product-skus'; 186 newDiv.appendChild(divElement); 187 } 188 }else if (element.classList.contains('cmp-contentfragment__element--shortDescription')) { 189 const pTag = document.createElement('p'); 190 pTag.textContent = contentValue; 191 divElement.appendChild(pTag);
192 newDiv.className = 'product-short-description'; 193 newDiv.appendChild(divElement); 194 195 } else if (element.classList.contains('cmp-contentfragment__element--ctalinkExternalUrl')) { 196 if (enableWheretoBuy) { 197 const pTag = document.createElement('p'); 198 pTag.textContent = ctaLabel; 199 pTag.setAttribute('title', productName); 200 divElement.appendChild(pTag); 201 newDiv.className = 'product-ctaLink'; 202 newDiv.appendChild(divElement); 203 } 204 } 205 else if (element.classList.contains('cmp-contentfragment__element--tags')) { 206 const ulTag = document.createElement('ul'); 207 const rawTagsContent = element.querySelector('.cmp-contentfragment__element-value')?.innerHTML.trim(); 208 const tagsValue = rawTagsContent.split(',').map(tag => tag.trim()); 209 tagsValue.forEach(tag => { 210 const liTag = document.createElement('li'); 211 liTag.textContent = decodeTagLabel(tag); 212 ulTag.appendChild(liTag); 213 }); 214 divElement.appendChild(ulTag); 215 newDiv.className = 'product-tags'; 216 newDiv.appendChild(divElement); 217 } 218 219 220 } 221 else if (isLinkPresent && clickAction === "individual") { 222 const newAnchor = document.createElement('a'); 223 newAnchor.href = ctaLinkExternalUrl; 224 newAnchor.className = 'element-content'; 225 newAnchor.addEventListener('click', (event) => event.stopPropagation()); 226 227 if (element.classList.contains('cmp-contentfragment__element--productAsset1')) { 228 const imgTag = document.createElement('img'); 229 imgTag.src = contentValue; 230 imgTag.alt = imageAltText; 231 newAnchor.appendChild(imgTag); 232 newDiv.className = 'product-image'; 233 newDiv.appendChild(newAnchor); 234 235 } else if (element.classList.contains('cmp-contentfragment__element--frontPackShot')) { 236 const imgTag = document.createElement('img'); 237 imgTag.src = contentValue; 238 imgTag.alt = imageAltText; 239 newAnchor.appendChild(imgTag); 240 newDiv.className = 'product-image'; 241 newDiv.appendChild(newAnchor); 242 243 } 244 else if (element.classList.contains('cmp-contentfragment__element--brand')) { 245 const pTag = document.createElement('p'); 246 pTag.textContent = contentValue; 247 newAnchor.appendChild(pTag); 248 newDiv.className = 'product-brand'; 249 newDiv.appendChild(newAnchor); 250 } 251 else if (element.classList.contains('cmp-contentfragment__element--name')) { 252 const pTag = document.createElement('p'); 253 pTag.textContent = contentValue; 254 newAnchor.appendChild(pTag); 255 newDiv.className = 'product-name'; 256 newDiv.appendChild(newAnchor); 257 258 }else if (element.classList.contains('cmp-contentfragment__element--productCardShortName')) { 259 const pTag = document.createElement('p'); 260 pTag.textContent = contentValue; 261 newAnchor.appendChild(pTag); 262 newDiv.className = 'product-card-short-name'; 263 newDiv.appendChild(newAnchor); 264 265 }else if (element.classList.contains('cmp-contentfragment__element--productCardShortDescription')) { 266 const pTag = document.createElement('p'); 267 pTag.textContent = contentValue; 268 newAnchor.appendChild(pTag); 269 newDiv.className = 'product-card-short-description'; 270 newDiv.appendChild(newAnchor); 271 272 } else if (element.classList.contains('cmp-contentfragment__element--description')) { 273 const pTag = document.createElement('p'); 274 pTag.textContent = contentValue; 275 newDiv.appendChild(pTag); 276 newDiv.className = 'product-description'; 277 278 }else if (bvRatingsCFProperty && element.classList.contains('cmp-contentfragment__element--'+bvRatingsCFProperty)) { 279 if (enableRatings) { 280 const customDiv = document.createElement('div'); 281 customDiv.setAttribute('data-bv-show', 'inline_rating'); 282 customDiv.setAttribute('data-bv-product-id', contentValue); 283 customDiv.setAttribute('data-bv-redirect-url', ctaLinkExternalUrl); 284 divElement.appendChild(customDiv); 285 newDiv.className = 'product-skus'; 286 newDiv.appendChild(divElement); 287 } 288 } else if (element.classList.contains('cmp-contentfragment__element--shortDescription')) { 289 const pTag = document.createElement('p'); 290 pTag.textContent = contentValue; 291 divElement.appendChild(pTag);
292 newDiv.className = 'product-short-description'; 293 newDiv.appendChild(divElement); 294 295 } else if (element.classList.contains('cmp-contentfragment__element--ctalinkExternalUrl')) { 296 if (enableWheretoBuy) { 297 const pTag = document.createElement('p'); 298 pTag.textContent = ctaLabel; 299 pTag.setAttribute('title', productName); 300 newAnchor.appendChild(pTag); 301 newDiv.className = 'product-ctaLink'; 302 newDiv.appendChild(newAnchor); 303 } 304 } 305 else if (element.classList.contains('cmp-contentfragment__element--tags')) { 306 const ulTag = document.createElement('ul'); 307 const rawTagsContent = element.querySelector('.cmp-contentfragment__element-value')?.innerHTML.trim(); 308 const tagsValue = rawTagsContent.split(',').map(tag => tag.trim()); 309 tagsValue.forEach(tag => { 310 const liTag = document.createElement('li'); 311 liTag.textContent = decodeTagLabel(tag); 312 ulTag.appendChild(liTag); 313 }); 314 newAnchor.appendChild(ulTag); 315 newDiv.className = 'product-tags'; 316 newDiv.appendChild(newAnchor); 317 } 318 } 319 else { 320 if (element.classList.contains('cmp-contentfragment__element--productAsset1')) { 321 const imgTag = document.createElement('img'); 322 imgTag.src = contentValue; 323 newDiv.appendChild(imgTag); 324 newDiv.className = 'product-image'; 325 326 } 327 else if (element.classList.contains('cmp-contentfragment__element--frontPackShot')) { 328 const imgTag = document.createElement('img'); 329 imgTag.src = contentValue; 330 imgTag.alt = frontPackShotAlttextEleValue ? frontPackShotAlttextEleValue : "Alt Text"; 331 newDiv.appendChild(imgTag); 332 newDiv.className = 'product-image'; 333 334 } 335 else if (element.classList.contains('cmp-contentfragment__element--brand')) { 336 const pTag = document.createElement('p'); 337 pTag.textContent = contentValue; 338 newDiv.appendChild(pTag); 339 newDiv.className = 'product-brand'; 340 } 341 else if (element.classList.contains('cmp-contentfragment__element--name')) { 342 const pTag = document.createElement('p'); 343 pTag.textContent = contentValue; 344 newDiv.appendChild(pTag); 345 newDiv.className = 'product-name'; 346 347 } else if (element.classList.contains('cmp-contentfragment__element--productCardShortName')) { 348 const pTag = document.createElement('p'); 349 pTag.textContent = contentValue; 350 newDiv.appendChild(pTag); 351 newDiv.className = 'product-card-short-name'; 352 353 } else if (element.classList.contains('cmp-contentfragment__element--productCardShortDescription')) { 354 const pTag = document.createElement('p'); 355 pTag.textContent = contentValue; 356 newDiv.appendChild(pTag); 357 newDiv.className = 'product-short-description'; 358 359 }else if (element.classList.contains('cmp-contentfragment__element--description')) { 360 const pTag = document.createElement('p'); 361 pTag.textContent = contentValue; 362 newDiv.appendChild(pTag); 363 newDiv.className = 'product-description'; 364 365 }else if (bvRatingsCFProperty && element.classList.contains('cmp-contentfragment__element--'+bvRatingsCFProperty)) { 366 if (enableRatings) { 367 const customDiv = document.createElement('div'); 368 customDiv.setAttribute('data-bv-show', 'inline_rating'); 369 customDiv.setAttribute('data-bv-product-id', contentValue); 370 newDiv.appendChild(customDiv); 371 newDiv.className = 'product-skus'; 372 } 373 374 } else if (element.classList.contains('cmp-contentfragment__element--shortDescription')) { 375 const pTag = document.createElement('p'); 376 pTag.textContent = contentValue; 377 divElement.appendChild(pTag);
378 newDiv.className = 'product-short-description'; 379 newDiv.appendChild(divElement); 380 381 } else if (element.classList.contains('cmp-contentfragment__element--ctalinkExternalUrl')) { 382 if (enableWheretoBuy) { 383 const pTag = document.createElement('p'); 384 pTag.textContent = ctaLabel; 385 pTag.setAttribute('title', productName); 386 newDiv.appendChild(pTag); 387 newDiv.className = 'product-ctaLink'; 388 } 389 } 390 else if (element.classList.contains('cmp-contentfragment__element--tags')) { 391 const ulTag = document.createElement('ul'); 392 const rawTagsContent = element.querySelector('.cmp-contentfragment__element-value')?.innerHTML.trim(); 393 const tagsValue = rawTagsContent.split(',').map(tag => tag.trim()); 394 tagsValue.forEach(tag => { 395 const liTag = document.createElement('li'); 396 liTag.textContent = decodeTagLabel(tag); 397 ulTag.appendChild(liTag); 398 }); 399 newDiv.className = 'product-tags'; 400 newDiv.appendChild(ulTag); 401 } 402 } 403 element.appendChild(newDiv); 404 } catch (error) { 405 // Elements are rendered in authored order, so a failure here would otherwise drop the 406 // tags element that follows and silently make the card unfilterable. 407 console.error('contentfragmentlist: element failed to process', error); 408 } 409 }); 410 } 411 412 if (Granite && Granite.author) { 413 Granite.$(window).on("dialog-closed", () => { 414 processArticles(); 415 }); 416 } else { 417 document.addEventListener("DOMContentLoaded", processArticles); 418 } 419 420 processArticles(); 421 422})(document, window.Granite);
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.