@@ -31,6 +31,7 @@ const extWebpack = (config, env) => {
|
|||||||
popup: paths.appSrc + "/popup.js",
|
popup: paths.appSrc + "/popup.js",
|
||||||
options: paths.appSrc + "/options.js",
|
options: paths.appSrc + "/options.js",
|
||||||
background: paths.appSrc + "/background.js",
|
background: paths.appSrc + "/background.js",
|
||||||
|
backgroundthunderbird: paths.appSrc + "/background.thunderbird.js",
|
||||||
content: paths.appSrc + "/content.js",
|
content: paths.appSrc + "/content.js",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -27,12 +27,13 @@
|
|||||||
"build:chrome": "rm -rf build/chrome && BUILD_PATH=./build/chrome REACT_APP_CLIENT=chrome react-app-rewired build && rm build/chrome/content.html",
|
"build:chrome": "rm -rf build/chrome && BUILD_PATH=./build/chrome REACT_APP_CLIENT=chrome react-app-rewired build && rm build/chrome/content.html",
|
||||||
"build:edge": "rm -rf build/edge && cp -r build/chrome build/edge",
|
"build:edge": "rm -rf build/edge && cp -r build/chrome build/edge",
|
||||||
"build:firefox": "rm -rf build/firefox && cp -r build/chrome build/firefox && cat ./build/firefox/manifest.firefox.json > ./build/firefox/manifest.json && rm build/*/manifest.firefox.json",
|
"build:firefox": "rm -rf build/firefox && cp -r build/chrome build/firefox && cat ./build/firefox/manifest.firefox.json > ./build/firefox/manifest.json && rm build/*/manifest.firefox.json",
|
||||||
|
"build:thunderbird":"rm -rf build/thunderbird && cp -r build/chrome build/thunderbird && cat ./build/thunderbird/manifest.thunderbird.json > ./build/thunderbird/manifest.json && cp ./build/thunderbird/backgroundthunderbird.js ./build/thunderbird/background.js && rm build/*/manifest.thunderbird.json && rm build/*/backgroundthunderbird.js && rm build/*/backgroundthunderbird.js.LICENSE.txt",
|
||||||
"build:web": "rm -rf build/web && BUILD_PATH=./build/web REACT_APP_CLIENT=userscript react-app-rewired build",
|
"build:web": "rm -rf build/web && BUILD_PATH=./build/web REACT_APP_CLIENT=userscript react-app-rewired build",
|
||||||
"build:userscript-ios": "file1=build/web/kiss-translator.user.js file2=build/web/kiss-translator-ios-safari.user.js && cp $file1 $file2 && sed -i 's|// @grant unsafeWindow|// @inject-into content|g' $file2",
|
"build:userscript-ios": "file1=build/web/kiss-translator.user.js file2=build/web/kiss-translator-ios-safari.user.js && cp $file1 $file2 && sed -i 's|// @grant unsafeWindow|// @inject-into content|g' $file2",
|
||||||
"build:userscript": "rm -rf build/userscript && mkdir build/userscript && cp build/web/*.user.js build/userscript/",
|
"build:userscript": "rm -rf build/userscript && mkdir build/userscript && cp build/web/*.user.js build/userscript/",
|
||||||
"build:rules": "babel-node src/rules.js",
|
"build:rules": "babel-node src/rules.js",
|
||||||
"build": "pnpm build:chrome && pnpm build:edge && pnpm build:firefox && pnpm build:web && pnpm build:userscript-ios && pnpm build:userscript && pnpm build:rules",
|
"build": "pnpm build:chrome && pnpm build:edge && pnpm build:firefox && pnpm build:thunderbird && pnpm build:web && pnpm build:userscript-ios && pnpm build:userscript && pnpm build:rules",
|
||||||
"zip": "cd build && zip -r chrome.zip chrome && zip -r edge.zip edge && cd firefox && zip -r ../firefox.zip .",
|
"zip": "cd build && zip -r chrome.zip chrome && zip -r edge.zip edge && (cd firefox && zip -r ../firefox.zip .) && (cd thunderbird && zip -r ../thunderbird.zip .)",
|
||||||
"test": "react-app-rewired test",
|
"test": "react-app-rewired test",
|
||||||
"eject": "react-scripts eject"
|
"eject": "react-scripts eject"
|
||||||
},
|
},
|
||||||
|
|||||||
78
public/manifest.thunderbird.json
Normal file
78
public/manifest.thunderbird.json
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"manifest_version": 2,
|
||||||
|
"name": "__MSG_app_name__",
|
||||||
|
"description": "__MSG_app_description__",
|
||||||
|
"version": "1.8.11",
|
||||||
|
"default_locale": "en",
|
||||||
|
"author": "Gabe<yugang2002@gmail.com>",
|
||||||
|
"homepage_url": "https://github.com/fishjar/kiss-translator",
|
||||||
|
"browser_specific_settings": {
|
||||||
|
"gecko": {
|
||||||
|
"id": "yugang2002@gmail.com",
|
||||||
|
"strict_min_version": "78.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"background": {
|
||||||
|
"scripts": ["background.js"]
|
||||||
|
},
|
||||||
|
"content_scripts": [
|
||||||
|
{
|
||||||
|
"js": ["content.js"],
|
||||||
|
"matches": ["<all_urls>"],
|
||||||
|
"all_frames": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"commands": {
|
||||||
|
"_execute_browser_action": {
|
||||||
|
"suggested_key": {
|
||||||
|
"default": "Alt+K"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"toggleTranslate": {
|
||||||
|
"suggested_key": {
|
||||||
|
"default": "Alt+Q"
|
||||||
|
},
|
||||||
|
"description": "__MSG_toggle_translate__"
|
||||||
|
},
|
||||||
|
"openTranbox": {
|
||||||
|
"suggested_key": {
|
||||||
|
"default": "Alt+S"
|
||||||
|
},
|
||||||
|
"description": "__MSG_open_tranbox__"
|
||||||
|
},
|
||||||
|
"toggleStyle": {
|
||||||
|
"suggested_key": {
|
||||||
|
"default": "Alt+C"
|
||||||
|
},
|
||||||
|
"description": "__MSG_toggle_style__"
|
||||||
|
},
|
||||||
|
"openOptions": {
|
||||||
|
"description": "__MSG_open_options__"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"permissions": [
|
||||||
|
"<all_urls>",
|
||||||
|
"storage",
|
||||||
|
"menus",
|
||||||
|
"messagesModify",
|
||||||
|
"scripting",
|
||||||
|
"declarativeNetRequest"
|
||||||
|
],
|
||||||
|
"icons": {
|
||||||
|
"16": "images/logo16.png",
|
||||||
|
"32": "images/logo32.png",
|
||||||
|
"48": "images/logo48.png",
|
||||||
|
"128": "images/logo128.png"
|
||||||
|
},
|
||||||
|
"browser_action": {
|
||||||
|
"default_icon": {
|
||||||
|
"128": "images/logo128.png"
|
||||||
|
},
|
||||||
|
"default_title": "__MSG_app_name__",
|
||||||
|
"default_popup": "popup.html"
|
||||||
|
},
|
||||||
|
"options_ui": {
|
||||||
|
"page": "options.html",
|
||||||
|
"open_in_tab": true
|
||||||
|
}
|
||||||
|
}
|
||||||
254
src/background.thunderbird.js
Normal file
254
src/background.thunderbird.js
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
import browser from "webextension-polyfill";
|
||||||
|
import {
|
||||||
|
MSG_FETCH,
|
||||||
|
MSG_GET_HTTPCACHE,
|
||||||
|
MSG_TRANS_TOGGLE,
|
||||||
|
MSG_OPEN_OPTIONS,
|
||||||
|
MSG_SAVE_RULE,
|
||||||
|
MSG_TRANS_TOGGLE_STYLE,
|
||||||
|
MSG_OPEN_TRANBOX,
|
||||||
|
MSG_CONTEXT_MENUS,
|
||||||
|
MSG_COMMAND_SHORTCUTS,
|
||||||
|
MSG_INJECT_JS,
|
||||||
|
MSG_INJECT_CSS,
|
||||||
|
MSG_UPDATE_CSP,
|
||||||
|
DEFAULT_CSPLIST,
|
||||||
|
CMD_TOGGLE_TRANSLATE,
|
||||||
|
CMD_TOGGLE_STYLE,
|
||||||
|
CMD_OPEN_OPTIONS,
|
||||||
|
CMD_OPEN_TRANBOX,
|
||||||
|
} from "./config";
|
||||||
|
import { getSettingWithDefault, tryInitDefaultData } from "./libs/storage";
|
||||||
|
import { trySyncSettingAndRules } from "./libs/sync";
|
||||||
|
import { fetchHandle, getHttpCache } from "./libs/fetch";
|
||||||
|
import { sendTabMsg } from "./libs/msg";
|
||||||
|
import { trySyncAllSubRules } from "./libs/subRules";
|
||||||
|
import { tryClearCaches } from "./libs";
|
||||||
|
import { saveRule } from "./libs/rules";
|
||||||
|
import { getCurTabId } from "./libs/msg";
|
||||||
|
import { injectInlineJs, injectInternalCss } from "./libs/injector";
|
||||||
|
import { kissLog } from "./libs/log";
|
||||||
|
|
||||||
|
globalThis.ContextType = "BACKGROUND";
|
||||||
|
|
||||||
|
const REMOVE_HEADERS = [
|
||||||
|
`content-security-policy`,
|
||||||
|
`content-security-policy-report-only`,
|
||||||
|
`x-webkit-csp`,
|
||||||
|
`x-content-security-policy`,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加右键菜单
|
||||||
|
*/
|
||||||
|
async function addmenus(contextMenuType = 1) {
|
||||||
|
// 添加前先删除,避免重复ID的错误
|
||||||
|
try {
|
||||||
|
await browser.menus.removeAll();
|
||||||
|
} catch (err) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (contextMenuType) {
|
||||||
|
case 1:
|
||||||
|
browser.menus.create({
|
||||||
|
id: CMD_TOGGLE_TRANSLATE,
|
||||||
|
title: browser.i18n.getMessage("app_name"),
|
||||||
|
contexts: ["page", "selection"],
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
browser.menus.create({
|
||||||
|
id: CMD_TOGGLE_TRANSLATE,
|
||||||
|
title: browser.i18n.getMessage("toggle_translate"),
|
||||||
|
contexts: ["page", "selection"],
|
||||||
|
});
|
||||||
|
browser.menus.create({
|
||||||
|
id: CMD_TOGGLE_STYLE,
|
||||||
|
title: browser.i18n.getMessage("toggle_style"),
|
||||||
|
contexts: ["page", "selection"],
|
||||||
|
});
|
||||||
|
browser.menus.create({
|
||||||
|
id: CMD_OPEN_TRANBOX,
|
||||||
|
title: browser.i18n.getMessage("open_tranbox"),
|
||||||
|
contexts: ["page", "selection"],
|
||||||
|
});
|
||||||
|
browser.menus.create({
|
||||||
|
id: "options_separator",
|
||||||
|
type: "separator",
|
||||||
|
contexts: ["page", "selection"],
|
||||||
|
});
|
||||||
|
browser.menus.create({
|
||||||
|
id: CMD_OPEN_OPTIONS,
|
||||||
|
title: browser.i18n.getMessage("open_options"),
|
||||||
|
contexts: ["page", "selection"],
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新CSP策略
|
||||||
|
* @param {*} csplist
|
||||||
|
*/
|
||||||
|
async function updateCspRules(csplist = DEFAULT_CSPLIST.join(",\n")) {
|
||||||
|
try {
|
||||||
|
const newRules = csplist
|
||||||
|
.split(/\n|,/)
|
||||||
|
.map((url) => url.trim())
|
||||||
|
.filter(Boolean)
|
||||||
|
.map((url, idx) => ({
|
||||||
|
id: idx + 1,
|
||||||
|
action: {
|
||||||
|
type: "modifyHeaders",
|
||||||
|
responseHeaders: REMOVE_HEADERS.map((header) => ({
|
||||||
|
operation: "remove",
|
||||||
|
header,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
condition: {
|
||||||
|
urlFilter: url,
|
||||||
|
resourceTypes: ["main_frame", "sub_frame"],
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
const oldRules = await browser.declarativeNetRequest.getDynamicRules();
|
||||||
|
const oldRuleIds = oldRules.map((rule) => rule.id);
|
||||||
|
await browser.declarativeNetRequest.updateDynamicRules({
|
||||||
|
removeRuleIds: oldRuleIds,
|
||||||
|
addRules: newRules,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
kissLog(err, "update csp rules");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 插件安装
|
||||||
|
*/
|
||||||
|
browser.runtime.onInstalled.addListener(() => {
|
||||||
|
tryInitDefaultData();
|
||||||
|
|
||||||
|
// 右键菜单
|
||||||
|
addmenus();
|
||||||
|
|
||||||
|
// 禁用CSP
|
||||||
|
updateCspRules();
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 浏览器启动
|
||||||
|
*/
|
||||||
|
browser.runtime.onStartup.addListener(async () => {
|
||||||
|
// 同步数据
|
||||||
|
await trySyncSettingAndRules();
|
||||||
|
|
||||||
|
const { clearCache, contextMenuType, subrulesList, csplist } =
|
||||||
|
await getSettingWithDefault();
|
||||||
|
|
||||||
|
// 清除缓存
|
||||||
|
if (clearCache) {
|
||||||
|
tryClearCaches();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 右键菜单
|
||||||
|
// firefox重启后菜单会消失,故重复添加
|
||||||
|
addmenus(contextMenuType);
|
||||||
|
|
||||||
|
// 禁用CSP
|
||||||
|
updateCspRules(csplist);
|
||||||
|
|
||||||
|
// 同步订阅规则
|
||||||
|
trySyncAllSubRules({ subrulesList });
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听消息
|
||||||
|
*/
|
||||||
|
browser.runtime.onMessage.addListener(async ({ action, args }) => {
|
||||||
|
switch (action) {
|
||||||
|
case MSG_FETCH:
|
||||||
|
return await fetchHandle(args);
|
||||||
|
case MSG_GET_HTTPCACHE:
|
||||||
|
const { input, init } = args;
|
||||||
|
return await getHttpCache(input, init);
|
||||||
|
case MSG_OPEN_OPTIONS:
|
||||||
|
return await browser.runtime.openOptionsPage();
|
||||||
|
case MSG_SAVE_RULE:
|
||||||
|
return await saveRule(args);
|
||||||
|
case MSG_INJECT_JS:
|
||||||
|
return await browser.scripting.executeScript({
|
||||||
|
target: { tabId: await getCurTabId(), allFrames: true },
|
||||||
|
func: injectInlineJs,
|
||||||
|
args: [args],
|
||||||
|
world: "MAIN",
|
||||||
|
});
|
||||||
|
case MSG_INJECT_CSS:
|
||||||
|
return await browser.scripting.executeScript({
|
||||||
|
target: { tabId: await getCurTabId(), allFrames: true },
|
||||||
|
func: injectInternalCss,
|
||||||
|
args: [args],
|
||||||
|
world: "MAIN",
|
||||||
|
});
|
||||||
|
case MSG_UPDATE_CSP:
|
||||||
|
return await updateCspRules(args);
|
||||||
|
case MSG_CONTEXT_MENUS:
|
||||||
|
return await addmenus(args);
|
||||||
|
case MSG_COMMAND_SHORTCUTS:
|
||||||
|
return await browser.commands.getAll();
|
||||||
|
default:
|
||||||
|
throw new Error(`message action is unavailable: ${action}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听快捷键
|
||||||
|
*/
|
||||||
|
browser.commands.onCommand.addListener((command) => {
|
||||||
|
// console.log(`Command: ${command}`);
|
||||||
|
switch (command) {
|
||||||
|
case CMD_TOGGLE_TRANSLATE:
|
||||||
|
sendTabMsg(MSG_TRANS_TOGGLE);
|
||||||
|
break;
|
||||||
|
case CMD_OPEN_TRANBOX:
|
||||||
|
sendTabMsg(MSG_OPEN_TRANBOX);
|
||||||
|
break;
|
||||||
|
case CMD_TOGGLE_STYLE:
|
||||||
|
sendTabMsg(MSG_TRANS_TOGGLE_STYLE);
|
||||||
|
break;
|
||||||
|
case CMD_OPEN_OPTIONS:
|
||||||
|
browser.runtime.openOptionsPage();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听右键菜单
|
||||||
|
*/
|
||||||
|
browser.menus.onClicked.addListener(({ menuItemId }) => {
|
||||||
|
switch (menuItemId) {
|
||||||
|
case CMD_TOGGLE_TRANSLATE:
|
||||||
|
sendTabMsg(MSG_TRANS_TOGGLE);
|
||||||
|
break;
|
||||||
|
case CMD_TOGGLE_STYLE:
|
||||||
|
sendTabMsg(MSG_TRANS_TOGGLE_STYLE);
|
||||||
|
break;
|
||||||
|
case CMD_OPEN_TRANBOX:
|
||||||
|
sendTabMsg(MSG_OPEN_TRANBOX);
|
||||||
|
break;
|
||||||
|
case CMD_OPEN_OPTIONS:
|
||||||
|
browser.runtime.openOptionsPage();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/**
|
||||||
|
* 邮件显示中注册脚本
|
||||||
|
*/
|
||||||
|
async function registerMsgDisplayScript() {
|
||||||
|
await messenger.messageDisplayScripts.register({
|
||||||
|
js: [{file: "/content.js"}]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
registerMsgDisplayScript();
|
||||||
Reference in New Issue
Block a user