1/* 2* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com) 3* 4* @author Jpresta 5* @copyright Jpresta 6* @license See the license of this module in file LICENSE.txt, thank you. 7*/ 8 9function jprestaPcGetParameterValue(e) { 10 let t = "[\\?&]" + e + "=([^&#]*)"; 11 let n = new RegExp(t); 12 let r = n.exec(window.location.href); 13 if (r == null) return ""; 14 else return r[1] 15} 16 17function jprestaPcSplitUri(uri) { 18 let splitRegExp = new RegExp('^' + '(?:' + '([^:/?#.]+)' + ':)?' + '(?://' + '(?:([^/?#]*)@)?' + '([\\w\\d\\-\\u0100-\\uffff.%]*)' + '(?:(:[0-9]+))?' + ')?' + '([^?#]+)?' + '(?:(\\?[^#]*))?' + '(?:(#.*))?' + '$'); 19 let split = uri.match(splitRegExp); 20 for (let i = 1; i < 8; i++) { 21 if (typeof split[i] === 'undefined') { 22 split[i] = ''; 23 } 24 } 25 return { 26 'scheme': split[1], 27 'user_info': split[2], 28 'domain': split[3], 29 'port': split[4], 30 'path': split[5], 31 'query_data': split[6], 32 'fragment': split[7] 33 } 34} 35 36function jprestaPcSetCookie(cname, cvalue, ttl_minutes, path) { 37 let d = new Date(); 38 d.setTime(d.getTime() + (ttl_minutes*60*1000)); 39 let expires = "expires="+ d.toUTCString(); 40 document.cookie = cname + "=" + cvalue + ";" + expires + ";path=" + path; 41} 42 43function jprestaPcGetCookie(cname, defaultValue) { 44 if (defaultValue === undefined) { 45 defaultValue = null; 46 } 47 let name = cname + "="; 48 let decodedCookie = decodeURIComponent(document.cookie); 49 let ca = decodedCookie.split(';'); 50 for(let i = 0; i <ca.length; i++) { 51 let c = ca[i]; 52 while (c.charAt(0) === ' ') { 53 c = c.substring(1); 54 } 55 if (c.indexOf(name) === 0) { 56 return c.substring(name.length, c.length); 57 } 58 } 59 return defaultValue; 60} 61 62function jprestaGetTTFB() { 63 let timing = null; 64 if (typeof window.performance.timing !== 'undefined') { 65 timing = window.performance.timing; 66 } 67 else { 68 timing = window.performance.getEntriesByType('navigation')[0]; 69 } 70 return timing.responseStart - timing.requestStart; 71} 72 73function jprestaIsBot() { 74 return /bot|googlebot|crawler|spider|robot|crawling|gtmetrix|chrome-lighthouse/i.test(navigator.userAgent); 75} 76 77function jprestaGetCacheType() {
78 let cache_type = -2; 79 let timing = null; 80 if (typeof window.performance.getEntriesByType == 'function') { 81 timing = window.performance.getEntriesByType('navigation')[0]; 82 } 83 if (!timing && typeof window.performance.timing !== 'undefined') { 84 timing = window.performance.timing; 85 } 86 if (timing && timing.transferSize === 0) { 87 cache_type = 2; 88 } 89 else if (timing && typeof timing.serverTiming != 'undefined') { 90 for (let i = 0; i < timing.serverTiming.length; i++) { 91 if (timing.serverTiming[i].name === 'jpresta_cache') { 92 cache_type = parseInt(timing.serverTiming[i].description); 93 break; 94 } 95 } 96 } 97 return cache_type; 98} 99 100/** 101 * Forward dbgpagecache parameter 102 */ 103function jprestaPcForwardDbgpagecacheParameter() { 104 try { 105 if (typeof prestashop !== 'undefined' && prestashop.urls && prestashop.urls.base_url) { 106 baseDir = prestashop.urls.base_url; 107 } else if (typeof baseDir === 'undefined') { 108 baseDir = window.location.origin + '/'; 109 } 110 111 if (window.location.href.indexOf("dbgpagecache=") > 0) { 112 $("a:not(.pagecache)").each(function () { 113 let e = $(this).attr("href"); 114 let t = this.search; 115 let n = "dbgpagecache=" + jprestaPcGetParameterValue("dbgpagecache"); 116 let r = baseDir.replace("https", "http"); 117 if (typeof e !== "undefined" && e.substr(0, 1) !== "#" && (e.replace("https", "http").substr(0, r.length) === r || e.indexOf('://') === -1) && e.indexOf('javascript:') === -1 && e.indexOf('mailto:') === -1 && e.indexOf('tel:') === -1 && e.indexOf('callto:') === -1) { 118 if (t.length === 0) this.search = n; 119 else this.search += "&" + n; 120 } 121 }); 122 console.log("Page Cache Ultimate - Parameter dbgpagecache has been added to all links"); 123 } 124 } catch (e) { 125 console.warn("Page Cache Ultimate - Cannot forward dbgpagecache parameter on all links: " + e.message, e); 126 } 127} 128 129jprestaPcStartsWith = function(str, search) { 130 return typeof str === 'string' && str.substr(0, search.length) === search; 131}; 132 133jprestaPcProcessDynamicModules = function(dyndatas) { 134 for (let key in dyndatas) { 135 if (key === 'js') { 136 // Keep spaces arround 'key', some Prestashop removes [key] otherwise (?!) 137 $('body').append(dyndatas[ key ]); 138 } 139 else if (jprestaPcStartsWith(key, 'dyn')) { 140 // Keep spaces arround 'key', some Prestashop removes [key] otherwise (?!) 141 try { 142 $('#'+key).replaceWith(dyndatas[ key ]); 143 } 144 catch (error) { 145 console.error('Page Cache Ultimate - A javasript error occured during the "eval" of the refreshed content ' + key + ': ' + error); 146 } 147 } 148 } 149 if (typeof pcRunDynamicModulesJs == 'function') { 150 pcRunDynamicModulesJs(); 151 } 152 $('header a[href]').each(function() { 153 $(this).attr('href', $(this).attr('href') 154 .replace(/(%26|%3F|\?|&)ajax(%3D|=)1(%26|&)page_cache_dynamics_mods(%3D|=)1(%26|&)action(%3D|=)refresh_dynamic_mods/, '') 155 ); 156 }); 157 console.timeEnd('Page Cache Ultimate - Dynamic modules have been refreshed in ') 158 if (typeof prestashop != 'undefined' && typeof prestashop.emit == 'function') { 159 prestashop.emit('jprestaDynamicContentLoaded'); 160 } 161}; 162 163/** 164 * Refresh dynamic modules 165 */ 166function jprestaPcRefreshDynamicModules(cacheSource) { 167 try { 168 console.time('Page Cache Ultimate - Dynamic modules have been refreshed in ') 169 let dynDatas = {}; 170 dynDatas['cache_source'] = cacheSource; 171 dynDatas['ttfb'] = jprestaGetTTFB(); 172 $('.dynhook').each(function(index, domhook){ 173 dynDatas['hk_' + index] = $(this).attr('id') + '|' + $(this).data('hooktype') + '|' + $(this).data('module') + '|' + $(this).data('hook') + '|' + $(this).data('hookargs'); 174 }); 175 let urlparts = jprestaPcSplitUri(document.URL); 176 let url = urlparts['scheme'] + '://' + urlparts['domain'] + urlparts['port'] + urlparts['path'] + urlparts['query_data']; 177 let indexEnd = url.indexOf('?'); 178 if (indexEnd >= 0 && indexEnd < url.length) { 179 url += '&ajax=1&page_cache_dynamics_mods=1&action=refresh_dynamic_mods'; 180 } 181 else { 182 url += '?ajax=1&page_cache_dynamics_mods=1&action=refresh_dynamic_mods'; 183 } 184 let headers = {}; 185 if (document.referrer) { 186 headers['x-jpresta-referer'] = document.referrer; 187 } 188 $.ajax({url: url, type: 'POST', data: dynDatas, dataType: 'json', cache: false, headers: headers, 189 success: jprestaPcProcessDynamicModules, 190 error: function(jqXHR, textStatus, errorThrown) { 191 let dyndatas; 192 try { 193 let indexStart = jqXHR.responseText.indexOf('{'); 194 let responseFixed = jqXHR.responseText.substring(indexStart, jqXHR.responseText.length); 195 dyndatas = $.parseJSON(responseFixed); 196 if (dyndatas != null) { 197 jprestaPcProcessDynamicModules(dyndatas); 198 return; 199 } 200 } catch (err) { 201 console.error("Page Cache Ultimate - Cannot parse data of error=" + err, err); 202 } 203 console.error("Page Cache Ultimate - Cannot display dynamic modules: error=" + textStatus + " exception=" + errorThrown); 204 console.log("Page Cache Ultimate - Dynamic module URL: " + url); 205 }}); 206 } catch (e) { 207 console.error("Page Cache Ultimate - Cannot display dynamic modules: " + e.message, e); 208 } 209} 210 211/** 212 * Stats TTFB (when using back/forward cache) 213 */ 214function jprestaPcSendStats(cacheSource, ttfb) { 215 try { 216 console.time('Page Cache Ultimate - Sending stats in '); 217 let dynDatas = {};
218 dynDatas['cache_source'] = cacheSource; 219 dynDatas['ttfb'] = ttfb; 220 let urlparts = jprestaPcSplitUri(document.URL); 221 let url = urlparts['scheme'] + '://' + urlparts['domain'] + urlparts['port'] + urlparts['path'] + urlparts['query_data']; 222 let indexEnd = url.indexOf('?'); 223 if (indexEnd >= 0 && indexEnd < url.length) { 224 url += '&ajax=1&page_cache_dynamics_mods=1&action=refresh_dynamic_mods&stats'; 225 } 226 else { 227 url += '?ajax=1&page_cache_dynamics_mods=1&action=refresh_dynamic_mods&stats'; 228 } 229 $.ajax({url: url, type: 'POST', data: dynDatas, dataType: 'json', cache: false, 230 error: function(jqXHR, textStatus, errorThrown) { 231 console.error("Page Cache Ultimate - Cannot display dynamic modules: error=" + textStatus + " exception=" + errorThrown); 232 console.log("Page Cache Ultimate - Stats URL: " + url); 233 }, 234 complete: function() { 235 console.timeEnd('Page Cache Ultimate - Sending stats in '); 236 } 237 }); 238 } catch (e) { 239 console.error("Page Cache Ultimate - Cannot stats: " + e.message, e); 240 } 241} 242 243let jprestaUpdateCartTryCount = 0; 244 245function jprestaUpdateCart() { 246 // Refresh the cart 247 if (typeof prestashop !== 'undefined' && typeof prestashop.emit == 'function') { 248 if (typeof prestashop._events['updateCart'] == 'undefined') { 249 if (jprestaUpdateCartTryCount < 10) { 250 // The cart is not yet attch to the event so we do it a little bit later 251 jprestaUpdateCartTryCount++; 252 console.log('Page Cache Ultimate - Cart is not ready, retrying...'); 253 setTimeout(jprestaUpdateCart, 100); 254 return; 255 } 256 else { 257 console.log('Page Cache Ultimate - Cart is not ready, NOT retrying because we tried too many times.'); 258 } 259 } 260 if (typeof jprestaUseCreativeElements == 'undefined' || !jprestaUseCreativeElements) { 261 // >= PS 1.7 262 console.log('Page Cache Ultimate - Refreshing the cart (PS >= 1.7)...'); 263 // Need to put it in a setTimeout to let other modules subscribes to the event 264 setTimeout("prestashop.emit('updateCart', {reason: {linkAction: 'refresh'}, resp: {errors: []}})", 10); 265 } 266 else { 267 // For CreativeElements 268 console.log('Page Cache Ultimate - Refreshing the cart (CreativeElements)...'); 269 $.ajax({ 270 url: prestashop.urls.pages.cart, 271 method: 'POST', 272 dataType: 'json', 273 data: { 274 ajax: 1, 275 action: 'update' 276 } 277 }).then(function(resp) { 278 if (resp.success && resp.cart) { 279 prestashop.emit('updateCart', { 280 reason: { 281 linkAction: 'refresh' 282 }, 283 resp: resp 284 }); 285 } 286 }); 287 } 288 } 289 else if(typeof ajaxCart !== 'undefined') { 290 // < PS 1.7 291 console.log('Page Cache Ultimate - Refreshing the cart (PS 1.5/1.6)...'); 292 $.ajax({ 293 type: 'POST', 294 headers: {"cache-control": "no-cache"}, 295 url: baseUri + '?rand=' + new Date().getTime(), 296 async: true, 297 cache: false, 298 dataType: "json", 299 data: 'controller=cart&ajax=1&token=' + static_token, 300 success: function (jsonData) { 301 ajaxCart.updateCart(jsonData); 302 } 303 }); 304 } 305} 306 307window.addEventListener('load', function(event) { 308 if (jprestaIsBot()) { 309 // For bots just send stats 310 jprestaPcSendStats(jprestaGetCacheType(), jprestaGetTTFB()); 311 return; 312 } 313 if (typeof jprestaUpdateCartDirectly != 'undefined' && jprestaUpdateCartDirectly) { 314 // Refresh the cart right now instead of waiting after dynamic modules are refreshed 315 if (typeof $ == 'function') { 316 // This hack makes sure the event "updateCart" will be emitted after all modules are attached "on" it 317 $(document).ready(jprestaUpdateCart); 318 } 319 else { 320 jprestaUpdateCart(); 321 } 322 } 323 // jpresta_cache_source => -1=cannot be cached; 0=no cache; 1=server cache; 2=browser cache, 3=static cache, 4=back/forward cache
324 let cacheSource = jprestaGetCacheType(); 325 switch (cacheSource) { 326 case -2: 327 jprestaPcRefreshDynamicModules(cacheSource); 328 console.log('Page Cache Ultimate - Cannot determine the cache type :-('); 329 break; 330 case -1: 331 console.log('Page Cache Ultimate - Cannot be cached'); 332 break; 333 case 0: 334 jprestaPcRefreshDynamicModules(cacheSource); 335 console.log('Page Cache Ultimate - No cache was used'); 336 break; 337 case 1: 338 jprestaPcRefreshDynamicModules(cacheSource); 339 console.log('Page Cache Ultimate - Server cache was used'); 340 break; 341 case 2: 342 jprestaPcRefreshDynamicModules(cacheSource); 343 console.log('Page Cache Ultimate - Browser cache was used'); 344 break; 345 case 3: 346 jprestaPcRefreshDynamicModules(cacheSource); 347 console.log('Page Cache Ultimate - Static cache was used'); 348 break; 349 case 4: 350 // Handled by 'pageshow' event 351 break; 352 } 353 $('.pctype' + cacheSource).show(); 354 jprestaPcForwardDbgpagecacheParameter(); 355 let ctxUuid = jprestaPcGetCookie('jpresta_cache_context', false); 356 if (ctxUuid) { 357 console.log('Page Cache Ultimate - Displaying the page with context \x1B[1;4m' + ctxUuid + '\x1B[m'); 358 } 359}); 360 361// Refresh the cart when back/forward cache is used 362// pageshow is not always executed, only when the back/forward cache is used 363window.addEventListener('pageshow', function(event) { 364 if (event.persisted) { 365 jprestaPcSendStats(4, 0); 366 // Refresh the cart 367 console.log('Page Cache Ultimate - Back/forward cache is used'); 368 jprestaUpdateCart(); 369 } 370}); 371 372window.addEventListener('resize', function(event) { 373 document.cookie = "jpresta_cache_context=;path=/;expires=Thu, 01 Jan 1970 00:00:00 GMT"; 374});
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.