1/** 2 * Time in milliseconds before a stored parameter expires (1 hour). 3 * @constant {number} 4 */ 5const EXPIRATION_MS = 3600000; 6 7/** 8 * Retrieves the specified query parameter value from the current URL. 9 * 10 * @param {string} name - The name of the query parameter to retrieve. 11 * @return {string|null} The value of the query parameter if it exists, or null if it does not exist. 12 */ 13function urlParam(name) { 14 const urlParams = new URLSearchParams(window.location.search); 15 const param = urlParams.get(name); 16 return param ? param.split('?')[0] : null; 17} 18 19/** 20 * Saves a value to LocalStorage with an expiration timestamp. 21 * 22 * @param {string} key - The key to store. 23 * @param {string} value - The value to store. 24 */ 25function setCachedParam(key, value) { 26 const expiresAt = new Date().getTime() + EXPIRATION_MS; 27 localStorage.setItem(key, value); 28 localStorage.setItem(key + '_exp', expiresAt); 29} 30 31/** 32 * Retrieves a parameter by name from URL or LocalStorage. 33 * Prioritizes URL. If found (in URL or valid Storage), refreshes the Storage cache. 34 * 35 * @param {string} name The name of the parameter to retrieve. 36 * @return {string|boolean} The value of the parameter if found, or `false`. 37 */ 38function resolveAndCacheParam(name) { 39 let lStorage = localStorage.getItem(name); 40 41 // Check expiration 42 if (lStorage) { 43 const lStorageExpire = localStorage.getItem(name + '_exp'); 44 if (lStorageExpire && new Date().getTime() > lStorageExpire) { 45 localStorage.removeItem(name); 46 localStorage.removeItem(name + '_exp'); 47 lStorage = false; 48 } 49 } 50 51 // URL takes precedence over Storage 52 const param = urlParam(name) || lStorage; 53 54 if (param) { 55 setCachedParam(name, param); 56 } 57 58 return param; 59} 60 61/**
62 * Initializes URL parameters by parsing `window.urlParams` configuration. 63 * Handles special logic for specific paths (e.g., /moldova). 64 * 65 * @return {Object} A flat object containing parameter keys and values. e.g., { "a_box": "123" } 66 */ 67function initUrlParams() { 68 const params = {}; 69 let configKeys = []; 70 71 try { 72 configKeys = JSON.parse(window.urlParams || '[]'); 73 } catch (e) { 74 console.warn('Failed to parse window.urlParams', e); 75 } 76 77 // 1. Resolve standard configuration params 78 configKeys.forEach(key => { 79 const val = resolveAndCacheParam(key); 80 if (val) { 81 params[key] = val; 82 } 83 }); 84 85 // 2. Apply overrides (e.g. Moldova special case) 86 // Using a flat object means simple assignment handles "last unique value" logic naturally. 87 if (window.location.href.includes('/moldova')) { 88 const moldovaKey = 'a_box'; 89 const moldovaVal = 'op_792ea190'; 90 91 // Force update storage and internal state 92 setCachedParam(moldovaKey, moldovaVal); 93 params[moldovaKey] = moldovaVal; 94 } 95 96 return params; 97} 98 99/**
100 * Updates outbound links on the page by appending specified query parameters to the URLs. 101 * 102 * @param {Array<Object>} paramsToAdd - An array of objects representing query parameters to add to outbound links. 103 * Each object should contain a single key-value pair where the key is the 104 * parameter name and the value is the parameter value. 105 * @return {void} This method does not return a value. 106 */ 107function updateOutboundLinks(paramsToAdd) { 108 const currentHostname = window.location.hostname; 109 const paramEntries = Object.entries(paramsToAdd); 110 111 if (paramEntries.length === 0) return; 112 113 document.querySelectorAll('a').forEach(linkElement => { 114 const href = linkElement.getAttribute('href'); 115 116 if (!href || (!href.startsWith('http') && !href.startsWith('//'))) { 117 return; 118 } 119 120 try { 121 // Use URL API for robust parsing 122 const targetUrl = new URL(href, window.location.origin); 123 124 // Check if external domain 125 if (targetUrl.hostname === currentHostname) { 126 return; 127 } 128 129 // Append parameters 130 paramEntries.forEach(([key, value]) => { 131 if (value != null) { 132 targetUrl.searchParams.set(key, value); 133 } 134 }); 135 136 linkElement.setAttribute('href', targetUrl.toString()); 137 } catch (e) { 138 // Ignore invalid URLs 139 } 140 }); 141} 142 143document.addEventListener('DOMContentLoaded', function () { 144 const paramsMap = initUrlParams(); 145 // Check if the object has at least one key 146 if (Object.keys(paramsMap).length > 0) { 147 updateOutboundLinks(paramsMap); 148 } 149});
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.