mirror of
https://github.com/hensm/fx_cast.git
synced 2026-06-12 02:29:59 +00:00
Rename directory: ext -> extension
This commit is contained in:
154
extension/src/cast/export.ts
Normal file
154
extension/src/cast/export.ts
Normal file
@@ -0,0 +1,154 @@
|
||||
import type { TypedMessagePort } from "../lib/TypedMessagePort";
|
||||
import messaging, { Message } from "../messaging";
|
||||
import type { ReceiverDevice } from "../types";
|
||||
|
||||
import pageMessaging from "./pageMessaging";
|
||||
|
||||
// Ensure extension-side is initialized first
|
||||
void pageMessaging.extension;
|
||||
|
||||
import CastSDK from "./sdk";
|
||||
|
||||
export type CastPort = TypedMessagePort<Message>;
|
||||
|
||||
let existingPort: CastPort;
|
||||
let existingInstance = new CastSDK();
|
||||
|
||||
export default existingInstance;
|
||||
|
||||
interface EnsureInitOpts {
|
||||
contextTabId?: number;
|
||||
/** Skip receiver selection. */
|
||||
receiverDevice?: ReceiverDevice;
|
||||
}
|
||||
|
||||
/**
|
||||
* To support exporting the API from a module, we need to retain the
|
||||
* MessageChannel-based pageMessaging layer despite not crossing any
|
||||
* context boundaries.
|
||||
*
|
||||
* The ensureInit function creates a messaging connection to the
|
||||
* cast manager, hooks it up to the pageMessaging layer and also
|
||||
* provides a messaging port so consumers of this module can communicate
|
||||
* with the cast manager.
|
||||
*/
|
||||
export function ensureInit(opts: EnsureInitOpts): Promise<CastPort> {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
// If already initialized
|
||||
if (existingPort) {
|
||||
existingPort.close();
|
||||
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"
|
||||
);
|
||||
|
||||
/**
|
||||
* 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.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);
|
||||
});
|
||||
managerPort.start();
|
||||
|
||||
// Cast instance -> cast manager
|
||||
pageMessaging.extension.addListener(message => {
|
||||
// Skip receiver selection
|
||||
if (opts.receiverDevice) {
|
||||
message = rewriteTrustedRequestSession(
|
||||
message,
|
||||
opts.receiverDevice
|
||||
);
|
||||
}
|
||||
|
||||
managerPort.postMessage(message);
|
||||
});
|
||||
} else {
|
||||
const managerPort = messaging.connect({ name: "trusted-cast" });
|
||||
|
||||
// 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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* If a receiver device was passed to `ensureInit`, messages to the cast
|
||||
* manager will be passed through this function and the receiver device
|
||||
* will be added to the message payload. This tells the cast manager to
|
||||
* skip receiver selection when requesting a session.
|
||||
*/
|
||||
function rewriteTrustedRequestSession(
|
||||
message: Message,
|
||||
receiverDevice: ReceiverDevice
|
||||
) {
|
||||
if (message.subject !== "main:requestSession") return message;
|
||||
message.data.receiverDevice = receiverDevice;
|
||||
return message;
|
||||
}
|
||||
Reference in New Issue
Block a user