diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..de1f3df --- /dev/null +++ b/.eslintrc.json @@ -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" + } +} diff --git a/app/.eslintrc.json b/app/.eslintrc.json new file mode 100644 index 0000000..9bd4207 --- /dev/null +++ b/app/.eslintrc.json @@ -0,0 +1,5 @@ +{ + "rules": { + "@typescript-eslint/no-non-null-assertion": "off" + } +} diff --git a/app/package.json b/app/package.json index 75e6fa7..620ce93 100644 --- a/app/package.json +++ b/app/package.json @@ -8,7 +8,7 @@ "package": "node bin/build.js --package", "install-manifest": "node bin/install-manifest.js", "remove-manifest": "node bin/install-manifest.js --remove", - "lint": "tslint -c tslint.json -p ." + "lint": "eslint src --ext .ts,.tsx" }, "dependencies": { "bplist-creator": "0.0.8", diff --git a/app/src/bridge/components/airplay/auth.ts b/app/src/bridge/components/airplay/auth.ts index bb3918f..438ad4d 100644 --- a/app/src/bridge/components/airplay/auth.ts +++ b/app/src/bridge/components/airplay/auth.ts @@ -26,7 +26,7 @@ export class AirPlayAuthCredentials { public clientSk: Uint8Array; public clientPk: Uint8Array; - constructor ( + constructor( clientId?: string , clientSk?: Uint8Array , clientPk?: Uint8Array) { @@ -53,7 +53,7 @@ export class AirPlayAuth { private credentials: AirPlayAuthCredentials; private baseUrl: URL; - constructor (address: string, credentials: AirPlayAuthCredentials) { + constructor(address: string, credentials: AirPlayAuthCredentials) { this.address = address; this.credentials = credentials; @@ -63,7 +63,7 @@ export class AirPlayAuth { /** * Begins pairing process. */ - public async beginPairing () { + public async beginPairing() { return this.sendPostRequest("/pair-pin-start"); } @@ -72,7 +72,7 @@ export class AirPlayAuth { * beginPairing(). Coordinates the three pairing stages and * manages request responses. */ - public async finishPairing (pin: string) { + public async finishPairing(pin: string) { // Stage 1 response const { pk: serverPk , salt: serverSalt } = await this.pairSetupPin1(); @@ -107,7 +107,7 @@ export class AirPlayAuth { * Triggering the receiver passcode display and receiving * its public key / salt. */ - public async pairSetupPin1 (): Promise { + public async pairSetupPin1(): Promise { const [ response ] = await this.sendPostRequestBplist( "/pair-setup-pin" , { @@ -125,7 +125,7 @@ export class AirPlayAuth { * public keys, sending them to the receiver and receiving its * proof. */ - public async pairSetupPin2 ( + public async pairSetupPin2( pk: Buffer , proof: Buffer): Promise { @@ -143,7 +143,7 @@ export class AirPlayAuth { * secret hash and sending it to the receiver. Receiver then * responds confirming the pairing is complete. */ - public async pairSetupPin3 ( + public async pairSetupPin3( sharedSecretHash: crypto.BinaryLike): Promise { // Create AES key @@ -182,7 +182,7 @@ export class AirPlayAuth { * Sends a POST request to receiver and returns the * response. */ - public async sendPostRequest ( + public async sendPostRequest( path: string , contentType?: string , data?: Buffer | string): Promise { @@ -216,7 +216,7 @@ export class AirPlayAuth { * Encodes binary plist data, sends a POST request to * receiver, then decodes and returns the response. */ - public async sendPostRequestBplist ( + public async sendPostRequestBplist( path: string , data?: object): Promise { diff --git a/app/src/bridge/components/chromecast/Media.ts b/app/src/bridge/components/chromecast/Media.ts index a218abd..7ff3ffb 100644 --- a/app/src/bridge/components/chromecast/Media.ts +++ b/app/src/bridge/components/chromecast/Media.ts @@ -5,7 +5,7 @@ import castv2 from "castv2"; import Session from "./Session"; import { Message } from "../../messaging"; -import { sendMessage } from "../../lib/nativeMessaging" +import { sendMessage } from "../../lib/nativeMessaging"; const NS_MEDIA = "urn:x-cast:com.google.cast.media"; @@ -27,7 +27,7 @@ export interface UpdateMessageData { export default class Media { private channel: castv2.Channel; - constructor ( + constructor( private referenceId: string , private session: Session) { @@ -67,7 +67,7 @@ export default class Media { }); } - public messageHandler (message: Message) { + public messageHandler(message: Message) { switch (message.subject) { case "bridge:media/sendMediaMessage": { 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; (sendMessage as any)({ subject diff --git a/app/src/bridge/components/chromecast/Session.ts b/app/src/bridge/components/chromecast/Session.ts index 5efaa74..16251c7 100644 --- a/app/src/bridge/components/chromecast/Session.ts +++ b/app/src/bridge/components/chromecast/Session.ts @@ -26,7 +26,7 @@ export default class Session { private transportConnection?: Channel; private app: any; - constructor ( + constructor( public host: string , public port: number , private appId: string @@ -46,7 +46,7 @@ export default class Session { this.client = client; } - private onConnect () { + private onConnect() { let transportHeartbeat: Channel; const sourceId = "sender-0"; @@ -67,7 +67,7 @@ export default class Session { transportHeartbeat.send({ type: "PING" }); } - this.clientHeartbeat!.send({ type: "PING" }); + this.clientHeartbeat?.send({ type: "PING" }); }, 5000); this.clientReceiver.send({ @@ -124,7 +124,7 @@ export default class Session { }); } - public messageHandler (message: Message) { + public messageHandler(message: Message) { switch (message.subject) { case "bridge:session/close": this.close(); @@ -159,7 +159,7 @@ export default class Session { } } - public createChannel (namespace: string) { + public createChannel(namespace: string) { if (!this.channelMap.has(namespace)) { this.channelMap.set(namespace, this.client.createChannel( this.clientId!, this.transportId! @@ -167,16 +167,16 @@ export default class Session { } } - public close () { + public close() { this.clientConnection?.send({ type: "CLOSE" }); this.transportConnection?.send({ type: "CLOSE" }); } - public stop () { + public stop() { this.clientConnection?.send({ type: "STOP" }); } - private sendMessage (subject: string, data: any = {}) { + private sendMessage(subject: string, data: any = {}) { data._id = this.referenceId; sendMessage({ // @ts-ignore @@ -185,7 +185,7 @@ export default class Session { }); } - private _impl_addMessageListener (namespace: string) { + private _impl_addMessageListener(namespace: string) { this.createChannel(namespace); this.channelMap.get(namespace)?.on("message", (data: any) => { this.sendMessage("shim:session/impl_addMessageListener", { @@ -195,7 +195,7 @@ export default class Session { }); } - private _impl_sendMessage ( + private _impl_sendMessage( namespace: string , message: {} | 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; @@ -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; @@ -260,7 +260,7 @@ export default class Session { }); } - private _impl_stop (stopId: string) { + private _impl_stop(stopId: string) { let error = false; try { diff --git a/app/src/bridge/components/chromecast/StatusListener.ts b/app/src/bridge/components/chromecast/StatusListener.ts index 616e757..a30b75e 100644 --- a/app/src/bridge/components/chromecast/StatusListener.ts +++ b/app/src/bridge/components/chromecast/StatusListener.ts @@ -17,7 +17,7 @@ export default class StatusListener extends EventEmitter { private clientReceiver?: Channel; private clientHeartbeatIntervalId?: NodeJS.Timeout; - constructor (host: string, port: number) { + constructor(host: string, port: number) { super(); this.client = new Client(); @@ -35,7 +35,7 @@ export default class StatusListener extends EventEmitter { /** * Closes status listener connection. */ - public deregister (): void { + public deregister(): void { if (this.clientReceiver) { 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 destinationId = "receiver-0"; diff --git a/app/src/bridge/components/chromecast/index.ts b/app/src/bridge/components/chromecast/index.ts index b954126..14c66fa 100644 --- a/app/src/bridge/components/chromecast/index.ts +++ b/app/src/bridge/components/chromecast/index.ts @@ -11,7 +11,7 @@ import { Receiver } from "../../types"; const existingSessions: Map = new Map(); const existingMedia: Map = new Map(); -export function handleSessionMessage (message: any) { +export function handleSessionMessage(message: any) { if (!message.data._id) { console.error("Session message missing _id"); return; @@ -34,7 +34,7 @@ export function handleSessionMessage (message: any) { } } -export function handleMediaMessage (message: any) { +export function handleMediaMessage(message: any) { if (!message.data._id) { console.error("Media message missing _id"); return; @@ -44,7 +44,7 @@ export function handleMediaMessage (message: any) { if (existingMedia.has(mediaId)) { // Forward message to instance message handler - existingMedia.get(mediaId)!.messageHandler(message); + existingMedia.get(mediaId)?.messageHandler(message); } else { if (message.subject === "bridge:media/initialize") { // 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(); client.connect({ host, port }, () => { diff --git a/app/src/bridge/components/discovery.ts b/app/src/bridge/components/discovery.ts index 4ff44cc..f77819b 100644 --- a/app/src/bridge/components/discovery.ts +++ b/app/src/bridge/components/discovery.ts @@ -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 if (!service.txtRecord) { 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 } @@ -56,7 +56,7 @@ interface InitializeOptions { shouldWatchStatus?: boolean; } -export function startDiscovery (options: InitializeOptions) { +export function startDiscovery(options: InitializeOptions) { if (options.shouldWatchStatus) { browser.on("serviceUp", onStatusBrowserServiceUp); browser.on("serviceDown", onStatusBrowserServiceDown); @@ -67,7 +67,7 @@ export function startDiscovery (options: InitializeOptions) { // Receiver status listeners for status mode const statusListeners = new Map(); - function onStatusBrowserServiceUp (service: mdns.Service) { + function onStatusBrowserServiceUp(service: mdns.Service) { if (!service.txtRecord) { return; } @@ -109,11 +109,11 @@ export function startDiscovery (options: InitializeOptions) { statusListeners.set(id, listener); } - function onStatusBrowserServiceDown (_service: mdns.Service) { + function onStatusBrowserServiceDown(_service: mdns.Service) { // TODO: Fix service down detection } } -export function stopDiscovery () { +export function stopDiscovery() { browser.stop(); } diff --git a/app/src/bridge/components/mediaServer.ts b/app/src/bridge/components/mediaServer.ts index 9906582..8a7f807 100644 --- a/app/src/bridge/components/mediaServer.ts +++ b/app/src/bridge/components/mediaServer.ts @@ -14,9 +14,9 @@ import { convertSrtToVtt } from "../lib/subtitles"; 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) { - await stopMediaServer(); + stopMediaServer(); } let fileDir: string; @@ -74,7 +74,9 @@ export async function startMediaServer (filePath: string, port: number) { path.join(fileDir, dirEntry.name))); } } - } catch (err) {} + } catch (err) { + // TODO: Handle? + } mediaServer = http.createServer(async (req, res) => { if (!req.url) { @@ -172,7 +174,7 @@ export async function startMediaServer (filePath: string, port: number) { mediaServer.listen(port); } -export function stopMediaServer () { +export function stopMediaServer() { if (mediaServer?.listening) { mediaServer.close(); mediaServer = undefined; diff --git a/app/src/bridge/components/receiverSelector.ts b/app/src/bridge/components/receiverSelector.ts index 1eb208e..0357129 100644 --- a/app/src/bridge/components/receiverSelector.ts +++ b/app/src/bridge/components/receiverSelector.ts @@ -6,7 +6,7 @@ import path from "path"; import { sendMessage } from "../lib/nativeMessaging"; -function fatal (message: string) { +function fatal(message: string) { console.error(message); process.exit(1); } @@ -15,7 +15,7 @@ function fatal (message: string) { let selectorApp: child_process.ChildProcess | undefined; let selectorAppOpen = false; -export function startReceiverSelector (data: string) { +export function startReceiverSelector(data: string) { if (process.platform !== "darwin") { 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) { selectorApp?.kill(); selectorAppOpen = false; diff --git a/app/src/bridge/lib/nativeMessaging.ts b/app/src/bridge/lib/nativeMessaging.ts index 0d47521..9b1a755 100644 --- a/app/src/bridge/lib/nativeMessaging.ts +++ b/app/src/bridge/lib/nativeMessaging.ts @@ -10,6 +10,6 @@ export const encodeTransform = new EncodeTransform(); process.stdin.pipe(decodeTransform); encodeTransform.pipe(process.stdout); -export function sendMessage (message: Message) { +export function sendMessage(message: Message) { encodeTransform.write(message); } diff --git a/app/src/bridge/lib/subtitles.ts b/app/src/bridge/lib/subtitles.ts index fe8c230..9c8c45d 100644 --- a/app/src/bridge/lib/subtitles.ts +++ b/app/src/bridge/lib/subtitles.ts @@ -6,7 +6,7 @@ import fs from "fs"; /** * 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( srtFilePath, { encoding: "utf-8" }); diff --git a/app/src/daemon.ts b/app/src/daemon.ts index d99b35d..4f060de 100644 --- a/app/src/daemon.ts +++ b/app/src/daemon.ts @@ -10,14 +10,16 @@ import { DecodeTransform , EncodeTransform } from "./transforms"; -export function init (port: number) { +export function init(port: number) { process.stdout.write("Starting WebSocket server... "); const wss = new WebSocket.Server({ port }, () => { + // eslint-disable-next-line no-console console.log("Done!"); }); wss.on("error", (err) => { + // eslint-disable-next-line no-console console.log("Failed!"); console.error(err); }); @@ -26,6 +28,7 @@ export function init (port: number) { wss.on("connection", socket => { // Stream for incoming WebSocket messages const messageStream = new Readable({ objectMode: true }); + // eslint-disable-next-line @typescript-eslint/no-empty-function messageStream._read = () => {}; socket.on("message", (message: string) => { diff --git a/app/src/main.ts b/app/src/main.ts index 83823cb..5593dd9 100644 --- a/app/src/main.ts +++ b/app/src/main.ts @@ -22,8 +22,10 @@ const argv = minimist(process.argv.slice(2), { if (argv.version) { + // eslint-disable-next-line no-console console.log(`v${__applicationVersion}`); } else if (argv.help) { + // eslint-disable-next-line no-console console.log( `Usage: ${argv.__name} [options] diff --git a/app/src/transforms.ts b/app/src/transforms.ts index 2a7141d..b72ed7f 100755 --- a/app/src/transforms.ts +++ b/app/src/transforms.ts @@ -11,14 +11,14 @@ type ResponseHandlerFunction = (message: Message) => Promise; * and calls the transform callback. */ export class ResponseTransform extends Transform { - constructor (private _handler: ResponseHandlerFunction) { + constructor(private _handler: ResponseHandlerFunction) { super({ readableObjectMode: true , writableObjectMode: true }); } - public _transform ( + public _transform( chunk: Message , _encoding: string // tslint:disable-next-line:ban-types @@ -45,13 +45,13 @@ export class DecodeTransform extends Transform { private _messageBuffer = Buffer.alloc(0); private _messageLength?: number; - constructor () { + constructor() { super({ readableObjectMode: true }); } - public _transform ( + public _transform( chunk: any , _encoding: string // tslint:disable-next-line:ban-types @@ -105,13 +105,13 @@ export class DecodeTransform extends Transform { * outputs the encoded result. */ export class EncodeTransform extends Transform { - constructor () { + constructor() { super({ writableObjectMode: true }); } - public _transform ( + public _transform( chunk: any , _encoding: string // tslint:disable-next-line:ban-types diff --git a/app/tslint.json b/app/tslint.json deleted file mode 100644 index aa5f8cd..0000000 --- a/app/tslint.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": [ - "../tslint.json" - ] -} diff --git a/ext/bin/lint.js b/ext/bin/lint.js deleted file mode 100644 index 3a0fb08..0000000 --- a/ext/bin/lint.js +++ /dev/null @@ -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 ] - }); diff --git a/ext/package.json b/ext/package.json index ee9d6ff..8d13c9d 100644 --- a/ext/package.json +++ b/ext/package.json @@ -8,7 +8,7 @@ "package": "node bin/build.js --package", "watch": "node bin/build.js --watch", "start": "web-ext run -s ../dist/ext/", - "lint": "node bin/lint.js" + "lint": "eslint src --ext .ts,.tsx" }, "devDependencies": { "@types/firefox-webext-browser": "^82.0.0", diff --git a/ext/src/background/ShimManager.ts b/ext/src/background/ShimManager.ts index 9ef71f0..1e0f5c2 100644 --- a/ext/src/background/ShimManager.ts +++ b/ext/src/background/ShimManager.ts @@ -26,15 +26,14 @@ export interface Shim { } -// tslint:disable-next-line:new-parens export default new class ShimManager { private activeShims = new Set(); - public async init () { + public async init() { await this.initStatusListeners(); } - public getShim (tabId: number, frameId?: number) { + public getShim(tabId: number, frameId?: number) { for (const activeShim of this.activeShims) { if (activeShim.contentTabId === tabId) { 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 ? this.createShimFromBackground(port) : this.createShimFromContent(port)); @@ -59,7 +58,7 @@ export default new class ShimManager { this.activeShims.add(shim); } - private async createShimFromBackground ( + private async createShimFromBackground( contentPort: MessagePort): Promise { const shim: Shim = { @@ -83,7 +82,7 @@ export default new class ShimManager { return shim; } - private async createShimFromContent ( + private async createShimFromContent( contentPort: Port): Promise { if (contentPort.sender?.tab?.id === undefined @@ -138,7 +137,7 @@ export default new class ShimManager { return shim; } - private async handleContentMessage (shim: Shim, message: Message) { + private async handleContentMessage(shim: Shim, message: Message) { const [ destination ] = message.subject.split(":"); if (destination === "bridge") { 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"); } - const contentTab = await browser.tabs.get(shim.contentTabId); - try { const selection = await ReceiverSelectorManager.getSelection( @@ -231,8 +228,8 @@ export default new class ShimManager { } /** - * TODO: If we're closing a selector, make sure it's the - * same one that caused the session creation. + * TODO: If we're closing a selector, make sure it's the same + * one that caused the session creation. */ case "main:sessionCreated": { const selector = await ReceiverSelectorManager.getSelector(); @@ -248,7 +245,7 @@ export default new class ShimManager { } } - private async initStatusListeners () { + private async initStatusListeners() { StatusManager.addEventListener("serviceUp", ev => { for (const shim of this.activeShims) { shim.contentPort.postMessage({ diff --git a/ext/src/background/StatusManager.ts b/ext/src/background/StatusManager.ts index e730b71..d7047f0 100644 --- a/ext/src/background/StatusManager.ts +++ b/ext/src/background/StatusManager.ts @@ -14,14 +14,13 @@ interface EventMap { "statusUpdate": { id: string, status: ReceiverStatus }; } -// tslint:disable-next-line:new-parens export default new class StatusManager extends TypedEventTarget { private bridgePort: (Port | null) = null; private receivers = new Map(); - constructor () { + constructor() { super(); // Bind listeners @@ -29,13 +28,13 @@ export default new class StatusManager this.onBridgePortDisconnect = this.onBridgePortDisconnect.bind(this); } - public async init () { + public async init() { if (!this.bridgePort) { this.bridgePort = await this.createBridgePort(); } } - public *getReceivers () { + public *getReceivers() { for (const [, receiver ] of this.receivers) { if (receiver.status && receiver.status.application && 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) { return; } @@ -55,7 +54,7 @@ export default new class StatusManager }); } - private async createBridgePort () { + private async createBridgePort() { const bridgePort = await bridge.connect(); bridgePort.onMessage.addListener(this.onBridgePortMessage); bridgePort.onDisconnect.addListener(this.onBridgePortDisconnect); @@ -74,7 +73,7 @@ export default new class StatusManager * Handles incoming bridge status messages, manages the * receiver list, and dispatches events. */ - private onBridgePortMessage (message: Message) { + private onBridgePortMessage(message: Message) { switch (message.subject) { case "main:serviceUp": { const { data: receiver } = message; @@ -136,7 +135,7 @@ export default new class StatusManager * triggered again and the timer is reset for another 10 * seconds. */ - private onBridgePortDisconnect () { + private onBridgePortDisconnect() { for (const [, receiver] of this.receivers) { const serviceDownEvent = new CustomEvent("serviceDown", { detail: { id: receiver.id } diff --git a/ext/src/background/background.ts b/ext/src/background/background.ts index 69f08fd..f563ab1 100755 --- a/ext/src/background/background.ts +++ b/ext/src/background/background.ts @@ -49,12 +49,12 @@ browser.runtime.onInstalled.addListener(async details => { * Sets up media overlay content script and handles toggling * on options change. */ -async function initMediaOverlay () { +async function initMediaOverlay() { logger.info("init (media overlay)"); let contentScript: browser.contentScripts.RegisteredContentScript; - async function registerMediaOverlayContentScript () { + async function registerMediaOverlayContentScript() { if (!(await options.get("mediaOverlayEnabled"))) { return; } @@ -71,7 +71,7 @@ async function initMediaOverlay () { } } - async function unregisterMediaOverlayContentScript () { + async function unregisterMediaOverlayContentScript() { await contentScript?.unregister(); } @@ -95,7 +95,7 @@ async function initMediaOverlay () { * with the current version of the extension. If not, triggers * a notification with the appropriate info. */ -async function notifyBridgeCompat () { +async function notifyBridgeCompat() { logger.info("checking for bridge..."); let info: BridgeInfo; @@ -136,7 +136,7 @@ async function notifyBridgeCompat () { let isInitialized = false; -async function init () { +async function init() { if (isInitialized) { return; } @@ -193,7 +193,7 @@ async function init () { */ messaging.onConnect.addListener(async port => { if (port.name === "shim") { - ShimManager.createShim(port as any); + ShimManager.createShim(port); } }); } diff --git a/ext/src/background/menus.ts b/ext/src/background/menus.ts index 63b3473..0185132 100644 --- a/ext/src/background/menus.ts +++ b/ext/src/background/menus.ts @@ -4,7 +4,7 @@ import loadSender from "../lib/loadSender"; import logger from "../lib/logger"; import options from "../lib/options"; -import { getMediaTypesForPageUrl, stringify } from "../lib/utils"; +import { stringify } from "../lib/utils"; import { ReceiverSelectionActionType , ReceiverSelectorMediaType } from "./receiverSelector"; @@ -33,7 +33,7 @@ let menuIdWhitelistRecommended: MenuId; const whitelistChildMenuPatterns = new Map(); -export async function initMenus () { +export async function initMenus() { logger.info("init (menus)"); 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."); } - - const availableMediaTypes = getMediaTypesForPageUrl(info.pageUrl); - switch (info.menuItemId) { case menuIdCast: { const selection = await ReceiverSelectorManager.getSelection( diff --git a/ext/src/background/receiverSelector/NativeReceiverSelector.ts b/ext/src/background/receiverSelector/NativeReceiverSelector.ts index 0547e0f..f8cf3db 100644 --- a/ext/src/background/receiverSelector/NativeReceiverSelector.ts +++ b/ext/src/background/receiverSelector/NativeReceiverSelector.ts @@ -20,20 +20,20 @@ const _ = browser.i18n.getMessage; // TODO: Figure out lifetime properly export default class NativeReceiverSelector extends ReceiverSelector { private bridgePort: (Port | null) = null; - private wasReceiverSelected: boolean = false; + private wasReceiverSelected = false; #isOpen = false; - constructor () { + constructor() { super(); this.onBridgePortMessage = this.onBridgePortMessage.bind(this); } - get isOpen () { + get isOpen() { return this.#isOpen; } - public async open ( + public async open( receivers: Receiver[] , defaultMediaType: ReceiverSelectorMediaType , availableMediaTypes: ReceiverSelectorMediaType @@ -86,11 +86,11 @@ export default class NativeReceiverSelector extends ReceiverSelector { this.#isOpen = true; } - public update (): void { + public update(): void { // TODO: Implement this } - public close (): void { + public close(): void { if (this.bridgePort) { this.bridgePort.postMessage({ subject: "bridge:closeReceiverSelector" @@ -100,7 +100,7 @@ export default class NativeReceiverSelector extends ReceiverSelector { this.#isOpen = false; } - private async onBridgePortMessage (message: Message) { + private async onBridgePortMessage(message: Message) { switch (message.subject) { case "main:receiverSelector/selected": { this.wasReceiverSelected = true; diff --git a/ext/src/background/receiverSelector/PopupReceiverSelector.ts b/ext/src/background/receiverSelector/PopupReceiverSelector.ts index d37a291..d431f27 100644 --- a/ext/src/background/receiverSelector/PopupReceiverSelector.ts +++ b/ext/src/background/receiverSelector/PopupReceiverSelector.ts @@ -24,13 +24,13 @@ export default class PopupReceiverSelector extends ReceiverSelector { private defaultMediaType?: ReceiverSelectorMediaType; private availableMediaTypes?: ReceiverSelectorMediaType; - private wasReceiverSelected: boolean = false; + private wasReceiverSelected = false; private appId?: string; #isOpen = false; - constructor () { + constructor() { super(); // Bind methods to pass to addListener @@ -48,11 +48,11 @@ export default class PopupReceiverSelector extends ReceiverSelector { messaging.onConnect.addListener(this.onConnect); } - get isOpen () { + get isOpen() { return this.#isOpen; } - public async open ( + public async open( receivers: Receiver[] , defaultMediaType: 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.messagePort?.postMessage({ subject: "popup:update" @@ -125,7 +125,7 @@ export default class PopupReceiverSelector extends ReceiverSelector { }); } - public async close (): Promise { + public async close(): Promise { if (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 }); if (port.name !== "popup") { @@ -181,7 +181,7 @@ export default class PopupReceiverSelector extends ReceiverSelector { /** * Handles popup messages. */ - private onPopupMessage (message: Message) { + private onPopupMessage(message: Message) { switch (message.subject) { case "receiverSelector:selected": { this.wasReceiverSelected = true; @@ -206,7 +206,7 @@ export default class PopupReceiverSelector extends ReceiverSelector { * Handles cancellation state where the popup window is closed * before a receiver is selected. */ - private onWindowsRemoved (windowId: number) { + private onWindowsRemoved(windowId: number) { // Only care about popup window if (windowId !== this.windowId) { return; @@ -234,7 +234,7 @@ export default class PopupReceiverSelector extends ReceiverSelector { * into focus. Doesn't apply if no window is 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 && windowId !== this.windowId) { diff --git a/ext/src/background/receiverSelector/ReceiverSelectorManager.ts b/ext/src/background/receiverSelector/ReceiverSelectorManager.ts index 8c74684..20faa6b 100644 --- a/ext/src/background/receiverSelector/ReceiverSelectorManager.ts +++ b/ext/src/background/receiverSelector/ReceiverSelectorManager.ts @@ -18,7 +18,7 @@ import NativeReceiverSelector from "./NativeReceiverSelector"; import PopupReceiverSelector from "./PopupReceiverSelector"; -async function createSelector () { +async function createSelector() { const type = await options.get("receiverSelectorType"); const platformInfo = await browser.runtime.getPlatformInfo(); @@ -33,7 +33,7 @@ async function createSelector () { let sharedSelector: ReceiverSelector; -async function getSelector () { +async function getSelector() { if (!sharedSelector) { try { sharedSelector = await createSelector(); @@ -56,7 +56,7 @@ async function getSelector () { * - Resolves to null if the selection is cancelled. * - Rejects if the selection fails. */ -async function getSelection ( +async function getSelection( contextTabId: number , contextFrameId = 0 , withMediaSender = false) @@ -119,7 +119,7 @@ async function getSelection ( sharedSelector = await createSelector(); - function onReceiverChange () { + function onReceiverChange() { sharedSelector.update(Array.from(StatusManager.getReceivers())); } @@ -136,7 +136,7 @@ async function getSelection ( type EvParamsType = Parameters[0]; - function storeListener (type: EvParamsType, fn: T) { + function storeListener(type: EvParamsType, fn: T) { if (type === "selected") { onSelected = fn; } else if (type === "cancelled") { @@ -150,7 +150,7 @@ async function getSelection ( return fn; } - function removeListeners () { + function removeListeners() { sharedSelector.removeEventListener("selected", onSelected); sharedSelector.removeEventListener("cancelled", onCancelled); sharedSelector.removeEventListener("error", onError); diff --git a/ext/src/background/whitelist.ts b/ext/src/background/whitelist.ts index dd21abf..12b634b 100644 --- a/ext/src/background/whitelist.ts +++ b/ext/src/background/whitelist.ts @@ -26,7 +26,7 @@ let platform: string; let chromeUserAgent: string | undefined; let chromeUserAgentHybrid: string | undefined; -export async function initWhitelist () { +export async function initWhitelist() { logger.info("init (whitelist)"); if (!platform) { @@ -66,7 +66,7 @@ export async function initWhitelist () { * as Chrome, so we should rewrite the User-Agent header * to reflect this on whitelisted sites. */ - async function onWhitelistedBeforeSendHeaders ( + async function onWhitelistedBeforeSendHeaders( details: OnBeforeSendHeadersDetails) { if (!details.requestHeaders) { @@ -100,7 +100,7 @@ export async function initWhitelist () { * players on other origins (like CDN domains) when the * main site is whitelisted. */ -function onWhitelistedChildBeforeSendHeaders ( +function onWhitelistedChildBeforeSendHeaders( details: OnBeforeSendHeadersDetails) { if (!details.requestHeaders || !details.frameAncestors) { @@ -137,7 +137,7 @@ function onWhitelistedChildBeforeSendHeaders ( * We can redirect this and inject our own script to setup * the API shim. */ -async function onBeforeCastSDKRequest (details: OnBeforeRequestDetails) { +async function onBeforeCastSDKRequest(details: OnBeforeRequestDetails) { if (!details.originUrl) { return {}; } @@ -183,7 +183,7 @@ async function onBeforeCastSDKRequest (details: OnBeforeRequestDetails) { } -async function registerUserAgentWhitelist () { +async function registerUserAgentWhitelist() { const { userAgentWhitelist , userAgentWhitelistEnabled } = await options.getAll(); @@ -209,7 +209,7 @@ async function registerUserAgentWhitelist () { , [ "blocking", "requestHeaders" ]); } -function unregisterUserAgentWhitelist () { +function unregisterUserAgentWhitelist() { originUrlCache.length = 0; browser.webRequest.onBeforeSendHeaders diff --git a/ext/src/global.d.ts b/ext/src/global.d.ts index de6a6a3..8b1ff97 100644 --- a/ext/src/global.d.ts +++ b/ext/src/global.d.ts @@ -5,7 +5,7 @@ declare const APPLICATION_VERSION: string; declare interface Object { - // tslint:disable-next-line:ban-types + // eslint-disable-next-line @typescript-eslint/ban-types wrappedJSObject: Object; } @@ -67,7 +67,6 @@ declare function exportFunction ( , options?: ExportFunctionOptions): ExportFunctionFunc; - // Fix issues with @types/firefox-webext-browser declare namespace browser.events { /** @@ -91,23 +90,8 @@ declare namespace browser.runtime { onMessage: browser.events.Event; } - function connect (connectInfo: { + function connect(connectInfo: { name?: string , includeTlsChannelId?: boolean }): browser.runtime.Port; } - - -// Allow default attribute on