Skip to content

Commit

Permalink
Web extension patches (#9068)
Browse files Browse the repository at this point in the history
  • Loading branch information
101arrowz committed Oct 3, 2023
1 parent 12f4809 commit ef759a2
Show file tree
Hide file tree
Showing 7 changed files with 226 additions and 167 deletions.
28 changes: 17 additions & 11 deletions packages/packagers/webextension/src/WebExtensionPackager.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {Packager} from '@parcel/plugin';
import {replaceURLReferences, relativeBundlePath} from '@parcel/utils';

export default (new Packager({
async package({bundle, bundleGraph, options}) {
async package({bundle, bundleGraph}) {
let assets = [];
bundle.traverseAssets(asset => {
assets.push(asset);
Expand Down Expand Up @@ -43,14 +43,24 @@ export default (new Packager({

contentScript.css = [
...new Set(
(contentScript.css || []).concat(
srcBundles
.flatMap(b => bundleGraph.getReferencedBundles(b))
.filter(b => b.type == 'css')
.map(relPath),
),
srcBundles
.flatMap(b => bundleGraph.getReferencedBundles(b))
.filter(b => b.type == 'css')
.map(relPath)
.concat(contentScript.css || []),
),
];

contentScript.js = [
...new Set(
srcBundles
.flatMap(b => bundleGraph.getReferencedBundles(b))
.filter(b => b.type == 'js')
.map(relPath)
.concat(contentScript.js || []),
),
];

const resources = srcBundles
.flatMap(b => {
const children = [];
Expand Down Expand Up @@ -80,10 +90,6 @@ export default (new Packager({
}
}

if (manifest.manifest_version == 3 && options.hmrOptions) {
war.push({matches: ['<all_urls>'], resources: ['__parcel_hmr_proxy__']});
}

const warResult = (manifest.web_accessible_resources || []).concat(
manifest.manifest_version == 2
? [...new Set(war.flatMap(entry => entry.resources))]
Expand Down
48 changes: 25 additions & 23 deletions packages/runtimes/hmr/src/loaders/hmr-runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,17 +96,26 @@ if ((!parent || !parent.isParcelRequire) && typeof WebSocket !== 'undefined') {
!/localhost|127.0.0.1|0.0.0.0/.test(hostname))
? 'wss'
: 'ws';
var ws = new WebSocket(
protocol + '://' + hostname + (port ? ':' + port : '') + '/',
);

var ws;
try {
ws = new WebSocket(
protocol + '://' + hostname + (port ? ':' + port : '') + '/',
);
} catch (err) {
if (err.message) {
console.error(err.message);
}
ws = {};
}

// Web extension context
var extCtx =
typeof chrome === 'undefined'
? typeof browser === 'undefined'
typeof browser === 'undefined'
? typeof chrome === 'undefined'
? null
: browser
: chrome;
: chrome
: browser;

// Safari doesn't support sourceURL in error stacks.
// eval may also be disabled via CSP, so do a quick check.
Expand Down Expand Up @@ -206,7 +215,9 @@ if ((!parent || !parent.isParcelRequire) && typeof WebSocket !== 'undefined') {
}
};
ws.onerror = function (e) {
console.error(e.message);
if (e.message) {
console.error(e.message);
}
};
ws.onclose = function (e) {
if (process.env.PARCEL_BUILD_ENV !== 'test') {
Expand Down Expand Up @@ -400,25 +411,16 @@ async function hmrApplyUpdates(assets) {
if (!supportsSourceURL) {
let promises = assets.map(asset =>
hmrDownload(asset)?.catch(err => {
// Web extension bugfix for Chromium
// https://bugs.chromium.org/p/chromium/issues/detail?id=1255412#c12
// Web extension fix
if (
extCtx &&
extCtx.runtime &&
extCtx.runtime.getManifest().manifest_version == 3
extCtx.runtime.getManifest().manifest_version == 3 &&
typeof ServiceWorkerGlobalScope != 'undefined' &&
global instanceof ServiceWorkerGlobalScope
) {
if (
typeof ServiceWorkerGlobalScope != 'undefined' &&
global instanceof ServiceWorkerGlobalScope
) {
extCtx.runtime.reload();
return;
}
asset.url = extCtx.runtime.getURL(
'/__parcel_hmr_proxy__?url=' +
encodeURIComponent(asset.url + '?t=' + Date.now()),
);
return hmrDownload(asset);
extCtx.runtime.reload();
return;
}
throw err;
}),
Expand Down
46 changes: 31 additions & 15 deletions packages/runtimes/webextension/src/WebExtensionRuntime.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// @flow strict-local

import {Runtime} from '@parcel/plugin';
import {replaceURLReferences} from '@parcel/utils';
import nullthrows from 'nullthrows';
import fs from 'fs';
import path from 'path';
Expand All @@ -11,14 +12,15 @@ const AUTORELOAD_BG = fs.readFileSync(
);

export default (new Runtime({
apply({bundle, bundleGraph, options}) {
loadConfig({config}) {
config.invalidateOnBuild();
},
async apply({bundle, bundleGraph, options}) {
if (!bundle.env.isBrowser() || bundle.env.isWorklet()) {
return;
}
if (bundle.name == 'manifest.json') {
const asset = bundle.getMainEntry();
if (asset?.meta.webextEntry !== true) return;

if (bundle.getMainEntry()?.meta.webextEntry === true) {
// Hack to bust packager cache when any descendants update
const descendants = [];
bundleGraph.traverseBundles(b => {
Expand All @@ -35,7 +37,7 @@ export default (new Runtime({
.find(b => b.getMainEntry()?.meta.webextEntry === true);
const entry = manifest?.getMainEntry();
const insertDep = entry?.meta.webextBGInsert;
if (insertDep == null) return;
if (!manifest || !entry || insertDep == null) return;
const insertBundle = bundleGraph.getReferencedBundle(
nullthrows(entry?.getDependencies().find(dep => dep.id === insertDep)),
nullthrows(manifest),
Expand All @@ -50,16 +52,30 @@ export default (new Runtime({

// Add autoreload
if (bundle === firstInsertableBundle) {
return {
filePath: __filename,
code:
`var HMR_HOST = ${JSON.stringify(
options.hmrOptions?.host ?? 'localhost',
)};` +
`var HMR_PORT = '${options.hmrOptions?.port ?? ''}';` +
AUTORELOAD_BG,
isEntry: true,
};
return [
{
filePath: __filename,
code: AUTORELOAD_BG,
isEntry: true,
},
{
filePath: __filename,
// cache bust on non-asset manifest.json changes
code: `JSON.parse(${JSON.stringify(
JSON.stringify(
JSON.parse(
replaceURLReferences({
bundle: manifest,
bundleGraph,
contents: await entry.getCode(),
getReplacement: () => '',
}).contents,
),
),
)})`,
isEntry: true,
},
];
}
}
},
Expand Down
64 changes: 40 additions & 24 deletions packages/runtimes/webextension/src/autoreload-bg.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,44 @@
/* global chrome, browser, addEventListener, HMR_HOST, HMR_PORT */
var env = typeof chrome == 'undefined' ? browser : chrome;
env.runtime.onMessage.addListener(function (msg) {
/* global chrome, browser */
let env = typeof browser === 'undefined' ? chrome : browser;
let origReload = env.runtime.reload;
let avoidID = -1;

let promisify =
(obj, fn) =>
(...args) => {
if (typeof browser === 'undefined') {
return new Promise((resolve, reject) =>
obj[fn](...args, res =>
env.runtime.lastError ? reject(env.runtime.lastError) : resolve(res),
),
);
}
return obj[fn](...args);
};

let queryTabs = promisify(env.tabs, 'query');
let messageTab = promisify(env.tabs, 'sendMessage');

env.runtime.reload = () => {
queryTabs({})
.then(tabs => {
return Promise.all(
tabs.map(tab => {
if (tab.id === avoidID) return;
return messageTab(tab.id, {
__parcel_hmr_reload__: true,
}).catch(() => {});
}),
);
})
.then(() => {
origReload.call(env.runtime);
});
};

env.runtime.onMessage.addListener((msg, sender) => {
if (msg.__parcel_hmr_reload__) {
avoidID = sender.tab.id;
env.runtime.reload();
}
});

if (env.runtime.getManifest().manifest_version == 3) {
var proxyLoc = env.runtime.getURL('/__parcel_hmr_proxy__?url=');
addEventListener('fetch', function (evt) {
var url = evt.request.url;
if (url.startsWith(proxyLoc)) {
url = new URL(decodeURIComponent(url.slice(proxyLoc.length)));
if (url.hostname == HMR_HOST && url.port == HMR_PORT) {
evt.respondWith(
fetch(url).then(function (res) {
return new Response(res.body, {
headers: {
'Content-Type': res.headers.get('Content-Type'),
},
});
}),
);
}
}
});
}
Loading

0 comments on commit ef759a2

Please sign in to comment.