diff --git a/demo/background.js b/demo/background.js index c6eea94..d63cd96 100644 --- a/demo/background.js +++ b/demo/background.js @@ -1,3 +1,19 @@ import addDomainPermissionToggle from '..'; addDomainPermissionToggle(); + +chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { + if (!tab.url) { + console.log('No access to tab', tabId); + return; + } + + console.log('Access to tab', tabId, tab.url); + chrome.scripting.executeScript({ + target: {tabId}, + function() { + document.body.style.backgroundColor = 'yellow'; + console.log('chrome.tabs.onUpdated was fired'); + }, + }); +}); diff --git a/demo/manifest.json b/demo/manifest.json index c3142a2..79e894f 100644 --- a/demo/manifest.json +++ b/demo/manifest.json @@ -1,19 +1,21 @@ { + "$schema": "https://json.schemastore.org/chrome-manifest", "name": "webext-domain-permission-toggle", "version": "0.0.0", - "manifest_version": 2, + "manifest_version": 3, "permissions": [ - "https://*.github.com/*", "activeTab", "contextMenus" ], - "browser_action": {}, - "optional_permissions": [ + "host_permissions": [ + "https://*.github.com/*" + ], + "action": {}, + "optional_host_permissions": [ "*://*/*" ], "background": { - "scripts": [ - "background.js" - ] + "service_worker": "background.js", + "type": "module" } } diff --git a/globals.d.ts b/globals.d.ts new file mode 100644 index 0000000..732c7da --- /dev/null +++ b/globals.d.ts @@ -0,0 +1,6 @@ +declare namespace chrome.runtime { + // eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- Must match the type on DefinitelyTyped + interface ManifestV3 extends ManifestBase { + optional_host_permissions?: string[] | undefined; + } +} diff --git a/index.ts b/index.ts index 2039305..60505ff 100644 --- a/index.ts +++ b/index.ts @@ -139,9 +139,9 @@ export default function addDomainPermissionToggle(options?: Options): void { throw new Error('webext-domain-permission-toggle can only be initialized once'); } - const {name, permissions, optional_permissions: optionalPermissions} = chrome.runtime.getManifest(); + const manifest = chrome.runtime.getManifest(); - if (!permissions?.includes('contextMenus')) { + if (!manifest.permissions?.includes('contextMenus')) { throw new Error('webext-domain-permission-toggle requires the `contextMenus` permission'); } @@ -151,27 +151,37 @@ export default function addDomainPermissionToggle(options?: Options): void { } globalOptions = { - title: `Enable ${name} on this domain`, + title: `Enable ${manifest.name} on this domain`, reloadOnSuccess: false, ...options, }; if (globalOptions.reloadOnSuccess === true) { - globalOptions.reloadOnSuccess = `Do you want to reload this page to apply ${name}?`; + globalOptions.reloadOnSuccess = `Do you want to reload this page to apply ${manifest.name}?`; } - const optionalHosts = optionalPermissions?.filter(permission => /|\*/.test(permission)); - if (!optionalHosts || optionalHosts.length === 0) { - throw new TypeError('webext-domain-permission-toggle requires some wildcard hosts to be specified in `optional_permissions`'); + const optionalHosts = [ + ...manifest.optional_permissions ?? [], + ...manifest.optional_host_permissions as string[] ?? [], + ].filter((permission: string) => permission === '' || permission.includes('*')); + + if (optionalHosts.length === 0) { + throw new TypeError('webext-domain-permission-toggle requires some wildcard hosts to be specified in `optional_permissions` or `optional_host_permissions` (MV3)'); } + // Remove any existing context menu item and silence any error chrome.contextMenus.remove(contextMenuId, () => chrome.runtime.lastError); + + const contexts: chromeP.contextMenus.ContextType[] = 'browser_action' in chrome + ? ['page_action', 'browser_action'] + : ['action']; + chrome.contextMenus.create({ id: contextMenuId, type: 'checkbox', checked: false, title: globalOptions.title, - contexts: ['page_action', 'browser_action'], + contexts, // Note: This is completely ignored by Chrome and Safari. Great. #14 documentUrlPatterns: optionalHosts, diff --git a/package-lock.json b/package-lock.json index 05f082b..cd175a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "webext-domain-permission-toggle", - "version": "4.0.1", + "version": "4.1.0-1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "webext-domain-permission-toggle", - "version": "4.0.1", + "version": "4.1.0-1", "license": "MIT", "dependencies": { "webext-additional-permissions": "^2.4.0", diff --git a/package.json b/package.json index 0c38077..83e8292 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "webext-domain-permission-toggle", - "version": "4.0.1", + "version": "4.1.0-1", "description": "Browser-action context menu to request permission for the current tab. Chrome, Firefox, Safari.", "keywords": [ "browser", @@ -40,8 +40,6 @@ "webextensions" ], "rules": { - "@typescript-eslint/no-implicit-any-catch": "off", - "@typescript-eslint/restrict-template-expressions": "off", "no-alert": "off" } }, diff --git a/readme.md b/readme.md index 73bc80f..0144cbd 100644 --- a/readme.md +++ b/readme.md @@ -2,7 +2,10 @@ Context menu -> WebExtension module: Browser-action context menu to request permission for the current tab. Chrome, Firefox, Safari. +> WebExtension module: Browser-action context menu to request permission for the current tab. + +- Browsers: Chrome, Firefox, and Safari +- Manifest: v2 and v3 Works great when paired with [webext-dynamic-content-scripts](https://github.com/fregante/webext-dynamic-content-scripts/blob/master/how-to-add-github-enterprise-support-to-web-extensions.md) if you want to also inject content scripts on the new domains. @@ -29,10 +32,39 @@ import addDomainPermissionToggle from 'webext-domain-permission-toggle'; addDomainPermissionToggle(); ``` -### manifest.json +### manifest.json v3 + +```js +// example background.worker.js +navigator.importScripts( + "webext-domain-permission-toggle.js" +) +``` +```js +{ + "version": 3, + "action": { /* Firefox support */ + "default_icon": "icon.png" + }, + "permissions": [ + "contextMenus", + "activeTab", + "scripting", + ], + "optional_host_permissions": [ + "*://*/*" + ], + "background": { + "service_worker": "background.worker.js" + } +} +``` + +### manifest.json v2 ```js { + "version": 2, "browser_action": { /* Firefox support */ "default_icon": "icon.png" }, diff --git a/tsconfig.json b/tsconfig.json index f56e336..051b694 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "@sindresorhus/tsconfig", "files": [ - "index.ts" + "index.ts", + "globals.d.ts" ] }