From 9bfb5043811e2c3eefd223991ac8ae7040f305fb Mon Sep 17 00:00:00 2001 From: htyxyt <62530172+htyxyt@users.noreply.github.com> Date: Fri, 14 Feb 2025 15:13:40 +0800 Subject: [PATCH] Add files via upload --- public/background.thunderbird.js | 254 +++++++++++++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 public/background.thunderbird.js diff --git a/public/background.thunderbird.js b/public/background.thunderbird.js new file mode 100644 index 0000000..7b8e29c --- /dev/null +++ b/public/background.thunderbird.js @@ -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(); \ No newline at end of file