Skip to content

Commit

Permalink
Migrate to Manifest V3 on Firefox & fix background script on Chromium
Browse files Browse the repository at this point in the history
  • Loading branch information
baptistecdr committed Oct 14, 2023
1 parent 7a11192 commit cc3d443
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 72 deletions.
17 changes: 17 additions & 0 deletions public/manifest.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"manifest_version": 3,
"name": "__MSG_extName__",
"author": "baptistecdr",
"homepage_url": "https://github.com/baptistecdr/aria2-extensions",
Expand Down Expand Up @@ -38,5 +39,21 @@
"128": "icons/icon128.png",
"256": "icons/icon256.png",
"512": "icons/icon512.png"
},
"action": {
"default_popup": "popup/popup.html",
"default_title": "__MSG_extName__",
"default_icon": {
"16": "icons/icon16.png",
"19": "icons/icon19.png",
"24": "icons/icon24.png",
"32": "icons/icon32.png",
"38": "icons/icon38.png",
"48": "icons/icon48.png",
"80": "icons/icon80.png",
"128": "icons/icon128.png",
"256": "icons/icon256.png",
"512": "icons/icon512.png"
}
}
}
38 changes: 3 additions & 35 deletions scripts/generate-manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,55 +6,23 @@ const rawManifest = fs.readFileSync("./public/manifest.json").toString();
const manifest = JSON.parse(rawManifest);

if (process.env.BROWSER === "firefox") {
manifest.manifest_version = 2;
manifest.background = {
type: "module",
scripts: ["js/background.js"],
};
manifest.browser_action = {
default_popup: "popup/popup.html",
default_title: "__MSG_extName__",
default_icon: {
16: "icons/icon16.png",
19: "icons/icon19.png",
24: "icons/icon24.png",
32: "icons/icon32.png",
38: "icons/icon38.png",
48: "icons/icon48.png",
80: "icons/icon80.png",
128: "icons/icon128.png",
256: "icons/icon256.png",
512: "icons/icon512.png",
},
};
manifest.permissions.push("<all_urls>");
manifest.host_permissions = ["<all_urls>"];
manifest.browser_specific_settings = {
gecko: {
id: "baptistecdr@users.noreply.github.com",
strict_min_version: "69.0",
},
};
} else if (process.env.BROWSER === "chromium") {
manifest.manifest_version = 3;
manifest.background = {
type: "module",
service_worker: "js/background.js",
};
manifest.host_permissions = ["*://*/*"];
manifest.action = {
default_popup: "popup/popup.html",
default_title: "__MSG_extName__",
default_icon: {
16: "icons/icon16.png",
19: "icons/icon19.png",
24: "icons/icon24.png",
32: "icons/icon32.png",
38: "icons/icon38.png",
48: "icons/icon48.png",
80: "icons/icon80.png",
128: "icons/icon128.png",
256: "icons/icon256.png",
512: "icons/icon512.png",
},
};
}

fs.writeFileSync("./dist/manifest.json", JSON.stringify(manifest));
48 changes: 26 additions & 22 deletions src/background/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,17 @@ import Server from "../models/server";

const CONTEXT_MENUS_PARENT_ID = "aria2-integration";

let extensionOptions = await ExtensionOptions.fromStorage();
let connections: Record<string, Aria2> = {};

