1import { calcVariable } from './config.js'; 2import { 3 getBrand, 4 getLocale, 5 removeKelloggsEpsilon, 6 removeNonAlphabetCharsEpsilon, 7} from './aem.js'; 8import { fallbackFetchRecipeDetail } from './fetch.js'; 9 10const pathName = window.location.pathname; 11const link = window.location.href; 12const variables = await calcVariable(); 13const { servletUrl } = variables; 14let promoId = ''; 15let department = ''; 16let productId = ''; 17let brand = ''; 18let loc = ''; 19let cachebuster = ''; 20let promoString = ''; 21let departmentString = ''; 22let productString = ''; 23let brandString = ''; 24let locString = ''; 25let newPromoId = ''; 26let recipeBrand = ''; 27let recipeBrandString = ''; 28 29async function waitHeadLoad() { 30 return new Promise((resolve) => { 31 if (document.head) { 32 resolve(document.head); 33 return; 34 } 35 const observer = new MutationObserver((mutations) => { // eslint-disable-line no-unused-vars 36 if (document.head) { 37 observer.disconnect(); 38 resolve(document.head); 39 } 40 }); 41 observer.observe(document.head, { 42 childList: true, 43 subtree: true, 44 }); 45 }); 46} 47 48async function generatePromoId() { 49 const headContent = await waitHeadLoad(); 50 const promoMeta = headContent.querySelector('meta[name="promo-id"]'); 51 if (!promoMeta) { 52 promoId = ''; 53 return promoId; 54 } 55 promoId = promoMeta.content; 56 if (!newPromoId) { 57 return promoId; 58 } 59 return newPromoId; 60} 61 62async function generateDepartment() { 63 const headContent = await waitHeadLoad(); 64 const departmentMeta = headContent.querySelector('meta[name="department"]'); 65 if (!departmentMeta) { 66 department = ''; 67 return department; 68 } 69 department = departmentMeta.content; 70 return department; 71} 72 73async function generateProductId(selector) { 74 if (pathName.includes('/products')) { 75 return new Promise((resolve) => { 76 if (document.querySelector(selector)) { 77 resolve(document.querySelector(selector)); 78 return; 79 } 80 const observer = new MutationObserver((mutations) => { // eslint-disable-line no-unused-vars 81 if (document.querySelector(selector)) { 82 observer.disconnect(); 83 resolve(document.querySelector(selector).dataset.id); 84 } 85 }); 86 observer.observe(document.body, { 87 childList: true, 88 subtree: true, 89 }); 90 }); 91 } 92 return ''; 93} 94 95async function generateBrand(selector) { 96 if (pathName.includes('/products') || pathName.includes('/produits') || pathName.includes('/our-foods/our-brands') || pathName.includes('/nos-aliments/nos-marques')) { 97 return new Promise((resolve) => { 98 if (document.querySelector(selector)) { 99 resolve(document.querySelector(selector).innerHTML); 100 return; 101 } 102 const observer = new MutationObserver((mutations) => { // eslint-disable-line no-unused-vars 103 if (document.querySelector(selector)) { 104 observer.disconnect(); 105 resolve(document.querySelector(selector)); 106 } 107 }); 108 observer.observe(document.body, { 109 childList: true, 110 subtree: true, 111 }); 112 }); 113 } 114 return ''; 115} 116 117function removeTagAndContent(str, tagname) { 118 const doc = new DOMParser().parseFromString(str, 'text/html'); 119 doc.querySelectorAll(tagname).forEach((el) => el.remove()); 120 return doc.body.textContent.trim(); 121} 122 123async function recreateBrand() { 124 let brandEl; 125 if (pathName.includes('/products') || pathName.includes('/produits')) { 126 brandEl = await generateBrand('.product-brand'); 127 } else if (pathName.includes('/our-foods/our-brands') || pathName.includes('/nos-aliments/nos-marques')) { 128 brandEl = await generateBrand('ol li[aria-current="page"]'); 129 } 130 let brandStr = ''; 131 if (brandEl) { 132 typeof brandEl === 'string' ? brandStr = brandEl : brandStr = brandEl.innerHTML; 133 const removeTag = removeTagAndContent(brandStr, 'sup'); 134 const cleanString = removeNonAlphabetCharsEpsilon(removeTag); 135 const cleanName = removeKelloggsEpsilon(cleanString); 136 const newStr = cleanName.replace(/\s+/g, ' '); 137 return newStr; 138 } 139 return getBrand(); 140} 141 142async function getRecipeBrand() { 143 const recipeLocale = getLocale(); 144 const pdpBrand = getBrand(); 145 if (pathName.includes('/recipes/') && recipeLocale === 'en_US') { 146 if (pdpBrand === 'wkkc') { 147 const responce = await fallbackFetchRecipeDetail(); 148 if (responce.recipeBrand) { 149 const cleanString = removeNonAlphabetCharsEpsilon(responce.recipeBrand[0]); 150 const removeKelloggs = removeKelloggsEpsilon(cleanString); 151 const newStr = removeKelloggs.replace(/\s+/g, ' '); 152 return newStr; 153 } 154 } 155 if (pdpBrand === 'rice-krispies') { 156 return 'Rice Krispies'; 157 } 158 } 159 if (pdpBrand === 'kashi' && recipeLocale === 'en_US' && (!pathName.includes('/products'))) { 160 return 'Kashi'; 161 } 162 if (pdpBrand === 'frostedflakes' && recipeLocale === 'en_US' && (!pathName.includes('/products'))) { 163 return 'Frosted Flakes'; 164 } 165 return ''; 166} 167 168async function generateLoc() { 169 const url = encodeURIComponent(link); 170 return url; 171} 172 173async function generateCachebuster() { 174 const timeStamp = Date.now(); 175 // eslint-disable-next-line no-console 176 // console.log('cachebuster', timeStamp); 177 return timeStamp; 178} 179 180async function generateConditionals() { 181 promoId = await generatePromoId('meta[name="promo-id"]'); 182 promoId ? (promoString = `&dtm_promo_id=${promoId}`) : (promoString = ''); 183 // eslint-disable-next-line no-console 184 // console.log('promoString', promoString); 185 department = await generateDepartment('meta[name="department"]'); 186 department ? (departmentString = `&dtmc_department=${department}`) : (departmentString = ''); 187 // eslint-disable-next-line no-console 188 // console.log('department', departmentString); 189 productId = await generateProductId('.product-title'); 190 productId ? productString = `&dtmc_product_id=${productId}` : (productString = ''); 191 // eslint-disable-next-line no-console 192 // console.log('product_id', productString); 193 brand = await recreateBrand(); 194 brand ? (brandString = `&dtmc_brand=${brand}`) : (brandString = ''); 195 recipeBrand = await getRecipeBrand(); 196 recipeBrand ? (recipeBrandString = `&dtmc_brand=${recipeBrand}`) : (recipeBrandString = ''); 197 // eslint-disable-next-line no-console 198 // console.log('brand', brandString); 199 loc = await generateLoc(); 200 loc ? (locString = `&dtmc_loc=${loc}
200`) : (locString = ''); 201 cachebuster = await generateCachebuster(); 202 // eslint-disable-next-line no-console 203 // console.log('loc', locString); 204 const pageTag = `${servletUrl}/tag_path/profile/visit/js/1_0?dtm_cid=82861&dtm_cmagic=e089cd&dtm_fid=101${promoString}${departmentString}${productString}${brandString}${recipeBrandString}${locString}&cachebuster=${cachebuster}`; 205 return pageTag; 206} 207 208const scriptString = await generateConditionals(); 209 210// eslint-disable-next-line no-console 211// console.log('script', scriptString); 212 213const script = document.createElement('script'); 214script.setAttribute('id', 'dtmtag'); 215script.setAttribute('src', scriptString); 216// Export the prepared script, but donât append it here 217 218export default script; 219 220function getViewPromotionDetails() { 221 if (pathName.includes('/our-foods/promotions') || pathName.includes('/nos-aliments/promotions')) { 222 window.onload = function triggerOnPageLoad() { 223 const noofcards = Array.from(document.querySelectorAll('.card')); 224 if (noofcards.length === 0) return; 225 async function promoClickHandler() { 226 newPromoId = '61'; 227 const prevscript = document.getElementById('dtmtag'); 228 if (prevscript) { 229 const conditionalFunction = await generateConditionals(); 230 const newscript = document.createElement('script'); 231 newscript.setAttribute('id', 'dtmtag'); 232 newscript.setAttribute('src', conditionalFunction); 233 prevscript.parentNode.replaceChild(newscript, prevscript); 234 } 235 } 236 noofcards.forEach((card) => { 237 const cardButton = card.querySelector('.button-container'); 238 if (cardButton) cardButton.addEventListener('click', promoClickHandler); 239 }); 240 }; 241 } 242} 243 244getViewPromotionDetails();
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.