Switch to eslint and fix issues

This commit is contained in:
hensm
2021-04-26 05:36:55 +01:00
parent 2d0fa4c844
commit d478742c4b
100 changed files with 1537 additions and 608 deletions

40
.eslintrc.json Normal file
View File

@@ -0,0 +1,40 @@
{
"root": true
, "parser": "@typescript-eslint/parser"
, "plugins": ["@typescript-eslint"]
, "extends": [
"eslint:recommended"
, "plugin:@typescript-eslint/recommended"
]
, "rules": {
"max-len": [ "error", 80, {
"tabWidth": 4
, "ignorePattern": "//|.*(\"|`);?$"
, "ignoreStrings": true
, "ignoreTemplateLiterals": true
, "ignoreRegExpLiterals": true
}]
, "space-before-function-paren": [ "error", {
"anonymous": "always"
, "named": "never"
, "asyncArrow": "always"
}]
, "no-useless-escape": "off"
, "no-prototype-builtins": "off"
, "no-async-promise-executor": "off"
, "semi": [ "error", "always"]
, "comma-dangle": [ "error", "never"]
, "comma-style": [ "error", "first"]
, "no-multiple-empty-lines": [ "error", { "max": 2 }]
, "no-console": [ "error", {
"allow": [ "info", "error" ]
}]
, "@typescript-eslint/no-empty-interface": "off"
, "@typescript-eslint/no-explicit-any": "off"
, "@typescript-eslint/explicit-module-boundary-types": "off"
, "@typescript-eslint/no-unused-vars": "off"
, "@typescript-eslint/ban-types": "off"
, "@typescript-eslint/ban-ts-comment": "off"
}
}

5
app/.eslintrc.json Normal file
View File

@@ -0,0 +1,5 @@
{
"rules": {
"@typescript-eslint/no-non-null-assertion": "off"
}
}

View File

