From b6aed7161e19a866b5990279c698592f97c94a9a Mon Sep 17 00:00:00 2001 From: Federico Date: Wed, 22 Jan 2025 17:02:37 +0100 Subject: [PATCH 1/3] Extract `createContextMenu` to `webext-tools` --- index.ts | 20 ++------------------ package-lock.json | 16 ++++++++-------- package.json | 2 +- 3 files changed, 11 insertions(+), 27 deletions(-) diff --git a/index.ts b/index.ts index 3156686..fbfb2f4 100644 --- a/index.ts +++ b/index.ts @@ -2,7 +2,7 @@ import chromePromised from 'webext-polyfill-kinda'; import {isBackground, isChrome} from 'webext-detect'; import {isUrlPermittedByManifest} from 'webext-permissions'; import {findMatchingPatterns} from 'webext-patterns'; -import {getTabUrl} from 'webext-tools'; +import {createContextMenu, getTabUrl} from 'webext-tools'; import alert from 'webext-alert'; import {executeFunction, isScriptableUrl} from 'webext-content-scripts'; @@ -210,19 +210,6 @@ export default function addPermissionToggle(options?: Options): void { const manifest = chrome.runtime.getManifest(); - if (!chrome.contextMenus) { - if ( - !manifest.permissions?.includes('contextMenus') - // Disable setup error on Firefox Android - && !/Android.+Firefox\//.test(navigator.userAgent) - ) { - throw new Error('webext-permission-toggle requires the `contextMenus` permission'); - } - - console.warn('chrome.contextMenus is not available'); - return; - } - globalOptions = { title: `Enable ${manifest.name} on this domain`, reloadOnSuccess: false, @@ -242,14 +229,11 @@ export default function addPermissionToggle(options?: Options): void { throw new TypeError('webext-permission-toggle requires some wildcard hosts to be specified in `optional_permissions` (MV2) or `optional_host_permissions` (MV3)'); } - // Remove any existing context menu item and silence any error - chrome.contextMenus.remove(contextMenuId, () => chrome.runtime.lastError); - const contexts: chrome.contextMenus.ContextType[] = manifest.manifest_version === 2 ? ['page_action', 'browser_action'] : ['action']; - chrome.contextMenus.create({ + void createContextMenu({ id: contextMenuId, type: 'checkbox', checked: false, diff --git a/package-lock.json b/package-lock.json index a022131..01b48e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "webext-patterns": "^1.5.0", "webext-permissions": "^3.1.3", "webext-polyfill-kinda": "^1.0.2", - "webext-tools": "^2.0.1" + "webext-tools": "^3.0.0" }, "devDependencies": { "@parcel/config-webextension": "^2.12.0", @@ -8685,9 +8685,9 @@ } }, "node_modules/webext-detect": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/webext-detect/-/webext-detect-5.0.2.tgz", - "integrity": "sha512-R/Jfape0ML8rxWxIlOk8qODkD9G7L6+HijSNktsAKY6ZWZwGGO0Mfxa5C3BcJkNwLBR5/44cGhpbGSf5dne3vQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/webext-detect/-/webext-detect-5.3.2.tgz", + "integrity": "sha512-RU/e8OLiPwU0efWs/cHp3sRCY+vakaTnbOS/x8VM/FkTtv6cfW/Ofed0i7WnkAKw2jbp4gki3WcpAdii+2QVMw==", "license": "MIT", "engines": { "node": ">=18" @@ -8749,13 +8749,13 @@ } }, "node_modules/webext-tools": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/webext-tools/-/webext-tools-2.0.1.tgz", - "integrity": "sha512-pk+lgvnTRMtzn1MvLeBien1nB15V5kIhung3w9ZFLyPXRzmZi5dHtr6BJJcNwJ8yzK+OeIsUk5qIDMEjEwgQKQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/webext-tools/-/webext-tools-3.0.0.tgz", + "integrity": "sha512-CqxJetvu7mxDf8yqr0/hFotxUP+9Zw7JT76tbdVo62Py2zhM+rRcsbordwX9jWXMX4q0qw1bk1aHXSxy0coCDw==", "license": "MIT", "dependencies": { "webext-content-scripts": "^2.7.0", - "webext-detect": "^5.0.2", + "webext-detect": "^5.3.2", "webext-polyfill-kinda": "^1.0.2" }, "engines": { diff --git a/package.json b/package.json index 0aacfa4..3e45f29 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "webext-patterns": "^1.5.0", "webext-permissions": "^3.1.3", "webext-polyfill-kinda": "^1.0.2", - "webext-tools": "^2.0.1" + "webext-tools": "^3.0.0" }, "devDependencies": { "@parcel/config-webextension": "^2.12.0", From e9c95a38221bed75ecf5e2ab510696f5fe60f86e Mon Sep 17 00:00:00 2001 From: Federico Date: Wed, 22 Jan 2025 17:05:06 +0100 Subject: [PATCH 2/3] Listeners first --- index.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/index.ts b/index.ts index fbfb2f4..c143dc2 100644 --- a/index.ts +++ b/index.ts @@ -199,7 +199,7 @@ async function handleClick( * * @param options {Options} */ -export default function addPermissionToggle(options?: Options): void { +export default async function addPermissionToggle(options?: Options): Promise { if (!isBackground()) { throw new Error('webext-permission-toggle can only be called from a background page'); } @@ -233,17 +233,6 @@ export default function addPermissionToggle(options?: Options): void { ? ['page_action', 'browser_action'] : ['action']; - void createContextMenu({ - id: contextMenuId, - type: 'checkbox', - checked: false, - title: globalOptions.title, - contexts, - - // Note: This is completely ignored by Chrome and Safari. Great. #14 - documentUrlPatterns: optionalHosts, - }); - chrome.contextMenus.onClicked.addListener(handleClick); chrome.tabs.onActivated.addListener(handleTabActivated); // Chrome won't fire `onFocusChanged` if the window is clicked when a context menu is open @@ -254,4 +243,15 @@ export default function addPermissionToggle(options?: Options): void { void updateItem(url ?? await getTabUrl(tabId) ?? ''); } }); + + await createContextMenu({ + id: contextMenuId, + type: 'checkbox', + checked: false, + title: globalOptions.title, + contexts, + + // Note: This is completely ignored by Chrome and Safari. Great. #14 + documentUrlPatterns: optionalHosts, + }); } From d0a3be06927373149969553e802c6b919973a074 Mon Sep 17 00:00:00 2001 From: Federico Date: Wed, 22 Jan 2025 22:44:36 +0100 Subject: [PATCH 3/3] Undo breaking --- index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.ts b/index.ts index c143dc2..88af8c6 100644 --- a/index.ts +++ b/index.ts @@ -199,7 +199,7 @@ async function handleClick( * * @param options {Options} */ -export default async function addPermissionToggle(options?: Options): Promise { +export default function addPermissionToggle(options?: Options): void { if (!isBackground()) { throw new Error('webext-permission-toggle can only be called from a background page'); } @@ -244,7 +244,7 @@ export default async function addPermissionToggle(options?: Options): Promise