function createConnections() {
const connections: Record<string, Aria2> = {};
function createConnections(extensionOptions: ExtensionOptions) {
const conns: Record<string, Aria2> = {};
Object.entries(extensionOptions.servers).forEach(([key, server]) => {
connections[key] = new Aria2(server);
conns[key] = new Aria2(server);
});
return connections;
return conns;
}

let connections: Record<string, Aria2> = createConnections();

async function createExtensionContextMenus() {
async function createExtensionContextMenus(extensionOptions: ExtensionOptions) {
await browser.contextMenus.removeAll();
if (Object.keys(extensionOptions.servers).length > 0) {
browser.contextMenus.create({
Expand All @@ -33,7 +31,7 @@ async function createExtensionContextMenus() {
}
}

async function createServersContextMenus() {
async function createServersContextMenus(extensionOptions: ExtensionOptions) {
Object.entries(extensionOptions.servers).forEach(([id, server]) => {
browser.contextMenus.create({
title: `${server.name}`,
Expand All @@ -44,7 +42,7 @@ async function createServersContextMenus() {
});
}

async function createSingleServerContextMenus() {
async function createSingleServerContextMenus(extensionOptions: ExtensionOptions) {
await browser.contextMenus.removeAll();
Object.entries(extensionOptions.servers).forEach(([id]) => {
browser.contextMenus.create({
Expand All @@ -55,28 +53,31 @@ async function createSingleServerContextMenus() {
});
}

async function createContextMenus() {
async function createContextMenus(extensionOptions: ExtensionOptions) {
if (Object.keys(extensionOptions.servers).length === 1) {
await createSingleServerContextMenus();
await createSingleServerContextMenus(extensionOptions);
} else if (Object.keys(extensionOptions.servers).length > 1) {
await createExtensionContextMenus();
await createServersContextMenus();
await createExtensionContextMenus(extensionOptions);
await createServersContextMenus(extensionOptions);
}
}

ExtensionOptions.fromStorage().then(async (extensionOptions) => {
connections = createConnections(extensionOptions);
await createContextMenus(extensionOptions);
});

browser.runtime.onInstalled.addListener(async (details) => {
if (details.reason === "install") {
await browser.runtime.openOptionsPage();
}
});

await createContextMenus();

browser.storage.onChanged.addListener(async (changes) => {
if (changes.options) {
extensionOptions = await ExtensionOptions.fromStorage();
await createContextMenus();
connections = createConnections();
const extensionOptions = await ExtensionOptions.fromStorage();
connections = createConnections(extensionOptions);
await createContextMenus(extensionOptions);
}
});

Expand Down Expand Up @@ -111,7 +112,7 @@ function getSelectedUrls(onClickData: Menus.OnClickData): string[] {
return [];
}

function downloadItemMustBeCaptured(item: Downloads.DownloadItem, referrer: string): boolean {
function downloadItemMustBeCaptured(extensionOptions: ExtensionOptions, item: Downloads.DownloadItem, referrer: string): boolean {
if (extensionOptions.captureServer !== "") {
const excludedProtocols = extensionOptions.excludedProtocols.map((p) => `${p}:`);
const excludedFileTypesRegExp = new RegExp(`${extensionOptions.excludedFileTypes.join("$|")}$`);
Expand Down Expand Up @@ -146,14 +147,15 @@ async function captureDownloadItem(aria2: any, server: Server, item: Downloads.D
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const url = item.finalUrl ?? item.url; // finalUrl (Chrome), url (Firefox)
const filename = basename(item.filename);
const filename = await basename(item.filename);
if (url.match(/\.torrent$|\.meta4$|\.metalink$/) || filename.match(/\.torrent$|\.meta4$|\.metalink$/)) {
return captureTorrentFromURL(aria2, server, url, filename);
}
return captureURL(aria2, server, url, referer, cookies, filename);
}

browser.downloads.onCreated.addListener(async (downloadItem) => {
const extensionOptions = await ExtensionOptions.fromStorage();
if (extensionOptions.captureDownloads && connections[extensionOptions.captureServer] !== undefined) {
const connection = connections[extensionOptions.captureServer];
const server = extensionOptions.servers[extensionOptions.captureServer];
Expand All @@ -163,7 +165,7 @@ browser.downloads.onCreated.addListener(async (downloadItem) => {
referrer = currentTab?.url ?? "";
}
const cookies = await getCookies(referrer, currentTab?.cookieStoreId);
if (downloadItemMustBeCaptured(downloadItem, referrer)) {
if (downloadItemMustBeCaptured(extensionOptions, downloadItem, referrer)) {
await browser.downloads.cancel(downloadItem.id).catch();
await browser.downloads.erase({ id: downloadItem.id }).catch();
try {
Expand All @@ -177,6 +179,7 @@ browser.downloads.onCreated.addListener(async (downloadItem) => {
});

browser.contextMenus.onClicked.addListener(async (info, tab) => {
const extensionOptions = await ExtensionOptions.fromStorage();
const connection = connections[info.menuItemId];
const server = extensionOptions.servers[info.menuItemId];

Expand All @@ -195,6 +198,7 @@ browser.contextMenus.onClicked.addListener(async (info, tab) => {
});

browser.commands.onCommand.addListener(async (command) => {
const extensionOptions = await ExtensionOptions.fromStorage();
if (command === "toggle_capture_downloads") {
const newCaptureDownloads = !extensionOptions.captureDownloads;
let newCaptureServer = extensionOptions.captureServer;
Expand Down
5 changes: 2 additions & 3 deletions src/models/basename.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import reBasenameWindows from "@stdlib/regexp-basename-windows";
import reBasenamePosix from "@stdlib/regexp-basename-posix";
import browser from "webextension-polyfill";

const isWin = (await browser.runtime.getPlatformInfo()).os === "win";

export default function basename(filename: string): string {
export default async function basename(filename: string): Promise<string> {
const isWin = (await browser.runtime.getPlatformInfo()).os === "win";
const result = isWin ? reBasenameWindows().exec(filename) : reBasenamePosix().exec(filename);
if (result === null || result.length !== 2) {
return filename;
Expand Down
30 changes: 18 additions & 12 deletions src/popup/components/server-task.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Col, OverlayTrigger, Row, Tooltip } from "react-bootstrap";
import { Duration } from "luxon";
import browser from "webextension-polyfill";
import { filesize } from "filesize";
import { useEffect, useState } from "react";
import { Task } from "../models/task";
import basename from "../../models/basename";
import ServerTaskManagement from "./server-task-management";
Expand All @@ -12,23 +13,28 @@ interface Props {
aria2: any;
}

async function getFilename(task: Task): Promise<string> {
if (task.bittorrent && task.bittorrent.info) {
return task.bittorrent.info.name;
}
if (task.files[0].path !== "") {
return basename(task.files[0].path);
}
return basename(task.files[0].uris[0].uri);
}

function ServerTask({ task, aria2 }: Props) {
const filesizeParameters = { base: 2 };
const [filename, setFilename] = useState("");

useEffect(() => {
getFilename(task).then((it) => setFilename(it));
}, [task]);

function toFirstUppercase(s: string): string {
return s.charAt(0).toUpperCase() + s.slice(1);
}

function getFilename(): string {
if (task.bittorrent && task.bittorrent.info) {
return task.bittorrent.info.name;
}
if (task.files[0].path !== "") {
return basename(task.files[0].path);
}
return basename(task.files[0].uris[0].uri);
}

function getProgressVariant(): string {
if (task.isComplete()) {
return "success";
Expand Down Expand Up @@ -76,11 +82,11 @@ function ServerTask({ task, aria2 }: Props) {
placement="top"
overlay={
<Tooltip id="tooltip-bottom">
<small>{getFilename()}</small>
<small>{filename}</small>
</Tooltip>
}
>
<span>{getFilename()}</span>
<span>{filename}</span>
</OverlayTrigger>
</Col>
<Col xs={12} sm={12} className="align-self-start ps-4 text-start">
Expand Down

0 comments on commit cc3d443

Please sign in to comment.