Files
Fluxup_PAP/node_modules/@expo/dom-webview/ios/DomWebViewBrowserScripts.swift
2026-03-10 16:18:05 +00:00

267 lines
9.0 KiB
Swift

// Copyright 2015-present 650 Industries. All rights reserved.
// swiftlint:disable line_length
/**
* This file contains the browser scripts that are injected into the WebView.
* @generated by buildBrowserScripts.ts
*/
internal let INSTALL_GLOBALS_SCRIPT: String = """
// browserScripts/InstallGlobals/Deferred.ts
class Deferred {
promise;
resolveCallback;
rejectCallback;
constructor() {
this.promise = new Promise((resolve, reject) => {
this.resolveCallback = resolve;
this.rejectCallback = reject;
});
}
resolve(value) {
this.resolveCallback(value);
}
reject(reason) {
this.rejectCallback(reason);
}
getPromise() {
return this.promise;
}
}
// browserScripts/InstallGlobals/EventEmitterProxy.ts
class EventEmitterProxy {
moduleName;
listeners;
constructor(moduleName) {
this.moduleName = moduleName;
}
addListener = (eventName, listener) => {
if (!this.listeners) {
this.listeners = new Map;
}
if (!this.listeners.has(eventName)) {
this.listeners.set(eventName, new Set);
}
this.listeners.get(eventName)?.add(listener);
const nativeListenerId = window.ExpoDomWebView.nextEventListenerId++;
listener.$$nativeListenerId = nativeListenerId;
const source = `
globalThis.expo.$$DomWebViewEventListenerMap ||= {};
globalThis.expo.$$DomWebViewEventListenerMap['${eventName}'] ||= new Map();
const listener = (...args) => {
const serializeArgs = args.map((arg) => JSON.stringify(arg)).join(',');
const script = 'window.ExpoDomWebView.eventEmitterProxy.${this.moduleName}.emit("${eventName}", ' + serializeArgs + ')';
globalThis.expo.modules.ExpoDomWebViewModule.evalJsForWebViewAsync("%%WEBVIEW_ID%%", script);
};
globalThis.expo.$$DomWebViewEventListenerMap['${eventName}'].set(${nativeListenerId}, listener);
globalThis.expo.modules.${this.moduleName}.addListener('${eventName}', listener);
`;
window.ExpoDomWebView.eval(source);
return {
remove: () => {
this.removeListener(eventName, listener);
}
};
};
removeListener = (eventName, listener) => {
const nativeListenerId = listener.$$nativeListenerId;
if (nativeListenerId != null) {
const source = `(function() {
const nativeListener = globalThis.expo.$$DomWebViewEventListenerMap['${eventName}'].get(${nativeListenerId});
if (nativeListener != null) {
globalThis.expo.modules.${this.moduleName}.removeListener('${eventName}', nativeListener);
globalThis.expo.$$DomWebViewEventListenerMap['${eventName}'].delete(${nativeListenerId});
}
})();
true;
`;
window.ExpoDomWebView.eval(source);
}
this.listeners?.get(eventName)?.delete(listener);
};
removeAllListeners = (eventName) => {
const source = `
globalThis.expo.$$DomWebViewEventListenerMap['${eventName}'].clear();
globalThis.expo.modules.${this.moduleName}.removeAllListeners('${eventName}');
`;
window.ExpoDomWebView.eval(source);
this.listeners?.get(eventName)?.clear();
};
emit = (eventName, ...args) => {
const listeners = new Set(this.listeners?.get(eventName));
listeners.forEach((listener) => {
try {
listener(...args);
} catch (error) {
console.error(error);
}
});
};
}
// browserScripts/InstallGlobals/utils.ts
function serializeArgs(args) {
return args.map((arg) => {
if (typeof arg === "object" && arg.sharedObjectId != null) {
return `globalThis.expo.sharedObjectRegistry.get(${arg.sharedObjectId})`;
}
return JSON.stringify(arg);
}).join(",");
}
// browserScripts/InstallGlobals/proxies.ts
function createSharedObjectProxy(sharedObjectId) {
return new Proxy({}, {
get: (target, prop) => {
const name = String(prop);
if (name === "sharedObjectId") {
return sharedObjectId;
}
return function(...args) {
const serializedArgs = serializeArgs(args);
const source = `globalThis.expo.sharedObjectRegistry.get(${sharedObjectId})?.${name}?.call(globalThis.expo.sharedObjectRegistry.get(${sharedObjectId}),${serializedArgs})`;
return window.ExpoDomWebView.eval(source);
};
}
});
}
function createConstructorProxy(moduleName, property, propertyName) {
return new Proxy(function() {
}, {
construct(target, args) {
const serializedArgs = serializeArgs(args);
const sharedObjectId = window.ExpoDomWebView.nextSharedObjectId++;
const sharedObjectProxy = createSharedObjectProxy(sharedObjectId);
window.ExpoDomWebView.sharedObjectFinalizationRegistry.register(sharedObjectProxy, sharedObjectId);
const source = `globalThis.expo.sharedObjectRegistry ||= new Map(); globalThis.expo.sharedObjectRegistry.set(${sharedObjectId}, new ${property}(${serializedArgs}));`;
window.ExpoDomWebView.eval(source);
return sharedObjectProxy;
}
});
}
function createPropertyProxy(propertyTypeCache, moduleName, propertyName) {
const property = `globalThis.expo.modules.${moduleName}.${propertyName}`;
let propertyType = propertyTypeCache[propertyName];
if (!propertyType) {
const typeCheck = `${property}?.prototype?.__expo_shared_object_id__ != null ? 'sharedObject' : typeof ${property}`;
propertyType = window.ExpoDomWebView.eval(typeCheck);
propertyTypeCache[propertyName] = propertyType;
}
if (propertyType === "sharedObject") {
return createConstructorProxy(moduleName, property, propertyName);
}
if (propertyType === "function") {
return function(...args) {
const serializedArgs = serializeArgs(args);
const source = `${property}(${serializedArgs})`;
return window.ExpoDomWebView.eval(source);
};
}
return window.ExpoDomWebView.eval(property);
}
function createExpoModuleProxy(moduleName) {
const propertyTypeCache = {};
return new Proxy({}, {
get: (target, prop) => {
const name = String(prop);
if (["addListener", "removeListener", "removeAllListeners"].includes(name)) {
return window.ExpoDomWebView.eventEmitterProxy[moduleName][name];
}
return createPropertyProxy(propertyTypeCache, moduleName, name);
}
});
}
// browserScripts/InstallGlobals/ExpoDomWebView.ts
class ExpoDomWebView {
nextDeferredId;
nextSharedObjectId;
nextEventListenerId;
deferredMap;
sharedObjectFinalizationRegistry;
expoModulesProxy;
eventEmitterProxy;
constructor() {
this.nextDeferredId = 0;
this.nextSharedObjectId = 0;
this.nextEventListenerId = 0;
this.deferredMap = new Map;
this.sharedObjectFinalizationRegistry = new FinalizationRegistry((sharedObjectId) => {
this.eval(`globalThis.expo.sharedObjectRegistry.delete(${sharedObjectId})`);
});
const expoModules = {};
const eventEmitterProxy = {};
this.eval("Object.keys(globalThis.expo.modules)").forEach((name) => {
expoModules[name] = createExpoModuleProxy(name);
eventEmitterProxy[name] = new EventEmitterProxy(name);
});
this.expoModulesProxy = expoModules;
this.eventEmitterProxy = eventEmitterProxy;
}
eval(source) {
const { deferredId, deferred } = this.createDeferred();
const args = JSON.stringify({ source, deferredId });
const result = JSON.parse(window.ExpoDomWebViewBridge.eval(args));
if (result.isPromise) {
return deferred.getPromise();
}
this.removeDeferred(deferredId);
return result.value;
}
createDeferred() {
const deferred = new Deferred;
const deferredId = this.nextDeferredId;
this.deferredMap.set(deferredId, deferred);
this.nextDeferredId += 1;
return { deferredId, deferred };
}
resolveDeferred(deferredId, value) {
const deferred = this.deferredMap.get(deferredId);
if (deferred) {
deferred.resolve(value);
this.deferredMap.delete(deferredId);
}
}
rejectDeferred(deferredId, reason) {
const deferred = this.deferredMap.get(deferredId);
if (deferred) {
deferred.reject(reason);
this.deferredMap.delete(deferredId);
}
}
removeDeferred(deferredId) {
this.deferredMap.delete(deferredId);
}
}
// browserScripts/InstallGlobals/index.ts
window.ExpoDomWebView = new ExpoDomWebView;
"""
internal let NATIVE_EVAL_WRAPPER_SCRIPT: String = """
// browserScripts/NativeEvalWrapper/index.ts
(function() {
const result = "%%SOURCE%%";
if (result instanceof Promise) {
result.then((resolved) => {
const resolvedString = JSON.stringify(resolved);
const script = 'window.ExpoDomWebView.resolveDeferred("%%DEFERRED_ID%%", ' + resolvedString + ")";
globalThis.expo.modules.ExpoDomWebViewModule.evalJsForWebViewAsync("%%WEBVIEW_ID%%", script);
}).catch((error) => {
const errorString = JSON.stringify(error);
const script = 'window.ExpoDomWebView.rejectDeferred("%%DEFERRED_ID%%", ' + errorString + ")";
globalThis.expo.modules.ExpoDomWebViewModule.evalJsForWebViewAsync("%%WEBVIEW_ID%%", script);
});
return JSON.stringify({ isPromise: true, value: null });
} else {
return JSON.stringify({ isPromise: false, value: result });
}
})();
"""
// swiftlint:enable line_length