1/** 2 * ============================================== 3 * Resident API Utility Functions 4 * ============================================== 5 * This script provides utility functions to interact with the Resident API, 6 * retrieve dynamic content, and update elements on a web page based on current 7 * promotions or configurations. The functions are modular and include checks 8 * to ensure that necessary APIs or data are available before attempting to 9 * perform any operations. 10 * 11 * Functions included: 12 * 13 * 1. isResidentAPI(): 14 * - Checks if the ResidentAPI object is available in the global scope. 15 * - Returns a Promise that resolves to true if ResidentAPI is available, 16 * and false if not after 5 seconds. 17 * 18 * 2. isConfigPromoData(): 19 * - Checks if the promotional configuration data (window.Configuration.activePromo) 20 * is available. 21 * - Returns a Promise that resolves to true if the promo data is available, 22 * and false if not after 5 seconds. 23 * 24 * 3. isEnvQa(): 25 * - Determines if the current environment is a QA environment based on the URL. 26 * - Returns true if the environment is QA, otherwise returns false. 27 * 28 * 4. renderPriceDynamic(): 29 * - Retrieves and displays the dynamic price of a product. 30 * - Takes optional parameters for the CSS class of the elements, the product name, 31 * and the product size. 32 * - Updates the elements with the specified class with the formatted price. 33 * 34 * 5. renderPromoDynamic(): 35 * - Retrieves and displays dynamic promotional content (promo title and taglines). 36 * - Updates the elements with the classes '.render__promoTitle', '.render__tagLine1', 37 * and '.render__tagLine2' with the fetched content. 38 * 39 * 6. renderTotalValue(): 40 * - Retrieves and displays the total value of a product. 41 * - Updates elements with the specified class with the total price. 42 * 43 * 7. renderPriceDynamicV2(): 44 * - Retrieves and displays the dynamic price of a product using a different API version. 45 * - Takes the same parameters as renderPriceDynamic but uses ResidentAPI.getProductPriceV2. 46 * 47 * 8. var appEnvironment: 48 * - A variable to determine the environment (production or QA) based on the host URL.
49 * - Set to 'production' if the host starts with 'www.', otherwise set to 'qa'. 50 */ 51 52 53 54 55/** 56 * Checks if the ResidentAPI object is available in the global scope. 57 * 58 * @returns {Promise<boolean>} A Promise that resolves to true if ResidentAPI 59 * is available, and false if not after 5 seconds. 60 */ 61function isResidentAPI() { 62 return new Promise((resolve) => { 63 const interval = setInterval(() => { 64 if (typeof ResidentAPI !== 'undefined') { 65 clearInterval(interval); 66 resolve(true); 67 } 68 }); 69 70 setTimeout(() => { 71 clearInterval(interval); 72 resolve(false); 73 }, 5000); 74 }); 75 } 76 77 /** 78 * Checks if the promotional configuration data (window.Configuration.activePromo) 79 * is available. 80 * 81 * @returns {Promise<boolean>} A Promise that resolves to true if the promo data 82 * is available, and false if not after 5 seconds. 83 */ 84 85 function isConfigPromoData() { 86 return new Promise((resolve) => { 87 const interval = setInterval(() => { 88 if (typeof window.Configuration.activePromo !== 'undefined') { 89 clearInterval(interval); 90 resolve(true); 91 } 92 }); 93 94 setTimeout(() => { 95 clearInterval(interval); 96 resolve(false); 97 }, 5000); 98 }); 99 } 100 101 /** 102 * Determines if the current environment is a QA environment based on the URL. 103 * 104 * @returns {boolean} true if the environment is QA (On Production it will return false). 105 */ 106 function isEnvQa() { 107 const isQa = 108 document.location.href.includes('qa') || 109 document.location.href.includes('next'); 110 return isQa; 111 } 112 113 /** 114 * Retrieves and displays the dynamic price of a product. 115 * 116 * @param {string} elementClass - The CSS class of the elements where the price 117 * should be rendered. Default is '.render__price'. 118 * @param {string} productName - The name of the product to retrieve the price 119 * for. Default is 'the-nectar-classic-mattress'. 120 * @param {string} size - The size of the product to retrieve the price for. 121 * Default is 'queen'. 122 */ 123 124 125 async function renderPriceDynamic( 126 elementClass = '.render__price', 127 productName = 'the-nectar-classic-mattress', 128 size = 'queen' 129 ) { 130 const priceElements = document.querySelectorAll(elementClass); 131 if (priceElements.length === 0) return; 132 133 const result = await isResidentAPI(); 134 if (result) { 135 const price = await ResidentAPI.getProductPrice(productName, size); 136 const formattedPrice = new Intl.NumberFormat('en-US', { 137 style: 'currency', 138 currency: 'USD', 139 maximumFractionDigits: 0, 140 }).format(price.discountedPrice); 141 142 priceElements.forEach((el) => { 143 el.textContent = formattedPrice; 144 }); 145 } 146 } 147 148 149 150 /** 151 * Retrieves and displays dynamic promotional content (promo title and taglines). 152 * 153 * @returns {Promise<void>} 154 */ 155 async function renderPromoDynamic() { 156 const promoTitleElements = document.querySelectorAll('.render__promoTitle'); 157 const tagLine1Elements = document.querySelectorAll('.render__tagLine1'); 158 const tagLine2Elements = document.querySelectorAll('.render__tagLine2'); 159 160 let dynamicPromoTitle = ''; 161 let dynamicTagline1 = ''; 162 let dynamicTagline2 = ''; 163 164 // If no elements found for either promoTitle or tagLine, exit the function 165 if ( 166 promoTitleElements.length === 0 && 167 tagLine1Elements.length === 0 && 168 tagLine2Elements.length === 0 169 ) 170 return; 171 172 // ==================== Promo Title ==================== 173 try { 174 const isResident = await isResidentAPI(); 175 if (isResident) { 176 const activePromoData = await ResidentAPI?.getPromotionData(); 177 dynamicPromoTitle = activePromoData?.promoTitle || ''; 178 dynamicTagline1 = activePromoData?.promoData?.tagLine1 || ''; 179 dynamicTagline2 = activePromoData?.promoData?.tagLine2 || ''; 180 } 181 } catch (error) { 182 console.error('Error fetching promotion data:', error); 183 } 184 185 186 // Skip updating if no dynamic content is available 187 if (!dynamicPromoTitle && !dynamicTagline1 && !dynamicTagline2) return; 188 189 // ==================== Update Elements ====================
190 promoTitleElements.forEach((el) => { 191 el.textContent = dynamicPromoTitle; 192 }); 193 194 tagLine1Elements.forEach((el) => { 195 el.textContent = dynamicTagline1; 196 }); 197 198 tagLine2Elements.forEach((el) => { 199 el.textContent = dynamicTagline2; 200 }); 201 } 202 203 // AppEnviournemt variable 204 var appEnvironment = window.location.host.indexOf('www.') === 0 ? 'production' : 'qa'; 205 206 // Render-total value 207 208 async function renderTotalValue(elementClass, productName, size) { 209 const priceElements = document.querySelectorAll(`${elementClass}`); 210 211 const res = await isResidentAPI(); 212 if (res) { 213 const price = await ResidentAPI.getProductTotalValue(productName, size); 214 priceElements.forEach((el) => { 215 el.textContent = `$${price}`; 216 }); 217 } 218 } 219 220 221 // RenderPriceV2 Function 222 223 async function renderPriceDynamicV2( 224 elementClass = '.render__price', 225 productName = 'the-nectar-classic-mattress', 226 size = 'queen' 227 ) { 228 const priceElements = document.querySelectorAll(elementClass); 229 if (priceElements.length === 0) return; 230 231 const result = await isResidentAPI(); 232 if (result) { 233 const price = await ResidentAPI.getProductPriceV2(productName, [{ name: 'Size', value: size }]); 234 const formattedPrice = new Intl.NumberFormat('en-US', { 235 style: 'currency', 236 currency: 'USD', 237 maximumFractionDigits: 0, 238 }).format(price.discountedPrice); 239 240 priceElements.forEach((el) => { 241 el.textContent = formattedPrice; 242 }); 243 } 244 } 245
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.