@@ -8,7 +8,7 @@
"package": "node bin/build.js --package", "package": "node bin/build.js --package",
"install-manifest": "node bin/install-manifest.js", "install-manifest": "node bin/install-manifest.js",
"remove-manifest": "node bin/install-manifest.js --remove", "remove-manifest": "node bin/install-manifest.js --remove",
"lint": "tslint -c tslint.json -p ." "lint": "eslint src --ext .ts,.tsx"
}, },
"dependencies": { "dependencies": {
"bplist-creator": "0.0.8", "bplist-creator": "0.0.8",

View File

@@ -26,7 +26,7 @@ export class AirPlayAuthCredentials {
public clientSk: Uint8Array; public clientSk: Uint8Array;
public clientPk: Uint8Array; public clientPk: Uint8Array;
constructor ( constructor(
clientId?: string clientId?: string
, clientSk?: Uint8Array , clientSk?: Uint8Array
, clientPk?: Uint8Array) { , clientPk?: Uint8Array) {
@@ -53,7 +53,7 @@ export class AirPlayAuth {
private credentials: AirPlayAuthCredentials; private credentials: AirPlayAuthCredentials;
private baseUrl: URL; private baseUrl: URL;
constructor (address: string, credentials: AirPlayAuthCredentials) { constructor(address: string, credentials: AirPlayAuthCredentials) {
this.address = address; this.address = address;
this.credentials = credentials; this.credentials = credentials;
@@ -63,7 +63,7 @@ export class AirPlayAuth {
/** /**
* Begins pairing process. * Begins pairing process.
*/ */
public async beginPairing () { public async beginPairing() {
return this.sendPostRequest("/pair-pin-start"); return this.sendPostRequest("/pair-pin-start");
} }
@@ -72,7 +72,7 @@ export class AirPlayAuth {
* beginPairing(). Coordinates the three pairing stages and * beginPairing(). Coordinates the three pairing stages and
* manages request responses. * manages request responses.
*/ */
public async finishPairing (pin: string) { public async finishPairing(pin: string) {
// Stage 1 response // Stage 1 response
const { pk: serverPk const { pk: serverPk
, salt: serverSalt } = await this.pairSetupPin1(); , salt: serverSalt } = await this.pairSetupPin1();
@@ -107,7 +107,7 @@ export class AirPlayAuth {
* Triggering the receiver passcode display and receiving * Triggering the receiver passcode display and receiving
* its public key / salt. * its public key / salt.
*/ */
public async pairSetupPin1 (): Promise<any> { public async pairSetupPin1(): Promise<any> {
const [ response ] = await this.sendPostRequestBplist( const [ response ] = await this.sendPostRequestBplist(
"/pair-setup-pin" "/pair-setup-pin"
, { , {
@@ -125,7 +125,7 @@ export class AirPlayAuth {
* public keys, sending them to the receiver and receiving its * public keys, sending them to the receiver and receiving its
* proof. * proof.
*/ */
public async pairSetupPin2 ( public async pairSetupPin2(
pk: Buffer pk: Buffer
, proof: Buffer): Promise<any> { , proof: Buffer): Promise<any> {
@@ -143,7 +143,7 @@ export class AirPlayAuth {
* secret hash and sending it to the receiver. Receiver then * secret hash and sending it to the receiver. Receiver then
* responds confirming the pairing is complete. * responds confirming the pairing is complete.
*/ */
public async pairSetupPin3 ( public async pairSetupPin3(
sharedSecretHash: crypto.BinaryLike): Promise<any> { sharedSecretHash: crypto.BinaryLike): Promise<any> {
// Create AES key // Create AES key
@@ -182,7 +182,7 @@ export class AirPlayAuth {
* Sends a POST request to receiver and returns the * Sends a POST request to receiver and returns the
* response. * response.
*/ */
public async sendPostRequest ( public async sendPostRequest(
path: string path: string
, contentType?: string , contentType?: string
, data?: Buffer | string): Promise<any> { , data?: Buffer | string): Promise<any> {
@@ -216,7 +216,7 @@ export class AirPlayAuth {
* Encodes binary plist data, sends a POST request to * Encodes binary plist data, sends a POST request to
* receiver, then decodes and returns the response. * receiver, then decodes and returns the response.
*/ */
public async sendPostRequestBplist ( public async sendPostRequestBplist(
path: string path: string
, data?: object): Promise<any> { , data?: object): Promise<any> {

View File

@@ -5,7 +5,7 @@ import castv2 from "castv2";
import Session from "./Session"; import Session from "./Session";
import { Message } from "../../messaging"; import { Message } from "../../messaging";
import { sendMessage } from "../../lib/nativeMessaging" import { sendMessage } from "../../lib/nativeMessaging";
const NS_MEDIA = "urn:x-cast:com.google.cast.media"; const NS_MEDIA = "urn:x-cast:com.google.cast.media";
@@ -27,7 +27,7 @@ export interface UpdateMessageData {
export default class Media { export default class Media {
private channel: castv2.Channel; private channel: castv2.Channel;
constructor ( constructor(
private referenceId: string private referenceId: string
, private session: Session) { , private session: Session) {
@@ -67,7 +67,7 @@ export default class Media {
}); });
} }
public messageHandler (message: Message) { public messageHandler(message: Message) {
switch (message.subject) { switch (message.subject) {
case "bridge:media/sendMediaMessage": { case "bridge:media/sendMediaMessage": {
let error = false; let error = false;
@@ -87,7 +87,7 @@ export default class Media {
} }
} }
private sendMessage (subject: string, data: any) { private sendMessage(subject: string, data: any) {
data._id = this.referenceId; data._id = this.referenceId;
(sendMessage as any)({ (sendMessage as any)({
subject subject

View File

@@ -26,7 +26,7 @@ export default class Session {
private transportConnection?: Channel; private transportConnection?: Channel;
private app: any; private app: any;
constructor ( constructor(
public host: string public host: string
, public port: number , public port: number
, private appId: string , private appId: string
@@ -46,7 +46,7 @@ export default class Session {
this.client = client; this.client = client;
} }
private onConnect () { private onConnect() {
let transportHeartbeat: Channel; let transportHeartbeat: Channel;
const sourceId = "sender-0"; const sourceId = "sender-0";
@@ -67,7 +67,7 @@ export default class Session {
transportHeartbeat.send({ type: "PING" }); transportHeartbeat.send({ type: "PING" });
} }
this.clientHeartbeat!.send({ type: "PING" }); this.clientHeartbeat?.send({ type: "PING" });
}, 5000); }, 5000);
this.clientReceiver.send({ this.clientReceiver.send({
@@ -124,7 +124,7 @@ export default class Session {
}); });
} }
public messageHandler (message: Message) { public messageHandler(message: Message) {
switch (message.subject) { switch (message.subject) {
case "bridge:session/close": case "bridge:session/close":
this.close(); this.close();
@@ -159,7 +159,7 @@ export default class Session {
} }
} }
public createChannel (namespace: string) { public createChannel(namespace: string) {
if (!this.channelMap.has(namespace)) { if (!this.channelMap.has(namespace)) {
this.channelMap.set(namespace, this.client.createChannel( this.channelMap.set(namespace, this.client.createChannel(
this.clientId!, this.transportId! this.clientId!, this.transportId!
@@ -167,16 +167,16 @@ export default class Session {
} }
} }
public close () { public close() {
this.clientConnection?.send({ type: "CLOSE" }); this.clientConnection?.send({ type: "CLOSE" });
this.transportConnection?.send({ type: "CLOSE" }); this.transportConnection?.send({ type: "CLOSE" });
} }
public stop () { public stop() {
this.clientConnection?.send({ type: "STOP" }); this.clientConnection?.send({ type: "STOP" });
} }
private sendMessage (subject: string, data: any = {}) { private sendMessage(subject: string, data: any = {}) {
data._id = this.referenceId; data._id = this.referenceId;
sendMessage({ sendMessage({
// @ts-ignore // @ts-ignore
@@ -185,7 +185,7 @@ export default class Session {
}); });
} }
private _impl_addMessageListener (namespace: string) { private _impl_addMessageListener(namespace: string) {
this.createChannel(namespace); this.createChannel(namespace);
this.channelMap.get(namespace)?.on("message", (data: any) => { this.channelMap.get(namespace)?.on("message", (data: any) => {
this.sendMessage("shim:session/impl_addMessageListener", { this.sendMessage("shim:session/impl_addMessageListener", {
@@ -195,7 +195,7 @@ export default class Session {
}); });
} }
private _impl_sendMessage ( private _impl_sendMessage(
namespace: string namespace: string
, message: {} | string , message: {} | string
, messageId: string) { , messageId: string) {
@@ -220,7 +220,7 @@ export default class Session {
}); });
} }
private _impl_setReceiverMuted (muted: boolean, volumeId: string) { private _impl_setReceiverMuted(muted: boolean, volumeId: string) {
let error = false; let error = false;
@@ -240,7 +240,7 @@ export default class Session {
}); });
} }
private _impl_setReceiverVolumeLevel (newLevel: number, volumeId: string) { private _impl_setReceiverVolumeLevel(newLevel: number, volumeId: string) {
let error = false; let error = false;
@@ -260,7 +260,7 @@ export default class Session {
}); });
} }
private _impl_stop (stopId: string) { private _impl_stop(stopId: string) {
let error = false; let error = false;
try { try {

View File

@@ -17,7 +17,7 @@ export default class StatusListener extends EventEmitter {
private clientReceiver?: Channel; private clientReceiver?: Channel;
private clientHeartbeatIntervalId?: NodeJS.Timeout; private clientHeartbeatIntervalId?: NodeJS.Timeout;
constructor (host: string, port: number) { constructor(host: string, port: number) {
super(); super();
this.client = new Client(); this.client = new Client();
@@ -35,7 +35,7 @@ export default class StatusListener extends EventEmitter {
/** /**
* Closes status listener connection. * Closes status listener connection.
*/ */
public deregister (): void { public deregister(): void {
if (this.clientReceiver) { if (this.clientReceiver) {
this.clientReceiver.send({ type: "CLOSE" }); this.clientReceiver.send({ type: "CLOSE" });
} }
@@ -44,7 +44,7 @@ export default class StatusListener extends EventEmitter {
} }
private onConnect (): void { private onConnect(): void {
const sourceId = "sender-0"; const sourceId = "sender-0";
const destinationId = "receiver-0"; const destinationId = "receiver-0";

View File

@@ -11,7 +11,7 @@ import { Receiver } from "../../types";
const existingSessions: Map<string, Session> = new Map(); const existingSessions: Map<string, Session> = new Map();
const existingMedia: Map<string, Media> = new Map(); const existingMedia: Map<string, Media> = new Map();
export function handleSessionMessage (message: any) { export function handleSessionMessage(message: any) {
if (!message.data._id) { if (!message.data._id) {
console.error("Session message missing _id"); console.error("Session message missing _id");
return; return;
@@ -34,7 +34,7 @@ export function handleSessionMessage (message: any) {
} }
} }
export function handleMediaMessage (message: any) { export function handleMediaMessage(message: any) {
if (!message.data._id) { if (!message.data._id) {
console.error("Media message missing _id"); console.error("Media message missing _id");
return; return;
@@ -44,7 +44,7 @@ export function handleMediaMessage (message: any) {
if (existingMedia.has(mediaId)) { if (existingMedia.has(mediaId)) {
// Forward message to instance message handler // Forward message to instance message handler
existingMedia.get(mediaId)!.messageHandler(message); existingMedia.get(mediaId)?.messageHandler(message);
} else { } else {
if (message.subject === "bridge:media/initialize") { if (message.subject === "bridge:media/initialize") {
// Get Session object media belongs to // Get Session object media belongs to
@@ -61,7 +61,7 @@ export function handleMediaMessage (message: any) {
} }
} }
export function stopReceiverApp (host: string, port: number) { export function stopReceiverApp(host: string, port: number) {
const client = new castv2.Client(); const client = new castv2.Client();
client.connect({ host, port }, () => { client.connect({ host, port }, () => {

View File

@@ -25,7 +25,7 @@ const browser = mdns.createBrowser(mdns.tcp("googlecast"), {
] ]
}); });
function onBrowserServiceUp (service: mdns.Service) { function onBrowserServiceUp(service: mdns.Service) {
// Ignore without txt record // Ignore without txt record
if (!service.txtRecord) { if (!service.txtRecord) {
return; return;
@@ -44,7 +44,7 @@ function onBrowserServiceUp (service: mdns.Service) {
}); });
} }
function onBrowserServiceDown (_service: mdns.Service) { function onBrowserServiceDown(_service: mdns.Service) {
// TODO: Fix service down detection // TODO: Fix service down detection
} }
@@ -56,7 +56,7 @@ interface InitializeOptions {
shouldWatchStatus?: boolean; shouldWatchStatus?: boolean;
} }
export function startDiscovery (options: InitializeOptions) { export function startDiscovery(options: InitializeOptions) {
if (options.shouldWatchStatus) { if (options.shouldWatchStatus) {
browser.on("serviceUp", onStatusBrowserServiceUp); browser.on("serviceUp", onStatusBrowserServiceUp);
browser.on("serviceDown", onStatusBrowserServiceDown); browser.on("serviceDown", onStatusBrowserServiceDown);
@@ -67,7 +67,7 @@ export function startDiscovery (options: InitializeOptions) {
// Receiver status listeners for status mode // Receiver status listeners for status mode
const statusListeners = new Map<string, StatusListener>(); const statusListeners = new Map<string, StatusListener>();
function onStatusBrowserServiceUp (service: mdns.Service) { function onStatusBrowserServiceUp(service: mdns.Service) {
if (!service.txtRecord) { if (!service.txtRecord) {
return; return;
} }
@@ -109,11 +109,11 @@ export function startDiscovery (options: InitializeOptions) {
statusListeners.set(id, listener); statusListeners.set(id, listener);
} }
function onStatusBrowserServiceDown (_service: mdns.Service) { function onStatusBrowserServiceDown(_service: mdns.Service) {
// TODO: Fix service down detection // TODO: Fix service down detection
} }
} }
export function stopDiscovery () { export function stopDiscovery() {
browser.stop(); browser.stop();
} }

View File

@@ -14,9 +14,9 @@ import { convertSrtToVtt } from "../lib/subtitles";
export let mediaServer: http.Server | undefined; export let mediaServer: http.Server | undefined;
export async function startMediaServer (filePath: string, port: number) { export async function startMediaServer(filePath: string, port: number) {
if (mediaServer?.listening) { if (mediaServer?.listening) {
await stopMediaServer(); stopMediaServer();
} }
let fileDir: string; let fileDir: string;
@@ -74,7 +74,9 @@ export async function startMediaServer (filePath: string, port: number) {
path.join(fileDir, dirEntry.name))); path.join(fileDir, dirEntry.name)));
} }
} }
} catch (err) {} } catch (err) {
// TODO: Handle?
}
mediaServer = http.createServer(async (req, res) => { mediaServer = http.createServer(async (req, res) => {
if (!req.url) { if (!req.url) {
@@ -172,7 +174,7 @@ export async function startMediaServer (filePath: string, port: number) {
mediaServer.listen(port); mediaServer.listen(port);
} }
export function stopMediaServer () { export function stopMediaServer() {
if (mediaServer?.listening) { if (mediaServer?.listening) {
mediaServer.close(); mediaServer.close();
mediaServer = undefined; mediaServer = undefined;

View File

@@ -6,7 +6,7 @@ import path from "path";
import { sendMessage } from "../lib/nativeMessaging"; import { sendMessage } from "../lib/nativeMessaging";
function fatal (message: string) { function fatal(message: string) {
console.error(message); console.error(message);
process.exit(1); process.exit(1);
} }
@@ -15,7 +15,7 @@ function fatal (message: string) {
let selectorApp: child_process.ChildProcess | undefined; let selectorApp: child_process.ChildProcess | undefined;
let selectorAppOpen = false; let selectorAppOpen = false;
export function startReceiverSelector (data: string) { export function startReceiverSelector(data: string) {
if (process.platform !== "darwin") { if (process.platform !== "darwin") {
fatal("Invalid platform for native receiver selector."); fatal("Invalid platform for native receiver selector.");
} }
@@ -80,7 +80,7 @@ export function startReceiverSelector (data: string) {
}); });
} }
export function stopReceiverSelector () { export function stopReceiverSelector() {
if (!selectorApp?.killed) { if (!selectorApp?.killed) {
selectorApp?.kill(); selectorApp?.kill();
selectorAppOpen = false; selectorAppOpen = false;

View File

@@ -10,6 +10,6 @@ export const encodeTransform = new EncodeTransform();
process.stdin.pipe(decodeTransform); process.stdin.pipe(decodeTransform);
encodeTransform.pipe(process.stdout); encodeTransform.pipe(process.stdout);
export function sendMessage (message: Message) { export function sendMessage(message: Message) {
encodeTransform.write(message); encodeTransform.write(message);
} }

View File

@@ -6,7 +6,7 @@ import fs from "fs";
/** /**
* Reads a SubRip file and outputs text content as WebVTT. * Reads a SubRip file and outputs text content as WebVTT.
*/ */
export async function convertSrtToVtt (srtFilePath: string) { export async function convertSrtToVtt(srtFilePath: string) {
const fileStream = fs.createReadStream( const fileStream = fs.createReadStream(
srtFilePath, { encoding: "utf-8" }); srtFilePath, { encoding: "utf-8" });

View File

@@ -10,14 +10,16 @@ import { DecodeTransform
, EncodeTransform } from "./transforms"; , EncodeTransform } from "./transforms";
export function init (port: number) { export function init(port: number) {
process.stdout.write("Starting WebSocket server... "); process.stdout.write("Starting WebSocket server... ");
const wss = new WebSocket.Server({ port }, () => { const wss = new WebSocket.Server({ port }, () => {
// eslint-disable-next-line no-console
console.log("Done!"); console.log("Done!");
}); });
wss.on("error", (err) => { wss.on("error", (err) => {
// eslint-disable-next-line no-console
console.log("Failed!"); console.log("Failed!");
console.error(err); console.error(err);
}); });
@@ -26,6 +28,7 @@ export function init (port: number) {
wss.on("connection", socket => { wss.on("connection", socket => {
// Stream for incoming WebSocket messages // Stream for incoming WebSocket messages
const messageStream = new Readable({ objectMode: true }); const messageStream = new Readable({ objectMode: true });
// eslint-disable-next-line @typescript-eslint/no-empty-function
messageStream._read = () => {}; messageStream._read = () => {};
socket.on("message", (message: string) => { socket.on("message", (message: string) => {

View File

@@ -22,8 +22,10 @@ const argv = minimist(process.argv.slice(2), {
if (argv.version) { if (argv.version) {
// eslint-disable-next-line no-console
console.log(`v${__applicationVersion}`); console.log(`v${__applicationVersion}`);
} else if (argv.help) { } else if (argv.help) {
// eslint-disable-next-line no-console
console.log( console.log(
`Usage: ${argv.__name} [options] `Usage: ${argv.__name} [options]

View File

@@ -11,14 +11,14 @@ type ResponseHandlerFunction = (message: Message) => Promise<any>;
* and calls the transform callback. * and calls the transform callback.
*/ */
export class ResponseTransform extends Transform { export class ResponseTransform extends Transform {
constructor (private _handler: ResponseHandlerFunction) { constructor(private _handler: ResponseHandlerFunction) {
super({ super({
readableObjectMode: true readableObjectMode: true
, writableObjectMode: true , writableObjectMode: true
}); });
} }
public _transform ( public _transform(
chunk: Message chunk: Message
, _encoding: string , _encoding: string
// tslint:disable-next-line:ban-types // tslint:disable-next-line:ban-types
@@ -45,13 +45,13 @@ export class DecodeTransform extends Transform {
private _messageBuffer = Buffer.alloc(0); private _messageBuffer = Buffer.alloc(0);
private _messageLength?: number; private _messageLength?: number;
constructor () { constructor() {
super({ super({
readableObjectMode: true readableObjectMode: true
}); });
} }
public _transform ( public _transform(
chunk: any chunk: any
, _encoding: string , _encoding: string
// tslint:disable-next-line:ban-types // tslint:disable-next-line:ban-types
@@ -105,13 +105,13 @@ export class DecodeTransform extends Transform {
* outputs the encoded result. * outputs the encoded result.
*/ */
export class EncodeTransform extends Transform { export class EncodeTransform extends Transform {
constructor () { constructor() {
super({ super({
writableObjectMode: true writableObjectMode: true
}); });
} }
public _transform ( public _transform(
chunk: any chunk: any
, _encoding: string , _encoding: string
// tslint:disable-next-line:ban-types // tslint:disable-next-line:ban-types

View File

@@ -1,5 +0,0 @@
{
"extends": [
"../tslint.json"
]
}

View File

@@ -1,13 +0,0 @@
"use strict";
const { spawnSync } = require("child_process");
const { ROOT, INCLUDE_PATH } = require("./lib/paths");
spawnSync(`tslint --config ${ROOT}/tslint.json \
--project ${ROOT}/tsconfig.json \
"${INCLUDE_PATH}/**/*.ts{,x}"`
, {
shell: true
, stdio: [ process.stdin, process.stdout, process.stderr ]
});

View File

@@ -8,7 +8,7 @@
"package": "node bin/build.js --package", "package": "node bin/build.js --package",
"watch": "node bin/build.js --watch", "watch": "node bin/build.js --watch",
"start": "web-ext run -s ../dist/ext/", "start": "web-ext run -s ../dist/ext/",
"lint": "node bin/lint.js" "lint": "eslint src --ext .ts,.tsx"
}, },
"devDependencies": { "devDependencies": {
"@types/firefox-webext-browser": "^82.0.0", "@types/firefox-webext-browser": "^82.0.0",

View File

@@ -26,15 +26,14 @@ export interface Shim {
} }
// tslint:disable-next-line:new-parens
export default new class ShimManager { export default new class ShimManager {
private activeShims = new Set<Shim>(); private activeShims = new Set<Shim>();
public async init () { public async init() {
await this.initStatusListeners(); await this.initStatusListeners();
} }
public getShim (tabId: number, frameId?: number) { public getShim(tabId: number, frameId?: number) {
for (const activeShim of this.activeShims) { for (const activeShim of this.activeShims) {
if (activeShim.contentTabId === tabId) { if (activeShim.contentTabId === tabId) {
if (frameId && activeShim.contentFrameId !== frameId) { if (frameId && activeShim.contentFrameId !== frameId) {
@@ -46,7 +45,7 @@ export default new class ShimManager {
} }
} }
public async createShim (port: AnyPort) { public async createShim(port: AnyPort) {
const shim = await (port instanceof MessagePort const shim = await (port instanceof MessagePort
? this.createShimFromBackground(port) ? this.createShimFromBackground(port)
: this.createShimFromContent(port)); : this.createShimFromContent(port));
@@ -59,7 +58,7 @@ export default new class ShimManager {
this.activeShims.add(shim); this.activeShims.add(shim);
} }
private async createShimFromBackground ( private async createShimFromBackground(
contentPort: MessagePort): Promise<Shim> { contentPort: MessagePort): Promise<Shim> {
const shim: Shim = { const shim: Shim = {
@@ -83,7 +82,7 @@ export default new class ShimManager {
return shim; return shim;
} }
private async createShimFromContent ( private async createShimFromContent(
contentPort: Port): Promise<Shim> { contentPort: Port): Promise<Shim> {
if (contentPort.sender?.tab?.id === undefined if (contentPort.sender?.tab?.id === undefined
@@ -138,7 +137,7 @@ export default new class ShimManager {
return shim; return shim;
} }
private async handleContentMessage (shim: Shim, message: Message) { private async handleContentMessage(shim: Shim, message: Message) {
const [ destination ] = message.subject.split(":"); const [ destination ] = message.subject.split(":");
if (destination === "bridge") { if (destination === "bridge") {
shim.bridgePort.postMessage(message); shim.bridgePort.postMessage(message);
@@ -164,8 +163,6 @@ export default new class ShimManager {
throw logger.error("Shim associated with content sender missing tab/frame ID"); throw logger.error("Shim associated with content sender missing tab/frame ID");
} }
const contentTab = await browser.tabs.get(shim.contentTabId);
try { try {
const selection = const selection =
await ReceiverSelectorManager.getSelection( await ReceiverSelectorManager.getSelection(
@@ -231,8 +228,8 @@ export default new class ShimManager {
} }
/** /**
* TODO: If we're closing a selector, make sure it's the * TODO: If we're closing a selector, make sure it's the same
* same one that caused the session creation. * one that caused the session creation.
*/ */
case "main:sessionCreated": { case "main:sessionCreated": {
const selector = await ReceiverSelectorManager.getSelector(); const selector = await ReceiverSelectorManager.getSelector();
@@ -248,7 +245,7 @@ export default new class ShimManager {
} }
} }
private async initStatusListeners () { private async initStatusListeners() {
StatusManager.addEventListener("serviceUp", ev => { StatusManager.addEventListener("serviceUp", ev => {
for (const shim of this.activeShims) { for (const shim of this.activeShims) {
shim.contentPort.postMessage({ shim.contentPort.postMessage({

View File

@@ -14,14 +14,13 @@ interface EventMap {
"statusUpdate": { id: string, status: ReceiverStatus }; "statusUpdate": { id: string, status: ReceiverStatus };
} }
// tslint:disable-next-line:new-parens
export default new class StatusManager export default new class StatusManager
extends TypedEventTarget<EventMap> { extends TypedEventTarget<EventMap> {
private bridgePort: (Port | null) = null; private bridgePort: (Port | null) = null;
private receivers = new Map<string, Receiver>(); private receivers = new Map<string, Receiver>();
constructor () { constructor() {
super(); super();
// Bind listeners // Bind listeners
@@ -29,13 +28,13 @@ export default new class StatusManager
this.onBridgePortDisconnect = this.onBridgePortDisconnect.bind(this); this.onBridgePortDisconnect = this.onBridgePortDisconnect.bind(this);
} }
public async init () { public async init() {
if (!this.bridgePort) { if (!this.bridgePort) {
this.bridgePort = await this.createBridgePort(); this.bridgePort = await this.createBridgePort();
} }
} }
public *getReceivers () { public *getReceivers() {
for (const [, receiver ] of this.receivers) { for (const [, receiver ] of this.receivers) {
if (receiver.status && receiver.status.application if (receiver.status && receiver.status.application
&& receiver.status.volume) { && receiver.status.volume) {
@@ -44,7 +43,7 @@ export default new class StatusManager
} }
} }
public async stopReceiverApp (receiver: Receiver) { public async stopReceiverApp(receiver: Receiver) {
if (!this.bridgePort) { if (!this.bridgePort) {
return; return;
} }
@@ -55,7 +54,7 @@ export default new class StatusManager
}); });
} }
private async createBridgePort () { private async createBridgePort() {
const bridgePort = await bridge.connect(); const bridgePort = await bridge.connect();
bridgePort.onMessage.addListener(this.onBridgePortMessage); bridgePort.onMessage.addListener(this.onBridgePortMessage);
bridgePort.onDisconnect.addListener(this.onBridgePortDisconnect); bridgePort.onDisconnect.addListener(this.onBridgePortDisconnect);
@@ -74,7 +73,7 @@ export default new class StatusManager
* Handles incoming bridge status messages, manages the * Handles incoming bridge status messages, manages the
* receiver list, and dispatches events. * receiver list, and dispatches events.
*/ */
private onBridgePortMessage (message: Message) { private onBridgePortMessage(message: Message) {
switch (message.subject) { switch (message.subject) {
case "main:serviceUp": { case "main:serviceUp": {
const { data: receiver } = message; const { data: receiver } = message;
@@ -136,7 +135,7 @@ export default new class StatusManager
* triggered again and the timer is reset for another 10 * triggered again and the timer is reset for another 10
* seconds. * seconds.
*/ */
private onBridgePortDisconnect () { private onBridgePortDisconnect() {
for (const [, receiver] of this.receivers) { for (const [, receiver] of this.receivers) {
const serviceDownEvent = new CustomEvent("serviceDown", { const serviceDownEvent = new CustomEvent("serviceDown", {
detail: { id: receiver.id } detail: { id: receiver.id }

View File

@@ -49,12 +49,12 @@ browser.runtime.onInstalled.addListener(async details => {
* Sets up media overlay content script and handles toggling * Sets up media overlay content script and handles toggling
* on options change. * on options change.
*/ */
async function initMediaOverlay () { async function initMediaOverlay() {
logger.info("init (media overlay)"); logger.info("init (media overlay)");
let contentScript: browser.contentScripts.RegisteredContentScript; let contentScript: browser.contentScripts.RegisteredContentScript;
async function registerMediaOverlayContentScript () { async function registerMediaOverlayContentScript() {
if (!(await options.get("mediaOverlayEnabled"))) { if (!(await options.get("mediaOverlayEnabled"))) {
return; return;
} }
@@ -71,7 +71,7 @@ async function initMediaOverlay () {
} }
} }
async function unregisterMediaOverlayContentScript () { async function unregisterMediaOverlayContentScript() {
await contentScript?.unregister(); await contentScript?.unregister();
} }
@@ -95,7 +95,7 @@ async function initMediaOverlay () {
* with the current version of the extension. If not, triggers * with the current version of the extension. If not, triggers
* a notification with the appropriate info. * a notification with the appropriate info.
*/ */
async function notifyBridgeCompat () { async function notifyBridgeCompat() {
logger.info("checking for bridge..."); logger.info("checking for bridge...");
let info: BridgeInfo; let info: BridgeInfo;
@@ -136,7 +136,7 @@ async function notifyBridgeCompat () {
let isInitialized = false; let isInitialized = false;
async function init () { async function init() {
if (isInitialized) { if (isInitialized) {
return; return;
} }
@@ -193,7 +193,7 @@ async function init () {
*/ */
messaging.onConnect.addListener(async port => { messaging.onConnect.addListener(async port => {
if (port.name === "shim") { if (port.name === "shim") {
ShimManager.createShim(port as any); ShimManager.createShim(port);
} }
}); });
} }

View File

@@ -4,7 +4,7 @@ import loadSender from "../lib/loadSender";
import logger from "../lib/logger"; import logger from "../lib/logger";
import options from "../lib/options"; import options from "../lib/options";
import { getMediaTypesForPageUrl, stringify } from "../lib/utils"; import { stringify } from "../lib/utils";
import { ReceiverSelectionActionType import { ReceiverSelectionActionType
, ReceiverSelectorMediaType } from "./receiverSelector"; , ReceiverSelectorMediaType } from "./receiverSelector";
@@ -33,7 +33,7 @@ let menuIdWhitelistRecommended: MenuId;
const whitelistChildMenuPatterns = new Map<MenuId, string>(); const whitelistChildMenuPatterns = new Map<MenuId, string>();
export async function initMenus () { export async function initMenus() {
logger.info("init (menus)"); logger.info("init (menus)");
const opts = await options.getAll(); const opts = await options.getAll();
@@ -98,9 +98,6 @@ browser.menus.onClicked.addListener(async (info, tab) => {
throw logger.error("Menu handler page URL not found."); throw logger.error("Menu handler page URL not found.");
} }
const availableMediaTypes = getMediaTypesForPageUrl(info.pageUrl);
switch (info.menuItemId) { switch (info.menuItemId) {
case menuIdCast: { case menuIdCast: {
const selection = await ReceiverSelectorManager.getSelection( const selection = await ReceiverSelectorManager.getSelection(

View File

@@ -20,20 +20,20 @@ const _ = browser.i18n.getMessage;
// TODO: Figure out lifetime properly // TODO: Figure out lifetime properly
export default class NativeReceiverSelector extends ReceiverSelector { export default class NativeReceiverSelector extends ReceiverSelector {
private bridgePort: (Port | null) = null; private bridgePort: (Port | null) = null;
private wasReceiverSelected: boolean = false; private wasReceiverSelected = false;
#isOpen = false; #isOpen = false;
constructor () { constructor() {
super(); super();
this.onBridgePortMessage = this.onBridgePortMessage.bind(this); this.onBridgePortMessage = this.onBridgePortMessage.bind(this);
} }
get isOpen () { get isOpen() {
return this.#isOpen; return this.#isOpen;
} }
public async open ( public async open(
receivers: Receiver[] receivers: Receiver[]
, defaultMediaType: ReceiverSelectorMediaType , defaultMediaType: ReceiverSelectorMediaType
, availableMediaTypes: ReceiverSelectorMediaType , availableMediaTypes: ReceiverSelectorMediaType
@@ -86,11 +86,11 @@ export default class NativeReceiverSelector extends ReceiverSelector {
this.#isOpen = true; this.#isOpen = true;
} }
public update (): void { public update(): void {
// TODO: Implement this // TODO: Implement this
} }
public close (): void { public close(): void {
if (this.bridgePort) { if (this.bridgePort) {
this.bridgePort.postMessage({ this.bridgePort.postMessage({
subject: "bridge:closeReceiverSelector" subject: "bridge:closeReceiverSelector"
@@ -100,7 +100,7 @@ export default class NativeReceiverSelector extends ReceiverSelector {
this.#isOpen = false; this.#isOpen = false;
} }
private async onBridgePortMessage (message: Message) { private async onBridgePortMessage(message: Message) {
switch (message.subject) { switch (message.subject) {
case "main:receiverSelector/selected": { case "main:receiverSelector/selected": {
this.wasReceiverSelected = true; this.wasReceiverSelected = true;

View File

@@ -24,13 +24,13 @@ export default class PopupReceiverSelector extends ReceiverSelector {
private defaultMediaType?: ReceiverSelectorMediaType; private defaultMediaType?: ReceiverSelectorMediaType;
private availableMediaTypes?: ReceiverSelectorMediaType; private availableMediaTypes?: ReceiverSelectorMediaType;
private wasReceiverSelected: boolean = false; private wasReceiverSelected = false;
private appId?: string; private appId?: string;
#isOpen = false; #isOpen = false;
constructor () { constructor() {
super(); super();
// Bind methods to pass to addListener // Bind methods to pass to addListener
@@ -48,11 +48,11 @@ export default class PopupReceiverSelector extends ReceiverSelector {
messaging.onConnect.addListener(this.onConnect); messaging.onConnect.addListener(this.onConnect);
} }
get isOpen () { get isOpen() {
return this.#isOpen; return this.#isOpen;
} }
public async open ( public async open(
receivers: Receiver[] receivers: Receiver[]
, defaultMediaType: ReceiverSelectorMediaType , defaultMediaType: ReceiverSelectorMediaType
, availableMediaTypes: ReceiverSelectorMediaType , availableMediaTypes: ReceiverSelectorMediaType
@@ -115,7 +115,7 @@ export default class PopupReceiverSelector extends ReceiverSelector {
} }
} }
public update (receivers: Receiver[]) { public update(receivers: Receiver[]) {
this.receivers = receivers; this.receivers = receivers;
this.messagePort?.postMessage({ this.messagePort?.postMessage({
subject: "popup:update" subject: "popup:update"
@@ -125,7 +125,7 @@ export default class PopupReceiverSelector extends ReceiverSelector {
}); });
} }
public async close (): Promise<void> { public async close(): Promise<void> {
if (this.windowId) { if (this.windowId) {
await browser.windows.remove(this.windowId); await browser.windows.remove(this.windowId);
} }
@@ -138,7 +138,7 @@ export default class PopupReceiverSelector extends ReceiverSelector {
} }
} }
private onConnect (port: Port) { private onConnect(port: Port) {
browser.history.deleteUrl({ url: POPUP_URL }); browser.history.deleteUrl({ url: POPUP_URL });
if (port.name !== "popup") { if (port.name !== "popup") {
@@ -181,7 +181,7 @@ export default class PopupReceiverSelector extends ReceiverSelector {
/** /**
* Handles popup messages. * Handles popup messages.
*/ */
private onPopupMessage (message: Message) { private onPopupMessage(message: Message) {
switch (message.subject) { switch (message.subject) {
case "receiverSelector:selected": { case "receiverSelector:selected": {
this.wasReceiverSelected = true; this.wasReceiverSelected = true;
@@ -206,7 +206,7 @@ export default class PopupReceiverSelector extends ReceiverSelector {
* Handles cancellation state where the popup window is closed * Handles cancellation state where the popup window is closed
* before a receiver is selected. * before a receiver is selected.
*/ */
private onWindowsRemoved (windowId: number) { private onWindowsRemoved(windowId: number) {
// Only care about popup window // Only care about popup window
if (windowId !== this.windowId) { if (windowId !== this.windowId) {
return; return;
@@ -234,7 +234,7 @@ export default class PopupReceiverSelector extends ReceiverSelector {
* into focus. Doesn't apply if no window is focused * into focus. Doesn't apply if no window is focused
* `WINDOW_ID_NONE` or if the popup window is re-focused. * `WINDOW_ID_NONE` or if the popup window is re-focused.
*/ */
private onWindowsFocusChanged (windowId: number) { private onWindowsFocusChanged(windowId: number) {
if (windowId !== browser.windows.WINDOW_ID_NONE if (windowId !== browser.windows.WINDOW_ID_NONE
&& windowId !== this.windowId) { && windowId !== this.windowId) {

View File

@@ -18,7 +18,7 @@ import NativeReceiverSelector from "./NativeReceiverSelector";
import PopupReceiverSelector from "./PopupReceiverSelector"; import PopupReceiverSelector from "./PopupReceiverSelector";
async function createSelector () { async function createSelector() {
const type = await options.get("receiverSelectorType"); const type = await options.get("receiverSelectorType");
const platformInfo = await browser.runtime.getPlatformInfo(); const platformInfo = await browser.runtime.getPlatformInfo();
@@ -33,7 +33,7 @@ async function createSelector () {
let sharedSelector: ReceiverSelector; let sharedSelector: ReceiverSelector;
async function getSelector () { async function getSelector() {
if (!sharedSelector) { if (!sharedSelector) {
try { try {
sharedSelector = await createSelector(); sharedSelector = await createSelector();
@@ -56,7 +56,7 @@ async function getSelector () {
* - Resolves to null if the selection is cancelled. * - Resolves to null if the selection is cancelled.
* - Rejects if the selection fails. * - Rejects if the selection fails.
*/ */
async function getSelection ( async function getSelection(
contextTabId: number contextTabId: number
, contextFrameId = 0 , contextFrameId = 0
, withMediaSender = false) , withMediaSender = false)
@@ -119,7 +119,7 @@ async function getSelection (
sharedSelector = await createSelector(); sharedSelector = await createSelector();
function onReceiverChange () { function onReceiverChange() {
sharedSelector.update(Array.from(StatusManager.getReceivers())); sharedSelector.update(Array.from(StatusManager.getReceivers()));
} }
@@ -136,7 +136,7 @@ async function getSelection (
type EvParamsType = type EvParamsType =
Parameters<typeof sharedSelector.addEventListener>[0]; Parameters<typeof sharedSelector.addEventListener>[0];
function storeListener<T> (type: EvParamsType, fn: T) { function storeListener<T>(type: EvParamsType, fn: T) {
if (type === "selected") { if (type === "selected") {
onSelected = fn; onSelected = fn;
} else if (type === "cancelled") { } else if (type === "cancelled") {
@@ -150,7 +150,7 @@ async function getSelection (
return fn; return fn;
} }
function removeListeners () { function removeListeners() {
sharedSelector.removeEventListener("selected", onSelected); sharedSelector.removeEventListener("selected", onSelected);
sharedSelector.removeEventListener("cancelled", onCancelled); sharedSelector.removeEventListener("cancelled", onCancelled);
sharedSelector.removeEventListener("error", onError); sharedSelector.removeEventListener("error", onError);

View File

@@ -26,7 +26,7 @@ let platform: string;
let chromeUserAgent: string | undefined; let chromeUserAgent: string | undefined;
let chromeUserAgentHybrid: string | undefined; let chromeUserAgentHybrid: string | undefined;
export async function initWhitelist () { export async function initWhitelist() {
logger.info("init (whitelist)"); logger.info("init (whitelist)");
if (!platform) { if (!platform) {
@@ -66,7 +66,7 @@ export async function initWhitelist () {
* as Chrome, so we should rewrite the User-Agent header * as Chrome, so we should rewrite the User-Agent header
* to reflect this on whitelisted sites. * to reflect this on whitelisted sites.
*/ */
async function onWhitelistedBeforeSendHeaders ( async function onWhitelistedBeforeSendHeaders(
details: OnBeforeSendHeadersDetails) { details: OnBeforeSendHeadersDetails) {
if (!details.requestHeaders) { if (!details.requestHeaders) {
@@ -100,7 +100,7 @@ export async function initWhitelist () {
* players on other origins (like CDN domains) when the * players on other origins (like CDN domains) when the
* main site is whitelisted. * main site is whitelisted.
*/ */
function onWhitelistedChildBeforeSendHeaders ( function onWhitelistedChildBeforeSendHeaders(
details: OnBeforeSendHeadersDetails) { details: OnBeforeSendHeadersDetails) {
if (!details.requestHeaders || !details.frameAncestors) { if (!details.requestHeaders || !details.frameAncestors) {
@@ -137,7 +137,7 @@ function onWhitelistedChildBeforeSendHeaders (
* We can redirect this and inject our own script to setup * We can redirect this and inject our own script to setup
* the API shim. * the API shim.
*/ */
async function onBeforeCastSDKRequest (details: OnBeforeRequestDetails) { async function onBeforeCastSDKRequest(details: OnBeforeRequestDetails) {
if (!details.originUrl) { if (!details.originUrl) {
return {}; return {};
} }
@@ -183,7 +183,7 @@ async function onBeforeCastSDKRequest (details: OnBeforeRequestDetails) {
} }
async function registerUserAgentWhitelist () { async function registerUserAgentWhitelist() {
const { userAgentWhitelist const { userAgentWhitelist
, userAgentWhitelistEnabled } = await options.getAll(); , userAgentWhitelistEnabled } = await options.getAll();
@@ -209,7 +209,7 @@ async function registerUserAgentWhitelist () {
, [ "blocking", "requestHeaders" ]); , [ "blocking", "requestHeaders" ]);
} }
function unregisterUserAgentWhitelist () { function unregisterUserAgentWhitelist() {
originUrlCache.length = 0; originUrlCache.length = 0;
browser.webRequest.onBeforeSendHeaders browser.webRequest.onBeforeSendHeaders

20
ext/src/global.d.ts vendored
View File

@@ -5,7 +5,7 @@ declare const APPLICATION_VERSION: string;
declare interface Object { declare interface Object {
// tslint:disable-next-line:ban-types // eslint-disable-next-line @typescript-eslint/ban-types
wrappedJSObject: Object; wrappedJSObject: Object;
} }
@@ -67,7 +67,6 @@ declare function exportFunction (
, options?: ExportFunctionOptions): ExportFunctionFunc; , options?: ExportFunctionOptions): ExportFunctionFunc;
// Fix issues with @types/firefox-webext-browser // Fix issues with @types/firefox-webext-browser
declare namespace browser.events { declare namespace browser.events {
/** /**
@@ -91,23 +90,8 @@ declare namespace browser.runtime {
onMessage: browser.events.Event; onMessage: browser.events.Event;
} }
function connect (connectInfo: { function connect(connectInfo: {
name?: string name?: string
, includeTlsChannelId?: boolean , includeTlsChannelId?: boolean
}): browser.runtime.Port; }): browser.runtime.Port;
} }
// Allow default attribute on <button>
declare namespace React {
interface ButtonHTMLAttributes<T> {
default?: boolean;
}
}
declare namespace JSX {
interface IntrinsicElements {
button: React.DetailedHTMLProps<
React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>;
}
}

View File

@@ -12,25 +12,25 @@ interface TabConnectInfo {
} }
export default class Messenger<T> { export default class Messenger<T> {
connect (connectInfo: RuntimeConnectInfo) { connect(connectInfo: RuntimeConnectInfo) {
return browser.runtime.connect(connectInfo) as return browser.runtime.connect(connectInfo) as
unknown as TypedPort<T>; unknown as TypedPort<T>;
} }
connectTab (tabId: number, connectInfo: TabConnectInfo) { connectTab(tabId: number, connectInfo: TabConnectInfo) {
return browser.tabs.connect(tabId, connectInfo) as return browser.tabs.connect(tabId, connectInfo) as
unknown as TypedPort<T>; unknown as TypedPort<T>;
} }
onConnect = { onConnect = {
addListener (cb: (port: TypedPort<T>) => void) { addListener(cb: (port: TypedPort<T>) => void) {
browser.runtime.onConnect.addListener(cb as any); browser.runtime.onConnect.addListener(cb as any);
} }
, removeListener (cb: (port: TypedPort<T>) => void) { , removeListener(cb: (port: TypedPort<T>) => void) {
browser.runtime.onConnect.removeListener(cb as any); browser.runtime.onConnect.removeListener(cb as any);
} }
, hasListener (cb: (port: TypedPort<T>) => void) { , hasListener(cb: (port: TypedPort<T>) => void) {
return browser.runtime.onConnect.hasListener(cb as any); return browser.runtime.onConnect.hasListener(cb as any);
} }
} }
}; }

View File

@@ -6,20 +6,20 @@ interface TypedEvents {
export class TypedEventTarget<T extends TypedEvents> extends EventTarget { export class TypedEventTarget<T extends TypedEvents> extends EventTarget {
// @ts-ignore // @ts-ignore
public addEventListener<K extends keyof T> ( public addEventListener<K extends keyof T>(
type: K, listener: (ev: CustomEvent<T[K]>) => void): void { type: K, listener: (ev: CustomEvent<T[K]>) => void): void {
// @ts-ignore // @ts-ignore
super.addEventListener(type as string, listener); super.addEventListener(type as string, listener);
} }
// @ts-ignore // @ts-ignore
public removeEventListener<K extends keyof T> ( public removeEventListener<K extends keyof T>(
type: K, listener: (ev: CustomEvent<T[K]>) => void): void { type: K, listener: (ev: CustomEvent<T[K]>) => void): void {
// @ts-ignore // @ts-ignore
super.removeEventListener(type as string, listener); super.removeEventListener(type as string, listener);
} }
public dispatchEvent<K extends keyof T> (ev: CustomEvent<T[K]>): boolean { public dispatchEvent<K extends keyof T>(ev: CustomEvent<T[K]>): boolean {
return super.dispatchEvent(ev); return super.dispatchEvent(ev);
} }
} }

View File

@@ -9,12 +9,12 @@
export class TypedStorageArea<Schema extends { [key: string]: any }> { export class TypedStorageArea<Schema extends { [key: string]: any }> {
private storageArea: any; private storageArea: any;
constructor (storageArea: browser.storage.StorageArea) { constructor(storageArea: browser.storage.StorageArea) {
this.storageArea = storageArea; this.storageArea = storageArea;
} }
public async get<SchemaKey extends keyof Schema public async get<SchemaKey extends keyof Schema
, SchemaPartial extends Partial<Schema>> ( , SchemaPartial extends Partial<Schema>>(
keys?: SchemaKey keys?: SchemaKey
| SchemaKey[] | SchemaKey[]
| SchemaPartial | SchemaPartial
@@ -25,23 +25,23 @@ export class TypedStorageArea<Schema extends { [key: string]: any }> {
return await this.storageArea.get(keys); return await this.storageArea.get(keys);
} }
public async getBytesInUse<SchemaKey extends keyof Schema> ( public async getBytesInUse<SchemaKey extends keyof Schema>(
keys?: Schema | SchemaKey[]): Promise<number> { keys?: Schema | SchemaKey[]): Promise<number> {
return await this.storageArea.getBytesInUse(keys); return await this.storageArea.getBytesInUse(keys);
} }
public async set (keys: Partial<Schema>): Promise<void> { public async set(keys: Partial<Schema>): Promise<void> {
await this.storageArea.set(keys); await this.storageArea.set(keys);
} }
public async remove<SchemaKey extends keyof Schema> ( public async remove<SchemaKey extends keyof Schema>(
keys: SchemaKey | SchemaKey[]): Promise<void> { keys: SchemaKey | SchemaKey[]): Promise<void> {
await this.storageArea.remove(keys); await this.storageArea.remove(keys);
} }
public async clear (): Promise<void> { public async clear(): Promise<void> {
await this.storageArea.clear(); await this.storageArea.clear();
} }
} }

View File

@@ -16,7 +16,7 @@ import { ReceiverSelectionCast
export const BRIDGE_TIMEOUT = 5000; export const BRIDGE_TIMEOUT = 5000;
async function connect (): Promise<Port> { async function connect(): Promise<Port> {
const applicationName = await options.get("bridgeApplicationName"); const applicationName = await options.get("bridgeApplicationName");
const bridgePort = nativeMessaging.connectNative(applicationName) as const bridgePort = nativeMessaging.connectNative(applicationName) as
unknown as Port; unknown as Port;

View File

@@ -20,7 +20,7 @@ interface LoadSenderOptions {
* Loads the appropriate sender for a given receiver * Loads the appropriate sender for a given receiver
* selector response. * selector response.
*/ */
export default async function loadSender (opts: LoadSenderOptions) { export default async function loadSender(opts: LoadSenderOptions) {
// Cancelled // Cancelled
if (!opts.selection) { if (!opts.selection) {
return; return;

View File

@@ -1,19 +1,19 @@
"use strict"; "use strict";
export class Logger { export class Logger {
constructor (private prefix: string) {} constructor(private prefix: string) {}
public log (message: string, data?: any) { public log(message: string, data?: any) {
const formattedMessage = `${this.prefix} (Log): ${message}`; const formattedMessage = `${this.prefix} (Log): ${message}`;
if (data) { if (data) {
// tslint:disable-next-line:no-console // eslint-disable-next-line no-console
console.log(formattedMessage, data); console.log(formattedMessage, data);
} else { } else {
// tslint:disable-next-line:no-console // eslint-disable-next-line no-console
console.log(formattedMessage); console.log(formattedMessage);
} }
} }
public info (message: string, data?: any) { public info(message: string, data?: any) {
const formattedMessage = `${this.prefix} (Info): ${message}`; const formattedMessage = `${this.prefix} (Info): ${message}`;
if (data) { if (data) {
console.info(formattedMessage, data); console.info(formattedMessage, data);
@@ -21,7 +21,7 @@ export class Logger {
console.info(formattedMessage); console.info(formattedMessage);
} }
} }
public error (message: string, data?: any) { public error(message: string, data?: any) {
const formattedMessage = `${this.prefix} (Error): ${message}`; const formattedMessage = `${this.prefix} (Error): ${message}`;
if (data) { if (data) {
console.error(formattedMessage, data); console.error(formattedMessage, data);

View File

@@ -6,11 +6,10 @@ import options from "./options";
import { Message, Port } from "../messaging"; import { Message, Port } from "../messaging";
type DisconnectListener = (port: Port) => void; type DisconnectListener = (port: Port) => void;
type MessageListener = (message: Message) => void; type MessageListener = (message: Message) => void;
function connectNative (application: string): Port { function connectNative(application: string): Port {
/** /**
* In order to preserve the synchronous API, messages are * In order to preserve the synchronous API, messages are
* queued before either the native messaging host or the * queued before either the native messaging host or the
@@ -39,35 +38,35 @@ function connectNative (application: string): Port {
, name: "" , name: ""
, onDisconnect: { , onDisconnect: {
addListener (cb: DisconnectListener) { addListener(cb: DisconnectListener) {
onDisconnectListeners.add(cb); onDisconnectListeners.add(cb);
} }
, removeListener (cb: DisconnectListener) { , removeListener(cb: DisconnectListener) {
onDisconnectListeners.delete(cb); onDisconnectListeners.delete(cb);
} }
, hasListener (cb: DisconnectListener) { , hasListener(cb: DisconnectListener) {
return onDisconnectListeners.has(cb); return onDisconnectListeners.has(cb);
} }
, hasListeners () { , hasListeners() {
return onDisconnectListeners.size > 0; return onDisconnectListeners.size > 0;
} }
} }
, onMessage: { , onMessage: {
addListener (cb: MessageListener) { addListener(cb: MessageListener) {
onMessageListeners.add(cb); onMessageListeners.add(cb);
} }
, removeListener (cb: MessageListener) { , removeListener(cb: MessageListener) {
onMessageListeners.delete(cb); onMessageListeners.delete(cb);
} }
, hasListener (cb: MessageListener) { , hasListener(cb: MessageListener) {
return onMessageListeners.has(cb); return onMessageListeners.has(cb);
} }
, hasListeners () { , hasListeners() {
return onMessageListeners.size > 0; return onMessageListeners.size > 0;
} }
} }
, disconnect () { , disconnect() {
if (socket) { if (socket) {
socket.close(); socket.close();
} else { } else {
@@ -75,7 +74,7 @@ function connectNative (application: string): Port {
} }
} }
, postMessage (message) { , postMessage(message) {
if (socket) { if (socket) {
switch (socket.readyState) { switch (socket.readyState) {
case WebSocket.CONNECTING: { case WebSocket.CONNECTING: {
@@ -168,7 +167,7 @@ function connectNative (application: string): Port {
return portObject; return portObject;
} }
async function sendNativeMessage ( async function sendNativeMessage(
application: string application: string
, message: Message) { , message: Message) {

View File

@@ -41,9 +41,8 @@ interface EventMap {
"changed": Array<keyof Options>; "changed": Array<keyof Options>;
} }
// tslint:disable-next-line:new-parens
export default new class extends TypedEventTarget<EventMap> { export default new class extends TypedEventTarget<EventMap> {
constructor () { constructor() {
super(); super();
this.onStorageChanged = this.onStorageChanged.bind(this); this.onStorageChanged = this.onStorageChanged.bind(this);
browser.storage.onChanged.addListener(this.onStorageChanged); browser.storage.onChanged.addListener(this.onStorageChanged);
@@ -105,7 +104,7 @@ export default new class extends TypedEventTarget<EventMap> {
* Fetches `options` key from storage and returns it as * Fetches `options` key from storage and returns it as
* Options interface type. * Options interface type.
*/ */
public async getAll (): Promise<Options> { public async getAll(): Promise<Options> {
const { options } = await storageArea.get("options"); const { options } = await storageArea.get("options");
return options; return options;
} }
@@ -114,7 +113,7 @@ export default new class extends TypedEventTarget<EventMap> {
* Takes Options object and sets to `options` storage key. * Takes Options object and sets to `options` storage key.
* Returns storage promise. * Returns storage promise.
*/ */
public async setAll (options: Options): Promise<void> { public async setAll(options: Options): Promise<void> {
return storageArea.set({ options }); return storageArea.set({ options });
} }
@@ -122,7 +121,7 @@ export default new class extends TypedEventTarget<EventMap> {
* Gets specific option from storage and returns it as its * Gets specific option from storage and returns it as its
* type from Options interface type. * type from Options interface type.
*/ */
public async get<T extends keyof Options> (name: T): Promise<Options[T]> { public async get<T extends keyof Options>(name: T): Promise<Options[T]> {
const options = await this.getAll(); const options = await this.getAll();
if (options.hasOwnProperty(name)) { if (options.hasOwnProperty(name)) {
@@ -136,7 +135,7 @@ export default new class extends TypedEventTarget<EventMap> {
* Sets specific option to storage. Returns storage * Sets specific option to storage. Returns storage
* promise. * promise.
*/ */
public async set<T extends keyof Options> ( public async set<T extends keyof Options>(
name: T name: T
, value: Options[T]): Promise<void> { , value: Options[T]): Promise<void> {
@@ -151,7 +150,7 @@ export default new class extends TypedEventTarget<EventMap> {
* against defaults. Any options in defaults and not in * against defaults. Any options in defaults and not in
* storage are set. Does not override any existing options. * storage are set. Does not override any existing options.
*/ */
public async update (defaults = defaultOptions): Promise<void> { public async update(defaults = defaultOptions): Promise<void> {
const newOpts = await this.getAll(); const newOpts = await this.getAll();
// Find options not already in storage // Find options not already in storage

View File

@@ -8,7 +8,7 @@ const PLATFORM_LINUX = "X11; Linux x86_64";
const UA_CHROME = "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36"; const UA_CHROME = "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36";
const UA_HYBRID = "Chrome/80.0.3987.87 Gecko/20100101 Firefox/72.0"; const UA_HYBRID = "Chrome/80.0.3987.87 Gecko/20100101 Firefox/72.0";
export function getChromeUserAgent (platform: string, hybrid = false) { export function getChromeUserAgent(platform: string, hybrid = false) {
let platformComponent: string; let platformComponent: string;
if (platform === "mac") { if (platform === "mac") {
platformComponent = hybrid platformComponent = hybrid

View File

@@ -5,13 +5,11 @@ import logger from "./logger";
import { ReceiverSelectorMediaType } from "../background/receiverSelector"; import { ReceiverSelectorMediaType } from "../background/receiverSelector";
export function getNextEllipsis (ellipsis: string): string { export function getNextEllipsis(ellipsis: string): string {
/* tslint:disable:curly */
if (ellipsis === "") return "."; if (ellipsis === "") return ".";
if (ellipsis === ".") return ".."; if (ellipsis === ".") return "..";
if (ellipsis === "..") return "..."; if (ellipsis === "..") return "...";
if (ellipsis === "...") return ""; if (ellipsis === "...") return "";
/* tslint:enable:curly */
return ""; return "";
} }
@@ -19,7 +17,7 @@ export function getNextEllipsis (ellipsis: string): string {
/** /**
* Template literal tag function, JSON-encodes substitutions. * Template literal tag function, JSON-encodes substitutions.
*/ */
export function stringify ( export function stringify(
templateStrings: TemplateStringsArray templateStrings: TemplateStringsArray
, ...substitutions: any[]) { , ...substitutions: any[]) {
@@ -36,7 +34,7 @@ export function stringify (
return formattedString; return formattedString;
} }
export function getMediaTypesForPageUrl ( export function getMediaTypesForPageUrl(
pageUrl: string): ReceiverSelectorMediaType { pageUrl: string): ReceiverSelectorMediaType {
const url = new URL(pageUrl); const url = new URL(pageUrl);
@@ -90,7 +88,7 @@ export interface WindowCenteredProps {
top: number; top: number;
} }
export function getWindowCenteredProps ( export function getWindowCenteredProps(
refWin: browser.windows.Window refWin: browser.windows.Window
, width: number , width: number
, height: number): WindowCenteredProps { , height: number): WindowCenteredProps {
@@ -111,11 +109,10 @@ export function getWindowCenteredProps (
} }
// tslint:disable-next-line:max-line-length
export const REMOTE_MATCH_PATTERN_REGEX = /^(?:(?:(\*|https?|ftp):\/\/(\*|(?:\*\.(?:[^\/\*:]\.?)+(?:[^\.])|[^\/\*:]*))?)(\/.*)|<all_urls>)$/; export const REMOTE_MATCH_PATTERN_REGEX = /^(?:(?:(\*|https?|ftp):\/\/(\*|(?:\*\.(?:[^\/\*:]\.?)+(?:[^\.])|[^\/\*:]*))?)(\/.*)|<all_urls>)$/;
export function loadScript ( export function loadScript(
scriptUrl: string scriptUrl: string
, doc: Document = document): HTMLScriptElement { , doc: Document = document): HTMLScriptElement {

View File

@@ -8,7 +8,7 @@ import { Message } from "../../messaging";
import { Receiver } from "../../types"; import { Receiver } from "../../types";
function startMediaServer (filePath: string, port: number) function startMediaServer(filePath: string, port: number)
: Promise<{ mediaPath: string : Promise<{ mediaPath: string
, subtitlePaths: string[] , subtitlePaths: string[]
, localAddress: string }> { , localAddress: string }> {
@@ -22,7 +22,7 @@ function startMediaServer (filePath: string, port: number)
} }
} as Message); } as Message);
backgroundPort.addEventListener("message", function onMessage (ev) { backgroundPort.addEventListener("message", function onMessage(ev) {
const message = ev.data as Message; const message = ev.data as Message;
if (message.subject.startsWith("mediaCast:mediaServer")) { if (message.subject.startsWith("mediaCast:mediaServer")) {
@@ -54,14 +54,14 @@ let currentMedia: cast.media.Media;
let mediaElement: HTMLMediaElement; let mediaElement: HTMLMediaElement;
function getSession (opts: InitOptions): Promise<cast.Session> { function getSession(opts: InitOptions): Promise<cast.Session> {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
/** /**
* If a receiver is available, call requestSession. If a * If a receiver is available, call requestSession. If a
* specific receiver was specified, bypass receiver selector * specific receiver was specified, bypass receiver selector
* and create session directly. * and create session directly.
*/ */
function receiverListener (availability: string) { function receiverListener(availability: string) {
if (availability === cast.ReceiverAvailability.AVAILABLE) { if (availability === cast.ReceiverAvailability.AVAILABLE) {
if (opts.receiver) { if (opts.receiver) {
cast._requestSession( cast._requestSession(
@@ -76,14 +76,14 @@ function getSession (opts: InitOptions): Promise<cast.Session> {
} }
} }
function sessionListener () { function sessionListener() {
// TODO: Handle this // TODO: Handle this
} }
function onRequestSessionSuccess (session: cast.Session) { function onRequestSessionSuccess(session: cast.Session) {
resolve(session); resolve(session);
} }
function onRequestSessionError (err: cast.Error) { function onRequestSessionError(err: cast.Error) {
reject(err.description); reject(err.description);
} }
@@ -101,7 +101,7 @@ function getSession (opts: InitOptions): Promise<cast.Session> {
}); });
} }
function getMedia (opts: InitOptions): Promise<cast.media.Media> { function getMedia(opts: InitOptions): Promise<cast.media.Media> {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
let mediaUrl = new URL(opts.mediaUrl); let mediaUrl = new URL(opts.mediaUrl);
let subtitleUrls: URL[] = []; let subtitleUrls: URL[] = [];
@@ -233,16 +233,15 @@ function getMedia (opts: InitOptions): Promise<cast.media.Media> {
let ignoreMediaEvents = false; let ignoreMediaEvents = false;
async function registerMediaElementListeners () { async function registerMediaElementListeners() {
if (await options.get("mediaSyncElement")) { function checkIgnore(ev: Event) {
if (ignoreMediaEvents) {
function checkIgnore (ev: Event) { ignoreMediaEvents = false;
if (ignoreMediaEvents) { ev.stopImmediatePropagation();
ignoreMediaEvents = false;
ev.stopImmediatePropagation();
}
} }
}
if (await options.get("mediaSyncElement")) {
mediaElement.addEventListener("play", checkIgnore, true); mediaElement.addEventListener("play", checkIgnore, true);
mediaElement.addEventListener("pause", checkIgnore, true); mediaElement.addEventListener("pause", checkIgnore, true);
mediaElement.addEventListener("suspend", checkIgnore, true); mediaElement.addEventListener("suspend", checkIgnore, true);
@@ -348,7 +347,7 @@ interface InitOptions {
targetElementId?: number; targetElementId?: number;
} }
export async function init (opts: InitOptions) { export async function init(opts: InitOptions) {
backgroundPort = await ensureInit(); backgroundPort = await ensureInit();
const isLocalMedia = opts.mediaUrl.startsWith("file://"); const isLocalMedia = opts.mediaUrl.startsWith("file://");
@@ -380,8 +379,7 @@ export async function init (opts: InitOptions) {
}); });
if (await options.get("mediaStopOnUnload")) { if (await options.get("mediaStopOnUnload")) {
// tslint:disable-next-line: no-empty currentSession.stop();
currentSession.stop(() => {}, () => {});
} }
}); });
} }

View File

@@ -4,7 +4,7 @@
* Walk up the prototype chain until the specified property * Walk up the prototype chain until the specified property
* descriptor is found, otherwise return undefined. * descriptor is found, otherwise return undefined.
*/ */
export function getPropertyDescriptor ( export function getPropertyDescriptor(
target: any, prop: string | number | symbol) target: any, prop: string | number | symbol)
: PropertyDescriptor | undefined { : PropertyDescriptor | undefined {
@@ -23,7 +23,7 @@ export function getPropertyDescriptor (
* Bind either the getter/setter functions or the value function * Bind either the getter/setter functions or the value function
* to a target object. * to a target object.
*/ */
export function bindPropertyDescriptor ( export function bindPropertyDescriptor(
desc: PropertyDescriptor, target: any) desc: PropertyDescriptor, target: any)
: PropertyDescriptor { : PropertyDescriptor {
@@ -42,7 +42,7 @@ export function bindPropertyDescriptor (
* be further up in the prototype chain), re-bind it to the target * be further up in the prototype chain), re-bind it to the target
* element and collect them into a property descriptor map. * element and collect them into a property descriptor map.
*/ */
export function clonePropsDescriptor<T> ( export function clonePropsDescriptor<T>(
target: T, props: any[]) target: T, props: any[])
: PropertyDescriptorMap { : PropertyDescriptorMap {
@@ -57,15 +57,15 @@ export function clonePropsDescriptor<T> (
}, {}); }, {});
} }
export function makeGetterDescriptor (val: any): PropertyDescriptor { export function makeGetterDescriptor(val: any): PropertyDescriptor {
return { return {
enumerable: true enumerable: true
, configurable: true , configurable: true
, get () { return val; } , get() { return val; }
}; };
} }
export function makeValueDescriptor (val: any): PropertyDescriptor { export function makeValueDescriptor(val: any): PropertyDescriptor {
return { return {
enumerable: true enumerable: true
, configurable: true , configurable: true

View File

@@ -28,8 +28,7 @@ Element.prototype.attachShadow = function (init) {
}; };
function getShadowRootFromNode(node: Node): ShadowRoot | undefined {
function getShadowRootFromNode (node: Node): ShadowRoot | undefined {
// Don't touch our custom element // Don't touch our custom element
if (node instanceof PlayerElement) { if (node instanceof PlayerElement) {
return; return;
@@ -45,13 +44,13 @@ const DQS_XPATH_EXPRESSION = `//*[contains(name(), "-")]`;
* Return the first matching querySelector result on any ShadowRoot * Return the first matching querySelector result on any ShadowRoot
* nodes present in the document. * nodes present in the document.
*/ */
function deepQuerySelector (selector: string): Element | null { function deepQuerySelector(selector: string): Element | null {
const result = document.evaluate( const result = document.evaluate(
DQS_XPATH_EXPRESSION, document, null DQS_XPATH_EXPRESSION, document, null
, XPathResult.ORDERED_NODE_ITERATOR_TYPE); , XPathResult.ORDERED_NODE_ITERATOR_TYPE);
let node: Node | null; let node: Node | null;
// tslint:disable-next-line: no-conditional-assignment // eslint-disable-next-line no-cond-assign
while (node = result.iterateNext()) { while (node = result.iterateNext()) {
const shadowRoot = getShadowRootFromNode(node); const shadowRoot = getShadowRootFromNode(node);
if (!shadowRoot) { if (!shadowRoot) {
@@ -71,7 +70,7 @@ function deepQuerySelector (selector: string): Element | null {
* Collect and return the results of querySelectorAll on any * Collect and return the results of querySelectorAll on any
* ShadowRoot nodes present in the document. * ShadowRoot nodes present in the document.
*/ */
function deepQuerySelectorAll (selector: string): Node[] { function deepQuerySelectorAll(selector: string): Node[] {
const result = document.evaluate( const result = document.evaluate(
DQS_XPATH_EXPRESSION, document, null DQS_XPATH_EXPRESSION, document, null
, XPathResult.ORDERED_NODE_ITERATOR_TYPE); , XPathResult.ORDERED_NODE_ITERATOR_TYPE);
@@ -79,7 +78,7 @@ function deepQuerySelectorAll (selector: string): Node[] {
const nodes: Node[] = []; const nodes: Node[] = [];
let node: Node | null; let node: Node | null;
// tslint:disable-next-line: no-conditional-assignment // eslint-disable-next-line no-cond-assign
while (node = result.iterateNext()) { while (node = result.iterateNext()) {
const shadowRoot = getShadowRootFromNode(node); const shadowRoot = getShadowRootFromNode(node);
if (shadowRoot) { if (shadowRoot) {
@@ -116,7 +115,7 @@ const mediaElementAttributes = mediaElementTypes
* functions are proxied to the internal media element. * functions are proxied to the internal media element.
*/ */
class PlayerElement extends HTMLElement { class PlayerElement extends HTMLElement {
constructor () { constructor() {
super(); super();
const shadowRoot = this.attachShadow({ mode: "closed" }); const shadowRoot = this.attachShadow({ mode: "closed" });
@@ -204,11 +203,11 @@ class PlayerElement extends HTMLElement {
class AudioPlayerElement extends PlayerElement {} class AudioPlayerElement extends PlayerElement {}
class VideoPlayerElement extends PlayerElement { class VideoPlayerElement extends PlayerElement {
set overlayHidden (val: boolean) { set overlayHidden(val: boolean) {
const shadowRoot = internalShadowRoots.get(this); const shadowRoot = internalShadowRoots.get(this);
(shadowRoot?.querySelector(".overlay") as HTMLDivElement).hidden = val; (shadowRoot?.querySelector(".overlay") as HTMLDivElement).hidden = val;
} }
get overlayHidden () { get overlayHidden() {
const shadowRoot = internalShadowRoots.get(this); const shadowRoot = internalShadowRoots.get(this);
return (shadowRoot?.querySelector(".overlay") as HTMLDivElement).hidden; return (shadowRoot?.querySelector(".overlay") as HTMLDivElement).hidden;
} }
@@ -234,7 +233,7 @@ const _createElementNS = document.createElementNS;
* custom element version that imitates the original. Otherwise, returns * custom element version that imitates the original. Otherwise, returns
* the result of the original. * the result of the original.
*/ */
function createElement ( function createElement(
tagName: string tagName: string
, options?: ElementCreationOptions) { , options?: ElementCreationOptions) {
@@ -264,7 +263,7 @@ function createElement (
* patched `createElement` function, otherwise return the result of the * patched `createElement` function, otherwise return the result of the
* original. * original.
*/ */
function createElementNS ( function createElementNS(
namespaceURI: string namespaceURI: string
, qualifiedName: string , qualifiedName: string
, options?: ElementCreationOptions) { , options?: ElementCreationOptions) {
@@ -298,7 +297,7 @@ Object.defineProperties(document, {
* `createElement` function, fetches the shadow root and copies any * `createElement` function, fetches the shadow root and copies any
* attributes before swapping with the original element in-place. * attributes before swapping with the original element in-place.
*/ */
function wrapMediaElement (mediaElement: HTMLMediaElement) { function wrapMediaElement(mediaElement: HTMLMediaElement) {
const wrappedMedia = document.createElement(mediaElement.tagName); const wrappedMedia = document.createElement(mediaElement.tagName);
const shadowRoot = internalShadowRoots.get(wrappedMedia); const shadowRoot = internalShadowRoots.get(wrappedMedia);

View File

@@ -27,7 +27,7 @@ let peerConnection: RTCPeerConnection;
* Sends a message to the fx_cast app running on the * Sends a message to the fx_cast app running on the
* receiver device. * receiver device.
*/ */
function sendAppMessage (subject: string, data: any) { function sendAppMessage(subject: string, data: any) {
if (!session) { if (!session) {
return; return;
} }
@@ -44,7 +44,7 @@ window.addEventListener("beforeunload", () => {
}); });
async function onRequestSessionSuccess (newSession: cast.Session) { async function onRequestSessionSuccess(newSession: cast.Session) {
cast.logMessage("onRequestSessionSuccess"); cast.logMessage("onRequestSessionSuccess");
session = newSession; session = newSession;
@@ -102,7 +102,7 @@ async function onRequestSessionSuccess (newSession: cast.Session) {
let lastFrame: DOMHighResTimeStamp; let lastFrame: DOMHighResTimeStamp;
window.requestAnimationFrame( window.requestAnimationFrame(
function draw (now: DOMHighResTimeStamp) { function draw(now: DOMHighResTimeStamp) {
if (!lastFrame) { if (!lastFrame) {
lastFrame = now; lastFrame = now;
@@ -153,7 +153,7 @@ async function onRequestSessionSuccess (newSession: cast.Session) {
} }
function receiverListener (availability: string) { function receiverListener(availability: string) {
cast.logMessage("receiverListener"); cast.logMessage("receiverListener");
if (wasSessionRequested) { if (wasSessionRequested) {
@@ -170,16 +170,16 @@ function receiverListener (availability: string) {
} }
function onRequestSessionError () { function onRequestSessionError() {
cast.logMessage("onRequestSessionError"); cast.logMessage("onRequestSessionError");
} }
function sessionListener () { function sessionListener() {
cast.logMessage("sessionListener"); cast.logMessage("sessionListener");
} }
function onInitializeSuccess () { function onInitializeSuccess() {
cast.logMessage("onInitializeSuccess"); cast.logMessage("onInitializeSuccess");
} }
function onInitializeError () { function onInitializeError() {
cast.logMessage("onInitializeError"); cast.logMessage("onInitializeError");
} }

View File

@@ -8,7 +8,7 @@ import { AutoJoinPolicy
export default class ApiConfig { export default class ApiConfig {
constructor ( constructor(
public sessionRequest: SessionRequest public sessionRequest: SessionRequest
, public sessionListener: (session: Session) => void , public sessionListener: (session: Session) => void
, public receiverListener: (availability: string) => void , public receiverListener: (availability: string) => void

View File

@@ -2,7 +2,7 @@
// https://developers.google.com/cast/docs/reference/chrome/chrome.cast.CredentialsData // https://developers.google.com/cast/docs/reference/chrome/chrome.cast.CredentialsData
export default class DialRequest { export default class DialRequest {
constructor ( constructor(
public credentials: string public credentials: string
, public credentialsData: string) { , public credentialsData: string) {
} }

View File

@@ -2,7 +2,7 @@
// https://developers.google.com/cast/docs/reference/chrome/chrome.cast.DialRequest // https://developers.google.com/cast/docs/reference/chrome/chrome.cast.DialRequest
export default class DialRequest { export default class DialRequest {
constructor ( constructor(
public appName: string public appName: string
, public launchParameter: (string | null) = null) { , public launchParameter: (string | null) = null) {
} }

View File

@@ -2,7 +2,7 @@
// https://developers.google.com/cast/docs/reference/chrome/chrome.cast.Error // https://developers.google.com/cast/docs/reference/chrome/chrome.cast.Error
export default class Error { export default class Error {
constructor ( constructor(
public code: string public code: string
, public description: (string | null) = null , public description: (string | null) = null
, public details: any = null) { , public details: any = null) {

View File

@@ -5,5 +5,5 @@ export default class Image {
public width: (number | null) = null; public width: (number | null) = null;
public height: (number | null) = null; public height: (number | null) = null;
constructor (public url: string) {} constructor(public url: string) {}
} }

View File

@@ -12,7 +12,7 @@ export default class Receiver {
public isActiveInput: (boolean | null) = null; public isActiveInput: (boolean | null) = null;
public receiverType: string = ReceiverType.CAST; public receiverType: string = ReceiverType.CAST;
constructor ( constructor(
public label: string public label: string
, public friendlyName: string , public friendlyName: string
, public capabilities: Capability[] = [] , public capabilities: Capability[] = []

View File

@@ -7,7 +7,7 @@ import Image from "./Image";
export default class ReceiverDisplayStatus { export default class ReceiverDisplayStatus {
public showStop: (boolean | null) = null; public showStop: (boolean | null) = null;
constructor ( constructor(
public statusText: string public statusText: string
, public appImages: Image[]) {} , public appImages: Image[]) {}
} }

View File

@@ -5,5 +5,5 @@ export default class SenderApplication {
public packageId: (string | null) = null; public packageId: (string | null) = null;
public url: (string | null) = null; public url: (string | null) = null;
constructor (public platform: string) {} constructor(public platform: string) {}
} }

View File

@@ -208,7 +208,7 @@ export default class Session {
public statusText: string | null; public statusText: string | null;
public transportId: string; public transportId: string;
constructor ( constructor(
public sessionId: string public sessionId: string
, public appId: string , public appId: string
, public displayName: string , public displayName: string
@@ -240,11 +240,11 @@ export default class Session {
} }
public addMediaListener (_mediaListener: MediaListener) { public addMediaListener(_mediaListener: MediaListener) {
logger.info("STUB :: Session#addMediaListener"); logger.info("STUB :: Session#addMediaListener");
} }
public addMessageListener ( public addMessageListener(
namespace: string namespace: string
, listener: MessageListener) { , listener: MessageListener) {
@@ -263,11 +263,11 @@ export default class Session {
}); });
} }
public addUpdateListener (listener: UpdateListener) { public addUpdateListener(listener: UpdateListener) {
this.#updateListeners.add(listener); this.#updateListeners.add(listener);
} }
public leave ( public leave(
successCallback?: SuccessCallback successCallback?: SuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
@@ -287,7 +287,7 @@ export default class Session {
]); ]);
} }
public loadMedia ( public loadMedia(
loadRequest: LoadRequest loadRequest: LoadRequest
, successCallback?: LoadSuccessCallback , successCallback?: LoadSuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
@@ -345,7 +345,7 @@ export default class Session {
}); });
} }
public queueLoad ( public queueLoad(
_queueLoadRequest: QueueLoadRequest _queueLoadRequest: QueueLoadRequest
, _successCallback?: LoadSuccessCallback , _successCallback?: LoadSuccessCallback
, _errorCallback?: ErrorCallback): void { , _errorCallback?: ErrorCallback): void {
@@ -353,25 +353,25 @@ export default class Session {
logger.info("STUB :: Session#queueLoad"); logger.info("STUB :: Session#queueLoad");
} }
public removeMediaListener (_mediaListener: MediaListener): void { public removeMediaListener(_mediaListener: MediaListener): void {
logger.info("STUB :: Session#removeMediaListener"); logger.info("STUB :: Session#removeMediaListener");
} }
public removeMessageListener ( public removeMessageListener(
namespace: string namespace: string
, listener: MessageListener): void { , listener: MessageListener): void {
this.#messageListeners.get(namespace)?.delete(listener); this.#messageListeners.get(namespace)?.delete(listener);
} }
public removeUpdateListener ( public removeUpdateListener(
_namespace: string _namespace: string
, listener: UpdateListener): void { , listener: UpdateListener): void {
this.#updateListeners.delete(listener); this.#updateListeners.delete(listener);
} }
public sendMessage ( public sendMessage(
namespace: string namespace: string
, message: {} | string , message: {} | string
, successCallback?: SuccessCallback , successCallback?: SuccessCallback
@@ -395,7 +395,7 @@ export default class Session {
]); ]);
} }
public setReceiverMuted ( public setReceiverMuted(
muted: boolean muted: boolean
, successCallback?: SuccessCallback , successCallback?: SuccessCallback
, errorCallback?: ErrorCallback) { , errorCallback?: ErrorCallback) {
@@ -417,7 +417,7 @@ export default class Session {
]); ]);
} }
public setReceiverVolumeLevel ( public setReceiverVolumeLevel(
newLevel: number newLevel: number
, successCallback?: SuccessCallback , successCallback?: SuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
@@ -439,7 +439,7 @@ export default class Session {
]); ]);
} }
public stop ( public stop(
successCallback?: SuccessCallback successCallback?: SuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
@@ -460,7 +460,7 @@ export default class Session {
} }
private _sendMediaMessage (message: string | {}) { private _sendMediaMessage(message: string | {}) {
this.sendMessage("urn:x-cast:com.google.cast.media", message); this.sendMessage("urn:x-cast:com.google.cast.media", message);
} }
} }

View File

@@ -10,11 +10,11 @@ import { Capability } from "../enums";
export default class SessionRequest { export default class SessionRequest {
public language: (string | null) = null; public language: (string | null) = null;
constructor ( constructor(
public appId: string public appId: string
, public capabilities = [ Capability.VIDEO_OUT , public capabilities = [ Capability.VIDEO_OUT
, Capability.AUDIO_OUT ] , Capability.AUDIO_OUT ]
, public requestSessionTimeout: number = (new Timeout()).requestSession , public requestSessionTimeout = (new Timeout()).requestSession
, public androidReceiverCompatible = false , public androidReceiverCompatible = false
, public credentialsData: (CredentialsData | null) = null) {} , public credentialsData: (CredentialsData | null) = null) {}
} }

View File

@@ -8,7 +8,7 @@ export default class Volume {
public controlType?: VolumeControlType; public controlType?: VolumeControlType;
public stepInterval?: number; public stepInterval?: number;
constructor ( constructor(
public level: (number | null) = null public level: (number | null) = null
, public muted: (boolean | null) = null) { , public muted: (boolean | null) = null) {
} }

View File

@@ -76,13 +76,13 @@ export let isAvailable = false;
export const timeout = new Timeout(); export const timeout = new Timeout();
export const VERSION = [1, 2]; export const VERSION = [1, 2];
export function addReceiverActionListener ( export function addReceiverActionListener(
listener: ReceiverActionListener): void { listener: ReceiverActionListener): void {
receiverActionListeners.add(listener); receiverActionListeners.add(listener);
} }
export function initialize ( export function initialize(
newApiConfig: ApiConfig newApiConfig: ApiConfig
, successCallback?: SuccessCallback , successCallback?: SuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
@@ -115,22 +115,22 @@ export function initialize (
: ReceiverAvailability.UNAVAILABLE); : ReceiverAvailability.UNAVAILABLE);
} }
export function logMessage (message: string): void { export function logMessage(message: string): void {
/* tslint:disable-next-line:no-console */ // eslint-disable-next-line no-console
console.log("CAST MSG:", message); console.log("CAST MSG:", message);
} }
export function precache (_data: string): void { export function precache(_data: string): void {
logger.info("STUB :: cast.precache"); logger.info("STUB :: cast.precache");
} }
export function removeReceiverActionListener ( export function removeReceiverActionListener(
listener: ReceiverActionListener): void { listener: ReceiverActionListener): void {
receiverActionListeners.delete(listener); receiverActionListeners.delete(listener);
} }
export function requestSession ( export function requestSession(
successCallback: RequestSessionSuccessCallback successCallback: RequestSessionSuccessCallback
, errorCallback: ErrorCallback , errorCallback: ErrorCallback
, _sessionRequest: SessionRequest = apiConfig.sessionRequest): void { , _sessionRequest: SessionRequest = apiConfig.sessionRequest): void {
@@ -176,7 +176,7 @@ export function requestSession (
}); });
} }
export function _requestSession ( export function _requestSession(
_receiver: Receiver _receiver: Receiver
, successCallback?: RequestSessionSuccessCallback , successCallback?: RequestSessionSuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
@@ -218,7 +218,7 @@ export function _requestSession (
(selectedReceiver as any)._address = _receiver.host; (selectedReceiver as any)._address = _receiver.host;
(selectedReceiver as any)._port = _receiver.port; (selectedReceiver as any)._port = _receiver.port;
function createSession () { function createSession() {
sessionList.push(new Session( sessionList.push(new Session(
sessionList.length.toString() // sessionId sessionList.length.toString() // sessionId
, apiConfig.sessionRequest.appId // appId , apiConfig.sessionRequest.appId // appId
@@ -250,11 +250,11 @@ export function _requestSession (
} }
} }
export function requestSessionById (_sessionId: string): void { export function requestSessionById(_sessionId: string): void {
logger.info("STUB :: cast.requestSessionById"); logger.info("STUB :: cast.requestSessionById");
} }
export function setCustomReceivers ( export function setCustomReceivers(
_receivers: Receiver_[] _receivers: Receiver_[]
, _successCallback?: SuccessCallback , _successCallback?: SuccessCallback
, _errorCallback?: ErrorCallback): void { , _errorCallback?: ErrorCallback): void {
@@ -262,15 +262,15 @@ export function setCustomReceivers (
logger.info("STUB :: cast.setCustomReceivers"); logger.info("STUB :: cast.setCustomReceivers");
} }
export function setPageContext (_win: Window): void { export function setPageContext(_win: Window): void {
logger.info("STUB :: cast.setPageContext"); logger.info("STUB :: cast.setPageContext");
} }
export function setReceiverDisplayStatus (_sessionId: string): void { export function setReceiverDisplayStatus(_sessionId: string): void {
logger.info("STUB :: cast.setReceiverDisplayStatus"); logger.info("STUB :: cast.setReceiverDisplayStatus");
} }
export function unescape (escaped: string): string { export function unescape(escaped: string): string {
return decodeURI(escaped); return decodeURI(escaped);
} }
@@ -343,7 +343,8 @@ onMessage(async message => {
(selectedReceiver as any)._address = message.data.receiver.host; (selectedReceiver as any)._address = message.data.receiver.host;
(selectedReceiver as any)._port = message.data.receiver.port; (selectedReceiver as any)._port = message.data.receiver.port;
function createSession () { // eslint-disable-next-line no-inner-declarations
function createSession() {
sessionList.push(new Session( sessionList.push(new Session(
sessionList.length.toString() // sessionId sessionList.length.toString() // sessionId
, apiConfig.sessionRequest.appId // appId , apiConfig.sessionRequest.appId // appId

View File

@@ -12,6 +12,6 @@ export default class ContainerMetadata {
public sections?: MediaMetadata[]; public sections?: MediaMetadata[];
public title?: string; public title?: string;
constructor (public containerType: ContainerType constructor(public containerType: ContainerType
= ContainerType.GENERIC_CONTAINER) {} = ContainerType.GENERIC_CONTAINER) {}
} }

View File

@@ -3,7 +3,7 @@
export default class EditTracksInfoRequest { export default class EditTracksInfoRequest {
public requestId = 0; public requestId = 0;
constructor ( constructor(
public activeTrackIds: (number[] | null) = null public activeTrackIds: (number[] | null) = null
, public textTrackStyle: (string | null) = null) { , public textTrackStyle: (string | null) = null) {
} }

View File

@@ -1,8 +1,9 @@
"use strict"; "use strict";
export default class LiveSeekableRange { export default class LiveSeekableRange {
constructor (public start?: number constructor(
, public end?: number public start?: number
, public isMovingWindow?: boolean , public end?: number
, public isLiveDone?: boolean) {} , public isMovingWindow?: boolean
, public isLiveDone?: boolean) {}
} }

View File

@@ -11,11 +11,11 @@ export default class LoadRequest {
public currentTime: (number | null) = null; public currentTime: (number | null) = null;
public customData: any = null; public customData: any = null;
public media: MediaInfo; public media: MediaInfo;
public requestId: number = 0; public requestId = 0;
public sessionId: (string | null) = null; public sessionId: (string | null) = null;
public type: string = "LOAD"; public type = "LOAD";
constructor (mediaInfo: MediaInfo) { constructor(mediaInfo: MediaInfo) {
this.media = mediaInfo; this.media = mediaInfo;
} }
} }

View File

@@ -103,13 +103,13 @@ export default class Media {
public breakStatus?: BreakStatus; public breakStatus?: BreakStatus;
public currentItemId: (number | null) = null; public currentItemId: (number | null) = null;
public customData: any = null; public customData: any = null;
public currentTime: number = 0; public currentTime = 0;
public idleReason: (string | null) = null; public idleReason: (string | null) = null;
public items: (QueueItem[] | null) = null; public items: (QueueItem[] | null) = null;
public liveSeekableRange?: LiveSeekableRange; public liveSeekableRange?: LiveSeekableRange;
public loadingItemId: (number | null) = null; public loadingItemId: (number | null) = null;
public media: (MediaInfo | null) = null; public media: (MediaInfo | null) = null;
public playbackRate: number = 1; public playbackRate = 1;
public playerState: string = PlayerState.IDLE; public playerState: string = PlayerState.IDLE;
public preloadedItemId: (number | null) = null; public preloadedItemId: (number | null) = null;
public queueData?: QueueData; public queueData?: QueueData;
@@ -119,7 +119,7 @@ export default class Media {
public volume: Volume = new Volume(); public volume: Volume = new Volume();
constructor ( constructor(
public sessionId: string public sessionId: string
, public mediaSessionId: number , public mediaSessionId: number
, _internalSessionId: string) { , _internalSessionId: string) {
@@ -135,11 +135,11 @@ export default class Media {
}); });
} }
public addUpdateListener (listener: UpdateListener): void { public addUpdateListener(listener: UpdateListener): void {
this.#updateListeners.add(listener); this.#updateListeners.add(listener);
} }
public editTracksInfo ( public editTracksInfo(
_editTracksInfoRequest: EditTracksInfoRequest _editTracksInfoRequest: EditTracksInfoRequest
, _successCallback?: SuccessCallback , _successCallback?: SuccessCallback
, _errorCallback?: ErrorCallback): void { , _errorCallback?: ErrorCallback): void {
@@ -147,17 +147,17 @@ export default class Media {
logger.info("STUB :: Media#editTracksInfo"); logger.info("STUB :: Media#editTracksInfo");
} }
public getEstimatedBreakClipTime () { public getEstimatedBreakClipTime() {
logger.info("STUB :: Media#getEstimatedBreakClipTime"); logger.info("STUB :: Media#getEstimatedBreakClipTime");
} }
public getEstimatedBreakTime () { public getEstimatedBreakTime() {
logger.info("STUB :: Media#getEstimatedBreakTime"); logger.info("STUB :: Media#getEstimatedBreakTime");
} }
public getEstimatedLiveSeekableRange () { public getEstimatedLiveSeekableRange() {
logger.info("STUB :: Media#getEstimatedLiveSeekableRange"); logger.info("STUB :: Media#getEstimatedLiveSeekableRange");
} }
public getEstimatedTime (): number { public getEstimatedTime(): number {
if (this.currentTime === undefined if (this.currentTime === undefined
|| this.#lastCurrentTime === undefined) { || this.#lastCurrentTime === undefined) {
return 0; return 0;
@@ -166,7 +166,7 @@ export default class Media {
return this.currentTime + ((Date.now() / 1000) - this.#lastCurrentTime); return this.currentTime + ((Date.now() / 1000) - this.#lastCurrentTime);
} }
public getStatus ( public getStatus(
_getStatusRequest?: GetStatusRequest _getStatusRequest?: GetStatusRequest
, successCallback?: SuccessCallback , successCallback?: SuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
@@ -175,7 +175,7 @@ export default class Media {
, successCallback, errorCallback); , successCallback, errorCallback);
} }
public pause ( public pause(
_pauseRequest?: PauseRequest _pauseRequest?: PauseRequest
, successCallback?: SuccessCallback , successCallback?: SuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
@@ -184,7 +184,7 @@ export default class Media {
, successCallback, errorCallback); , successCallback, errorCallback);
} }
public play ( public play(
_playRequest?: PlayRequest _playRequest?: PlayRequest
, successCallback?: SuccessCallback , successCallback?: SuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
@@ -193,28 +193,28 @@ export default class Media {
, successCallback, errorCallback); , successCallback, errorCallback);
} }
public queueAppendItem ( public queueAppendItem(
_item: QueueItem _item: QueueItem
, _successCallback?: SuccessCallback , _successCallback?: SuccessCallback
, _errorCallback?: ErrorCallback): void { , _errorCallback?: ErrorCallback): void {
logger.info("STUB :: Media#queueAppendItem"); logger.info("STUB :: Media#queueAppendItem");
} }
public queueInsertItems ( public queueInsertItems(
_queueInsertItemsRequest: QueueInsertItemsRequest _queueInsertItemsRequest: QueueInsertItemsRequest
, _successCallback?: SuccessCallback , _successCallback?: SuccessCallback
, _errorCallback?: ErrorCallback): void { , _errorCallback?: ErrorCallback): void {
logger.info("STUB :: Media#queueInsertItems"); logger.info("STUB :: Media#queueInsertItems");
} }
public queueJumpToItem ( public queueJumpToItem(
_itemId: number _itemId: number
, _successCallback?: SuccessCallback , _successCallback?: SuccessCallback
, _errorCallback?: ErrorCallback): void { , _errorCallback?: ErrorCallback): void {
logger.info("STUB :: Media#queueJumpToItem"); logger.info("STUB :: Media#queueJumpToItem");
} }
public queueMoveItemToNewIndex ( public queueMoveItemToNewIndex(
_itemId: number _itemId: number
, _newIndex: number , _newIndex: number
, _successCallback?: SuccessCallback , _successCallback?: SuccessCallback
@@ -222,51 +222,51 @@ export default class Media {
logger.info("STUB :: Media#queueMoveItemToNewIndex"); logger.info("STUB :: Media#queueMoveItemToNewIndex");
} }
public queueNext ( public queueNext(
_successCallback?: SuccessCallback _successCallback?: SuccessCallback
, _errorCallback?: ErrorCallback): void { , _errorCallback?: ErrorCallback): void {
logger.info("STUB :: Media#queueNext"); logger.info("STUB :: Media#queueNext");
} }
public queuePrev ( public queuePrev(
_successCallback?: SuccessCallback _successCallback?: SuccessCallback
, _errorCallback?: ErrorCallback): void { , _errorCallback?: ErrorCallback): void {
logger.info("STUB :: Media#queuePrev"); logger.info("STUB :: Media#queuePrev");
} }
public queueRemoveItem ( public queueRemoveItem(
_itemId: number _itemId: number
, _successCallback?: SuccessCallback , _successCallback?: SuccessCallback
, _errorCallback?: ErrorCallback): void { , _errorCallback?: ErrorCallback): void {
logger.info("STUB :: Media#queueRemoveItem"); logger.info("STUB :: Media#queueRemoveItem");
} }
public queueReorderItems ( public queueReorderItems(
_queueReorderItemsRequest: QueueReorderItemsRequest _queueReorderItemsRequest: QueueReorderItemsRequest
, _successCallback?: SuccessCallback , _successCallback?: SuccessCallback
, _errorCallback?: ErrorCallback): void { , _errorCallback?: ErrorCallback): void {
logger.info("STUB :: Media#queueReorderItems"); logger.info("STUB :: Media#queueReorderItems");
} }
public queueSetRepeatMode ( public queueSetRepeatMode(
_repeatMode: string _repeatMode: string
, _successCallback?: SuccessCallback , _successCallback?: SuccessCallback
, _errorCallback?: ErrorCallback): void { , _errorCallback?: ErrorCallback): void {
logger.info("STUB :: Media#queueSetRepeatMode"); logger.info("STUB :: Media#queueSetRepeatMode");
} }
public queueUpdateItems ( public queueUpdateItems(
_queueUpdateItemsRequest: QueueUpdateItemsRequest _queueUpdateItemsRequest: QueueUpdateItemsRequest
, _successCallback?: SuccessCallback , _successCallback?: SuccessCallback
, _errorCallback?: ErrorCallback): void { , _errorCallback?: ErrorCallback): void {
logger.info("STUB :: Media#queueUpdateItems"); logger.info("STUB :: Media#queueUpdateItems");
} }
public removeUpdateListener (listener: UpdateListener) { public removeUpdateListener(listener: UpdateListener) {
this.#updateListeners.delete(listener); this.#updateListeners.delete(listener);
} }
public seek ( public seek(
seekRequest: SeekRequest seekRequest: SeekRequest
, successCallback?: SuccessCallback , successCallback?: SuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
@@ -277,7 +277,7 @@ export default class Media {
}, successCallback, errorCallback); }, successCallback, errorCallback);
} }
public setVolume ( public setVolume(
volumeRequest: VolumeRequest volumeRequest: VolumeRequest
, successCallback?: SuccessCallback , successCallback?: SuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
@@ -288,7 +288,7 @@ export default class Media {
}, successCallback, errorCallback); }, successCallback, errorCallback);
} }
public stop ( public stop(
_stopRequest: StopRequest _stopRequest: StopRequest
, successCallback?: SuccessCallback , successCallback?: SuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
@@ -306,13 +306,13 @@ export default class Media {
, errorCallback); , errorCallback);
} }
public supportsCommand (_command: string): boolean { public supportsCommand(_command: string): boolean {
logger.info("STUB :: Media#supportsCommand"); logger.info("STUB :: Media#supportsCommand");
return true; return true;
} }
public _sendMediaMessage ( public _sendMediaMessage(
message: any message: any
, successCallback?: SuccessCallback , successCallback?: SuccessCallback
, errorCallback?: ErrorCallback) { , errorCallback?: ErrorCallback) {

View File

@@ -42,7 +42,7 @@ export default class MediaInfo {
public userActionStates?: UserActionState[]; public userActionStates?: UserActionState[];
public vmapAdsRequest?: VastAdsRequest; public vmapAdsRequest?: VastAdsRequest;
constructor ( constructor(
public contentId: string public contentId: string
, public contentType: string) {} , public contentType: string) {}
} }

View File

@@ -12,7 +12,7 @@ export default class MediaMetadata {
public type: MetadataType; public type: MetadataType;
public metadataType: MetadataType; public metadataType: MetadataType;
constructor (type: MetadataType) { constructor(type: MetadataType) {
this.type = type; this.type = type;
this.metadataType = type; this.metadataType = type;
} }

View File

@@ -8,8 +8,8 @@ export default class QueueInsertItemsRequest {
public insertBefore: (number | null) = null; public insertBefore: (number | null) = null;
public requestId: (number | null) = null; public requestId: (number | null) = null;
public sessionId: (string | null) = null; public sessionId: (string | null) = null;
public type: string = "QUEUE_INSERT"; public type = "QUEUE_INSERT";
constructor ( constructor(
public items: QueueItem[]) {} public items: QueueItem[]) {}
} }

View File

@@ -5,15 +5,15 @@ import MediaInfo from "./MediaInfo";
export default class QueueItem { export default class QueueItem {
public activeTrackIds: (number[] | null) = null; public activeTrackIds: (number[] | null) = null;
public autoplay: boolean = true; public autoplay = true;
public customData: any = null; public customData: any = null;
public itemId: (number | null) = null; public itemId: (number | null) = null;
public media: MediaInfo; public media: MediaInfo;
public playbackDuration: (number | null) = null; public playbackDuration: (number | null) = null;
public preloadTime: number = 0; public preloadTime = 0;
public startTime: number = 0; public startTime = 0;
constructor (mediaInfo: MediaInfo) { constructor(mediaInfo: MediaInfo) {
this.media = mediaInfo; this.media = mediaInfo;
} }
} }

View File

@@ -10,9 +10,9 @@ export default class QueueLoadRequest {
public repeatMode: string = RepeatMode.OFF; public repeatMode: string = RepeatMode.OFF;
public requestId: (number | null) = null; public requestId: (number | null) = null;
public sessionId: (string | null) = null; public sessionId: (string | null) = null;
public startIndex: number = 0; public startIndex = 0;
public type: string = "QUEUE_LOAD"; public type = "QUEUE_LOAD";
constructor ( constructor(
public items: QueueItem[]) {} public items: QueueItem[]) {}
} }

View File

@@ -4,8 +4,8 @@ export default class QueueRemoveItemsRequest {
public customData: any = null; public customData: any = null;
public requestId: (number | null) = null; public requestId: (number | null) = null;
public sessionId: (string | null) = null; public sessionId: (string | null) = null;
public type: string = "QUEUE_REMOVE"; public type = "QUEUE_REMOVE";
constructor ( constructor(
public itemIds: number[]) {} public itemIds: number[]) {}
} }

View File

@@ -5,8 +5,8 @@ export default class QueueReorderItemsRequest {
public insertBefore: (number | null) = null; public insertBefore: (number | null) = null;
public requestId: (number | null) = null; public requestId: (number | null) = null;
public sessionId: (string | null) = null; public sessionId: (string | null) = null;
public type: string = "QUEUE_REORDER"; public type = "QUEUE_REORDER";
constructor ( constructor(
public itemIds: number[]) {} public itemIds: number[]) {}
} }

View File

@@ -5,5 +5,5 @@ export default class QueueSetPropertiesRequest {
public repeatMode: (string | null) = null; public repeatMode: (string | null) = null;
public requestId: (number | null) = null; public requestId: (number | null) = null;
public sessionId: (string | null) = null; public sessionId: (string | null) = null;
public type: string = "QUEUE_UPDATE"; public type = "QUEUE_UPDATE";
} }

View File

@@ -7,8 +7,8 @@ export default class QueueUpdateItemsRequest {
public customData: any = null; public customData: any = null;
public requestId: (number | null) = null; public requestId: (number | null) = null;
public sessionId: (string | null) = null; public sessionId: (string | null) = null;
public type: string = "QUEUE_UPDATE"; public type = "QUEUE_UPDATE";
constructor ( constructor(
public items: QueueItem[]) {} public items: QueueItem[]) {}
} }

View File

@@ -8,7 +8,7 @@ export default class Track {
public trackContentId: (string | null) = null; public trackContentId: (string | null) = null;
public trackContentType: (string | null) = null; public trackContentType: (string | null) = null;
constructor ( constructor(
public trackId: number public trackId: number
, public type: string) {} , public type: string) {}
} }

View File

@@ -6,5 +6,6 @@ import { UserAction } from "../enums";
export default class UserActionState { export default class UserActionState {
public customData: any = null; public customData: any = null;
constructor (public userAction: UserAction) {} constructor(
public userAction: UserAction) {}
} }

View File

@@ -4,7 +4,8 @@ import { HdrType } from "../enums";
export default class VideoInformation { export default class VideoInformation {
constructor (public width: number constructor(
, public height: number public width: number
, public hdrType: HdrType) {} , public height: number
, public hdrType: HdrType) {}
} }

View File

@@ -6,6 +6,6 @@ import Volume from "../../classes/Volume";
export default class VolumeRequest { export default class VolumeRequest {
public customData: any = null; public customData: any = null;
constructor ( constructor(
public volume: Volume) {} public volume: Volume) {}
} }

View File

@@ -35,7 +35,7 @@ Reflect.defineProperty(
, enumerable: true , enumerable: true
, get: desc?.get , get: desc?.get
, set: exportFunction(function setFunc (this: HTMLScriptElement, value) { , set: exportFunction(function setFunc(this: HTMLScriptElement, value) {
if (CAST_SCRIPT_URLS.includes(value)) { if (CAST_SCRIPT_URLS.includes(value)) {
return desc?.set?.call(this, CAST_LOADER_SCRIPT_URL); return desc?.set?.call(this, CAST_LOADER_SCRIPT_URL);
} }

View File

@@ -10,8 +10,8 @@ export interface ListenerObject {
} }
export function onMessage (listener: ListenerFunc): ListenerObject { export function onMessage(listener: ListenerFunc): ListenerObject {
function on__castMessage (ev: CustomEvent) { function on__castMessage(ev: CustomEvent) {
listener(JSON.parse(ev.detail)); listener(JSON.parse(ev.detail));
/** /**
@@ -31,7 +31,7 @@ export function onMessage (listener: ListenerFunc): ListenerObject {
, on__castMessage, true); , on__castMessage, true);
return { return {
disconnect () { disconnect() {
// @ts-ignore // @ts-ignore
document.removeEventListener( document.removeEventListener(
"__castMessage" "__castMessage"
@@ -40,7 +40,7 @@ export function onMessage (listener: ListenerFunc): ListenerObject {
}; };
} }
export function sendMessageResponse (message: Message) { export function sendMessageResponse(message: Message) {
const event = new CustomEvent("__castMessageResponse", { const event = new CustomEvent("__castMessageResponse", {
detail: JSON.stringify(message) detail: JSON.stringify(message)
}); });
@@ -49,8 +49,8 @@ export function sendMessageResponse (message: Message) {
} }
export function onMessageResponse (listener: ListenerFunc): ListenerObject { export function onMessageResponse(listener: ListenerFunc): ListenerObject {
function on__castMessageResponse (ev: CustomEvent) { function on__castMessageResponse(ev: CustomEvent) {
listener(JSON.parse(ev.detail)); listener(JSON.parse(ev.detail));
} }
@@ -60,7 +60,7 @@ export function onMessageResponse (listener: ListenerFunc): ListenerObject {
, on__castMessageResponse, true); , on__castMessageResponse, true);
return { return {
disconnect () { disconnect() {
// @ts-ignore // @ts-ignore
document.removeEventListener( document.removeEventListener(
"__castMessageResponse" "__castMessageResponse"
@@ -69,7 +69,7 @@ export function onMessageResponse (listener: ListenerFunc): ListenerObject {
}; };
} }
export function sendMessage (message: Message) { export function sendMessage(message: Message) {
const event = new CustomEvent("__castMessage", { const event = new CustomEvent("__castMessage", {
detail: JSON.stringify(message) detail: JSON.stringify(message)
}); });

View File

@@ -21,7 +21,7 @@ let initializedBackgroundPort: MessagePort;
* for and emits these messages, and changing that behavior * for and emits these messages, and changing that behavior
* is too messy. * is too messy.
*/ */
export function ensureInit (): Promise<TypedMessagePort<Message>> { export function ensureInit(): Promise<TypedMessagePort<Message>> {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
// If already initialized, just return existing bridge info // If already initialized, just return existing bridge info
@@ -88,7 +88,7 @@ export function ensureInit (): Promise<TypedMessagePort<Message>> {
onMessage(handleIncomingMessageToShim); onMessage(handleIncomingMessageToShim);
} }
function handleIncomingMessageToShim (message: Message) { function handleIncomingMessageToShim(message: Message) {
switch (message.subject) { switch (message.subject) {
case "shim:initialized": { case "shim:initialized": {
initializedBridgeInfo = message.data; initializedBridgeInfo = message.data;

View File

@@ -8,7 +8,7 @@ import logger from "../../lib/logger";
* a cast icon and manages visibility state and event handling. * a cast icon and manages visibility state and event handling.
*/ */
export default class GoogleCastLauncher extends HTMLElement { export default class GoogleCastLauncher extends HTMLElement {
constructor () { constructor() {
super(); super();
this.style.display = "none"; this.style.display = "none";
@@ -26,8 +26,6 @@ export default class GoogleCastLauncher extends HTMLElement {
} }
`; `;
// tslint:disable:max-line-length
const SVG_NAMESPACE = "http://www.w3.org/2000/svg"; const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
const icon = document.createElementNS(SVG_NAMESPACE, "svg"); const icon = document.createElementNS(SVG_NAMESPACE, "svg");
@@ -67,9 +65,6 @@ export default class GoogleCastLauncher extends HTMLElement {
// Add icon paths to SVG // Add icon paths to SVG
icon.append(iconArch0, iconArch1, iconArch2, iconBox, iconBoxFill); icon.append(iconArch0, iconArch1, iconArch2, iconBox, iconBoxFill);
// tslint:enable:max-line-length
const shadow = this.attachShadow({ mode: "open" }); const shadow = this.attachShadow({ mode: "open" });
shadow.append(icon, style); shadow.append(icon, style);

View File

@@ -6,7 +6,7 @@ import { SessionEventType } from "../enums";
export default class ActiveInputStateEventData extends EventData { export default class ActiveInputStateEventData extends EventData {
constructor ( constructor(
public activeInputState: number) { public activeInputState: number) {
super(SessionEventType.ACTIVE_INPUT_STATE_CHANGED); super(SessionEventType.ACTIVE_INPUT_STATE_CHANGED);

View File

@@ -9,7 +9,7 @@ export default class ApplicationMetadata {
public name: string; public name: string;
public namespaces: string[]; public namespaces: string[];
constructor (sessionObj: cast.Session) { constructor(sessionObj: cast.Session) {
this.applicationId = sessionObj.appId; this.applicationId = sessionObj.appId;
this.images = sessionObj.appImages; this.images = sessionObj.appImages;
this.name = sessionObj.displayName; this.name = sessionObj.displayName;

View File

@@ -7,7 +7,7 @@ import { SessionEventType } from "../enums";
export default class ApplicationMetadataEventData extends EventData { export default class ApplicationMetadataEventData extends EventData {
constructor ( constructor(
public metadata: ApplicationMetadata) { public metadata: ApplicationMetadata) {
super(SessionEventType.APPLICATION_METADATA_CHANGED); super(SessionEventType.APPLICATION_METADATA_CHANGED);

View File

@@ -6,7 +6,7 @@ import { SessionEventType } from "../enums";
export default class ApplicationStatusEventData extends EventData { export default class ApplicationStatusEventData extends EventData {
constructor ( constructor(
public status: string) { public status: string) {
super(SessionEventType.APPLICATION_STATUS_CHANGED); super(SessionEventType.APPLICATION_STATUS_CHANGED);

View File

@@ -7,31 +7,31 @@ import CastSession from "./CastSession";
export default class CastContext extends EventTarget { export default class CastContext extends EventTarget {
public endCurrentSession (_stopCasting: boolean): void { public endCurrentSession(_stopCasting: boolean): void {
logger.info("STUB :: CastContext#endCurrentSession"); logger.info("STUB :: CastContext#endCurrentSession");
} }
// @ts-ignore // @ts-ignore
public getCastState (): string { public getCastState(): string {
logger.info("STUB :: CastContext#getCastState"); logger.info("STUB :: CastContext#getCastState");
} }
// @ts-ignore // @ts-ignore
public getCurrentSession (): CastSession { public getCurrentSession(): CastSession {
logger.info("STUB :: CastContext#getCurrentSession"); logger.info("STUB :: CastContext#getCurrentSession");
} }
// @ts-ignore // @ts-ignore
public getSessionState (): string { public getSessionState(): string {
logger.info("STUB :: CastContext#getSessionState"); logger.info("STUB :: CastContext#getSessionState");
} }
// @ts-ignore // @ts-ignore
public requestSession (): Promise<string> { public requestSession(): Promise<string> {
logger.info("STUB :: CastContext#requestSession"); logger.info("STUB :: CastContext#requestSession");
} }
public setOptions (_options: CastOptions): void { public setOptions(_options: CastOptions): void {
logger.info("STUB :: CastContext#setOptions"); logger.info("STUB :: CastContext#setOptions");
} }
} }

View File

@@ -7,9 +7,9 @@ export default class CastOptions {
public autoJoinPolicy: string = cast.AutoJoinPolicy.TAB_AND_ORIGIN_SCOPED; public autoJoinPolicy: string = cast.AutoJoinPolicy.TAB_AND_ORIGIN_SCOPED;
public language: (string | null) = null; public language: (string | null) = null;
public receiverApplicationId: (string | null) = null; public receiverApplicationId: (string | null) = null;
public resumeSavedSession: boolean = true; public resumeSavedSession = true;
constructor (options: CastOptions = ({} as CastOptions)) { constructor(options: CastOptions = ({} as CastOptions)) {
if (options.autoJoinPolicy) { if (options.autoJoinPolicy) {
this.autoJoinPolicy = options.autoJoinPolicy; this.autoJoinPolicy = options.autoJoinPolicy;
} }

View File

@@ -11,85 +11,85 @@ type MessageListener = (namespace: string, message: string) => void;
export default class CastSession extends EventTarget { export default class CastSession extends EventTarget {
constructor (_sessionObj: cast.Session, _state: string) { constructor(_sessionObj: cast.Session, _state: string) {
super(); super();
logger.info("STUB :: CastSession#constructor"); logger.info("STUB :: CastSession#constructor");
} }
public addMessageListener ( public addMessageListener(
_namespace: string _namespace: string
, _listener: MessageListener): void { , _listener: MessageListener): void {
logger.info("STUB :: CastSession#addMessageListener"); logger.info("STUB :: CastSession#addMessageListener");
} }
public endSession (_stopCasting: boolean): void { public endSession(_stopCasting: boolean): void {
logger.info("STUB :: CastSession#endSession"); logger.info("STUB :: CastSession#endSession");
} }
// @ts-ignore // @ts-ignore
public getActiveInputState (): number { public getActiveInputState(): number {
logger.info("STUB :: CastSession#getActiveInputState"); logger.info("STUB :: CastSession#getActiveInputState");
} }
// @ts-ignore // @ts-ignore
public getApplicationMetadata (): ApplicationMetadata { public getApplicationMetadata(): ApplicationMetadata {
logger.info("STUB :: CastSession#getApplicationMetadata"); logger.info("STUB :: CastSession#getApplicationMetadata");
} }
// @ts-ignore // @ts-ignore
public getApplicationStatus (): string { public getApplicationStatus(): string {
logger.info("STUB :: CastSession#getApplicationStatus"); logger.info("STUB :: CastSession#getApplicationStatus");
} }
// @ts-ignore // @ts-ignore
public getCastDevice (): cast.Receiver { public getCastDevice(): cast.Receiver {
logger.info("STUB :: CastSession#getCastDevice"); logger.info("STUB :: CastSession#getCastDevice");
} }
// @ts-ignore // @ts-ignore
public getMediaSession (): cast.media.Media { public getMediaSession(): cast.media.Media {
logger.info("STUB :: CastSession#getMediaSession"); logger.info("STUB :: CastSession#getMediaSession");
} }
// @ts-ignore // @ts-ignore
public getSessionId (): string { public getSessionId(): string {
logger.info("STUB :: CastSession#getSessionId"); logger.info("STUB :: CastSession#getSessionId");
} }
// @ts-ignore // @ts-ignore
public getSessionObj (): cast.Session { public getSessionObj(): cast.Session {
logger.info("STUB :: CastSession#getSessionObj"); logger.info("STUB :: CastSession#getSessionObj");
} }
// @ts-ignore // @ts-ignore
public getSessionState (): string { public getSessionState(): string {
logger.info("STUB :: CastSession#getSessionState"); logger.info("STUB :: CastSession#getSessionState");
} }
// @ts-ignore // @ts-ignore
public getVolume (): number { public getVolume(): number {
logger.info("STUB :: CastSession#getVolume"); logger.info("STUB :: CastSession#getVolume");
} }
// @ts-ignore // @ts-ignore
public isMute (): boolean { public isMute(): boolean {
logger.info("STUB :: CastSession#isMute"); logger.info("STUB :: CastSession#isMute");
} }
// @ts-ignore // @ts-ignore
public loadMedia (_loadRequest: cast.media.LoadRequest): Promise<string> { public loadMedia(_loadRequest: cast.media.LoadRequest): Promise<string> {
logger.info("STUB :: CastSession#loadMedia"); logger.info("STUB :: CastSession#loadMedia");
} }
public removeMessageListener ( public removeMessageListener(
_namespace: string _namespace: string
, _listener: MessageListener): void { , _listener: MessageListener): void {
logger.info("STUB :: CastSession#removeMessageListener"); logger.info("STUB :: CastSession#removeMessageListener");
} }
public sendMessage ( public sendMessage(
_namespace: string _namespace: string
// @ts-ignore // @ts-ignore
, _data: any): Promise<string> { , _data: any): Promise<string> {
@@ -98,12 +98,12 @@ export default class CastSession extends EventTarget {
} }
// @ts-ignore // @ts-ignore
public setMute (_isMute: boolean): Promise<string> { public setMute(_isMute: boolean): Promise<string> {
logger.info("STUB :: CastSession#setMute"); logger.info("STUB :: CastSession#setMute");
} }
// @ts-ignore // @ts-ignore
public setVolume (_volume: number): Promise<string> { public setVolume(_volume: number): Promise<string> {
logger.info("STUB :: CastSession#setVolume"); logger.info("STUB :: CastSession#setVolume");
} }
} }

View File

@@ -6,7 +6,7 @@ import { CastContextEventType } from "../enums";
export default class CastStateEventData extends EventData { export default class CastStateEventData extends EventData {
constructor ( constructor(
public castState: string) { public castState: string) {
super(CastContextEventType.CAST_STATE_CHANGED); super(CastContextEventType.CAST_STATE_CHANGED);

View File

@@ -1,6 +1,6 @@
"use strict"; "use strict";
export default class EventData { export default class EventData {
constructor ( constructor(
public type: string) {} public type: string) {}
} }

View File

@@ -8,7 +8,7 @@ import { SessionEventType } from "../enums";
export default class MediaSessionEventData extends EventData { export default class MediaSessionEventData extends EventData {
constructor ( constructor(
public mediaSession: cast.media.Media) { public mediaSession: cast.media.Media) {
super(SessionEventType.MEDIA_SESSION); super(SessionEventType.MEDIA_SESSION);

View File

@@ -1,7 +1,7 @@
"use strict"; "use strict";
export default class RemotePlayerChangedEvent { export default class RemotePlayerChangedEvent {
constructor ( constructor(
public type: string public type: string
, public field: string , public field: string
, public value: any) {} , public value: any) {}

View File

@@ -6,12 +6,12 @@ import RemotePlayer from "./RemotePlayer";
export default class RemotePlayerController extends EventTarget { export default class RemotePlayerController extends EventTarget {
constructor (_player: RemotePlayer) { constructor(_player: RemotePlayer) {
super(); super();
logger.info("STUB :: RemotePlayerController#constructor"); logger.info("STUB :: RemotePlayerController#constructor");
} }
public getFormattedTime (timeInSec: number): string { public getFormattedTime(timeInSec: number): string {
const hours = Math.floor(timeInSec / 3600) % 24; const hours = Math.floor(timeInSec / 3600) % 24;
const minutes = Math.floor(timeInSec / 60) % 60; const minutes = Math.floor(timeInSec / 60) % 60;
const seconds = timeInSec % 60; const seconds = timeInSec % 60;
@@ -21,31 +21,31 @@ export default class RemotePlayerController extends EventTarget {
.join(":"); .join(":");
} }
public getSeekPosition (currentTime: number, duration: number) { public getSeekPosition(currentTime: number, duration: number) {
return (currentTime / duration) * 100; return (currentTime / duration) * 100;
} }
public getSeekTime (currentPosition: number, duration: number) { public getSeekTime(currentPosition: number, duration: number) {
return (duration / 100) * currentPosition; return (duration / 100) * currentPosition;
} }
public muteOrUnmute (): void { public muteOrUnmute(): void {
logger.info("STUB :: RemotePlayerController#muteOrUnmute"); logger.info("STUB :: RemotePlayerController#muteOrUnmute");
} }
public playOrPause (): void { public playOrPause(): void {
logger.info("STUB :: RemotePlayerController#playOrPause"); logger.info("STUB :: RemotePlayerController#playOrPause");
} }
public seek (): void { public seek(): void {
logger.info("STUB :: RemotePlayerController#seek"); logger.info("STUB :: RemotePlayerController#seek");
} }
public setVolumeLevel (): void { public setVolumeLevel(): void {
logger.info("STUB :: RemotePlayerController#setVolumeLevel"); logger.info("STUB :: RemotePlayerController#setVolumeLevel");
} }
public stop (): void { public stop(): void {
logger.info("STUB :: RemotePlayerController#stop"); logger.info("STUB :: RemotePlayerController#stop");
} }
} }

View File

@@ -7,7 +7,7 @@ import { SessionEventType } from "../enums";
export default class SessionStateEventData extends EventData { export default class SessionStateEventData extends EventData {
constructor ( constructor(
public session: CastSession public session: CastSession
, public sessionState: string , public sessionState: string
, public errorCode: (string | null) = null) { , public errorCode: (string | null) = null) {

View File

@@ -6,7 +6,7 @@ import { SessionEventType } from "../enums";
export default class VolumeEventData { export default class VolumeEventData {
public type = SessionEventType.VOLUME_CHANGED; public type = SessionEventType.VOLUME_CHANGED;
constructor ( constructor(
public volume: number public volume: number
, public isMute: boolean) {} , public isMute: boolean) {}
} }

View File

@@ -48,14 +48,14 @@ export default {
, CastContext: { , CastContext: {
...CastContext ...CastContext
, getInstance () { , getInstance() {
return instance; return instance;
} }
} }
, VERSION: "1.0.07" , VERSION: "1.0.07"
, setLoggerLevel (_level: number) { , setLoggerLevel(_level: number) {
logger.info("STUB :: cast.framework.setLoggerLevel"); logger.info("STUB :: cast.framework.setLoggerLevel");
} }
}; };

View File

@@ -25,7 +25,7 @@ let bridgeInfo: any;
let isFramework = false; let isFramework = false;
// Call page's API loaded function if defined // Call page's API loaded function if defined
function callPageReadyFunction () { function callPageReadyFunction() {
const readyFunction = _window.__onGCastApiAvailable; const readyFunction = _window.__onGCastApiAvailable;
if (readyFunction && typeof readyFunction === "function") { if (readyFunction && typeof readyFunction === "function") {
readyFunction(bridgeInfo && bridgeInfo.isVersionCompatible); readyFunction(bridgeInfo && bridgeInfo.isVersionCompatible);

View File

@@ -1,4 +1,4 @@
/* tslint:disable:max-line-length */ /* eslint-disable max-len */
"use strict"; "use strict";
import React, { Component } from "react"; import React, { Component } from "react";
@@ -79,7 +79,7 @@ export default class Bridge extends Component<BridgeProps, BridgeState> {
private updateData: any; private updateData: any;
private updateStatusTimeout?: number; private updateStatusTimeout?: number;
constructor (props: BridgeProps) { constructor(props: BridgeProps) {
super(props); super(props);
this.state = { this.state = {
@@ -95,7 +95,7 @@ export default class Bridge extends Component<BridgeProps, BridgeState> {
this.onUpdate = this.onUpdate.bind(this); this.onUpdate = this.onUpdate.bind(this);
} }
public render () { public render() {
const [ backupMessageStart, backupMessageEnd ] const [ backupMessageStart, backupMessageEnd ]
= _("optionsBridgeBackupEnabled", "\0").split("\0"); = _("optionsBridgeBackupEnabled", "\0").split("\0");
@@ -177,7 +177,7 @@ export default class Bridge extends Component<BridgeProps, BridgeState> {
); );
} }
private renderStatus () { private renderStatus() {
const infoClasses = `bridge__info ${!this.props.info const infoClasses = `bridge__info ${!this.props.info
? this.props.loadingTimedOut ? this.props.loadingTimedOut
? "bridge__info--timed-out" ? "bridge__info--timed-out"
@@ -228,7 +228,7 @@ export default class Bridge extends Component<BridgeProps, BridgeState> {
); );
} }
private onCheckUpdates () { private onCheckUpdates() {
this.setState({ this.setState({
isCheckingUpdates: true isCheckingUpdates: true
}); });
@@ -249,7 +249,7 @@ export default class Bridge extends Component<BridgeProps, BridgeState> {
.catch(this.onCheckUpdatesError); .catch(this.onCheckUpdatesError);
} }
private async onCheckUpdatesResponse (res: any) { private async onCheckUpdatesResponse(res: any) {
let latestBridgeRelease; let latestBridgeRelease;
for (const release of res) { for (const release of res) {
if (release.assets.find((asset: any) => if (release.assets.find((asset: any) =>
@@ -290,7 +290,7 @@ export default class Bridge extends Component<BridgeProps, BridgeState> {
this.showUpdateStatus(); this.showUpdateStatus();
} }
private onCheckUpdatesError () { private onCheckUpdatesError() {
this.setState({ this.setState({
isCheckingUpdates: false isCheckingUpdates: false
, wasErrorCheckingUpdates: true , wasErrorCheckingUpdates: true
@@ -300,7 +300,7 @@ export default class Bridge extends Component<BridgeProps, BridgeState> {
this.showUpdateStatus(); this.showUpdateStatus();
} }
private showUpdateStatus () { private showUpdateStatus() {
if (this.updateStatusTimeout) { if (this.updateStatusTimeout) {
window.clearTimeout(this.updateStatusTimeout); window.clearTimeout(this.updateStatusTimeout);
} }
@@ -311,7 +311,7 @@ export default class Bridge extends Component<BridgeProps, BridgeState> {
}, 1500); }, 1500);
} }
private async onUpdate () { private async onUpdate() {
// Open downloads page // Open downloads page
if (this.updateData.html_url) { if (this.updateData.html_url) {
browser.tabs.create({ browser.tabs.create({

View File

@@ -1,4 +1,4 @@
/* tslint:disable:max-line-length */ /* eslint-disable max-len */
"use strict"; "use strict";
import React, { Component } from "react"; import React, { Component } from "react";
@@ -24,7 +24,7 @@ export default class EditableList extends Component<
private rawViewTextArea: (HTMLTextAreaElement | null) = null; private rawViewTextArea: (HTMLTextAreaElement | null) = null;
constructor (props: EditableListProps) { constructor(props: EditableListProps) {
super(props); super(props);
this.state = { this.state = {
@@ -43,7 +43,7 @@ export default class EditableList extends Component<
this.handleNewItemEdit = this.handleNewItemEdit.bind(this); this.handleNewItemEdit = this.handleNewItemEdit.bind(this);
} }
public render () { public render() {
return ( return (
<div className="editable-list"> <div className="editable-list">
{ this.state.rawView { this.state.rawView
@@ -102,21 +102,21 @@ export default class EditableList extends Component<
); );
} }
private handleItemRemove (item: string) { private handleItemRemove(item: string) {
const newItems = new Set(this.props.data); const newItems = new Set(this.props.data);
newItems.delete(item); newItems.delete(item);
this.props.onChange([...newItems]); this.props.onChange([...newItems]);
} }
private handleItemEdit (item: string, newValue: string) { private handleItemEdit(item: string, newValue: string) {
this.props.onChange(this.props.data.map( this.props.onChange(this.props.data.map(
currentItem => currentItem === item currentItem => currentItem === item
? newValue ? newValue
: currentItem)); : currentItem));
} }
private handleSwitchView () { private handleSwitchView() {
this.setState(currentState => { this.setState(currentState => {
if (currentState.rawView) { if (currentState.rawView) {
return { return {
@@ -132,7 +132,7 @@ export default class EditableList extends Component<
}); });
} }
private handleSaveRaw () { private handleSaveRaw() {
this.setState(currentState => { this.setState(currentState => {
const newItems = currentState.rawViewValue.split("\n") const newItems = currentState.rawViewValue.split("\n")
.filter(item => item !== ""); .filter(item => item !== "");
@@ -153,7 +153,7 @@ export default class EditableList extends Component<
}); });
} }
private handleRawViewTextAreaChange (ev: React.ChangeEvent<HTMLTextAreaElement>) { private handleRawViewTextAreaChange(ev: React.ChangeEvent<HTMLTextAreaElement>) {
if (!this.rawViewTextArea) { if (!this.rawViewTextArea) {
return; return;
} }
@@ -167,19 +167,19 @@ export default class EditableList extends Component<
}); });
} }
private handleAddItem () { private handleAddItem() {
this.setState({ this.setState({
addingNewItem: true addingNewItem: true
}); });
} }
private handleNewItemRemove () { private handleNewItemRemove() {
this.setState({ this.setState({
addingNewItem: false addingNewItem: false
}); });
} }
private handleNewItemEdit (_item: string, newItem: string) { private handleNewItemEdit(_item: string, newItem: string) {
this.setState({ this.setState({
addingNewItem: false addingNewItem: false
}, () => { }, () => {
@@ -208,7 +208,7 @@ class EditableListItem extends Component<
private input: (HTMLInputElement | null) = null; private input: (HTMLInputElement | null) = null;
constructor (props: EditableListItemProps) { constructor(props: EditableListItemProps) {
super(props); super(props);
this.state = { this.state = {
@@ -223,7 +223,7 @@ class EditableListItem extends Component<
this.handleInputKeyPress = this.handleInputKeyPress.bind(this); this.handleInputKeyPress = this.handleInputKeyPress.bind(this);
} }
public render () { public render() {
const selected = this.state.editing const selected = this.state.editing
? "editable-list__item--selected" : ""; ? "editable-list__item--selected" : "";
@@ -260,7 +260,7 @@ class EditableListItem extends Component<
); );
} }
private stopEditing (input: HTMLInputElement) { private stopEditing(input: HTMLInputElement) {
if (this.props.editing if (this.props.editing
&& !this.props.itemPattern.test(this.state.editValue)) { && !this.props.itemPattern.test(this.state.editValue)) {
input.setCustomValidity(this.props.itemPatternError()); input.setCustomValidity(this.props.itemPatternError());
@@ -277,11 +277,11 @@ class EditableListItem extends Component<
}); });
} }
private handleRemove () { private handleRemove() {
this.props.onRemove(this.props.text); this.props.onRemove(this.props.text);
} }
private handleEditBegin () { private handleEditBegin() {
if (!this.state.editing) { if (!this.state.editing) {
this.setState({ this.setState({
editing: true editing: true
@@ -293,11 +293,11 @@ class EditableListItem extends Component<
} }
} }
private handleEditEnd (ev: React.FocusEvent<HTMLInputElement>) { private handleEditEnd(ev: React.FocusEvent<HTMLInputElement>) {
this.stopEditing(ev.target); this.stopEditing(ev.target);
} }
private handleInputChange (ev: React.ChangeEvent<HTMLInputElement>) { private handleInputChange(ev: React.ChangeEvent<HTMLInputElement>) {
this.setState({ this.setState({
editValue: ev.target.value editValue: ev.target.value
}); });
@@ -308,7 +308,7 @@ class EditableListItem extends Component<
: ""); : "");
} }
private handleInputKeyPress (ev: React.KeyboardEvent<HTMLInputElement>) { private handleInputKeyPress(ev: React.KeyboardEvent<HTMLInputElement>) {
if (ev.key === "Enter") { if (ev.key === "Enter") {
this.stopEditing(ev.target as HTMLInputElement); this.stopEditing(ev.target as HTMLInputElement);
} }

View File

@@ -1,4 +1,4 @@
/* tslint:disable:max-line-length */ /* eslint-disable max-len */
"use strict"; "use strict";
import React, { Component } from "react"; import React, { Component } from "react";
@@ -40,7 +40,7 @@ browser.runtime.getPlatformInfo()
}); });
function getInputValue (input: HTMLInputElement) { function getInputValue(input: HTMLInputElement) {
switch (input.type) { switch (input.type) {
case "checkbox": case "checkbox":
return input.checked; return input.checked;
@@ -78,7 +78,7 @@ class OptionsApp extends Component<
, hasSaved: false , hasSaved: false
}; };
constructor (props: OptionsAppProps) { constructor(props: OptionsAppProps) {
super(props); super(props);
this.handleReset = this.handleReset.bind(this); this.handleReset = this.handleReset.bind(this);
@@ -94,7 +94,7 @@ class OptionsApp extends Component<
this.getWhitelistItemPatternError.bind(this); this.getWhitelistItemPatternError.bind(this);
} }
public async componentDidMount () { public async componentDidMount() {
this.setState({ this.setState({
hasLoaded: true hasLoaded: true
, options: await options.getAll() , options: await options.getAll()
@@ -131,7 +131,7 @@ class OptionsApp extends Component<
} }
} }
public render () { public render() {
if (!this.state.hasLoaded) { if (!this.state.hasLoaded) {
return; return;
} }
@@ -402,6 +402,7 @@ class OptionsApp extends Component<
{ _("optionsReset") } { _("optionsReset") }
</button> </button>
<button type="submit" <button type="submit"
// @ts-ignore
default default
disabled={ !this.state.isFormValid }> disabled={ !this.state.isFormValid }>
{ _("optionsSave") } { _("optionsSave") }
@@ -413,13 +414,13 @@ class OptionsApp extends Component<
} }
private handleReset () { private handleReset() {
this.setState({ this.setState({
options: { ...defaultOptions } options: { ...defaultOptions }
}); });
} }
private async handleFormSubmit (ev: React.FormEvent<HTMLFormElement>) { private async handleFormSubmit(ev: React.FormEvent<HTMLFormElement>) {
ev.preventDefault(); ev.preventDefault();
this.form?.reportValidity(); this.form?.reportValidity();
@@ -443,7 +444,7 @@ class OptionsApp extends Component<
} }
} }
private handleFormChange (ev: React.FormEvent<HTMLFormElement>) { private handleFormChange(ev: React.FormEvent<HTMLFormElement>) {
ev.preventDefault(); ev.preventDefault();
const isFormValid = this.form?.checkValidity(); const isFormValid = this.form?.checkValidity();
@@ -454,7 +455,7 @@ class OptionsApp extends Component<
} }
} }
private handleInputChange (ev: React.ChangeEvent<HTMLInputElement>) { private handleInputChange(ev: React.ChangeEvent<HTMLInputElement>) {
this.setState(currentState => { this.setState(currentState => {
if (currentState.options) { if (currentState.options) {
currentState.options[ev.target.name] = getInputValue(ev.target); currentState.options[ev.target.name] = getInputValue(ev.target);
@@ -464,19 +465,20 @@ class OptionsApp extends Component<
}); });
} }
private handleReceiverSelectorTypeChange ( private handleReceiverSelectorTypeChange(
ev: React.ChangeEvent<HTMLSelectElement>) { ev: React.ChangeEvent<HTMLSelectElement>) {
this.setState(currentState => { this.setState(currentState => {
if (currentState.options) { if (currentState.options) {
currentState.options[ev.target.name] = parseInt(ev.target.value); currentState.options[ev.target.name] =
parseInt(ev.target.value);
} }
return currentState; return currentState;
}); });
} }
private handleWhitelistChange (whitelist: string[]) { private handleWhitelistChange(whitelist: string[]) {
this.setState(currentState => { this.setState(currentState => {
if (currentState.options) { if (currentState.options) {
currentState.options.userAgentWhitelist = whitelist; currentState.options.userAgentWhitelist = whitelist;
@@ -486,7 +488,7 @@ class OptionsApp extends Component<
}); });
} }
private getWhitelistItemPatternError (info: string): string { private getWhitelistItemPatternError(info: string): string {
return _("optionsUserAgentWhitelistInvalidMatchPattern", info); return _("optionsUserAgentWhitelistInvalidMatchPattern", info);
} }
} }

View File

@@ -1,4 +1,4 @@
/* tslint:disable:max-line-length */ /* eslint-disable max-len */
"use strict"; "use strict";
import React, { Component } from "react"; import React, { Component } from "react";
@@ -29,6 +29,7 @@ browser.runtime.getPlatformInfo()
}); });
interface PopupAppProps {}
interface PopupAppState { interface PopupAppState {
receivers: Receiver[]; receivers: Receiver[];
mediaType: ReceiverSelectorMediaType; mediaType: ReceiverSelectorMediaType;
@@ -41,12 +42,12 @@ interface PopupAppState {
mirroringEnabled: boolean; mirroringEnabled: boolean;
} }
class PopupApp extends Component<{}, PopupAppState> { class PopupApp extends Component<PopupAppProps, PopupAppState> {
private port?: Port; private port?: Port;
private win?: browser.windows.Window; private win?: browser.windows.Window;
private defaultMediaType?: ReceiverSelectorMediaType; private defaultMediaType?: ReceiverSelectorMediaType;
constructor (props: {}) { constructor(props: PopupAppProps) {
super(props); super(props);
this.state = { this.state = {
@@ -67,7 +68,7 @@ class PopupApp extends Component<{}, PopupAppState> {
this.onStop = this.onStop.bind(this); this.onStop = this.onStop.bind(this);
} }
public async componentDidMount () { public async componentDidMount() {
this.port = messaging.connect({ name: "popup" }); this.port = messaging.connect({ name: "popup" });
this.port.onMessage.addListener((message: Message) => { this.port.onMessage.addListener((message: Message) => {
@@ -111,7 +112,7 @@ class PopupApp extends Component<{}, PopupAppState> {
}); });
} }
public componentDidUpdate () { public componentDidUpdate() {
setTimeout(() => { setTimeout(() => {
if (this.win?.id === undefined) { if (this.win?.id === undefined) {
return; return;
@@ -127,7 +128,11 @@ class PopupApp extends Component<{}, PopupAppState> {
}, 1); }, 1);
} }
public render () { public render() {
/*
// TODO: Add file support back to popup
let truncatedFileName: string; let truncatedFileName: string;
if (this.state.filePath) { if (this.state.filePath) {
@@ -138,6 +143,7 @@ class PopupApp extends Component<{}, PopupAppState> {
? `${fileName.substring(0, 12)}...` ? `${fileName.substring(0, 12)}...`
: fileName; : fileName;
} }
*/
const isAppMediaTypeSelected = const isAppMediaTypeSelected =
this.state.mediaType === ReceiverSelectorMediaType.App; this.state.mediaType === ReceiverSelectorMediaType.App;
@@ -147,7 +153,7 @@ class PopupApp extends Component<{}, PopupAppState> {
this.state.mediaType === ReceiverSelectorMediaType.Screen; this.state.mediaType === ReceiverSelectorMediaType.Screen;
const isSelectedMediaTypeAvailable = const isSelectedMediaTypeAvailable =
!!(this.state.availableMediaTypes & this.state.mediaType) !!(this.state.availableMediaTypes & this.state.mediaType);
const isAppMediaTypeAvailable = !!(this.state.availableMediaTypes const isAppMediaTypeAvailable = !!(this.state.availableMediaTypes
& ReceiverSelectorMediaType.App); & ReceiverSelectorMediaType.App);
@@ -208,7 +214,7 @@ class PopupApp extends Component<{}, PopupAppState> {
</>; </>;
} }
private onCast (receiver: Receiver) { private onCast(receiver: Receiver) {
this.setState({ this.setState({
isLoading: true isLoading: true
}); });
@@ -224,7 +230,7 @@ class PopupApp extends Component<{}, PopupAppState> {
}); });
} }
private onStop (receiver: Receiver) { private onStop(receiver: Receiver) {
this.port?.postMessage({ this.port?.postMessage({
subject: "receiverSelector:stop" subject: "receiverSelector:stop"
, data: { , data: {
@@ -234,7 +240,7 @@ class PopupApp extends Component<{}, PopupAppState> {
}); });
} }
private onSelectChange (ev: React.ChangeEvent<HTMLSelectElement>) { private onSelectChange(ev: React.ChangeEvent<HTMLSelectElement>) {
const mediaType = parseInt(ev.target.value); const mediaType = parseInt(ev.target.value);
if (mediaType === ReceiverSelectorMediaType.File) { if (mediaType === ReceiverSelectorMediaType.File) {
@@ -282,7 +288,7 @@ interface ReceiverEntryState {
} }
class ReceiverEntry extends Component<ReceiverEntryProps, ReceiverEntryState> { class ReceiverEntry extends Component<ReceiverEntryProps, ReceiverEntryState> {
constructor (props: ReceiverEntryProps) { constructor(props: ReceiverEntryProps) {
super(props); super(props);
this.state = { this.state = {
@@ -313,7 +319,7 @@ class ReceiverEntry extends Component<ReceiverEntryProps, ReceiverEntryState> {
this.handleCast = this.handleCast.bind(this); this.handleCast = this.handleCast.bind(this);
} }
public render () { public render() {
if (!this.props.receiver.status) { if (!this.props.receiver.status) {
return; return;
} }
@@ -349,7 +355,7 @@ class ReceiverEntry extends Component<ReceiverEntryProps, ReceiverEntryState> {
); );
} }
private handleCast () { private handleCast() {
if (!this.props.receiver.status) { if (!this.props.receiver.status) {
return; return;
} }

View File

@@ -1,8 +0,0 @@
{
"extends": [
"../tslint.json"
]
, "rules": {
"no-bitwise": false
}
}

1148
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -26,13 +26,15 @@
"@types/semver": "^7.3.4", "@types/semver": "^7.3.4",
"@types/uuid": "^8.3.0", "@types/uuid": "^8.3.0",
"@types/ws": "^7.4.0", "@types/ws": "^7.4.0",
"@typescript-eslint/eslint-plugin": "^4.22.0",
"@typescript-eslint/parser": "^4.22.0",
"eslint": "^7.25.0",
"fs-extra": "^9.1.0", "fs-extra": "^9.1.0",
"glob": "^7.1.6", "glob": "^7.1.6",
"jasmine-console-reporter": "^3.1.0", "jasmine-console-reporter": "^3.1.0",
"minimist": "^1.2.5", "minimist": "^1.2.5",
"selenium-webdriver": "^4.0.0-beta.1", "selenium-webdriver": "^4.0.0-beta.1",
"semver": "^7.3.4", "semver": "^7.3.4",
"tslint": "^6.1.3",
"typescript": "^4.1.5", "typescript": "^4.1.5",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"ws": "^7.4.3" "ws": "^7.4.3"

View File

@@ -1,33 +0,0 @@
{
"defaultSeverity": "error"
, "extends": [
"tslint:recommended"
]
, "jsRules": false
, "rules": {
"array-type": [ true, "array-simple" ],
"arrow-parens": false
, "import-spacing": false
, "interface-name": false
, "max-classes-per-file": false
, "max-line-length": [ true, {
"limit": 80
, "ignore-pattern": "//|.*(\"|`);?$"
}]
, "member-access": [ true ]
, "no-consecutive-blank-lines": false
, "no-console": [ true, "log" ]
, "no-namespace": [ true, "allow-declarations" ]
, "object-literal-sort-keys": false
, "radix": false
, "semicolon": [ true, "always" ]
, "space-before-function-paren": [ true, "always" ]
, "trailing-comma": false
, "variable-name": [ true
, "ban-keywords"
, "check-format"
, "allow-pascal-case"
, "allow-leading-underscore" ]
}
, "rulesDirectory": []
}