Convert extension to manifest v3

This commit is contained in:
hensm
2026-03-08 12:40:56 +00:00
parent c5846a05d9
commit d6099f6f08
19 changed files with 343 additions and 360 deletions

View File

@@ -23,7 +23,13 @@ if (document.currentScript) {
);
if (currentScriptParams.get("loadCastFramework") === "1") {
frameworkScriptPromise = loadScript(CAST_FRAMEWORK_SCRIPT_URL);
frameworkScriptPromise = new Promise((resolve, reject) => {
const scriptEl = document.createElement("script");
scriptEl.src = CAST_FRAMEWORK_SCRIPT_URL;
(document.head ?? document.documentElement).append(scriptEl);
scriptEl.addEventListener("load", () => resolve(scriptEl));
scriptEl.addEventListener("error", () => reject());
});
frameworkScriptPromise.catch(() => {
logger.error("Failed to load CAF script!");
});

View File

@@ -17,7 +17,6 @@ let existingInstance = new CastSDK();
export default existingInstance;
interface EnsureInitOpts {
contextTabId?: number;
/** Skip receiver selection. */
receiverDevice?: ReceiverDevice;
}
@@ -32,7 +31,7 @@ interface EnsureInitOpts {
* provides a messaging port so consumers of this module can communicate
* with the cast manager.
*/
export function ensureInit(opts: EnsureInitOpts): Promise<CastPort> {
export function ensureInit(opts?: EnsureInitOpts): Promise<CastPort> {
return new Promise(async (resolve, reject) => {
// If already initialized
if (existingPort) {
@@ -40,101 +39,39 @@ export function ensureInit(opts: EnsureInitOpts): Promise<CastPort> {
existingInstance = new CastSDK();
}
/**
* If imported into a background script context, the location
* will be the internal extension URL, whereas in a content
* script, it will be the content page URL.
*/
if (
window.location.protocol === "moz-extension:" &&
window.location.pathname === "_generated_background_page.html"
) {
const { default: castManager } = await import(
"../background/castManager"
);
const managerPort = messaging.connect({ name: "trusted-cast" });
/**
* port1 will handle cast manager messages.
* port2 will handle cast instance messages.
*/
const { port1: managerPort, port2: instancePort } =
new MessageChannel();
/**
* Provide cast manager with a port to send messages to
* cast instance.
*/
if (opts.contextTabId) {
await castManager.createInstance(instancePort, {
tabId: opts.contextTabId,
frameId: 0
});
} else {
await castManager.createInstance(instancePort);
// Cast manager -> cast instance
managerPort.onMessage.addListener(message => {
if (message.subject === "cast:instanceCreated") {
if (message.data.isAvailable) {
resolve(pageMessaging.page.messagePort);
} else {
reject();
}
}
// cast manager -> cast instance
managerPort.addEventListener("message", ev => {
const message = ev.data as Message;
if (message.subject === "cast:instanceCreated") {
if (message.data.isAvailable) {
resolve(existingPort);
} else {
reject();
}
}
pageMessaging.extension.sendMessage(message);
});
pageMessaging.extension.sendMessage(message);
});
managerPort.start();
// Cast instance -> cast manager
pageMessaging.extension.addListener(message => {
// Skip receiver selection
if (opts?.receiverDevice) {
message = rewriteTrustedRequestSession(
message,
opts.receiverDevice
);
}
// Cast instance -> cast manager
pageMessaging.extension.addListener(message => {
// Skip receiver selection
if (opts.receiverDevice) {
message = rewriteTrustedRequestSession(
message,
opts.receiverDevice
);
}
managerPort.postMessage(message);
});
managerPort.postMessage(message);
});
} else {
const managerPort = messaging.connect({ name: "trusted-cast" });
managerPort.onDisconnect.addListener(() => {
pageMessaging.extension.close();
});
// Cast manager -> cast instance
managerPort.onMessage.addListener(message => {
if (message.subject === "cast:instanceCreated") {
if (message.data.isAvailable) {
resolve(pageMessaging.page.messagePort);
} else {
reject();
}
}
pageMessaging.extension.sendMessage(message);
});
// Cast instance -> cast manager
pageMessaging.extension.addListener(message => {
// Skip receiver selection
if (opts.receiverDevice) {
message = rewriteTrustedRequestSession(
message,
opts.receiverDevice
);
}
managerPort.postMessage(message);
});
managerPort.onDisconnect.addListener(() => {
pageMessaging.extension.close();
});
existingPort = pageMessaging.page.messagePort;
}
existingPort = pageMessaging.page.messagePort;
});
}

View File

@@ -14,7 +14,6 @@ const logger = new Logger("fx_cast [media sender]");
interface MediaSenderOpts {
mediaUrl: string;
contextTabId?: number;
mediaElement?: HTMLMediaElement;
}
@@ -22,7 +21,6 @@ export default class MediaSender {
private port?: CastPort;
private mediaUrl: string;
private contextTabId?: number;
/** Target media element if loaded as a content script. */
private mediaElement?: HTMLMediaElement;
@@ -38,7 +36,6 @@ export default class MediaSender {
constructor(opts: MediaSenderOpts) {
this.mediaUrl = opts.mediaUrl;
this.contextTabId = opts.contextTabId;
this.mediaElement = opts.mediaElement;
this.init();
@@ -51,7 +48,7 @@ export default class MediaSender {
private async init() {
try {
this.port = await ensureInit({ contextTabId: this.contextTabId });
this.port = await ensureInit();
} catch (err) {
logger.error("Failed to initialize cast API", err);
}