From df009a63103fffedacbbb883cdeb6320751a36c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alan=20P=C5=82=C3=B3cieniak?= Date: Sun, 2 Oct 2022 21:45:10 +0200 Subject: [PATCH] #147 | Migrate to manifest v3 --- app/chrome/background.ts | 18 +-- app/chrome/contentscript.ts | 2 +- app/manifest.json | 79 +++++++------ typings/chrome/chrome.d.ts | 225 ++++++++++++++++++++++++++++++++++++ 4 files changed, 282 insertions(+), 42 deletions(-) diff --git a/app/chrome/background.ts b/app/chrome/background.ts index 11fc055..dfb0c87 100644 --- a/app/chrome/background.ts +++ b/app/chrome/background.ts @@ -9,28 +9,32 @@ chrome.runtime.onInstalled.addListener(details => { }); chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { + if (sender.tab == null) { + console.log("Tab cannot be null"); + return; + } if (request.sc_ext_setBadgeText_request) { - chrome.browserAction.setBadgeText({ tabId: sender.tab.id, text: request.modulesCount }); + chrome.action.setBadgeText({ tabId: sender.tab.id, text: request.modulesCount }); } if (request.sc_ext_setIcon_request) { - chrome.browserAction.setIcon({ - path: request.newIconPath, + chrome.action.setIcon({ + path: chrome.runtime.getURL(request.newIconPath), tabId: sender.tab.id }); } - chrome.browserAction.setPopup({ + chrome.action.setPopup({ tabId: sender.tab.id, popup: 'chrome/popup/popup.html' }); - chrome.browserAction.setBadgeBackgroundColor({ color: '#666' }); + chrome.action.setBadgeBackgroundColor({ color: '#666' }); if (request.sc_ext_checkVersion_request) { console.log(chrome.runtime.getManifest().version); console.log(request.version); if (request.version == null || request.version != chrome.runtime.getManifest().version) { - chrome.browserAction.setBadgeText({ tabId: sender.tab.id, text: "NEW", }); - chrome.browserAction.setPopup({ + chrome.action.setBadgeText({ tabId: sender.tab.id, text: "NEW", }); + chrome.action.setPopup({ tabId: sender.tab.id, popup: 'chrome/popup/popup-new-version.html' }); diff --git a/app/chrome/contentscript.ts b/app/chrome/contentscript.ts index 0300fdd..c6b09bc 100644 --- a/app/chrome/contentscript.ts +++ b/app/chrome/contentscript.ts @@ -106,7 +106,7 @@ window.addEventListener('message', function (event) { function createScriptElement(src: string): HTMLScriptElement { var script = document.createElement("script"); - script.src = chrome.extension.getURL(src); + script.src = chrome.runtime.getURL(src); return script; } diff --git a/app/manifest.json b/app/manifest.json index 09aef6a..8c182dd 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -2,7 +2,7 @@ "name": "__MSG_appName__", "short_name": "__MSG_appShortName__", "version": "3.4.0", - "manifest_version": 2, + "manifest_version": 3, "description": "__MSG_appDescription__", "icons": { "16": "chrome/images/icon-16.png", @@ -11,39 +11,41 @@ }, "default_locale": "en", "background": { - "scripts": [ - "chrome/background.js" - ] + "service_worker": "chrome/background.js" }, "permissions": [ "activeTab", - "http://*/*", - "https://*/*", "storage" ], - "content_scripts": [{ - "matches": [ - "http://*/*", - "https://*/*" - ], - "js": [ - "chrome/contentscript.js", - "common/optionsProvider.js" - ], - "css": [ - "sc_ext/styles/launcher.css", - "sc_ext/styles/databaseName.css", - "sc_ext/styles/fieldSearch.css", - "sc_ext/styles/treelistField.css", - "sc_ext/styles/fieldInspector.css", - "sc_ext/styles/toggleRibbon.css", - "sc_ext/styles/treeScope.css", - "sc_ext/libraries/iziToast.css" - ], - "run_at": "document_end", - "all_frames": true - }], - "browser_action": { + "host_permissions": [ + "http://*/*", + "https://*/*" + ], + "content_scripts": [ + { + "matches": [ + "http://*/*", + "https://*/*" + ], + "js": [ + "chrome/contentscript.js", + "common/optionsProvider.js" + ], + "css": [ + "sc_ext/styles/launcher.css", + "sc_ext/styles/databaseName.css", + "sc_ext/styles/fieldSearch.css", + "sc_ext/styles/treelistField.css", + "sc_ext/styles/fieldInspector.css", + "sc_ext/styles/toggleRibbon.css", + "sc_ext/styles/treeScope.css", + "sc_ext/libraries/iziToast.css" + ], + "run_at": "document_end", + "all_frames": true + } + ], + "action": { "default_icon": { "19": "chrome/images/icon-disabled-128.png", "38": "chrome/images/icon-disabled-128.png" @@ -51,12 +53,21 @@ "default_popup": "chrome/popup/popup.html" }, "options_ui": { - "page": "options/options.html", - "chrome_style": true + "page": "options/options.html" }, "web_accessible_resources": [ - "common/optionsProvider.js", - "sc_ext/Application.js", - "sc_ext/libraries/iziToast.js" + { + "resources": [ + "common/optionsProvider.js", + "sc_ext/Application.js", + "sc_ext/libraries/iziToast.js" + ], + "matches": [ + "https://*/*" + ], + "extension_ids": [ + "aoclhcccfdkjddgpaaajldgljhllhgmd" + ] + } ] } \ No newline at end of file diff --git a/typings/chrome/chrome.d.ts b/typings/chrome/chrome.d.ts index cdb48b2..3f06134 100644 --- a/typings/chrome/chrome.d.ts +++ b/typings/chrome/chrome.d.ts @@ -4466,6 +4466,231 @@ declare namespace chrome.pageAction { var onClicked: PageActionClickedEvent; } + +//////////////////// +// Action +//////////////////// +/** + * Use the chrome.action API to control the extension's icon in the Google Chrome toolbar. + * Availability: Since Chrome 88. Manifest v3. + * Manifest: "action": {...} + */ +declare namespace chrome.action { + export interface BadgeBackgroundColorDetails { + /** An array of four integers in the range [0,255] that make up the RGBA color of the badge. For example, opaque red is [255, 0, 0, 255]. Can also be a string with a CSS value, with opaque red being #FF0000 or #F00. */ + color: string | ColorArray; + /** Optional. Limits the change to when a particular tab is selected. Automatically resets when the tab is closed. */ + tabId?: number | undefined; + } + + export interface BadgeTextDetails { + /** Any number of characters can be passed, but only about four can fit in the space. */ + text: string; + /** Optional. Limits the change to when a particular tab is selected. Automatically resets when the tab is closed. */ + tabId?: number | undefined; + } + + export type ColorArray = [number, number, number, number]; + + export interface TitleDetails { + /** The string the action should display when moused over. */ + title: string; + /** Optional. Limits the change to when a particular tab is selected. Automatically resets when the tab is closed. */ + tabId?: number | undefined; + } + + export interface PopupDetails { + /** Optional. Limits the change to when a particular tab is selected. Automatically resets when the tab is closed. */ + tabId?: number | undefined; + /** The html file to show in a popup. If set to the empty string (''), no popup is shown. */ + popup: string; + } + + export interface BrowserClickedEvent extends chrome.events.Event<(tab: chrome.tabs.Tab) => void> { } + + export interface TabIconDetails { + /** Optional. Either a relative image path or a dictionary {size -> relative image path} pointing to icon to be set. If the icon is specified as a dictionary, the actual image to be used is chosen depending on screen's pixel density. If the number of image pixels that fit into one screen space unit equals scale, then image with size scale * 19 will be selected. Initially only scales 1 and 2 will be supported. At least one image must be specified. Note that 'details.path = foo' is equivalent to 'details.imageData = {'19': foo}' */ + path?: string | { [index: number]: string } | undefined; + /** Optional. Limits the change to when a particular tab is selected. Automatically resets when the tab is closed. */ + tabId?: number | undefined; + /** Optional. Either an ImageData object or a dictionary {size -> ImageData} representing icon to be set. If the icon is specified as a dictionary, the actual image to be used is chosen depending on screen's pixel density. If the number of image pixels that fit into one screen space unit equals scale, then image with size scale * 19 will be selected. Initially only scales 1 and 2 will be supported. At least one image must be specified. Note that 'details.imageData = foo' is equivalent to 'details.imageData = {'19': foo}' */ + imageData?: ImageData | { [index: number]: ImageData } | undefined; + } + + export interface TabDetails { + /** Optional. The ID of the tab to query state for. If no tab is specified, the non-tab-specific state is returned. */ + tabId?: number | undefined; + } + + /** + * Since Chrome 88. + * Disables the action for a tab. + * @param tabId The id of the tab for which you want to modify the action. + * @return The `disable` method provides its result via callback or returned as a `Promise` (MV3 only). It has no parameters. + */ + export function disable(tabId?: number): Promise; + + /** + * Since Chrome 88. + * Disables the action for a tab. + * @param tabId The id of the tab for which you want to modify the action. + * @param callback + */ + export function disable(tabId?: number, callback?: () => void): void; + + /** + * Since Chrome 88. + * Enables the action for a tab. By default, actions are enabled. + * @param tabId The id of the tab for which you want to modify the action. + * @return The `enable` method provides its result via callback or returned as a `Promise` (MV3 only). It has no parameters. + */ + export function enable(tabId?: number): Promise; + + /** + * Since Chrome 88. + * Enables the action for a tab. By default, actions are enabled. + * @param tabId The id of the tab for which you want to modify the action. + * @param callback + */ + export function enable(tabId?: number, callback?: () => void): void; + + /** + * Since Chrome 88. + * Gets the background color of the action. + * @param callback The callback parameter should be a function that looks like this: + * (result: ColorArray) => {...} + */ + export function getBadgeBackgroundColor(details: TabDetails, callback: (result: ColorArray) => void): void; + /** + * Since Chrome 88. + * Gets the background color of the action. + * @return The `getBadgeBackgroundColor` method provides its result via callback or returned as a `Promise` (MV3 only). + */ + export function getBadgeBackgroundColor(details: TabDetails): Promise; + + /** + * Since Chrome 88. + * Gets the badge text of the action. If no tab is specified, the non-tab-specific badge text is returned. + * If displayActionCountAsBadgeText is enabled, a placeholder text will be returned unless the + * declarativeNetRequestFeedback permission is present or tab-specific badge text was provided. + * @param callback The callback parameter should be a function that looks like this: + * (result: string) => {...} + */ + export function getBadgeText(details: TabDetails, callback: (result: string) => void): void; + + /** + * Since Chrome 88. + * Gets the badge text of the action. If no tab is specified, the non-tab-specific badge text is returned. + * If displayActionCountAsBadgeText is enabled, a placeholder text will be returned unless the + * declarativeNetRequestFeedback permission is present or tab-specific badge text was provided. + * @return The `getBadgeText` method provides its result via callback or returned as a `Promise` (MV3 only). + */ + export function getBadgeText(details: TabDetails): Promise; + + /** + * Since Chrome 88. + * Gets the html document set as the popup for this action. + * @param callback The callback parameter should be a function that looks like this: + * (result: string) => {...} + */ + export function getPopup(details: TabDetails, callback: (result: string) => void): void; + + /** + * Since Chrome 88. + * Gets the html document set as the popup for this action. + * @return The `getPopup` method provides its result via callback or returned as a `Promise` (MV3 only). + */ + export function getPopup(details: TabDetails): Promise; + + /** + * Since Chrome 88. + * Gets the title of the action. + * @param callback The callback parameter should be a function that looks like this: + * (result: string) => {...} + */ + export function getTitle(details: TabDetails, callback: (result: string) => void): void; + + /** + * Since Chrome 88. + * Gets the title of the action. + * @return The `getTitle` method provides its result via callback or returned as a `Promise` (MV3 only). + */ + export function getTitle(details: TabDetails): Promise; + + /** + * Since Chrome 88. + * Sets the background color for the badge. + * @return The `setBadgeBackgroundColor` method provides its result via callback or returned as a `Promise` (MV3 only). It has no parameters. + */ + export function setBadgeBackgroundColor(details: BadgeBackgroundColorDetails): Promise; + + /** + * Since Chrome 88. + * Sets the background color for the badge. + * @param callback The callback parameter should be a function that looks like this: + * () => {...} + */ + export function setBadgeBackgroundColor(details: BadgeBackgroundColorDetails, callback?: () => void): void; + + /** + * Since Chrome 88. + * Sets the badge text for the action. The badge is displayed on top of the icon. + * @return The `setBadgeText` method provides its result via callback or returned as a `Promise` (MV3 only). It has no parameters. + */ + export function setBadgeText(details: BadgeTextDetails): Promise; + + /** + * Since Chrome 88. + * Sets the badge text for the action. The badge is displayed on top of the icon. + * @param callback The callback parameter should be a function that looks like this: + * () => {...} + */ + export function setBadgeText(details: BadgeTextDetails, callback?: () => void): void; + + /** + * Since Chrome 88. + * Sets the icon for the action. The icon can be specified either as the path to an image file or as the pixel data from a canvas element, + * or as dictionary of either one of those. Either the path or the imageData property must be specified. + * @param callback The callback parameter should be a function that looks like this: + * () => {...} + */ + export function setIcon(details: TabIconDetails, callback?: () => void): void; + + /** + * Since Chrome 88. + * Sets the html document to be opened as a popup when the user clicks on the action's icon. + * @return The `setPopup` method provides its result via callback or returned as a `Promise` (MV3 only). It has no parameters. + */ + export function setPopup(details: PopupDetails): Promise; + + /** + * Since Chrome 88. + * Sets the html document to be opened as a popup when the user clicks on the action's icon. + * @param callback The callback parameter should be a function that looks like this: + * () => {...} + */ + export function setPopup(details: PopupDetails, callback?: () => void): void; + + /** + * Since Chrome 88. + * Sets the title of the action. This shows up in the tooltip. + * @return The `setTitle` method provides its result via callback or returned as a `Promise` (MV3 only). It has no parameters. + */ + export function setTitle(details: TitleDetails): Promise; + + /** + * Since Chrome 88. + * Sets the title of the action. This shows up in the tooltip. + * @param callback The callback parameter should be a function that looks like this: + * () => {...} + */ + export function setTitle(details: TitleDetails, callback?: () => void): void; + + /** Fired when an action icon is clicked. This event will not fire if the action has a popup. */ + export var onClicked: BrowserClickedEvent; +} + + //////////////////// // Page Capture ////////////////////