Skip to content

Commit 3856898

Browse files
shakyShanegithub-actions[bot]
authored andcommitted
Release build 4.38.0 [ci release]
1 parent 74b6142 commit 3856898

File tree

24 files changed

+4390
-121
lines changed

24 files changed

+4390
-121
lines changed

Sources/ContentScopeScripts/dist/contentScope.js

Lines changed: 204 additions & 2 deletions
Large diffs are not rendered by default.

Sources/ContentScopeScripts/dist/contentScopeIsolated.js

Lines changed: 345 additions & 3 deletions
Large diffs are not rendered by default.

Sources/ContentScopeScripts/dist/pages/duckplayer/index.html

Lines changed: 205 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,207 @@
867867
};
868868
}
869869

870+
// ../messaging/lib/android.js
871+
var AndroidMessagingTransport = class {
872+
/**
873+
* @param {AndroidMessagingConfig} config
874+
* @param {import('../index.js').MessagingContext} messagingContext
875+
* @internal
876+
*/
877+
constructor(config, messagingContext) {
878+
this.messagingContext = messagingContext;
879+
this.config = config;
880+
}
881+
/**
882+
* @param {import('../index.js').NotificationMessage} msg
883+
*/
884+
notify(msg) {
885+
try {
886+
this.config.sendMessageThrows?.(JSON.stringify(msg));
887+
} catch (e) {
888+
console.error(".notify failed", e);
889+
}
890+
}
891+
/**
892+
* @param {import('../index.js').RequestMessage} msg
893+
* @return {Promise<any>}
894+
*/
895+
request(msg) {
896+
return new Promise((resolve, reject) => {
897+
const unsub = this.config.subscribe(msg.id, handler);
898+
try {
899+
this.config.sendMessageThrows?.(JSON.stringify(msg));
900+
} catch (e) {
901+
unsub();
902+
reject(new Error("request failed to send: " + e.message || "unknown error"));
903+
}
904+
function handler(data) {
905+
if (isResponseFor(msg, data)) {
906+
if (data.result) {
907+
resolve(data.result || {});
908+
return unsub();
909+
}
910+
if (data.error) {
911+
reject(new Error(data.error.message));
912+
return unsub();
913+
}
914+
unsub();
915+
throw new Error("unreachable: must have `result` or `error` key by this point");
916+
}
917+
}
918+
});
919+
}
920+
/**
921+
* @param {import('../index.js').Subscription} msg
922+
* @param {(value: unknown | undefined) => void} callback
923+
*/
924+
subscribe(msg, callback) {
925+
const unsub = this.config.subscribe(msg.subscriptionName, (data) => {
926+
if (isSubscriptionEventFor(msg, data)) {
927+
callback(data.params || {});
928+
}
929+
});
930+
return () => {
931+
unsub();
932+
};
933+
}
934+
};
935+
var AndroidMessagingConfig = class {
936+
/** @type {(json: string, secret: string) => void} */
937+
_capturedHandler;
938+
/**
939+
* @param {object} params
940+
* @param {Record<string, any>} params.target
941+
* @param {boolean} params.debug
942+
* @param {string} params.secret - a secret to ensure that messages are only
943+
* processed by the correct handler
944+
* @param {string} params.javascriptInterface - the name of the javascript interface
945+
* registered on the native side
946+
* @param {string} params.messageCallback - the name of the callback that the native
947+
* side will use to send messages back to the javascript side
948+
*/
949+
constructor(params) {
950+
this.target = params.target;
951+
this.debug = params.debug;
952+
this.javascriptInterface = params.javascriptInterface;
953+
this.secret = params.secret;
954+
this.messageCallback = params.messageCallback;
955+
this.listeners = new globalThis.Map();
956+
this._captureGlobalHandler();
957+
this._assignHandlerMethod();
958+
}
959+
/**
960+
* The transport can call this to transmit a JSON payload along with a secret
961+
* to the native Android handler.
962+
*
963+
* Note: This can throw - it's up to the transport to handle the error.
964+
*
965+
* @type {(json: string) => void}
966+
* @throws
967+
* @internal
968+
*/
969+
sendMessageThrows(json) {
970+
this._capturedHandler(json, this.secret);
971+
}
972+
/**
973+
* A subscription on Android is just a named listener. All messages from
974+
* android -> are delivered through a single function, and this mapping is used
975+
* to route the messages to the correct listener.
976+
*
977+
* Note: Use this to implement request->response by unsubscribing after the first
978+
* response.
979+
*
980+
* @param {string} id
981+
* @param {(msg: MessageResponse | SubscriptionEvent) => void} callback
982+
* @returns {() => void}
983+
* @internal
984+
*/
985+
subscribe(id, callback) {
986+
this.listeners.set(id, callback);
987+
return () => {
988+
this.listeners.delete(id);
989+
};
990+
}
991+
/**
992+
* Accept incoming messages and try to deliver it to a registered listener.
993+
*
994+
* This code is defensive to prevent any single handler from affecting another if
995+
* it throws (producer interference).
996+
*
997+
* @param {MessageResponse | SubscriptionEvent} payload
998+
* @internal
999+
*/
1000+
_dispatch(payload) {
1001+
if (!payload)
1002+
return this._log("no response");
1003+
if ("id" in payload) {
1004+
if (this.listeners.has(payload.id)) {
1005+
this._tryCatch(() => this.listeners.get(payload.id)?.(payload));
1006+
} else {
1007+
this._log("no listeners for ", payload);
1008+
}
1009+
}
1010+
if ("subscriptionName" in payload) {
1011+
if (this.listeners.has(payload.subscriptionName)) {
1012+
this._tryCatch(() => this.listeners.get(payload.subscriptionName)?.(payload));
1013+
} else {
1014+
this._log("no subscription listeners for ", payload);
1015+
}
1016+
}
1017+
}
1018+
/**
1019+
*
1020+
* @param {(...args: any[]) => any} fn
1021+
* @param {string} [context]
1022+
*/
1023+
_tryCatch(fn, context = "none") {
1024+
try {
1025+
return fn();
1026+
} catch (e) {
1027+
if (this.debug) {
1028+
console.error("AndroidMessagingConfig error:", context);
1029+
console.error(e);
1030+
}
1031+
}
1032+
}
1033+
/**
1034+
* @param {...any} args
1035+
*/
1036+
_log(...args) {
1037+
if (this.debug) {
1038+
console.log("AndroidMessagingConfig", ...args);
1039+
}
1040+
}
1041+
/**
1042+
* Capture the global handler and remove it from the global object.
1043+
*/
1044+
_captureGlobalHandler() {
1045+
const { target, javascriptInterface } = this;
1046+
if (Object.prototype.hasOwnProperty.call(target, javascriptInterface)) {
1047+
this._capturedHandler = target[javascriptInterface].process.bind(target[javascriptInterface]);
1048+
delete target[javascriptInterface];
1049+
} else {
1050+
this._capturedHandler = () => {
1051+
this._log("Android messaging interface not available", javascriptInterface);
1052+
};
1053+
}
1054+
}
1055+
/**
1056+
* Assign the incoming handler method to the global object.
1057+
* This is the method that Android will call to deliver messages.
1058+
*/
1059+
_assignHandlerMethod() {
1060+
const responseHandler = (providedSecret, response) => {
1061+
if (providedSecret === this.secret) {
1062+
this._dispatch(response);
1063+
}
1064+
};
1065+
Object.defineProperty(this.target, this.messageCallback, {
1066+
value: responseHandler
1067+
});
1068+
}
1069+
};
1070+
8701071
// ../messaging/index.js
8711072
var MessagingContext = class {
8721073
/**
@@ -885,7 +1086,7 @@
8851086
var Messaging = class {
8861087
/**
8871088
* @param {MessagingContext} messagingContext
888-
* @param {WebkitMessagingConfig | WindowsMessagingConfig | TestTransportConfig} config
1089+
* @param {WebkitMessagingConfig | WindowsMessagingConfig | AndroidMessagingConfig | TestTransportConfig} config
8891090
*/
8901091
constructor(messagingContext, config) {
8911092
this.messagingContext = messagingContext;
@@ -986,6 +1187,9 @@
9861187
if (config instanceof WindowsMessagingConfig) {
9871188
return new WindowsMessagingTransport(config, messagingContext);
9881189
}
1190+
if (config instanceof AndroidMessagingConfig) {
1191+
return new AndroidMessagingTransport(config, messagingContext);
1192+
}
9891193
if (config instanceof TestTransportConfig) {
9901194
return new TestTransport(config, messagingContext);
9911195
}

0 commit comments

Comments
 (0)