Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add compatibility with manifest V3 #319

Merged
merged 2 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/messages/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ the provided on 'manifest.json' or 'entry.background' \
option of the plugin",
);

export const bgScriptManifestRequiredMsg = new Message(ERROR, 2, "Background script on manifest is required");
export const bgScriptManifestRequiredMsg = new Message(
ERROR,
2,
"Background script or service worker on manifest is required",
);
11 changes: 7 additions & 4 deletions src/middleware/wer-middleware.raw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/* This will be converted into a lodash templ., any */
/* external argument must be provided using it */
/* -------------------------------------------------- */
(function(window) {
(function() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I locally compiled and tested with Manifest v3. I still get error Uncaught ReferenceError: window is not defined
at
var injectionContext = this || window || {

Copy link

@sherifmayika sherifmayika Nov 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

commented the "window" as var injectionContext = this || /*window ||*/ { then "window" error is gone in MV 3. not tested with Mv2. But now get Uncaught TypeError: Cannot read properties of null (reading 'extension') var extension = browser.extension,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain how to reproduce the bug? (Browser version, manifest content, steps to follow...). Thanks!

Copy link

@sherifmayika sherifmayika Nov 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lmichelin lmichelin (#319 (comment))

Chromium
Version 107.0.5304.110 (Official Build) Arch Linux (64-bit)

Manifest
{ "manifest_version": 3, "name": "__MSG_extName__", "homepage_url": "http://localhost:8080/", "description": "A Vue Browser Extension", "default_locale": "en", "permissions": [ "activeTab" ], "icons": { "16": "icons/16.png", "48": "icons/48.png", "128": "icons/128.png" }, "background": { "service_worker": "js/background.js", "type": "module" }, "content_security_policy": { "extension_pages": "script-src 'self'; object-src 'self'; script-src-elem 'self' 'unsafe-inline'; connect-src https://* data: blob: filesystem:" }, "action": { "default_popup": "popup.html", "default_title": "__MSG_extName__", "default_icon": { "19": "icons/19.png", "38": "icons/38.png" } }, "version": "0.1.0" }
no content script
Background

chrome.action.onClicked.addListener(() => { console.log("browser action clicked"); // openApp("popup.html"); chrome.tabs.create({ url: chrome.runtime.getURL("popup.html"), }); });

package,json
{ "name": "my-extension", "version": "0.1.0", "private": true, "scripts": { "serve": "vue-cli-service build --mode development --watch", "build": "vue-cli-service build", "lint": "vue-cli-service lint" }, "dependencies": { "axios": "^0.20.0", "core-js": "^3.8.3", "vue": "^2.6.14", "vue-router": "^3.5.1", "vuex": "^3.6.2" }, "devDependencies": { "@babel/core": "^7.12.16", "@babel/eslint-parser": "^7.12.16", "@vue/cli-plugin-babel": "~5.0.0", "@vue/cli-plugin-eslint": "~5.0.0", "@vue/cli-plugin-router": "~5.0.0", "@vue/cli-plugin-vuex": "~5.0.0", "@vue/cli-service": "~5.0.0", "eslint": "^7.32.0", "eslint-plugin-vue": "^8.0.3", "sass": "^1.32.7", "sass-loader": "^12.0.0", "vue-cli-plugin-browser-extension": "npm:@rhilip/vue-cli-plugin-browser-extension@^0.26.0", "vue-template-compiler": "^2.6.14" } }

Copy link

@sherifmayika sherifmayika Nov 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lmichelin
Somehow I managed to remove errors in serviceworker
1)

-/* eslint:disable */ +/* eslint-disable */

-(function(window) {

+(function() { +try {window} catch {var window: any;}

this solves the "window is not defined" error

to remove 'extension'is undefined error

- const { extension, runtime, tabs } = browser; const manifest = runtime.getManifest()

+ const { runtime, tabs } = browser; const manifest = runtime.getManifest()

refer this
voyage-finance@3c96c5c
4)
to resolve "runtime" is undefined error

I replaced browser.runtime with chrome.runtime and browser.tabs with chrome.tabs in

node_modules/webpack-ext-reloader/dist/webpack-ext-reloader.js

now everything working fine for me.

browser.runtime comes from 'webextension-polyfill'

mozilla/webextension-polyfill#329 has clue how to make changes in wer-middleware.raw.ts


const injectionContext = this || window || {browser: null};

Expand Down Expand Up @@ -71,7 +71,9 @@
if (type === SIGN_CHANGE && (!payload || !payload.onlyPageChanged)) {
tabs.query({ status: "complete" }).then(loadedTabs => {
loadedTabs.forEach(
tab => tab.id && tabs.sendMessage(tab.id, { type: SIGN_RELOAD }),
// in MV3 tabs.sendMessage returns a Promise and we need to catch the errors
// https://groups.google.com/a/chromium.org/g/chromium-extensions/c/st_Nh7j3908/m/1muOgSX5AwAJ
tab => tab.id && tabs.sendMessage(tab.id, { type: SIGN_RELOAD })?.catch(() => null),
);
socket.send(
JSON.stringify({
Expand Down Expand Up @@ -137,9 +139,10 @@

// ======================= Bootstraps the middleware =========================== //
runtime.reload
? extension.getBackgroundPage() === window ? backgroundWorker(new WebSocket(wsHost)) : extensionPageWorker()
// in MV3 background service workers don't have access to the DOM
? (typeof window === 'undefined' || extension.getBackgroundPage() === window) ? backgroundWorker(new WebSocket(wsHost)) : extensionPageWorker()
: contentScriptWorker();
})(window);
})();

/* ----------------------------------------------- */
/* End of Webpack Hot Extension Middleware */
Expand Down
4 changes: 2 additions & 2 deletions src/utils/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ export function extractEntries(
throw new Error("Please specify the `output.filename` in your webpack config.");
}

if (!background?.scripts) {
if (!(background?.scripts || background?.service_worker)) {
throw new TypeError(bgScriptManifestRequiredMsg.get());
}

const bgScriptFileNames = background.scripts;
const bgScriptFileNames = background.service_worker ? [background.service_worker] : background.scripts ?? [];
const toRemove = (filename as string).replace("[name]", "");

const bgWebpackEntry = Object.keys(webpackEntry).find((entryName) =>
Expand Down
22 changes: 4 additions & 18 deletions typings/declarations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ declare interface IMiddlewareTemplateParams {
reloadPage: boolean;
}

declare type InjectMiddleware = (
assets: Record<string, any>,
chunks: Set<any>,
) => Record<string, any>;
declare type InjectMiddleware = (assets: Record<string, any>, chunks: Set<any>) => Record<string, any>;

declare type MiddlewareInjector = (
{ background, contentScript, extensionPage }: IEntriesOption,
Expand All @@ -22,10 +19,7 @@ declare type MiddlewareInjector = (

declare type Triggerer = (onlyPageChanged: boolean) => Promise<any>;

declare type TriggererFactory = (
port: number,
reloadPage: boolean,
) => Triggerer;
declare type TriggererFactory = (port: number, reloadPage: boolean) => Triggerer;

declare type VersionPair = [number | undefined, number | undefined];

Expand All @@ -45,13 +39,7 @@ declare type LOG_WARN = 3;
declare type LOG_ERROR = 4;
declare type LOG_DEBUG = 5;

declare type LOG_LEVEL =
| LOG_NONE
| LOG_LOG
| LOG_INFO
| LOG_WARN
| LOG_ERROR
| LOG_DEBUG;
declare type LOG_LEVEL = LOG_NONE | LOG_LOG | LOG_INFO | LOG_WARN | LOG_ERROR | LOG_DEBUG;

declare interface IWebpackChunk {
files: string[];
Expand All @@ -73,13 +61,11 @@ declare interface IExtensionManifest {
background?: {
page?: string;
scripts?: string[];
service_worker?: string;
};
icons?: {
[key: string]: string;
};
browser_action?: {
default_popup: string;
};
content_scripts?: [
{
matches: string[];
Expand Down