|
2829 | 2829 | android: [...baseFeatures, "webCompat", "breakageReporting", "duckPlayer", "messageBridge"],
|
2830 | 2830 | "android-broker-protection": ["brokerProtection"],
|
2831 | 2831 | "android-autofill-password-import": ["autofillPasswordImport"],
|
2832 |
| - windows: ["cookie", ...baseFeatures, "windowsPermissionUsage", "duckPlayer", "brokerProtection", "breakageReporting"], |
| 2832 | + windows: ["cookie", ...baseFeatures, "windowsPermissionUsage", "duckPlayer", "brokerProtection", "breakageReporting", "messageBridge"], |
2833 | 2833 | firefox: ["cookie", ...baseFeatures, "clickToLoad"],
|
2834 | 2834 | chrome: ["cookie", ...baseFeatures, "clickToLoad"],
|
2835 | 2835 | "chrome-mv3": ["cookie", ...baseFeatures, "clickToLoad"],
|
@@ -13875,6 +13875,168 @@
|
13875 | 13875 | }
|
13876 | 13876 | };
|
13877 | 13877 |
|
| 13878 | + // src/features/message-bridge.js |
| 13879 | + init_define_import_meta_trackerLookup(); |
| 13880 | + var MessageBridge = class extends ContentFeature { |
| 13881 | + constructor() { |
| 13882 | + super(...arguments); |
| 13883 | + /** @type {Captured} */ |
| 13884 | + __publicField(this, "captured", captured_globals_exports); |
| 13885 | + /** |
| 13886 | + * A mapping of feature names to instances of `Messaging`. |
| 13887 | + * This allows the bridge to handle more than 1 feature at a time. |
| 13888 | + * @type {Map<string, Messaging>} |
| 13889 | + */ |
| 13890 | + __publicField(this, "proxies", new Map2()); |
| 13891 | + /** |
| 13892 | + * If any subscriptions are created, we store the cleanup functions |
| 13893 | + * for later use. |
| 13894 | + * @type {Map<string, () => void>} |
| 13895 | + */ |
| 13896 | + __publicField(this, "subscriptions", new Map2()); |
| 13897 | + /** |
| 13898 | + * This side of the bridge can only be instantiated once, |
| 13899 | + * so we use this flag to ensure we can handle multiple invocations |
| 13900 | + */ |
| 13901 | + __publicField(this, "installed", false); |
| 13902 | + } |
| 13903 | + init(args) { |
| 13904 | + if (isBeingFramed() || !isSecureContext) return; |
| 13905 | + if (!args.messageSecret) return; |
| 13906 | + const { captured: captured2 } = this; |
| 13907 | + function appendToken(eventName) { |
| 13908 | + return `${eventName}-${args.messageSecret}`; |
| 13909 | + } |
| 13910 | + const reply = (incoming) => { |
| 13911 | + if (!args.messageSecret) return this.log("ignoring because args.messageSecret was absent"); |
| 13912 | + const eventName = appendToken(incoming.name + "-" + incoming.id); |
| 13913 | + const event = new captured2.CustomEvent(eventName, { detail: incoming }); |
| 13914 | + captured2.dispatchEvent(event); |
| 13915 | + }; |
| 13916 | + const accept = (ClassType, callback) => { |
| 13917 | + captured2.addEventListener(appendToken(ClassType.NAME), (e) => { |
| 13918 | + this.log(`${ClassType.NAME}`, JSON.stringify(e.detail)); |
| 13919 | + const instance = ClassType.create(e.detail); |
| 13920 | + if (instance) { |
| 13921 | + callback(instance); |
| 13922 | + } else { |
| 13923 | + this.log("Failed to create an instance"); |
| 13924 | + } |
| 13925 | + }); |
| 13926 | + }; |
| 13927 | + this.log(`bridge is installing...`); |
| 13928 | + accept(InstallProxy, (install) => { |
| 13929 | + this.installProxyFor(install, args.messagingConfig, reply); |
| 13930 | + }); |
| 13931 | + accept(ProxyNotification, (notification) => this.proxyNotification(notification)); |
| 13932 | + accept(ProxyRequest, (request) => this.proxyRequest(request, reply)); |
| 13933 | + accept(SubscriptionRequest, (subscription) => this.proxySubscription(subscription, reply)); |
| 13934 | + accept(SubscriptionUnsubscribe, (unsubscribe) => this.removeSubscription(unsubscribe.id)); |
| 13935 | + } |
| 13936 | + /** |
| 13937 | + * Installing a feature proxy is the act of creating a fresh instance of 'Messaging', but |
| 13938 | + * using the same underlying transport |
| 13939 | + * |
| 13940 | + * @param {InstallProxy} install |
| 13941 | + * @param {import('@duckduckgo/messaging').MessagingConfig} config |
| 13942 | + * @param {(payload: {name: string; id: string} & Record<string, any>) => void} reply |
| 13943 | + */ |
| 13944 | + installProxyFor(install, config, reply) { |
| 13945 | + const { id, featureName } = install; |
| 13946 | + if (this.proxies.has(featureName)) return this.log("ignoring `installProxyFor` because it exists", featureName); |
| 13947 | + const allowed = this.getFeatureSettingEnabled(featureName); |
| 13948 | + if (!allowed) { |
| 13949 | + return this.log("not installing proxy, because", featureName, "was not enabled"); |
| 13950 | + } |
| 13951 | + const ctx = { ...this.messaging.messagingContext, featureName }; |
| 13952 | + const messaging = new Messaging(ctx, config); |
| 13953 | + this.proxies.set(featureName, messaging); |
| 13954 | + this.log("did install proxy for ", featureName); |
| 13955 | + reply(new DidInstall({ id })); |
| 13956 | + } |
| 13957 | + /** |
| 13958 | + * @param {ProxyRequest} request |
| 13959 | + * @param {(payload: {name: string; id: string} & Record<string, any>) => void} reply |
| 13960 | + */ |
| 13961 | + async proxyRequest(request, reply) { |
| 13962 | + const { id, featureName, method, params } = request; |
| 13963 | + const proxy = this.proxies.get(featureName); |
| 13964 | + if (!proxy) return this.log("proxy was not installed for ", featureName); |
| 13965 | + this.log("will proxy", request); |
| 13966 | + try { |
| 13967 | + const result = await proxy.request(method, params); |
| 13968 | + const responseEvent = new ProxyResponse({ |
| 13969 | + method, |
| 13970 | + featureName, |
| 13971 | + result, |
| 13972 | + id |
| 13973 | + }); |
| 13974 | + reply(responseEvent); |
| 13975 | + } catch (e) { |
| 13976 | + const errorResponseEvent = new ProxyResponse({ |
| 13977 | + method, |
| 13978 | + featureName, |
| 13979 | + error: { message: e.message }, |
| 13980 | + id |
| 13981 | + }); |
| 13982 | + reply(errorResponseEvent); |
| 13983 | + } |
| 13984 | + } |
| 13985 | + /** |
| 13986 | + * @param {SubscriptionRequest} subscription |
| 13987 | + * @param {(payload: {name: string; id: string} & Record<string, any>) => void} reply |
| 13988 | + */ |
| 13989 | + proxySubscription(subscription, reply) { |
| 13990 | + const { id, featureName, subscriptionName } = subscription; |
| 13991 | + const proxy = this.proxies.get(subscription.featureName); |
| 13992 | + if (!proxy) return this.log("proxy was not installed for", featureName); |
| 13993 | + this.log("will setup subscription", subscription); |
| 13994 | + const prev = this.subscriptions.get(id); |
| 13995 | + if (prev) { |
| 13996 | + this.removeSubscription(id); |
| 13997 | + } |
| 13998 | + const unsubscribe = proxy.subscribe(subscriptionName, (data2) => { |
| 13999 | + const responseEvent = new SubscriptionResponse({ |
| 14000 | + subscriptionName, |
| 14001 | + featureName, |
| 14002 | + params: data2, |
| 14003 | + id |
| 14004 | + }); |
| 14005 | + reply(responseEvent); |
| 14006 | + }); |
| 14007 | + this.subscriptions.set(id, unsubscribe); |
| 14008 | + } |
| 14009 | + /** |
| 14010 | + * @param {string} id |
| 14011 | + */ |
| 14012 | + removeSubscription(id) { |
| 14013 | + const unsubscribe = this.subscriptions.get(id); |
| 14014 | + this.log(`will remove subscription`, id); |
| 14015 | + unsubscribe?.(); |
| 14016 | + this.subscriptions.delete(id); |
| 14017 | + } |
| 14018 | + /** |
| 14019 | + * @param {ProxyNotification} notification |
| 14020 | + */ |
| 14021 | + proxyNotification(notification) { |
| 14022 | + const proxy = this.proxies.get(notification.featureName); |
| 14023 | + if (!proxy) return this.log("proxy was not installed for", notification.featureName); |
| 14024 | + this.log("will proxy notification", notification); |
| 14025 | + proxy.notify(notification.method, notification.params); |
| 14026 | + } |
| 14027 | + /** |
| 14028 | + * @param {Parameters<console['log']>} args |
| 14029 | + */ |
| 14030 | + log(...args) { |
| 14031 | + if (this.isDebug) { |
| 14032 | + console.log("[isolated]", ...args); |
| 14033 | + } |
| 14034 | + } |
| 14035 | + load(_args2) { |
| 14036 | + } |
| 14037 | + }; |
| 14038 | + var message_bridge_default = MessageBridge; |
| 14039 | + |
13878 | 14040 | // ddg:platformFeatures:ddg:platformFeatures
|
13879 | 14041 | var ddg_platformFeatures_default = {
|
13880 | 14042 | ddg_feature_cookie: CookieFeature,
|
|
13894 | 14056 | ddg_feature_windowsPermissionUsage: WindowsPermissionUsage,
|
13895 | 14057 | ddg_feature_duckPlayer: DuckPlayerFeature,
|
13896 | 14058 | ddg_feature_brokerProtection: BrokerProtection,
|
13897 |
| - ddg_feature_breakageReporting: BreakageReporting |
| 14059 | + ddg_feature_breakageReporting: BreakageReporting, |
| 14060 | + ddg_feature_messageBridge: message_bridge_default |
13898 | 14061 | };
|
13899 | 14062 |
|
13900 | 14063 | // src/url-change.js
|
|
14024 | 14187 | platform: processedConfig.platform,
|
14025 | 14188 | site: processedConfig.site,
|
14026 | 14189 | bundledConfig: processedConfig.bundledConfig,
|
14027 |
| - messagingConfig: processedConfig.messagingConfig |
| 14190 | + messagingConfig: processedConfig.messagingConfig, |
| 14191 | + messageSecret: processedConfig.messageSecret |
14028 | 14192 | });
|
14029 | 14193 | init(processedConfig);
|
14030 | 14194 | }
|
|
0 commit comments