mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Clipper: Improve support for future versions of Chrome (upgrade to manifest version 3) (#10109)
This commit is contained in:
parent
78b8839ae3
commit
e72cce0d07
@ -1229,6 +1229,7 @@ packages/tools/packageJsonLint.js
|
||||
packages/tools/postPreReleasesToForum.js
|
||||
packages/tools/release-android.js
|
||||
packages/tools/release-cli.js
|
||||
packages/tools/release-clipper.js
|
||||
packages/tools/release-electron.js
|
||||
packages/tools/release-ios.js
|
||||
packages/tools/release-plugin-repo-cli.js
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1209,6 +1209,7 @@ packages/tools/packageJsonLint.js
|
||||
packages/tools/postPreReleasesToForum.js
|
||||
packages/tools/release-android.js
|
||||
packages/tools/release-cli.js
|
||||
packages/tools/release-clipper.js
|
||||
packages/tools/release-electron.js
|
||||
packages/tools/release-ios.js
|
||||
packages/tools/release-plugin-repo-cli.js
|
||||
|
@ -11,13 +11,9 @@
|
||||
if (typeof browser !== 'undefined') {
|
||||
// eslint-disable-next-line no-undef
|
||||
browser_ = browser;
|
||||
// eslint-disable-next-line no-undef
|
||||
browserSupportsPromises_ = true;
|
||||
} else if (typeof chrome !== 'undefined') {
|
||||
// eslint-disable-next-line no-undef
|
||||
browser_ = chrome;
|
||||
// eslint-disable-next-line no-undef
|
||||
browserSupportsPromises_ = false;
|
||||
}
|
||||
|
||||
function escapeHtml(s) {
|
||||
@ -461,6 +457,7 @@
|
||||
tags: command.tags,
|
||||
windowInnerWidth: window.innerWidth,
|
||||
windowInnerHeight: window.innerHeight,
|
||||
devicePixelRatio: window.devicePixelRatio,
|
||||
};
|
||||
|
||||
browser_.runtime.sendMessage({
|
||||
|
@ -1,10 +1,12 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"manifest_version": 3,
|
||||
"name": "Joplin Web Clipper [DEV]",
|
||||
"version": "3.0.0",
|
||||
"description": "Capture and save web pages and screenshots from your browser to Joplin.",
|
||||
"homepage_url": "https://joplinapp.org",
|
||||
"content_security_policy": "script-src 'self'; object-src 'self'",
|
||||
"content_security_policy": {
|
||||
"extension_pages": "script-src 'self'; object-src 'self'"
|
||||
},
|
||||
"icons": {
|
||||
"32": "icons/32.png",
|
||||
"48": "icons/48.png",
|
||||
@ -13,18 +15,21 @@
|
||||
"permissions": [
|
||||
"activeTab",
|
||||
"tabs",
|
||||
"http://*/",
|
||||
"https://*/",
|
||||
"<all_urls>",
|
||||
"scripting",
|
||||
"storage"
|
||||
],
|
||||
"browser_action": {
|
||||
"host_permissions": [
|
||||
"http://*/",
|
||||
"https://*/",
|
||||
"<all_urls>"
|
||||
],
|
||||
"action": {
|
||||
"default_icon": "icons/32.png",
|
||||
"default_title": "Joplin Web Clipper",
|
||||
"default_popup": "popup/build/index.html"
|
||||
},
|
||||
"commands": {
|
||||
"_execute_browser_action": {
|
||||
"_execute_action": {
|
||||
"suggested_key": {
|
||||
"default": "Alt+Shift+J"
|
||||
}
|
||||
@ -49,12 +54,12 @@
|
||||
}
|
||||
},
|
||||
"background": {
|
||||
"scripts": [
|
||||
"background.js"
|
||||
],
|
||||
"persistent": false
|
||||
"scripts": ["service_worker.mjs"],
|
||||
|
||||
"service_worker": "service_worker.mjs",
|
||||
"type": "module"
|
||||
},
|
||||
"applications": {
|
||||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
"id": "{8419486a-54e9-11e8-9401-ac9e17909436}"
|
||||
}
|
||||
|
@ -115,6 +115,13 @@ class AppComponent extends Component {
|
||||
|
||||
this.clipScreenshot_click = async () => {
|
||||
try {
|
||||
// Firefox requires the <all_urls> host permission to take a
|
||||
// screenshot of the current page, however, this may change
|
||||
// in the future. Note that Firefox also forces this permission
|
||||
// to be optional.
|
||||
// See https://discourse.mozilla.org/t/browser-tabs-capturevisibletab-not-working-in-firefox-for-mv3/122965/3
|
||||
await bridge().browser().permissions.request({ origins: ['<all_urls>'] });
|
||||
|
||||
const baseUrl = await bridge().clipperServerBaseUrl();
|
||||
|
||||
await bridge().sendCommandToActiveTab({
|
||||
@ -179,12 +186,14 @@ class AppComponent extends Component {
|
||||
}
|
||||
|
||||
async loadContentScripts() {
|
||||
await bridge().tabsExecuteScript({ file: '/content_scripts/setUpEnvironment.js' });
|
||||
await bridge().tabsExecuteScript({ file: '/content_scripts/JSDOMParser.js' });
|
||||
await bridge().tabsExecuteScript({ file: '/content_scripts/Readability.js' });
|
||||
await bridge().tabsExecuteScript({ file: '/content_scripts/Readability-readerable.js' });
|
||||
await bridge().tabsExecuteScript({ file: '/content_scripts/clipperUtils.js' });
|
||||
await bridge().tabsExecuteScript({ file: '/content_scripts/index.js' });
|
||||
await bridge().tabsExecuteScript([
|
||||
'/content_scripts/setUpEnvironment.js',
|
||||
'/content_scripts/JSDOMParser.js',
|
||||
'/content_scripts/Readability.js',
|
||||
'/content_scripts/Readability-readerable.js',
|
||||
'/content_scripts/clipperUtils.js',
|
||||
'/content_scripts/index.js',
|
||||
]);
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
|
@ -1,5 +1,7 @@
|
||||
/* eslint-disable no-console */
|
||||
|
||||
import getActiveTabs from '../../util/getActiveTabs.mjs';
|
||||
import joplinEnv from '../../util/joplinEnv.mjs';
|
||||
const { randomClipperPort } = require('./randomClipperPort');
|
||||
|
||||
function msleep(ms) {
|
||||
@ -17,13 +19,12 @@ class Bridge {
|
||||
this.token_ = null;
|
||||
}
|
||||
|
||||
async init(browser, browserSupportsPromises, store) {
|
||||
async init(browser, store) {
|
||||
console.info('Popup: Init bridge');
|
||||
|
||||
this.browser_ = browser;
|
||||
this.dispatch_ = store.dispatch;
|
||||
this.store_ = store;
|
||||
this.browserSupportsPromises_ = browserSupportsPromises;
|
||||
this.clipperServerPort_ = null;
|
||||
this.clipperServerPortStatus_ = 'searching';
|
||||
|
||||
@ -74,12 +75,7 @@ class Bridge {
|
||||
}
|
||||
};
|
||||
this.browser_.runtime.onMessage.addListener(this.browser_notify);
|
||||
const backgroundPage = await this.backgroundPage(this.browser_);
|
||||
|
||||
// Not sure why the getBackgroundPage() sometimes returns null, so
|
||||
// in that case default to "prod" environment, which means the live
|
||||
// extension won't be affected by this bug.
|
||||
this.env_ = backgroundPage ? backgroundPage.joplinEnv() : 'prod';
|
||||
this.env_ = joplinEnv();
|
||||
|
||||
console.info('Popup: Env:', this.env());
|
||||
|
||||
@ -197,17 +193,6 @@ class Bridge {
|
||||
}
|
||||
}
|
||||
|
||||
async backgroundPage(browser) {
|
||||
const bgp = browser.extension.getBackgroundPage();
|
||||
if (bgp) return bgp;
|
||||
|
||||
return new Promise((resolve) => {
|
||||
browser.runtime.getBackgroundPage((bgp) => {
|
||||
resolve(bgp);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
env() {
|
||||
return this.env_;
|
||||
}
|
||||
@ -305,50 +290,26 @@ class Bridge {
|
||||
return `http://127.0.0.1:${port}`;
|
||||
}
|
||||
|
||||
async tabsExecuteScript(options) {
|
||||
if (this.browserSupportsPromises_) return this.browser().tabs.executeScript(options);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.browser().tabs.executeScript(options, () => {
|
||||
const e = this.browser().runtime.lastError;
|
||||
if (e) {
|
||||
const msg = [`tabsExecuteScript: Cannot load ${JSON.stringify(options)}`];
|
||||
if (e.message) msg.push(e.message);
|
||||
reject(new Error(msg.join(': ')));
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
async tabsExecuteScript(files) {
|
||||
const activeTabs = await getActiveTabs(this.browser());
|
||||
await this.browser().scripting.executeScript({
|
||||
target: {
|
||||
tabId: activeTabs[0].id,
|
||||
},
|
||||
files,
|
||||
});
|
||||
}
|
||||
|
||||
async tabsQuery(options) {
|
||||
if (this.browserSupportsPromises_) return this.browser().tabs.query(options);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
this.browser().tabs.query(options, (tabs) => {
|
||||
resolve(tabs);
|
||||
});
|
||||
});
|
||||
return this.browser().tabs.query(options);
|
||||
}
|
||||
|
||||
async tabsSendMessage(tabId, command) {
|
||||
if (this.browserSupportsPromises_) return this.browser().tabs.sendMessage(tabId, command);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
this.browser().tabs.sendMessage(tabId, command, (result) => {
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
return this.browser().tabs.sendMessage(tabId, command);
|
||||
}
|
||||
|
||||
async tabsCreate(options) {
|
||||
if (this.browserSupportsPromises_) return this.browser().tabs.create(options);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
this.browser().tabs.create(options, () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
return this.browser().tabs.create(options);
|
||||
}
|
||||
|
||||
async folderTree() {
|
||||
@ -356,29 +317,15 @@ class Bridge {
|
||||
}
|
||||
|
||||
async storageSet(keys) {
|
||||
if (this.browserSupportsPromises_) return this.browser().storage.local.set(keys);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
this.browser().storage.local.set(keys, () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
return this.browser().storage.local.set(keys);
|
||||
}
|
||||
|
||||
async storageGet(keys, defaultValue = null) {
|
||||
if (this.browserSupportsPromises_) {
|
||||
try {
|
||||
const r = await this.browser().storage.local.get(keys);
|
||||
return r;
|
||||
} catch (error) {
|
||||
return defaultValue;
|
||||
}
|
||||
} else {
|
||||
return new Promise((resolve) => {
|
||||
this.browser().storage.local.get(keys, (result) => {
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
try {
|
||||
const r = await this.browser().storage.local.get(keys);
|
||||
return r;
|
||||
} catch (error) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ async function main() {
|
||||
|
||||
console.info('Popup: Init bridge and restore state...');
|
||||
|
||||
await bridge().init(window.browser ? window.browser : window.chrome, !!window.browser, store);
|
||||
await bridge().init(window.browser ? window.browser : window.chrome, store);
|
||||
|
||||
console.info('Popup: Creating React app...');
|
||||
|
||||
|
@ -1,25 +1,13 @@
|
||||
import joplinEnv from './util/joplinEnv.mjs';
|
||||
import getActiveTabs from './util/getActiveTabs.mjs';
|
||||
|
||||
let browser_ = null;
|
||||
if (typeof browser !== 'undefined') {
|
||||
browser_ = browser;
|
||||
browserSupportsPromises_ = true;
|
||||
} else if (typeof chrome !== 'undefined') {
|
||||
browser_ = chrome;
|
||||
browserSupportsPromises_ = false;
|
||||
}
|
||||
|
||||
let env_ = null;
|
||||
|
||||
// Make this function global so that it can be accessed
|
||||
// from the popup too.
|
||||
// https://stackoverflow.com/questions/6323184/communication-between-background-page-and-popup-page-in-a-chrome-extension
|
||||
window.joplinEnv = function() {
|
||||
if (env_) return env_;
|
||||
|
||||
const manifest = browser_.runtime.getManifest();
|
||||
env_ = manifest.name.indexOf('[DEV]') >= 0 ? 'dev' : 'prod';
|
||||
return env_;
|
||||
};
|
||||
|
||||
async function browserCaptureVisibleTabs(windowId) {
|
||||
const options = {
|
||||
format: 'jpeg',
|
||||
@ -31,53 +19,19 @@ async function browserCaptureVisibleTabs(windowId) {
|
||||
// https://discourse.joplinapp.org/t/clip-screenshot-image-quality/12302/4
|
||||
quality: 92,
|
||||
};
|
||||
if (browserSupportsPromises_) return browser_.tabs.captureVisibleTab(windowId, options);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
browser_.tabs.captureVisibleTab(windowId, options, (image) => {
|
||||
resolve(image);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function browserGetZoom(tabId) {
|
||||
if (browserSupportsPromises_) return browser_.tabs.getZoom(tabId);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
browser_.tabs.getZoom(tabId, (zoom) => {
|
||||
resolve(zoom);
|
||||
});
|
||||
});
|
||||
return browser_.tabs.captureVisibleTab(windowId, options);
|
||||
}
|
||||
|
||||
browser_.runtime.onInstalled.addListener(() => {
|
||||
if (window.joplinEnv() === 'dev') {
|
||||
browser_.browserAction.setIcon({
|
||||
if (joplinEnv() === 'dev') {
|
||||
browser_.action.setIcon({
|
||||
path: 'icons/32-dev.png',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
async function getImageSize(dataUrl) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const image = new Image();
|
||||
|
||||
image.onload = function() {
|
||||
resolve({ width: image.width, height: image.height });
|
||||
};
|
||||
|
||||
image.onerror = function(event) {
|
||||
reject(event);
|
||||
};
|
||||
|
||||
image.src = dataUrl;
|
||||
});
|
||||
}
|
||||
|
||||
browser_.runtime.onMessage.addListener(async (command) => {
|
||||
if (command.name === 'screenshotArea') {
|
||||
const browserZoom = await browserGetZoom();
|
||||
|
||||
// The dimensions of the image returned by Firefox are the regular ones,
|
||||
// while the one returned by Chrome depend on the screen pixel ratio. So
|
||||
// it would return a 600*400 image if the window dimensions are 300x200
|
||||
@ -90,15 +44,18 @@ browser_.runtime.onMessage.addListener(async (command) => {
|
||||
//
|
||||
// The crop rectangle is always in real pixels, so we need to multiply
|
||||
// it by the ratio we've calculated.
|
||||
//
|
||||
// 8/3/2024: With manifest v3, we don't have access to DOM APIs in Chrome.
|
||||
// As a result, we can't easily calculate the size of the captured image.
|
||||
// We instead base the crop region exclusively on window.devicePixelRatio,
|
||||
// which seems to work in modern Firefox and Chrome.
|
||||
const imageDataUrl = await browserCaptureVisibleTabs(null);
|
||||
const imageSize = await getImageSize(imageDataUrl);
|
||||
const imagePixelRatio = imageSize.width / command.content.windowInnerWidth;
|
||||
|
||||
const content = { ...command.content };
|
||||
content.image_data_url = imageDataUrl;
|
||||
if ('url' in content) content.source_url = content.url;
|
||||
|
||||
const ratio = browserZoom * imagePixelRatio;
|
||||
const ratio = content.devicePixelRatio;
|
||||
const newArea = { ...command.content.crop_rect };
|
||||
newArea.x *= ratio;
|
||||
newArea.y *= ratio;
|
||||
@ -117,19 +74,8 @@ browser_.runtime.onMessage.addListener(async (command) => {
|
||||
}
|
||||
});
|
||||
|
||||
async function getActiveTabs() {
|
||||
const options = { active: true, currentWindow: true };
|
||||
if (browserSupportsPromises_) return browser_.tabs.query(options);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
browser_.tabs.query(options, (tabs) => {
|
||||
resolve(tabs);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function sendClipMessage(clipType) {
|
||||
const tabs = await getActiveTabs();
|
||||
const tabs = await getActiveTabs(browser_);
|
||||
if (!tabs || !tabs.length) {
|
||||
console.error('No active tabs');
|
||||
return;
|
7
packages/app-clipper/util/getActiveTabs.mjs
Normal file
7
packages/app-clipper/util/getActiveTabs.mjs
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
const getActiveTabs = async (browser) => {
|
||||
const options = { active: true, currentWindow: true };
|
||||
return await browser.tabs.query(options);
|
||||
}
|
||||
|
||||
export default getActiveTabs;
|
3
packages/app-clipper/util/joplinEnv.mjs
Normal file
3
packages/app-clipper/util/joplinEnv.mjs
Normal file
@ -0,0 +1,3 @@
|
||||
// AUTOGENERATED by release-clipper
|
||||
|
||||
export default () => 'dev';
|
@ -1,26 +1,27 @@
|
||||
const fs = require('fs-extra');
|
||||
const { execCommand, rootDir } = require('./tool-utils.js');
|
||||
import * as fs from 'fs-extra';
|
||||
import { execCommand, rootDir } from './tool-utils';
|
||||
const md5File = require('md5-file');
|
||||
const glob = require('glob');
|
||||
import * as glob from 'glob';
|
||||
|
||||
const clipperDir = `${rootDir}/packages/app-clipper`;
|
||||
const tmpSourceDirName = 'Clipper-source';
|
||||
|
||||
async function copyDir(baseSourceDir, sourcePath, baseDestDir) {
|
||||
async function copyDir(baseSourceDir: string, sourcePath: string, baseDestDir: string) {
|
||||
await fs.mkdirp(`${baseDestDir}/${sourcePath}`);
|
||||
await fs.copy(`${baseSourceDir}/${sourcePath}`, `${baseDestDir}/${sourcePath}`);
|
||||
}
|
||||
|
||||
async function copyToDist(distDir) {
|
||||
async function copyToDist(distDir: string) {
|
||||
await copyDir(clipperDir, 'popup/build', distDir);
|
||||
await copyDir(clipperDir, 'content_scripts', distDir);
|
||||
await copyDir(clipperDir, 'icons', distDir);
|
||||
await fs.copy(`${clipperDir}/background.js`, `${distDir}/background.js`);
|
||||
await copyDir(clipperDir, 'util', distDir);
|
||||
await fs.copy(`${clipperDir}/service_worker.mjs`, `${distDir}/service_worker.mjs`);
|
||||
await fs.copy(`${clipperDir}/manifest.json`, `${distDir}/manifest.json`);
|
||||
await fs.remove(`${distDir}/popup/build/manifest.json`);
|
||||
}
|
||||
|
||||
async function updateManifestVersionNumber(manifestPath) {
|
||||
async function updateManifestVersionNumber(manifestPath: string) {
|
||||
const manifestText = await fs.readFile(manifestPath, 'utf-8');
|
||||
const manifest = JSON.parse(manifestText);
|
||||
const v = manifest.version.split('.');
|
||||
@ -47,11 +48,11 @@ async function createSourceZip() {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
async function compareFiles(path1, path2) {
|
||||
async function compareFiles(path1: string, path2: string) {
|
||||
return await md5File(path1) === await md5File(path2);
|
||||
}
|
||||
|
||||
async function compareDir(dir1, dir2) {
|
||||
async function compareDir(dir1: string, dir2: string) {
|
||||
console.info(`Comparing directories ${dir1} to ${dir2}`);
|
||||
|
||||
const globOptions = {
|
||||
@ -61,7 +62,7 @@ async function compareDir(dir1, dir2) {
|
||||
],
|
||||
};
|
||||
|
||||
const filterFiles = (f) => {
|
||||
const filterFiles = (f: string) => {
|
||||
const stat = fs.statSync(f);
|
||||
return !stat.isDirectory();
|
||||
};
|
||||
@ -69,11 +70,11 @@ async function compareDir(dir1, dir2) {
|
||||
const files1 = glob.sync(`${dir1}/**/*`, globOptions).filter(filterFiles).map(f => f.substr(dir1.length + 1));
|
||||
const files2 = glob.sync(`${dir2}/**/*`, globOptions).filter(filterFiles).map(f => f.substr(dir2.length + 1));
|
||||
|
||||
const missingFiles1 = [];
|
||||
const missingFiles2 = [];
|
||||
const canBeMissing1 = [];
|
||||
const canBeMissing2 = ['manifest.json'];
|
||||
const differentFiles = [];
|
||||
const missingFiles1: string[] = [];
|
||||
const missingFiles2: string[] = [];
|
||||
const canBeMissing1: string[] = [];
|
||||
const canBeMissing2: string[] = ['manifest.json'];
|
||||
const differentFiles: string[] = [];
|
||||
for (const f of files1) {
|
||||
if (!files2.includes(f)) {
|
||||
if (canBeMissing2.includes(f)) continue;
|
||||
@ -104,7 +105,7 @@ async function compareDir(dir1, dir2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
async function checkSourceZip(sourceZip, compiledZip) {
|
||||
async function checkSourceZip(sourceZip: string, compiledZip: string) {
|
||||
const tmpDir = `${require('os').tmpdir()}/${Date.now()}`;
|
||||
|
||||
console.info(`Checking source ZIP in ${tmpDir}`);
|
||||
@ -119,6 +120,7 @@ async function checkSourceZip(sourceZip, compiledZip) {
|
||||
console.info(await execCommand(`unzip "${sourceZip}"`));
|
||||
process.chdir(`${sourceDir}/Clipper-source/popup`);
|
||||
console.info(await execCommand('npm install'));
|
||||
console.info(await execCommand('npm run build'));
|
||||
|
||||
process.chdir(compiledDir);
|
||||
console.info(await execCommand(`cp "${compiledZip}" .`));
|
||||
@ -132,6 +134,11 @@ async function checkSourceZip(sourceZip, compiledZip) {
|
||||
}
|
||||
}
|
||||
|
||||
async function setReleaseMode(isReleaseMode: boolean) {
|
||||
const joplinEnvPath = `${clipperDir}/util/joplinEnv.mjs`;
|
||||
await fs.writeFile(joplinEnvPath, `// AUTOGENERATED by release-clipper\n\nexport default () => '${isReleaseMode ? 'prod' : 'dev'}';`);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.info(await execCommand('git pull'));
|
||||
|
||||
@ -139,24 +146,34 @@ async function main() {
|
||||
|
||||
console.info('Building extension...');
|
||||
process.chdir(`${clipperDir}/popup`);
|
||||
// SKIP_PREFLIGHT_CHECK avoids the error "There might be a problem with the project dependency tree." due to eslint 5.12.0 being
|
||||
// installed by CRA and 6.1.0 by us. It doesn't affect anything though, and the behaviour of the preflight
|
||||
// check is buggy so we can ignore it.
|
||||
await setReleaseMode(true);
|
||||
console.info(await execCommand(`rm -rf ${clipperDir}/popup/build`));
|
||||
console.info(await execCommand('npm run build'));
|
||||
|
||||
const dists = {
|
||||
type PlatformDistOptions = {
|
||||
removeManifestKeys(manifest: Record<string, any>): Record<string, any>;
|
||||
outputPath?: string;
|
||||
};
|
||||
const dists: Record<string, PlatformDistOptions> = {
|
||||
chrome: {
|
||||
removeManifestKeys: (manifest) => {
|
||||
manifest = { ...manifest };
|
||||
delete manifest.applications;
|
||||
delete manifest.browser_specific_settings;
|
||||
|
||||
manifest.background = { ...manifest.background };
|
||||
delete manifest.background.scripts;
|
||||
delete manifest.background.persistent;
|
||||
|
||||
return manifest;
|
||||
},
|
||||
},
|
||||
firefox: {
|
||||
removeManifestKeys: (manifest) => {
|
||||
manifest = { ...manifest };
|
||||
delete manifest.background.persistent;
|
||||
|
||||
manifest.background = { ...manifest.background };
|
||||
delete manifest.background.service_worker;
|
||||
|
||||
return manifest;
|
||||
},
|
||||
},
|
||||
@ -186,12 +203,16 @@ async function main() {
|
||||
const sourceZip = await createSourceZip();
|
||||
await checkSourceZip(sourceZip, dists.firefox.outputPath);
|
||||
|
||||
await setReleaseMode(false);
|
||||
|
||||
process.chdir(clipperDir);
|
||||
console.info(await execCommand('git add -A'));
|
||||
console.info(await execCommand(`git commit -m "Clipper release v${newVersion}"`));
|
||||
console.info(await execCommand(`git tag clipper-${newVersion}`));
|
||||
console.info(await execCommand('git push'));
|
||||
console.info(await execCommand('git push --tags'));
|
||||
if (!process.argv.includes('--no-publish')) {
|
||||
console.info(await execCommand('git add -A'));
|
||||
console.info(await execCommand(`git commit -m "Clipper release v${newVersion}"`));
|
||||
console.info(await execCommand(`git tag clipper-${newVersion}`));
|
||||
console.info(await execCommand('git push'));
|
||||
console.info(await execCommand('git push --tags'));
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
Loading…
Reference in New Issue
Block a user