UNPKG

66.2 kBJavaScriptView Raw
1/* Partytown 0.2.1 - MIT builder.io */
2(self => {
3 const WinIdKey = Symbol();
4 const InstanceIdKey = Symbol();
5 const NodeNameKey = Symbol();
6 const NamespaceKey = Symbol();
7 const ApplyPathKey = Symbol();
8 const InstanceStateKey = Symbol();
9 const HookContinue = Symbol();
10 const HookPrevent = Symbol();
11 const webWorkerInstances = new Map;
12 const webWorkerRefsByRefId = {};
13 const webWorkerRefIdsByRef = new WeakMap;
14 const nodeConstructors = {};
15 const envGlobalConstructors = new Map;
16 const webWorkerCtx = {};
17 const environments = {};
18 const cachedDimensions = new Map;
19 const cachedStructure = new Map;
20 const commaSplit = str => str.split(",");
21 const getterDimensionPropNames = commaSplit("clientWidth,clientHeight,clientTop,clientLeft,innerWidth,innerHeight,offsetWidth,offsetHeight,offsetTop,offsetLeft,outerWidth,outerHeight,pageXOffset,pageYOffset,scrollWidth,scrollHeight,scrollTop,scrollLeft");
22 const nodeStructurePropNames = commaSplit("childNodes,firstChild,isConnected,lastChild,nextSibling,parentElement,parentNode,previousSibling");
23 const elementStructurePropNames = commaSplit("childElementCount,children,firstElementChild,lastElementChild,nextElementSibling,previousElementSibling");
24 const structureChangingMethodNames = commaSplit("insertBefore,remove,removeChild,replaceChild");
25 const dimensionChangingSetterNames = commaSplit("className,width,height,hidden,innerHTML,innerText,textContent");
26 const dimensionChangingMethodNames = commaSplit("setAttribute,setProperty");
27 const elementGetterDimensionMethodNames = commaSplit("getClientRects,getBoundingClientRect");
28 const windowGetterDimensionMethodNames = [ "getComputedStyle" ];
29 const eventTargetMethods = commaSplit("addEventListener,dispatchEvent,removeEventListener");
30 const noop = () => true;
31 const len = obj => obj.length;
32 const getConstructorName = obj => {
33 try {
34 return obj.constructor.name;
35 } catch (e) {}
36 return "";
37 };
38 const EMPTY_ARRAY = [];
39 const randomId = () => Math.round(999999999 * Math.random() + 4);
40 const defineProperty = (obj, memberName, descriptor) => Object.defineProperty(obj, memberName, {
41 ...descriptor,
42 configurable: true
43 });
44 const defineConstructorName = (Cstr, value) => defineProperty(Cstr, "name", {
45 value: value
46 });
47 const definePrototypeProperty = (Cstr, memberName, descriptor) => defineProperty(Cstr.prototype, memberName, descriptor);
48 const definePrototypePropertyDescriptor = (Cstr, propertyDescriptorMap) => Object.defineProperties(Cstr.prototype, propertyDescriptorMap);
49 const definePrototypeValue = (Cstr, memberName, value) => definePrototypeProperty(Cstr, memberName, {
50 value: value,
51 writable: true
52 });
53 const hasInstanceStateValue = (instance, stateKey) => stateKey in instance[InstanceStateKey];
54 const getInstanceStateValue = (instance, stateKey) => instance[InstanceStateKey][stateKey];
55 const setInstanceStateValue = (instance, stateKey, stateValue) => instance[InstanceStateKey][stateKey] = stateValue;
56 const setWorkerRef = (ref, refId) => {
57 refId = webWorkerRefIdsByRef.get(ref);
58 if (!refId) {
59 webWorkerRefIdsByRef.set(ref, refId = randomId());
60 webWorkerRefsByRefId[refId] = ref;
61 }
62 return refId;
63 };
64 const logWorker = (msg, winId = -1) => {
65 try {
66 const config = webWorkerCtx.$config$;
67 if (config.logStackTraces) {
68 const frames = (new Error).stack.split("\n");
69 const i = frames.findIndex((f => f.includes("logWorker")));
70 msg += "\n" + frames.slice(i + 1).join("\n");
71 }
72 let prefix;
73 let color;
74 if (winId > -1) {
75 prefix = `Worker (${normalizedWinId(winId)}) 🎉`;
76 color = winColor(winId);
77 } else {
78 prefix = self.name;
79 color = "#9844bf";
80 }
81 if (webWorkerCtx.lastLog !== msg) {
82 webWorkerCtx.lastLog = msg;
83 console.debug.apply(console, [ `%c${prefix}`, `background: ${color}; color: white; padding: 2px 3px; border-radius: 2px; font-size: 0.8em;`, msg ]);
84 }
85 } catch (e) {}
86 };
87 const winIds = [];
88 const normalizedWinId = winId => {
89 winIds.includes(winId) || winIds.push(winId);
90 return winIds.indexOf(winId) + 1;
91 };
92 const winColor = winId => {
93 const colors = [ "#00309e", "#ea3655", "#eea727" ];
94 const index = normalizedWinId(winId) - 1;
95 return colors[index] || colors[colors.length - 1];
96 };
97 const getTargetProp = (target, applyPath) => {
98 let n = "";
99 if (target) {
100 const instanceId = target[InstanceIdKey];
101 const cstrName = getConstructorName(target);
102 if (0 === instanceId) {
103 n = "";
104 } else if (1 === instanceId) {
105 n = "document.";
106 } else if (2 === instanceId) {
107 n = "document.documentElement.";
108 } else if (3 === instanceId) {
109 n = "document.head.";
110 } else if (4 === instanceId) {
111 n = "document.body.";
112 } else if (target[NodeNameKey]) {
113 let nodeName = target[NodeNameKey];
114 n = "#text" === nodeName ? "textNode." : "#comment" === nodeName ? "commentNode." : "#document" === nodeName ? "document." : "html" === nodeName ? "doctype." : nodeName.toLowerCase() + ".";
115 } else {
116 n = 2 === target.nodeType ? "attributes." : "CanvasRenderingContext2D" === cstrName ? "context2D." : "CanvasRenderingContextWebGL" === cstrName ? "contextWebGL." : "CSSStyleDeclaration" === cstrName ? "value." : "MutationObserver" === cstrName ? "mutationObserver." : "NamedNodeMap" === cstrName ? "namedNodeMap." : "ResizeObserver" === cstrName ? "resizeObserver." : cstrName.substring(0, 1).toLowerCase() + cstrName.substring(1) + ".";
117 }
118 target[ApplyPathKey] && target[ApplyPathKey].length && (n += [ ...target[ApplyPathKey] ].join(".") + ".");
119 }
120 if (applyPath.length > 1) {
121 const first = applyPath.slice(0, applyPath.length - 1);
122 const last = applyPath[applyPath.length - 1];
123 if (!isNaN(last)) {
124 return n + `${first.join(".")}[${last}]`;
125 }
126 }
127 return n + applyPath.join(".");
128 };
129 const getLogValue = (applyPath, v) => {
130 const type = typeof v;
131 if (void 0 === v) {
132 return "undefined";
133 }
134 if ("boolean" === type || "number" === type || null == v) {
135 return JSON.stringify(v);
136 }
137 if ("string" === type) {
138 return applyPath.includes("cookie") ? JSON.stringify(v.substr(0, 10) + "...") : JSON.stringify(v.length > 50 ? v.substr(0, 40) + "..." : v);
139 }
140 if (Array.isArray(v)) {
141 return `[${v.map(getLogValue).join(", ")}]`;
142 }
143 if ("object" === type) {
144 const instanceId = v[InstanceIdKey];
145 if ("number" == typeof instanceId) {
146 if (4 === instanceId) {
147 return "<body>";
148 }
149 if (1 === instanceId) {
150 return "#document";
151 }
152 if (2 === instanceId) {
153 return "<html>";
154 }
155 if (3 === instanceId) {
156 return "<head>";
157 }
158 if (0 === instanceId) {
159 return "window";
160 }
161 if (v[NodeNameKey]) {
162 if (1 === v.nodeType) {
163 return `<${v[NodeNameKey].toLowerCase()}>`;
164 }
165 if (10 === v.nodeType) {
166 return `<!DOCTYPE ${v[NodeNameKey]}>`;
167 }
168 if (v.nodeType <= 11) {
169 return v[NodeNameKey];
170 }
171 }
172 return "¯\\_(ツ)_/¯ instance obj";
173 }
174 return v[Symbol.iterator] ? `[${Array.from(v).map((i => getLogValue(applyPath, i))).join(", ")}]` : "value" in v ? "string" == typeof v.value ? `"${v.value}"` : objToString(v.value) : objToString(v);
175 }
176 return (v => "object" == typeof v && v && v.then)(v) ? "Promise" : "function" === type ? `ƒ() ${v.name || ""}`.trim() : `¯\\_(ツ)_/¯ ${String(v)}`.trim();
177 };
178 const objToString = obj => {
179 const s = [];
180 for (let key in obj) {
181 const value = obj[key];
182 const type = typeof value;
183 "string" === type ? s.push(`${key}: "${value}"`) : "function" === type ? s.push(`${key}: Æ’`) : Array.isArray(type) ? s.push(`${key}: [..]`) : "object" === type && value ? s.push(`${key}: {..}`) : s.push(`${key}: ${String(value)}`);
184 }
185 let str = s.join(", ");
186 str.length > 200 && (str = str.substring(0, 200) + "..");
187 return `{ ${str} }`;
188 };
189 const logDimensionCacheClearMethod = (target, methodName) => {
190 (webWorkerCtx.$config$.logGetters || webWorkerCtx.$config$.logCalls) && logWorker(`Dimension cache cleared from method call ${methodName}()`, target[WinIdKey]);
191 };
192 const taskQueue = [];
193 let asyncMsgTimer = 0;
194 const queue = (instance, $applyPath$, callType, $assignInstanceId$, $groupedGetters$, buffer, task) => {
195 task = {
196 $winId$: instance[WinIdKey],
197 $instanceId$: instance[InstanceIdKey],
198 $applyPath$: [ ...instance[ApplyPathKey], ...$applyPath$ ],
199 $assignInstanceId$: $assignInstanceId$,
200 $groupedGetters$: $groupedGetters$
201 };
202 task.$debug$ = ((target, applyPath, callType) => {
203 let m = getTargetProp(target, applyPath);
204 1 === callType ? m += " (blocking)" : 2 === callType ? m += " (non-blocking)" : 3 === callType && (m += " (non-blocking, no-side-effect)");
205 return m.trim();
206 })(instance, $applyPath$, callType);
207 if (3 === callType) {
208 webWorkerCtx.$postMessage$([ 10, {
209 $msgId$: randomId(),
210 $tasks$: [ task ]
211 } ], buffer ? [ buffer instanceof ArrayBuffer ? buffer : buffer.buffer ] : void 0);
212 } else {
213 taskQueue.push(task);
214 buffer && console.error("buffer must be sent NonBlockingNoSideEffect");
215 if (1 === callType) {
216 return sendToMain(true);
217 }
218 asyncMsgTimer = setTimeout(sendToMain, 20);
219 }
220 };
221 const sendToMain = isBlocking => {
222 clearTimeout(asyncMsgTimer);
223 if (len(taskQueue)) {
224 webWorkerCtx.$config$.logMainAccess && logWorker(`Main access, tasks sent: ${taskQueue.length}`);
225 const endTask = taskQueue[len(taskQueue) - 1];
226 const accessReq = {
227 $msgId$: randomId(),
228 $tasks$: taskQueue.slice()
229 };
230 taskQueue.length = 0;
231 if (isBlocking) {
232 const accessRsp = ((webWorkerCtx, accessReq) => {
233 const sharedDataBuffer = webWorkerCtx.$sharedDataBuffer$;
234 const sharedData = new Int32Array(sharedDataBuffer);
235 Atomics.store(sharedData, 0, 0);
236 webWorkerCtx.$postMessage$([ 9, accessReq ]);
237 Atomics.wait(sharedData, 0, 0);
238 let dataLength = Atomics.load(sharedData, 0);
239 let accessRespStr = "";
240 let i = 0;
241 for (;i < dataLength; i++) {
242 accessRespStr += String.fromCharCode(sharedData[i + 1]);
243 }
244 return JSON.parse(accessRespStr);
245 })(webWorkerCtx, accessReq);
246 const isPromise = accessRsp.$isPromise$;
247 const rtnValue = deserializeFromMain(endTask.$winId$, endTask.$instanceId$, endTask.$applyPath$, accessRsp.$rtnValue$);
248 if (accessRsp.$error$) {
249 if (isPromise) {
250 return Promise.reject(accessRsp.$error$);
251 }
252 throw new Error(accessRsp.$error$);
253 }
254 return isPromise ? Promise.resolve(rtnValue) : rtnValue;
255 }
256 webWorkerCtx.$postMessage$([ 10, accessReq ]);
257 }
258 };
259 const getter = (instance, applyPath, groupedGetters, rtnValue) => {
260 if (webWorkerCtx.$config$.get) {
261 rtnValue = webWorkerCtx.$config$.get(createHookOptions(instance, applyPath));
262 if (rtnValue !== HookContinue) {
263 return rtnValue;
264 }
265 }
266 rtnValue = queue(instance, applyPath, 1, void 0, groupedGetters);
267 ((target, applyPath, rtnValue, restrictedToWorker = false, groupedGetters = false) => {
268 if (webWorkerCtx.$config$.logGetters) {
269 try {
270 const msg = `Get ${getTargetProp(target, applyPath)}, returned: ${getLogValue(applyPath, rtnValue)}${restrictedToWorker ? " (restricted to worker)" : ""}${groupedGetters ? " (grouped getter)" : ""}`;
271 msg.includes("Symbol(") || logWorker(msg, target[WinIdKey]);
272 } catch (e) {}
273 }
274 })(instance, applyPath, rtnValue, false, !!groupedGetters);
275 return rtnValue;
276 };
277 const setter = (instance, applyPath, value, hookSetterValue) => {
278 if (webWorkerCtx.$config$.set) {
279 hookSetterValue = webWorkerCtx.$config$.set({
280 value: value,
281 prevent: HookPrevent,
282 ...createHookOptions(instance, applyPath)
283 });
284 if (hookSetterValue === HookPrevent) {
285 return;
286 }
287 hookSetterValue !== HookContinue && (value = hookSetterValue);
288 }
289 if (dimensionChangingSetterNames.some((s => applyPath.includes(s)))) {
290 cachedDimensions.clear();
291 ((target, propName) => {
292 (webWorkerCtx.$config$.logGetters || webWorkerCtx.$config$.logSetters) && logWorker(`Dimension cache cleared from setter "${propName}"`, target[WinIdKey]);
293 })(instance, applyPath[applyPath.length - 1]);
294 }
295 applyPath = [ ...applyPath, serializeInstanceForMain(instance, value), 0 ];
296 ((target, applyPath, value, restrictedToWorker = false) => {
297 if (webWorkerCtx.$config$.logSetters) {
298 try {
299 applyPath = applyPath.slice(0, applyPath.length - 2);
300 logWorker(`Set ${getTargetProp(target, applyPath)}, value: ${getLogValue(applyPath, value)}${restrictedToWorker ? " (restricted to worker)" : ""}`, target[WinIdKey]);
301 } catch (e) {}
302 }
303 })(instance, applyPath, value);
304 queue(instance, applyPath, 2);
305 };
306 const callMethod = (instance, applyPath, args, callType, assignInstanceId, buffer, rtnValue, methodName) => {
307 if (webWorkerCtx.$config$.apply) {
308 rtnValue = webWorkerCtx.$config$.apply({
309 args: args,
310 ...createHookOptions(instance, applyPath)
311 });
312 if (rtnValue !== HookContinue) {
313 return rtnValue;
314 }
315 }
316 methodName = applyPath[len(applyPath) - 1];
317 applyPath = [ ...applyPath, serializeInstanceForMain(instance, args) ];
318 callType = callType || 1;
319 if ("setAttribute" === methodName && hasInstanceStateValue(instance, args[0])) {
320 setInstanceStateValue(instance, args[0], args[1]);
321 } else if (structureChangingMethodNames.includes(methodName)) {
322 cachedDimensions.clear();
323 cachedStructure.clear();
324 ((target, methodName) => {
325 (webWorkerCtx.$config$.logGetters || webWorkerCtx.$config$.logCalls) && logWorker(`Dimension and DOM structure cache cleared from method call ${methodName}()`, target[WinIdKey]);
326 })(instance, methodName);
327 } else if (dimensionChangingMethodNames.includes(methodName)) {
328 callType = 2;
329 cachedDimensions.clear();
330 logDimensionCacheClearMethod(instance, methodName);
331 }
332 rtnValue = queue(instance, applyPath, callType, assignInstanceId, void 0, buffer);
333 ((target, applyPath, args, rtnValue) => {
334 if (webWorkerCtx.$config$.logCalls) {
335 try {
336 applyPath = applyPath.slice(0, applyPath.length - 1);
337 logWorker(`Call ${getTargetProp(target, applyPath)}(${args.map((v => getLogValue(applyPath, v))).join(", ")}), returned: ${getLogValue(applyPath, rtnValue)}`, target[WinIdKey]);
338 } catch (e) {}
339 }
340 })(instance, applyPath, args, rtnValue);
341 return rtnValue;
342 };
343 const constructGlobal = (instance, cstrName, args) => {
344 ((target, cstrName, args) => {
345 if (webWorkerCtx.$config$.logCalls) {
346 try {
347 logWorker(`Construct new ${cstrName}(${args.map((v => getLogValue([], v))).join(", ")})`, target[WinIdKey]);
348 } catch (e) {}
349 }
350 })(instance, cstrName, args);
351 queue(instance, [ 1, cstrName, serializeInstanceForMain(instance, args) ], 1);
352 };
353 const createHookOptions = (instance, applyPath) => ({
354 name: applyPath.join("."),
355 continue: HookContinue,
356 nodeName: instance[NodeNameKey],
357 constructor: getConstructorName(instance)
358 });
359 const addStorageApi = (win, storageName, items) => {
360 let getIndexByKey = key => items.findIndex((i => i[STORAGE_KEY] === key));
361 let index;
362 let item;
363 let storage = {
364 getItem(key) {
365 index = getIndexByKey(key);
366 return index > -1 ? items[index][STORAGE_VALUE] : null;
367 },
368 setItem(key, value) {
369 index = getIndexByKey(key);
370 index > -1 ? items[index][STORAGE_VALUE] = value : items.push([ key, value ]);
371 callMethod(win, [ storageName, "setItem" ], [ key, value ], 2);
372 },
373 removeItem(key) {
374 index = getIndexByKey(key);
375 index > -1 && items.splice(index, 1);
376 callMethod(win, [ storageName, "removeItem" ], [ key ], 2);
377 },
378 key(index) {
379 item = items[index];
380 return item ? item[STORAGE_KEY] : null;
381 },
382 clear() {
383 items.length = 0;
384 callMethod(win, [ storageName, "clear" ], EMPTY_ARRAY, 2);
385 },
386 get length() {
387 return items.length;
388 }
389 };
390 win[storageName] = storage;
391 };
392 const STORAGE_KEY = 0;
393 const STORAGE_VALUE = 1;
394 class WorkerProxy {
395 constructor(winId, instanceId, applyPath, nodeName, namespace) {
396 this[WinIdKey] = winId;
397 this[InstanceIdKey] = instanceId;
398 this[ApplyPathKey] = applyPath || [];
399 this[NodeNameKey] = nodeName;
400 this[InstanceStateKey] = {};
401 namespace && (this[NamespaceKey] = namespace);
402 }
403 }
404 class WorkerEventTargetProxy extends WorkerProxy {}
405 eventTargetMethods.map((methodName => WorkerEventTargetProxy.prototype[methodName] = function(...args) {
406 return callMethod(this, [ methodName ], args, 2);
407 }));
408 class WorkerTrapProxy extends WorkerProxy {
409 constructor(winId, instanceId, applyPath, nodeName) {
410 super(winId, instanceId, applyPath, nodeName);
411 return new Proxy(this, {
412 get: (instance, propName) => getter(instance, [ propName ]),
413 set(instance, propName, propValue) {
414 setter(instance, [ propName ], propValue);
415 return true;
416 }
417 });
418 }
419 }
420 const lazyLoadMedia = () => {
421 if (!self.ptm) {
422 self.ptm = [ getter, setter, callMethod, constructGlobal, definePrototypePropertyDescriptor, randomId, WorkerProxy, WorkerEventTargetProxy, WinIdKey, InstanceIdKey, ApplyPathKey ];
423 webWorkerCtx.$importScripts$(webWorkerCtx.$libPath$ + "partytown-media.js");
424 }
425 return self.ptm;
426 };
427 const htmlMedia = commaSplit("AUDIO,CANVAS,VIDEO");
428 const windowMediaConstructors = commaSplit("Audio,MediaSource");
429 const getOrCreateNodeInstance = (winId, instanceId, nodeName, namespace, instance) => {
430 instance = webWorkerInstances.get(instanceId);
431 if (!instance) {
432 instance = createNodeInstance(winId, instanceId, nodeName, namespace);
433 webWorkerInstances.set(instanceId, instance);
434 }
435 return instance;
436 };
437 const createNodeInstance = (winId, instanceId, nodeName, namespace) => {
438 htmlMedia.includes(nodeName) && lazyLoadMedia();
439 const NodeCstr = nodeConstructors[nodeName] ? nodeConstructors[nodeName] : nodeName.includes("-") ? nodeConstructors.UNKNOWN : self.HTMLElement;
440 return new NodeCstr(winId, instanceId, [], nodeName, namespace);
441 };
442 const runScriptContent = (env, instanceId, scriptContent, winId, errorMsg) => {
443 try {
444 webWorkerCtx.$config$.logScriptExecution && logWorker(`Execute script (${instanceId}): ${scriptContent.substr(0, 100).split("\n").map((l => l.trim())).join(" ").trim().substr(0, 60)}...`, winId);
445 env.$currentScriptId$ = instanceId;
446 run(env, scriptContent);
447 } catch (contentError) {
448 console.error(scriptContent, contentError);
449 errorMsg = String(contentError.stack || contentError);
450 }
451 env.$currentScriptId$ = -1;
452 return errorMsg;
453 };
454 const run = (env, scriptContent, scriptUrl) => new Function(`with(this){${scriptContent.replace(/\bthis\b/g, "thi$(this)").replace(/\/\/# so/g, "//Xso")};function thi$(t){return t===this?window:t}}` + (scriptUrl ? "\n//# sourceURL=" + scriptUrl : "")).call(env.$window$);
455 const runStateLoadHandlers = (instance, type, handlers) => {
456 handlers = getInstanceStateValue(instance, type);
457 handlers && setTimeout((() => handlers.map((cb => cb({
458 type: type
459 })))));
460 };
461 const resolveToUrl = (env, url, noUserHook, baseLocation) => {
462 baseLocation = env.$location$;
463 while (!baseLocation.host) {
464 env = environments[env.$parentWinId$];
465 baseLocation = env.$location$;
466 if (env.$winId$ === env.$parentWinId$) {
467 break;
468 }
469 }
470 const resolvedUrl = new URL(url || "", baseLocation);
471 if (!noUserHook && webWorkerCtx.$config$.resolveUrl) {
472 const configResolvedUrl = webWorkerCtx.$config$.resolveUrl(resolvedUrl, baseLocation);
473 if (configResolvedUrl) {
474 return configResolvedUrl;
475 }
476 }
477 return resolvedUrl;
478 };
479 const resolveUrl = (env, url, noUserHook) => resolveToUrl(env, url, noUserHook) + "";
480 const getUrl = elm => resolveToUrl(getEnv(elm), getInstanceStateValue(elm, 4));
481 const getPartytownScript = () => `<script src=${JSON.stringify(webWorkerCtx.$libPath$ + "partytown.js")} async><\/script>`;
482 const createImageConstructor = env => class HTMLImageElement {
483 constructor() {
484 this.s = "";
485 this.l = [];
486 this.e = [];
487 }
488 get src() {
489 return this.s;
490 }
491 set src(src) {
492 webWorkerCtx.$config$.logImageRequests && logWorker(`Image() request: ${resolveUrl(env, src)}`, env.$winId$);
493 fetch(resolveUrl(env, src, true), {
494 mode: "no-cors",
495 keepalive: true
496 }).then((rsp => {
497 rsp.ok || 0 === rsp.status ? this.l.map((cb => cb({
498 type: "load"
499 }))) : this.e.map((cb => cb({
500 type: "error"
501 })));
502 }), (() => this.e.forEach((cb => cb({
503 type: "error"
504 })))));
505 }
506 addEventListener(eventName, cb) {
507 "load" === eventName && this.l.push(cb);
508 "error" === eventName && this.e.push(cb);
509 }
510 get onload() {
511 return this.l[0];
512 }
513 set onload(cb) {
514 this.l = [ cb ];
515 }
516 get onerror() {
517 return this.e[0];
518 }
519 set onerror(cb) {
520 this.e = [ cb ];
521 }
522 };
523 class Location extends URL {
524 assign() {
525 logWorker("location.assign(), noop");
526 }
527 reload() {
528 logWorker("location.reload(), noop");
529 }
530 replace() {
531 logWorker("location.replace(), noop");
532 }
533 }
534 class Window extends WorkerProxy {
535 constructor($winId$, $parentWinId$, url) {
536 super($winId$, 0);
537 let _this = this;
538 let globalName;
539 let value;
540 let win;
541 for (globalName in self) {
542 if (!(globalName in _this) && "onmessage" !== globalName) {
543 value = self[globalName];
544 if (null != value) {
545 const isFunction = "function" == typeof value && !value.toString().startsWith("class");
546 _this[globalName] = isFunction ? value.bind(self) : value;
547 }
548 }
549 }
550 Object.getOwnPropertyNames(self).map((globalName => {
551 globalName in _this || (_this[globalName] = self[globalName]);
552 }));
553 envGlobalConstructors.forEach(((GlobalCstr, cstrName) => {
554 _this[cstrName] = defineConstructorName(class {
555 constructor(...args) {
556 const instance = new GlobalCstr($winId$, randomId());
557 constructGlobal(instance, cstrName, args);
558 return instance;
559 }
560 }, cstrName);
561 }));
562 windowMediaConstructors.map((cstrName => defineProperty(_this, cstrName, {
563 get() {
564 delete _this[cstrName];
565 const initMediaConstructors = lazyLoadMedia();
566 const initMediaConstructor = initMediaConstructors[cstrName];
567 return _this[cstrName] = initMediaConstructor(getEnv(_this), _this, cstrName);
568 }
569 })));
570 "trustedTypes" in self && (_this.trustedTypes = self.trustedTypes);
571 win = new Proxy(_this, {
572 has: () => true
573 });
574 environments[$winId$] = {
575 $winId$: $winId$,
576 $parentWinId$: $parentWinId$,
577 $window$: win,
578 $document$: createNodeInstance($winId$, 1, "#document"),
579 $documentElement$: createNodeInstance($winId$, 2, "HTML"),
580 $head$: createNodeInstance($winId$, 3, "HEAD"),
581 $body$: createNodeInstance($winId$, 4, "BODY"),
582 $location$: new Location(url)
583 };
584 _this.requestAnimationFrame = cb => setTimeout((() => cb(performance.now())), 9);
585 _this.cancelAnimationFrame = id => clearTimeout(id);
586 _this.requestIdleCallback = (cb, start) => {
587 start = Date.now();
588 return setTimeout((() => cb({
589 didTimeout: false,
590 timeRemaining: () => Math.max(0, 50 - (Date.now() - start))
591 })), 1);
592 };
593 _this.cancelIdleCallback = id => clearTimeout(id);
594 addStorageApi(_this, "localStorage", webWorkerCtx.$localStorage$);
595 addStorageApi(_this, "sessionStorage", webWorkerCtx.$sessionStorage$);
596 _this.Worker = void 0;
597 return win;
598 }
599 get body() {
600 return getEnv(this).$body$;
601 }
602 get document() {
603 return getEnv(this).$document$;
604 }
605 get documentElement() {
606 return getEnv(this).$documentElement$;
607 }
608 fetch(input, init) {
609 input = "string" == typeof input || input instanceof URL ? String(input) : input.url;
610 return fetch(resolveUrl(getEnv(this), input), init);
611 }
612 get frameElement() {
613 const env = getEnv(this);
614 const parentWinId = env.$parentWinId$;
615 const winId = env.$winId$;
616 return winId === parentWinId ? null : getOrCreateNodeInstance(parentWinId, winId, "IFRAME");
617 }
618 get globalThis() {
619 return this;
620 }
621 get head() {
622 return getEnv(this).$head$;
623 }
624 get location() {
625 return getEnv(this).$location$;
626 }
627 set location(loc) {
628 getEnv(this).$location$.href = loc + "";
629 }
630 get Image() {
631 return createImageConstructor(getEnv(this));
632 }
633 get name() {
634 return name + `${normalizedWinId(this[WinIdKey])} (${this[WinIdKey]})`;
635 }
636 get navigator() {
637 return (env => {
638 const navigator = self.navigator;
639 navigator.sendBeacon = (url, body) => {
640 if (webWorkerCtx.$config$.logSendBeaconRequests) {
641 try {
642 logWorker(`sendBeacon: ${resolveUrl(env, url, true)}${body ? ", data: " + JSON.stringify(body) : ""}`);
643 } catch (e) {
644 console.error(e);
645 }
646 }
647 try {
648 fetch(resolveUrl(env, url, true), {
649 method: "POST",
650 body: body,
651 mode: "no-cors",
652 keepalive: true
653 });
654 return true;
655 } catch (e) {
656 console.error(e);
657 return false;
658 }
659 };
660 return navigator;
661 })(getEnv(this));
662 }
663 get origin() {
664 return getEnv(this).$location$.origin;
665 }
666 get parent() {
667 return environments[getEnv(this).$parentWinId$].$window$;
668 }
669 get self() {
670 return this;
671 }
672 get top() {
673 for (let envWinId in environments) {
674 if (environments[envWinId].$winId$ === environments[envWinId].$parentWinId$) {
675 return environments[envWinId].$window$;
676 }
677 }
678 }
679 get window() {
680 return this;
681 }
682 }
683 const createEnvironment = ({$winId$: $winId$, $parentWinId$: $parentWinId$, $url$: $url$}) => {
684 if (environments[$winId$]) {
685 environments[$winId$].$location$.href = $url$;
686 } else {
687 new Window($winId$, $parentWinId$, $url$);
688 {
689 const winType = $winId$ === $parentWinId$ ? "top" : "iframe";
690 logWorker(`Created ${winType} window ${normalizedWinId($winId$)} environment (${$winId$})`, $winId$);
691 }
692 }
693 webWorkerCtx.$postMessage$([ 6, $winId$ ]);
694 return environments[$winId$];
695 };
696 const getEnv = instance => environments[instance[WinIdKey]];
697 const HTMLSrcElementDescriptorMap = {
698 addEventListener: {
699 value(...args) {
700 const eventName = args[0];
701 const callbacks = getInstanceStateValue(this, eventName) || [];
702 callbacks.push(args[1]);
703 setInstanceStateValue(this, eventName, callbacks);
704 }
705 },
706 async: {
707 get: noop,
708 set: noop
709 },
710 defer: {
711 get: noop,
712 set: noop
713 },
714 onload: {
715 get() {
716 let callbacks = getInstanceStateValue(this, "load");
717 return callbacks && callbacks[0] || null;
718 },
719 set(cb) {
720 setInstanceStateValue(this, "load", cb ? [ cb ] : null);
721 }
722 },
723 onerror: {
724 get() {
725 let callbacks = getInstanceStateValue(this, "error");
726 return callbacks && callbacks[0] || null;
727 },
728 set(cb) {
729 setInstanceStateValue(this, "error", cb ? [ cb ] : null);
730 }
731 }
732 };
733 const innerHTMLDescriptor = {
734 get() {
735 return getInstanceStateValue(this, 3) || "";
736 },
737 set(scriptContent) {
738 setInstanceStateValue(this, 3, scriptContent);
739 }
740 };
741 const HTMLScriptDescriptorMap = {
742 innerHTML: innerHTMLDescriptor,
743 innerText: innerHTMLDescriptor,
744 src: {
745 get() {
746 return getInstanceStateValue(this, 4) || "";
747 },
748 set(url) {
749 const env = getEnv(this);
750 const orgUrl = resolveUrl(env, url, true);
751 url = resolveUrl(env, url);
752 setInstanceStateValue(this, 4, url);
753 setter(this, [ "src" ], url);
754 orgUrl !== url && setter(this, [ "dataset", "ptsrc" ], orgUrl);
755 }
756 },
757 getAttribute: {
758 value(attrName) {
759 return "src" === attrName ? this.src : callMethod(this, [ "getAttribute" ], [ attrName ]);
760 }
761 },
762 setAttribute: {
763 value(attrName, attrValue) {
764 scriptAttrPropNames.includes(attrName) ? this[attrName] = attrValue : callMethod(this, [ "setAttribute" ], [ attrName, attrValue ]);
765 }
766 },
767 textContent: innerHTMLDescriptor,
768 type: {
769 get() {
770 return getter(this, [ "type" ]);
771 },
772 set(type) {
773 if (!isScriptJsType(type)) {
774 setInstanceStateValue(this, 5, type);
775 setter(this, [ "type" ], type);
776 }
777 }
778 },
779 ...HTMLSrcElementDescriptorMap
780 };
781 const isScriptJsType = scriptType => !scriptType || "text/javascript" === scriptType;
782 const scriptAttrPropNames = commaSplit("src,type");
783 class Node extends WorkerProxy {
784 appendChild(node) {
785 return this.insertBefore(node, null);
786 }
787 get href() {}
788 set href(_) {}
789 insertBefore(newNode, referenceNode) {
790 const winId = newNode[WinIdKey] = this[WinIdKey];
791 const instanceId = newNode[InstanceIdKey];
792 const nodeName = newNode[NodeNameKey];
793 const isScript = "SCRIPT" === nodeName;
794 const isIFrame = "IFRAME" === nodeName;
795 if (isScript) {
796 const scriptContent = getInstanceStateValue(newNode, 3);
797 const scriptType = getInstanceStateValue(newNode, 5);
798 if (scriptContent) {
799 if (isScriptJsType(scriptType)) {
800 const errorMsg = runScriptContent(getEnv(newNode), instanceId, scriptContent, winId, "");
801 const datasetType = errorMsg ? "pterror" : "ptid";
802 const datasetValue = errorMsg || instanceId;
803 setter(newNode, [ "type" ], "text/partytown-x");
804 setter(newNode, [ "dataset", datasetType ], datasetValue);
805 }
806 setter(newNode, [ "innerHTML" ], scriptContent);
807 }
808 }
809 callMethod(this, [ "insertBefore" ], [ newNode, referenceNode ]);
810 isIFrame && ((winId, iframe) => {
811 let i = 0;
812 let type;
813 let handlers;
814 setter(iframe, [ "dataset", "ptwindow" ], winId);
815 const callback = () => {
816 if (environments[winId] && environments[winId].$isInitialized$) {
817 type = getInstanceStateValue(iframe, 1) ? "error" : "load";
818 handlers = getInstanceStateValue(iframe, type);
819 handlers && handlers.map((handler => handler({
820 type: type
821 })));
822 } else if (i++ > 2e3) {
823 handlers = getInstanceStateValue(iframe, "error");
824 handlers && handlers.map((handler => handler({
825 type: "error"
826 })));
827 } else {
828 setTimeout(callback, 9);
829 }
830 };
831 callback();
832 })(instanceId, newNode);
833 if (isScript) {
834 sendToMain(true);
835 webWorkerCtx.$postMessage$([ 6, winId ]);
836 }
837 return newNode;
838 }
839 get nodeName() {
840 return this[NodeNameKey];
841 }
842 get nodeType() {
843 return 3;
844 }
845 get ownerDocument() {
846 return getEnv(this).$document$;
847 }
848 }
849 class Attr {
850 constructor(serializedAttr) {
851 this.name = serializedAttr[0];
852 this.value = serializedAttr[1];
853 }
854 get nodeName() {
855 return this.name;
856 }
857 get nodeType() {
858 return 2;
859 }
860 }
861 class CSSStyleDeclaration extends WorkerProxy {
862 constructor(winId, instanceId, applyPath, styles) {
863 super(winId, instanceId, applyPath);
864 Object.assign(this, styles);
865 return new Proxy(this, {
866 get: (target, propName) => target[propName],
867 set(target, propName, propValue) {
868 setter(target, [ propName ], propValue);
869 ((target, propName) => {
870 (webWorkerCtx.$config$.logGetters || webWorkerCtx.$config$.logSetters) && logWorker(`Dimension cache cleared from style.${propName} setter`, target[WinIdKey]);
871 })(target, propName);
872 cachedDimensions.clear();
873 return true;
874 }
875 });
876 }
877 getPropertyValue(propName) {
878 return this[propName];
879 }
880 setProperty(propName, propValue) {
881 this[propName] = propValue;
882 }
883 }
884 class NodeList {
885 constructor(nodes) {
886 (this._ = nodes).map(((node, index) => this[index] = node));
887 }
888 entries() {
889 return this._.entries();
890 }
891 forEach(cb, thisArg) {
892 this._.map(cb, thisArg);
893 }
894 item(index) {
895 return this[index];
896 }
897 keys() {
898 return this._.keys();
899 }
900 get length() {
901 return len(this._);
902 }
903 values() {
904 return this._.values();
905 }
906 [Symbol.iterator]() {
907 return this._[Symbol.iterator]();
908 }
909 }
910 const serializeForMain = ($winId$, $instanceId$, value, added, type) => void 0 !== value && (type = typeof value) ? "string" === type || "boolean" === type || "number" === type || null == value ? [ 0, value ] : "function" === type ? [ 4, {
911 $winId$: $winId$,
912 $instanceId$: $instanceId$,
913 $refId$: setWorkerRef(value)
914 } ] : (added = added || new Set) && Array.isArray(value) ? added.has(value) ? [ 1, [] ] : added.add(value) && [ 1, value.map((v => serializeForMain($winId$, $instanceId$, v, added))) ] : "object" === type ? "number" == typeof value[InstanceIdKey] ? [ 3, {
915 $winId$: value[WinIdKey],
916 $instanceId$: value[InstanceIdKey]
917 } ] : value instanceof Event ? [ 5, serializeObjectForMain($winId$, $instanceId$, value, false, added) ] : supportsTrustedHTML && value instanceof TrustedHTML ? [ 0, value.toString() ] : value instanceof ArrayBuffer ? [ 8, value ] : ArrayBuffer.isView(value) ? [ 9, value.buffer, getConstructorName(value) ] : [ 2, serializeObjectForMain($winId$, $instanceId$, value, true, added) ] : void 0 : value;
918 const supportsTrustedHTML = "undefined" != typeof TrustedHTML;
919 const serializeObjectForMain = (winId, instanceId, obj, includeFunctions, added, serializedObj, propName, propValue) => {
920 serializedObj = {};
921 if (!added.has(obj)) {
922 added.add(obj);
923 for (propName in obj) {
924 propValue = obj[propName];
925 (includeFunctions || "function" != typeof propValue) && (serializedObj[propName] = serializeForMain(winId, instanceId, propValue, added));
926 }
927 }
928 return serializedObj;
929 };
930 const serializeInstanceForMain = (instance, value) => instance ? serializeForMain(instance[WinIdKey], instance[InstanceIdKey], value) : [ 0, value ];
931 const deserializeFromMain = (winId, instanceId, applyPath, serializedValueTransfer, serializedType, serializedValue, obj, key) => {
932 if (serializedValueTransfer) {
933 serializedType = serializedValueTransfer[0];
934 serializedValue = serializedValueTransfer[1];
935 if (0 === serializedType || 11 === serializedType || 12 === serializedType) {
936 return serializedValue;
937 }
938 if (4 === serializedType) {
939 return deserializeRefFromMain(applyPath, serializedValue);
940 }
941 if (6 === serializedType) {
942 return noop;
943 }
944 if (3 === serializedType) {
945 return getOrCreateSerializedInstance(serializedValue);
946 }
947 if (7 === serializedType) {
948 return new NodeList(serializedValue.map(getOrCreateSerializedInstance));
949 }
950 if (10 === serializedType) {
951 return new Attr(serializedValue);
952 }
953 if (1 === serializedType) {
954 return serializedValue.map((v => deserializeFromMain(winId, instanceId, applyPath, v)));
955 }
956 obj = {};
957 for (key in serializedValue) {
958 obj[key] = deserializeFromMain(winId, instanceId, [ ...applyPath, key ], serializedValue[key]);
959 }
960 if (13 === serializedType) {
961 return new CSSStyleDeclaration(winId, instanceId, applyPath, obj);
962 }
963 if (5 === serializedType) {
964 return (eventProps => new Proxy(new Event(eventProps.type, eventProps), {
965 get: (target, propName) => propName in eventProps ? eventProps[propName] : target[String(propName)]
966 }))(obj);
967 }
968 if (2 === serializedType) {
969 return obj;
970 }
971 }
972 };
973 const getOrCreateSerializedInstance = ({$winId$: $winId$, $instanceId$: $instanceId$, $nodeName$: $nodeName$}) => getPlatformInstance($winId$, $instanceId$) || getOrCreateNodeInstance($winId$, $instanceId$, $nodeName$);
974 const getPlatformInstance = (winId, instanceId) => {
975 const env = environments[winId];
976 return 0 === instanceId ? env.$window$ : 1 === instanceId ? env.$document$ : 2 === instanceId ? env.$documentElement$ : 3 === instanceId ? env.$head$ : 4 === instanceId ? env.$body$ : void 0;
977 };
978 const deserializeRefFromMain = (applyPath, {$winId$: $winId$, $instanceId$: $instanceId$, $nodeName$: $nodeName$, $refId$: $refId$}) => {
979 webWorkerRefsByRefId[$refId$] || webWorkerRefIdsByRef.set(webWorkerRefsByRefId[$refId$] = function(...args) {
980 const instance = getOrCreateNodeInstance($winId$, $instanceId$, $nodeName$);
981 return callMethod(instance, applyPath, args);
982 }, $refId$);
983 return webWorkerRefsByRefId[$refId$];
984 };
985 const HTMLStyleDescriptorMap = {
986 sheet: {
987 get() {
988 return new CSSStyleSheet(this);
989 }
990 }
991 };
992 class CSSStyleSheet {
993 constructor(ownerNode) {
994 this.ownerNode = ownerNode;
995 }
996 get cssRules() {
997 const ownerNode = this.ownerNode;
998 return new Proxy({}, {
999 get(target, propKey) {
1000 const propName = String(propKey);
1001 return "item" === propName ? index => getCssRule(ownerNode, index) : "length" === propName ? getCssRules(ownerNode).length : isNaN(propName) ? target[propKey] : getCssRule(ownerNode, propName);
1002 }
1003 });
1004 }
1005 insertRule(ruleText, index) {
1006 const cssRules = getCssRules(this.ownerNode);
1007 index = void 0 === index ? 0 : index;
1008 if (index >= 0 && index <= cssRules.length) {
1009 callMethod(this.ownerNode, [ "sheet", "insertRule" ], [ ruleText, index ]);
1010 cssRules.splice(index, 0, 0);
1011 }
1012 logDimensionCacheClearMethod(this.ownerNode, "insertRule");
1013 cachedDimensions.clear();
1014 return index;
1015 }
1016 deleteRule(index) {
1017 callMethod(this.ownerNode, [ "sheet", "deleteRule" ], [ index ]);
1018 getCssRules(this.ownerNode).splice(index, 1);
1019 logDimensionCacheClearMethod(this.ownerNode, "deleteRule");
1020 cachedDimensions.clear();
1021 }
1022 }
1023 const getCssRules = (ownerNode, cssRules) => {
1024 cssRules = getInstanceStateValue(ownerNode, 2);
1025 if (!cssRules) {
1026 cssRules = getter(ownerNode, [ "sheet", "cssRules" ]);
1027 setInstanceStateValue(ownerNode, 2, cssRules);
1028 }
1029 return cssRules;
1030 };
1031 const getCssRule = (ownerNode, index, cssRules) => {
1032 cssRules = getCssRules(ownerNode);
1033 0 === cssRules[index] && (cssRules[index] = getter(ownerNode, [ "sheet", "cssRules", parseInt(index, 10) ]));
1034 return cssRules[index];
1035 };
1036 const DocumentDescriptorMap = {
1037 body: {
1038 get() {
1039 return getEnv(this).$body$;
1040 }
1041 },
1042 createElement: {
1043 value(tagName) {
1044 tagName = tagName.toUpperCase();
1045 const winId = this[WinIdKey];
1046 const instanceId = randomId();
1047 const elm = getOrCreateNodeInstance(winId, instanceId, tagName);
1048 callMethod(this, [ "createElement" ], [ tagName ], 2, instanceId);
1049 if ("IFRAME" === tagName) {
1050 const env = createEnvironment({
1051 $winId$: instanceId,
1052 $parentWinId$: winId,
1053 $url$: "about:blank"
1054 });
1055 env.$window$.fetch = fetch;
1056 setter(elm, [ "srcdoc" ], getPartytownScript());
1057 } else if ("SCRIPT" === tagName) {
1058 const scriptType = getInstanceStateValue(elm, 5);
1059 isScriptJsType(scriptType) && setter(elm, [ "type" ], "text/partytown");
1060 }
1061 return elm;
1062 }
1063 },
1064 createElementNS: {
1065 value(namespace, tagName) {
1066 tagName = tagName.toLowerCase();
1067 const winId = this[WinIdKey];
1068 const instanceId = randomId();
1069 const nsElm = getOrCreateNodeInstance(winId, instanceId, tagName, namespace);
1070 callMethod(this, [ "createElementNS" ], [ namespace, tagName ], 2, instanceId);
1071 return nsElm;
1072 }
1073 },
1074 createTextNode: {
1075 value(text) {
1076 const winId = this[WinIdKey];
1077 const instanceId = randomId();
1078 const textNode = getOrCreateNodeInstance(winId, instanceId, "#text");
1079 callMethod(this, [ "createTextNode" ], [ text ], 2, instanceId);
1080 return textNode;
1081 }
1082 },
1083 createEvent: {
1084 value: type => new Event(type)
1085 },
1086 currentScript: {
1087 get() {
1088 const winId = this[WinIdKey];
1089 const currentScriptId = getEnv(this).$currentScriptId$;
1090 return currentScriptId > 0 ? getOrCreateNodeInstance(winId, currentScriptId, "SCRIPT") : null;
1091 }
1092 },
1093 defaultView: {
1094 get() {
1095 return (instance => getEnv(instance).$window$)(this);
1096 }
1097 },
1098 documentElement: {
1099 get() {
1100 return getEnv(this).$documentElement$;
1101 }
1102 },
1103 getElementsByTagName: {
1104 value(tagName) {
1105 tagName = tagName.toUpperCase();
1106 return "BODY" === tagName ? [ getEnv(this).$body$ ] : "HEAD" === tagName ? [ getEnv(this).$head$ ] : callMethod(this, [ "getElementsByTagName" ], [ tagName ]);
1107 }
1108 },
1109 head: {
1110 get() {
1111 return getEnv(this).$head$;
1112 }
1113 },
1114 implementation: {
1115 value: {
1116 hasFeature: noop
1117 }
1118 },
1119 location: {
1120 get() {
1121 return getEnv(this).$location$;
1122 },
1123 set(url) {
1124 getEnv(this).$location$.href = url + "";
1125 }
1126 },
1127 nodeType: {
1128 value: 9
1129 },
1130 parentNode: {
1131 value: null
1132 },
1133 parentElement: {
1134 value: null
1135 },
1136 readyState: {
1137 value: "complete"
1138 }
1139 };
1140 const DocumentElementChildDescriptorMap = {
1141 parentElement: {
1142 get() {
1143 return this.parentNode;
1144 }
1145 },
1146 parentNode: {
1147 get() {
1148 return getEnv(this).$documentElement$;
1149 }
1150 }
1151 };
1152 const DocumentElementDescriptorMap = {
1153 parentElement: {
1154 value: null
1155 },
1156 parentNode: {
1157 get() {
1158 return getEnv(this).$document$;
1159 }
1160 }
1161 };
1162 const ElementDescriptorMap = {
1163 localName: {
1164 get() {
1165 return this[NodeNameKey].toLowerCase();
1166 }
1167 },
1168 namespaceURI: {
1169 get() {
1170 return this[NamespaceKey] || "http://www.w3.org/1999/xhtml";
1171 }
1172 },
1173 nodeType: {
1174 value: 1
1175 },
1176 tagName: {
1177 get() {
1178 return this[NodeNameKey];
1179 }
1180 }
1181 };
1182 const HTMLAnchorDescriptorMap = {
1183 hash: {
1184 get() {
1185 return getUrl(this).hash;
1186 }
1187 },
1188 host: {
1189 get() {
1190 return getUrl(this).host;
1191 }
1192 },
1193 hostname: {
1194 get() {
1195 return getUrl(this).hostname;
1196 }
1197 },
1198 href: {
1199 get() {
1200 return getUrl(this).href;
1201 },
1202 set(href) {
1203 href += "";
1204 setInstanceStateValue(this, 4, href);
1205 setter(this, [ "href" ], href);
1206 }
1207 },
1208 origin: {
1209 get() {
1210 return getUrl(this).origin;
1211 }
1212 },
1213 pathname: {
1214 get() {
1215 return getUrl(this).pathname;
1216 }
1217 },
1218 port: {
1219 get() {
1220 return getUrl(this).port;
1221 }
1222 },
1223 protocol: {
1224 get() {
1225 return getUrl(this).protocol;
1226 }
1227 },
1228 search: {
1229 get() {
1230 return getUrl(this).search;
1231 }
1232 }
1233 };
1234 const HTMLIFrameDescriptorMap = {
1235 contentDocument: {
1236 get() {
1237 return this.contentWindow.document;
1238 }
1239 },
1240 contentWindow: {
1241 get() {
1242 const iframeContentWinId = this[InstanceIdKey];
1243 const env = environments[iframeContentWinId];
1244 return env.$window$;
1245 }
1246 },
1247 src: {
1248 get() {
1249 return getInstanceStateValue(this, 4) || "";
1250 },
1251 set(url) {
1252 let xhr = new XMLHttpRequest;
1253 let xhrStatus;
1254 url = resolveUrl(getEnv(this), url);
1255 setInstanceStateValue(this, 1, void 0);
1256 setInstanceStateValue(this, 4, url);
1257 xhr.open("GET", url, false);
1258 xhr.send();
1259 xhrStatus = xhr.status;
1260 xhrStatus > 199 && xhrStatus < 300 ? setter(this, [ "srcdoc" ], ((url, html) => `<base href="${url}">` + html.replace(/<script>/g, '<script type="text/partytown">').replace(/<script /g, '<script type="text/partytown" ').replace(/text\/javascript/g, "text/partytown") + getPartytownScript())(url, xhr.responseText)) : setInstanceStateValue(this, 1, xhrStatus);
1261 }
1262 },
1263 ...HTMLSrcElementDescriptorMap
1264 };
1265 const defineWorkerInterface = ([cstrName, superCstrName, members, interfaceType, nodeName]) => {
1266 const SuperCstr = TrapConstructors[cstrName] ? WorkerTrapProxy : "EventTarget" === superCstrName ? WorkerEventTargetProxy : "Object" === superCstrName ? WorkerProxy : self[superCstrName];
1267 const Cstr = self[cstrName] = defineConstructorName(self[cstrName] || class extends SuperCstr {}, cstrName);
1268 12 === interfaceType && envGlobalConstructors.set(cstrName, Cstr);
1269 nodeName && (nodeConstructors[nodeName] = Cstr);
1270 members.map((([memberName, memberType, staticValue]) => {
1271 memberName in Cstr.prototype || memberName in SuperCstr.prototype || ("string" == typeof memberType ? definePrototypeProperty(Cstr, memberName, {
1272 get() {
1273 if (!hasInstanceStateValue(this, memberName)) {
1274 const winId = this[WinIdKey];
1275 const instanceId = this[InstanceIdKey];
1276 const applyPath = [ ...this[ApplyPathKey], memberName ];
1277 const nodeName = this[NodeNameKey];
1278 const PropCstr = self[memberType];
1279 setInstanceStateValue(this, memberName, new PropCstr(winId, instanceId, applyPath, nodeName));
1280 }
1281 return getInstanceStateValue(this, memberName);
1282 },
1283 set(value) {
1284 setInstanceStateValue(this, memberName, value);
1285 }
1286 }) : 5 === memberType ? definePrototypeValue(Cstr, memberName, (function(...args) {
1287 return callMethod(this, [ memberName ], args);
1288 })) : memberType > 0 && (void 0 !== staticValue ? definePrototypeValue(Cstr, memberName, staticValue) : definePrototypeProperty(Cstr, memberName, {
1289 get() {
1290 return getter(this, [ memberName ]);
1291 },
1292 set(value) {
1293 return setter(this, [ memberName ], value);
1294 }
1295 })));
1296 }));
1297 };
1298 const TrapConstructors = {
1299 CSSStyleDeclaration: 1,
1300 DOMStringMap: 1,
1301 NamedNodeMap: 1
1302 };
1303 const definePrototypeNodeType = (Cstr, nodeType) => definePrototypeValue(Cstr, "nodeType", nodeType);
1304 const cachedTreeProps = (Cstr, treeProps) => treeProps.map((propName => definePrototypeProperty(Cstr, propName, {
1305 get() {
1306 let cacheKey = getInstanceCacheKey(this, propName);
1307 let result = cachedStructure.get(cacheKey);
1308 if (!result) {
1309 result = getter(this, [ propName ]);
1310 cachedStructure.set(cacheKey, result);
1311 }
1312 return result;
1313 }
1314 })));
1315 const getInstanceCacheKey = (instance, memberName, args) => [ instance[WinIdKey], instance[InstanceIdKey], memberName, ...(args || EMPTY_ARRAY).map((arg => String(arg && arg[WinIdKey] ? arg[InstanceIdKey] : arg))) ].join(".");
1316 const cachedProps = (Cstr, propNames) => commaSplit(propNames).map((propName => definePrototypeProperty(Cstr, propName, {
1317 get() {
1318 hasInstanceStateValue(this, propName) || setInstanceStateValue(this, propName, getter(this, [ propName ]));
1319 return getInstanceStateValue(this, propName);
1320 },
1321 set(val) {
1322 getInstanceStateValue(this, propName) !== val && setter(this, [ propName ], val);
1323 setInstanceStateValue(this, propName, val);
1324 }
1325 })));
1326 const constantProps = (Cstr, props) => Object.keys(props).map((propName => definePrototypeValue(Cstr, propName, props[propName])));
1327 const cachedDimensionProps = Cstr => getterDimensionPropNames.map((propName => definePrototypeProperty(Cstr, propName, {
1328 get() {
1329 const dimension = cachedDimensions.get(getInstanceCacheKey(this, propName));
1330 if ("number" == typeof dimension) {
1331 return dimension;
1332 }
1333 const groupedDimensions = getter(this, [ propName ], getterDimensionPropNames);
1334 if (groupedDimensions && "object" == typeof groupedDimensions) {
1335 Object.entries(groupedDimensions).map((([dimensionPropName, value]) => cachedDimensions.set(getInstanceCacheKey(this, dimensionPropName), value)));
1336 return groupedDimensions[propName];
1337 }
1338 return groupedDimensions;
1339 }
1340 })));
1341 const cachedDimensionMethods = (Cstr, dimensionMethodNames) => dimensionMethodNames.map((methodName => {
1342 Cstr.prototype[methodName] = function(...args) {
1343 let cacheKey = getInstanceCacheKey(this, methodName, args);
1344 let dimensions = cachedDimensions.get(cacheKey);
1345 if (!dimensions) {
1346 dimensions = callMethod(this, [ methodName ], args);
1347 cachedDimensions.set(cacheKey, dimensions);
1348 }
1349 return dimensions;
1350 };
1351 }));
1352 class Performance extends WorkerProxy {
1353 now() {
1354 return performance.now();
1355 }
1356 }
1357 const initWebWorker = initWebWorkerData => {
1358 const config = webWorkerCtx.$config$ = JSON.parse(initWebWorkerData.$config$);
1359 [ "resolveUrl", "get", "set", "apply" ].map((configName => {
1360 config[configName] && (config[configName] = new Function("return " + config[configName])());
1361 }));
1362 webWorkerCtx.$importScripts$ = importScripts.bind(self);
1363 webWorkerCtx.$libPath$ = initWebWorkerData.$libPath$;
1364 webWorkerCtx.$localStorage$ = initWebWorkerData.$localStorage$;
1365 webWorkerCtx.$sessionStorage$ = initWebWorkerData.$sessionStorage$;
1366 webWorkerCtx.$postMessage$ = postMessage.bind(self);
1367 webWorkerCtx.$sharedDataBuffer$ = initWebWorkerData.$sharedDataBuffer$;
1368 self.postMessage = self.importScripts = void 0;
1369 self.Node = Node;
1370 self.Window = Window;
1371 self.CSSStyleSheet = CSSStyleSheet;
1372 self.Performance = Performance;
1373 initWebWorkerData.$interfaces$.map(defineWorkerInterface);
1374 (() => {
1375 const Document = self.Document;
1376 const DocumentFragment = self.DocumentFragment;
1377 const Element = self.Element;
1378 commaSplit("atob,btoa,crypto,indexedDB,setTimeout,setInterval,clearTimeout,clearInterval").map((memberName => delete Window.prototype[memberName]));
1379 definePrototypePropertyDescriptor(Element, ElementDescriptorMap);
1380 definePrototypePropertyDescriptor(Document, DocumentDescriptorMap);
1381 definePrototypePropertyDescriptor(self.HTMLAnchorElement, HTMLAnchorDescriptorMap);
1382 definePrototypePropertyDescriptor(self.HTMLIFrameElement, HTMLIFrameDescriptorMap);
1383 definePrototypePropertyDescriptor(self.HTMLScriptElement, HTMLScriptDescriptorMap);
1384 definePrototypePropertyDescriptor(self.HTMLStyleElement, HTMLStyleDescriptorMap);
1385 definePrototypePropertyDescriptor(self.HTMLHeadElement, DocumentElementChildDescriptorMap);
1386 definePrototypePropertyDescriptor(self.HTMLBodyElement, DocumentElementChildDescriptorMap);
1387 definePrototypePropertyDescriptor(self.HTMLHtmlElement, DocumentElementDescriptorMap);
1388 constantProps(CSSStyleSheet, {
1389 type: "text/css"
1390 });
1391 definePrototypeNodeType(self.Comment, 8);
1392 definePrototypeNodeType(self.DocumentType, 10);
1393 definePrototypeNodeType(DocumentFragment, 11);
1394 cachedTreeProps(Node, nodeStructurePropNames);
1395 cachedTreeProps(Element, elementStructurePropNames);
1396 cachedTreeProps(DocumentFragment, elementStructurePropNames);
1397 cachedDimensionProps(Element);
1398 cachedDimensionMethods(Element, elementGetterDimensionMethodNames);
1399 cachedDimensionProps(Window);
1400 cachedDimensionMethods(Window, windowGetterDimensionMethodNames);
1401 cachedProps(Window, "devicePixelRatio");
1402 cachedProps(Document, "compatMode,referrer");
1403 cachedProps(Element, "id");
1404 })();
1405 webWorkerCtx.$isInitialized$ = 1;
1406 logWorker("Initialized web worker");
1407 };
1408 const queuedEvents = [];
1409 const receiveMessageFromSandboxToWorker = ev => {
1410 const msg = ev.data;
1411 const msgType = msg[0];
1412 if (webWorkerCtx.$isInitialized$) {
1413 if (6 === msgType) {
1414 (async initScript => {
1415 let winId = initScript.$winId$;
1416 let instanceId = initScript.$instanceId$;
1417 let instance = getOrCreateNodeInstance(winId, instanceId, "SCRIPT");
1418 let scriptContent = initScript.$content$;
1419 let scriptSrc = initScript.$url$;
1420 let scriptOrgSrc = initScript.$orgUrl$;
1421 let errorMsg = "";
1422 let env = environments[winId];
1423 let rsp;
1424 if (scriptSrc) {
1425 try {
1426 scriptSrc = resolveToUrl(env, scriptSrc) + "";
1427 setInstanceStateValue(instance, 4, scriptSrc);
1428 webWorkerCtx.$config$.logScriptExecution && logWorker(`Execute script (${instanceId}) src: ${scriptOrgSrc}`, winId);
1429 rsp = await self.fetch(scriptSrc);
1430 if (rsp.ok) {
1431 scriptContent = await rsp.text();
1432 env.$currentScriptId$ = instanceId;
1433 run(env, scriptContent, scriptOrgSrc || scriptSrc);
1434 runStateLoadHandlers(instance, "load");
1435 } else {
1436 errorMsg = rsp.statusText;
1437 runStateLoadHandlers(instance, "error");
1438 }
1439 } catch (urlError) {
1440 console.error(urlError);
1441 errorMsg = String(urlError.stack || urlError);
1442 runStateLoadHandlers(instance, "error");
1443 }
1444 } else {
1445 scriptContent && (errorMsg = runScriptContent(env, instanceId, scriptContent, winId, errorMsg));
1446 }
1447 env.$currentScriptId$ = -1;
1448 webWorkerCtx.$postMessage$([ 5, winId, instanceId, errorMsg ]);
1449 })(msg[1]);
1450 } else if (7 === msgType) {
1451 (({$instanceId$: $instanceId$, $refId$: $refId$, $thisArg$: $thisArg$, $args$: $args$}) => {
1452 if (webWorkerRefsByRefId[$refId$]) {
1453 try {
1454 const thisArg = deserializeFromMain(null, $instanceId$, [], $thisArg$);
1455 const args = deserializeFromMain(null, $instanceId$, [], $args$);
1456 webWorkerRefsByRefId[$refId$].apply(thisArg, args);
1457 } catch (e) {
1458 console.error(e);
1459 }
1460 }
1461 })(msg[1]);
1462 } else if (8 === msgType) {
1463 (({$winId$: $winId$, $forward$: $forward$, $args$: $args$}) => {
1464 try {
1465 let target = environments[$winId$].$window$;
1466 let i = 0;
1467 let l = len($forward$);
1468 for (;i < l; i++) {
1469 i + 1 < l ? target = target[$forward$[i]] : target[$forward$[i]].apply(target, deserializeFromMain(null, 0, [], $args$));
1470 }
1471 } catch (e) {
1472 console.error(e);
1473 }
1474 })(msg[1]);
1475 } else if (3 === msgType) {
1476 createEnvironment(msg[1]);
1477 } else if (4 === msgType) {
1478 environments[msg[1]].$isInitialized$ = 1;
1479 {
1480 const winId = msg[1];
1481 const env = environments[winId];
1482 const winType = env.$winId$ === env.$parentWinId$ ? "top" : "iframe";
1483 logWorker(`Initialized ${winType} window ${normalizedWinId(winId)} environment (${winId}) 🎉`, winId);
1484 }
1485 } else {
1486 11 === msgType && (environments[msg[1]].$location$.href = msg[2]);
1487 }
1488 } else if (1 === msgType) {
1489 initWebWorker(msg[1]);
1490 webWorkerCtx.$postMessage$([ 2 ]);
1491 queuedEvents.length && logWorker(`Queued ready messages: ${queuedEvents.length}`);
1492 queuedEvents.slice().forEach(receiveMessageFromSandboxToWorker);
1493 queuedEvents.length = 0;
1494 } else {
1495 queuedEvents.push(ev);
1496 }
1497 };
1498 self.onmessage = receiveMessageFromSandboxToWorker;
1499 postMessage([ 0 ]);
1500})(self);