optimizely.js (4065B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 /** 6 * Bug 1714431 - Shim Optimizely 7 * 8 * This shim stubs out window.optimizely for those sites which 9 * break when it is not successfully loaded. 10 */ 11 12 if (!window.optimizely?.state) { 13 const behavior = { 14 query: () => [], 15 }; 16 17 const dcp = { 18 getAttributeValue() {}, 19 waitForAttributeValue: () => Promise.resolve(), 20 }; 21 22 const data = { 23 accountId: "", 24 audiences: {}, 25 campaigns: {}, 26 clientName: "js", 27 clientVersion: "0.166.0", 28 dcpServiceId: null, 29 events: {}, 30 experiments: {}, 31 groups: {}, 32 pages: {}, 33 projectId: "", 34 revision: "", 35 snippetId: null, 36 variations: {}, 37 }; 38 39 const activationId = String(Date.now()); 40 41 const state = { 42 getActivationId() { 43 return activationId; 44 }, 45 getActiveExperimentIds() { 46 return []; 47 }, 48 getCampaignStateLists() { 49 return {}; 50 }, 51 getCampaignStates() { 52 return {}; 53 }, 54 getDecisionObject() { 55 return null; 56 }, 57 getDecisionString() { 58 return null; 59 }, 60 getExperimentStates() { 61 return {}; 62 }, 63 getPageStates() { 64 return {}; 65 }, 66 getRedirectInfo() { 67 return null; 68 }, 69 getVariationMap() { 70 return {}; 71 }, 72 isGlobalHoldback() { 73 return false; 74 }, 75 }; 76 77 const poll = (fn, to) => { 78 setInterval(() => { 79 try { 80 fn(); 81 } catch (_) {} 82 }, to); 83 }; 84 85 const waitUntil = test => { 86 let interval, resolve; 87 function check() { 88 try { 89 if (test()) { 90 clearInterval(interval); 91 resolve?.(); 92 return true; 93 } 94 } catch (_) {} 95 return false; 96 } 97 return new Promise(r => { 98 resolve = r; 99 if (check()) { 100 resolve(); 101 return; 102 } 103 interval = setInterval(check, 250); 104 }); 105 }; 106 107 const waitForElement = sel => { 108 return waitUntil(() => { 109 document.querySelector(sel); 110 }); 111 }; 112 113 const observeSelector = (sel, fn, opts) => { 114 let interval; 115 const observed = new Set(); 116 function check() { 117 try { 118 for (const e of document.querySelectorAll(sel)) { 119 if (observed.has(e)) { 120 continue; 121 } 122 observed.add(e); 123 try { 124 fn(e); 125 } catch (_) {} 126 if (opts.once) { 127 clearInterval(interval); 128 } 129 } 130 } catch (_) {} 131 } 132 interval = setInterval(check, 250); 133 const timeout = { opts }; 134 if (timeout) { 135 setTimeout(() => { 136 clearInterval(interval); 137 }, timeout); 138 } 139 }; 140 141 const utils = { 142 Promise: window.Promise, 143 observeSelector, 144 poll, 145 waitForElement, 146 waitUntil, 147 }; 148 149 const visitorId = { 150 randomId: "", 151 }; 152 153 let browserVersion = ""; 154 try { 155 browserVersion = navigator.userAgent.match(/rv:(.*)\)/)[1]; 156 } catch (_) {} 157 158 const visitor = { 159 browserId: "ff", 160 browserVersion, 161 currentTimestamp: Date.now(), 162 custom: {}, 163 customBehavior: {}, 164 device: "desktop", 165 device_type: "desktop_laptop", 166 events: [], 167 first_session: true, 168 offset: 240, 169 referrer: null, 170 source_type: "direct", 171 visitorId, 172 }; 173 174 window.optimizely = { 175 data: { 176 note: "Obsolete, use optimizely.get('data') instead", 177 }, 178 get(e) { 179 switch (e) { 180 case "behavior": 181 return behavior; 182 case "data": 183 return data; 184 case "dcp": 185 return dcp; 186 case "jquery": 187 throw new Error("jQuery not implemented"); 188 case "session": 189 return undefined; 190 case "state": 191 return state; 192 case "utils": 193 return utils; 194 case "visitor": 195 return visitor; 196 case "visitor_id": 197 return visitorId; 198 } 199 return undefined; 200 }, 201 initialized: true, 202 push() {}, 203 state: {}, 204 }; 205 }