From e89da9120c5766620d91bce150a92a80630f70bd Mon Sep 17 00:00:00 2001 From: Gabe Yuan Date: Mon, 23 Oct 2023 13:35:57 +0800 Subject: [PATCH] add common.js --- src/common.js | 95 +++++++++++++++++++++++ src/content.js | 129 +++++++++---------------------- src/libs/webfix.js | 3 +- src/userscript.js | 185 +++++++++++++++------------------------------ 4 files changed, 194 insertions(+), 218 deletions(-) create mode 100644 src/common.js diff --git a/src/common.js b/src/common.js new file mode 100644 index 0000000..a35cada --- /dev/null +++ b/src/common.js @@ -0,0 +1,95 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import Action from "./views/Action"; +import createCache from "@emotion/cache"; +import { CacheProvider } from "@emotion/react"; +import { + MSG_TRANS_TOGGLE, + MSG_TRANS_TOGGLE_STYLE, + MSG_TRANS_GETRULE, + MSG_TRANS_PUTRULE, + APP_LCNAME, +} from "./config"; +import { getRulesWithDefault, getFabWithDefault } from "./libs/storage"; +import { Translator } from "./libs/translator"; +import { sendIframeMsg, sendParentMsg } from "./libs/iframe"; +import { matchRule } from "./libs/rules"; + +export async function runTranslator(setting) { + const href = document.location.href; + const rules = await getRulesWithDefault(); + const rule = await matchRule(rules, href, setting); + const translator = new Translator(rule, setting); + + return { translator, rule }; +} + +export function runIframe(setting) { + let translator; + window.addEventListener("message", (e) => { + const { action, args } = e.data || {}; + switch (action) { + case MSG_TRANS_TOGGLE: + translator?.toggle(); + break; + case MSG_TRANS_TOGGLE_STYLE: + translator?.toggleStyle(); + break; + case MSG_TRANS_PUTRULE: + if (!translator) { + translator = new Translator(args, setting); + } else { + translator.updateRule(args || {}); + } + break; + default: + } + }); + sendParentMsg(MSG_TRANS_GETRULE); +} + +export async function showFab(translator) { + const fab = await getFabWithDefault(); + if (!fab.isHide) { + const $action = document.createElement("div"); + $action.setAttribute("id", APP_LCNAME); + document.body.parentElement.appendChild($action); + const shadowContainer = $action.attachShadow({ mode: "closed" }); + const emotionRoot = document.createElement("style"); + const shadowRootElement = document.createElement("div"); + shadowContainer.appendChild(emotionRoot); + shadowContainer.appendChild(shadowRootElement); + const cache = createCache({ + key: APP_LCNAME, + prepend: true, + container: emotionRoot, + }); + ReactDOM.createRoot(shadowRootElement).render( + + + + + + ); + } +} + +export function windowListener(rule) { + window.addEventListener("message", (e) => { + const { action } = e.data || {}; + switch (action) { + case MSG_TRANS_GETRULE: + sendIframeMsg(MSG_TRANS_PUTRULE, rule); + break; + default: + } + }); +} + +export function showErr(err) { + console.error("[KISS-Translator]", err); + const $err = document.createElement("div"); + $err.innerText = `KISS-Translator: ${err.message}`; + $err.style.cssText = "background:red; color:#fff;"; + document.body.prepend($err); +} diff --git a/src/content.js b/src/content.js index 63e4334..50518ab 100644 --- a/src/content.js +++ b/src/content.js @@ -1,64 +1,22 @@ import { browser } from "./libs/browser"; -import React from "react"; -import ReactDOM from "react-dom/client"; -import Action from "./views/Action"; -import createCache from "@emotion/cache"; -import { CacheProvider } from "@emotion/react"; import { MSG_TRANS_TOGGLE, MSG_TRANS_TOGGLE_STYLE, MSG_TRANS_GETRULE, MSG_TRANS_PUTRULE, - APP_LCNAME, } from "./config"; +import { getSettingWithDefault } from "./libs/storage"; +import { isIframe, sendIframeMsg } from "./libs/iframe"; +import { runWebfix } from "./libs/webfix"; import { - getSettingWithDefault, - getRulesWithDefault, - getFabWithDefault, -} from "./libs/storage"; -import { Translator } from "./libs/translator"; -import { isIframe, sendIframeMsg, sendParentMsg } from "./libs/iframe"; -import { matchRule } from "./libs/rules"; -import { webfix } from "./libs/webfix"; + runIframe, + runTranslator, + showFab, + windowListener, + showErr, +} from "./common"; -/** - * 入口函数 - */ -const init = async () => { - const setting = await getSettingWithDefault(); - - if (isIframe) { - let translator; - window.addEventListener("message", (e) => { - const { action, args } = e.data || {}; - switch (action) { - case MSG_TRANS_TOGGLE: - translator?.toggle(); - break; - case MSG_TRANS_TOGGLE_STYLE: - translator?.toggleStyle(); - break; - case MSG_TRANS_PUTRULE: - if (!translator) { - translator = new Translator(args, setting); - } else { - translator.updateRule(args || {}); - } - break; - default: - } - }); - sendParentMsg(MSG_TRANS_GETRULE); - return; - } - - const href = document.location.href; - const rules = await getRulesWithDefault(); - const rule = await matchRule(rules, href, setting); - const translator = new Translator(rule, setting); - webfix(href, setting); - - // 监听消息 +function runtimeListener(translator) { browser?.runtime.onMessage.addListener(async ({ action, args }) => { switch (action) { case MSG_TRANS_TOGGLE: @@ -80,50 +38,35 @@ const init = async () => { } return { data: translator.rule }; }); - window.addEventListener("message", (e) => { - const { action } = e.data || {}; - switch (action) { - case MSG_TRANS_GETRULE: - sendIframeMsg(MSG_TRANS_PUTRULE, rule); - break; - default: - } - }); - - // 浮球按钮 - const fab = await getFabWithDefault(); - if (!fab.isHide) { - const $action = document.createElement("div"); - $action.setAttribute("id", APP_LCNAME); - document.body.parentElement.appendChild($action); - const shadowContainer = $action.attachShadow({ mode: "closed" }); - const emotionRoot = document.createElement("style"); - const shadowRootElement = document.createElement("div"); - shadowContainer.appendChild(emotionRoot); - shadowContainer.appendChild(shadowRootElement); - const cache = createCache({ - key: APP_LCNAME, - prepend: true, - container: emotionRoot, - }); - ReactDOM.createRoot(shadowRootElement).render( - - - - - - ); - } -}; +} +/** + * 入口函数 + */ (async () => { try { - await init(); + // 读取设置信息 + const setting = await getSettingWithDefault(); + + // 适配iframe + if (isIframe) { + runIframe(setting); + return; + } + + // 不规范网页修复 + await runWebfix(setting); + + // 翻译网页 + const { translator, rule } = await runTranslator(setting); + + // 监听消息 + windowListener(rule); + runtimeListener(translator); + + // 浮球按钮 + await showFab(translator); } catch (err) { - console.error("[KISS-Translator]", err); - const $err = document.createElement("div"); - $err.innerText = `KISS-Translator: ${err.message}`; - $err.style.cssText = "background:red; color:#fff;"; - document.body.prepend($err); + showErr(err); } })(); diff --git a/src/libs/webfix.js b/src/libs/webfix.js index d7c2858..6168770 100644 --- a/src/libs/webfix.js +++ b/src/libs/webfix.js @@ -199,12 +199,13 @@ export const loadOrFetchWebfix = async (url) => { /** * 匹配站点 */ -export async function webfix(href, { injectWebfix }) { +export async function runWebfix({ injectWebfix }) { try { if (!injectWebfix) { return; } + const href = document.location.href; const sites = await loadOrFetchWebfix(process.env.REACT_APP_WEBFIXURL); for (var i = 0; i < sites.length; i++) { var site = sites[i]; diff --git a/src/userscript.js b/src/userscript.js index d0794a9..e3fe7ee 100644 --- a/src/userscript.js +++ b/src/userscript.js @@ -1,136 +1,73 @@ -import React from "react"; -import ReactDOM from "react-dom/client"; -import Action from "./views/Action"; -import createCache from "@emotion/cache"; -import { CacheProvider } from "@emotion/react"; -import { - getSettingWithDefault, - getRulesWithDefault, - getFabWithDefault, -} from "./libs/storage"; -import { Translator } from "./libs/translator"; +import { getSettingWithDefault } from "./libs/storage"; import { trySyncAllSubRules } from "./libs/subRules"; -import { - MSG_TRANS_TOGGLE, - MSG_TRANS_TOGGLE_STYLE, - MSG_TRANS_GETRULE, - MSG_TRANS_PUTRULE, - APP_LCNAME, -} from "./config"; -import { isIframe, sendIframeMsg, sendParentMsg } from "./libs/iframe"; +import { isIframe } from "./libs/iframe"; import { handlePing, injectScript } from "./libs/gm"; -import { matchRule } from "./libs/rules"; import { genEventName } from "./libs/utils"; -import { webfix } from "./libs/webfix"; +import { runWebfix } from "./libs/webfix"; +import { + runIframe, + runTranslator, + showFab, + windowListener, + showErr, +} from "./common"; + +function runSettingPage() { + if (GM?.info?.script?.grant?.includes("unsafeWindow")) { + unsafeWindow.GM = GM; + unsafeWindow.APP_INFO = { + name: process.env.REACT_APP_NAME, + version: process.env.REACT_APP_VERSION, + }; + } else { + const ping = genEventName(); + window.addEventListener(ping, handlePing); + // window.eval(`(${injectScript})("${ping}")`); // eslint-disable-line + const script = document.createElement("script"); + script.textContent = `(${injectScript})("${ping}")`; + document.head.append(script); + } +} /** * 入口函数 */ -const init = async () => { - // 设置页面 - if ( - document.location.href.includes(process.env.REACT_APP_OPTIONSPAGE_DEV) || - document.location.href.includes(process.env.REACT_APP_OPTIONSPAGE) || - document.location.href.includes(process.env.REACT_APP_OPTIONSPAGE2) - ) { - if (GM?.info?.script?.grant?.includes("unsafeWindow")) { - unsafeWindow.GM = GM; - unsafeWindow.APP_INFO = { - name: process.env.REACT_APP_NAME, - version: process.env.REACT_APP_VERSION, - }; - } else { - const ping = genEventName(); - window.addEventListener(ping, handlePing); - // window.eval(`(${injectScript})("${ping}")`); // eslint-disable-line - const script = document.createElement("script"); - script.textContent = `(${injectScript})("${ping}")`; - document.head.append(script); - } - - return; - } - - // 翻译页面 - const setting = await getSettingWithDefault(); - - if (isIframe) { - let translator; - window.addEventListener("message", (e) => { - const { action, args } = e.data || {}; - switch (action) { - case MSG_TRANS_TOGGLE: - translator?.toggle(); - break; - case MSG_TRANS_TOGGLE_STYLE: - translator?.toggleStyle(); - break; - case MSG_TRANS_PUTRULE: - if (!translator) { - translator = new Translator(args, setting); - } else { - translator.updateRule(args || {}); - } - break; - default: - } - }); - sendParentMsg(MSG_TRANS_GETRULE); - return; - } - - const href = isIframe ? document.referrer : document.location.href; - const rules = await getRulesWithDefault(); - const rule = await matchRule(rules, href, setting); - const translator = new Translator(rule, setting); - webfix(href, setting); - - // 监听消息 - window.addEventListener("message", (e) => { - const { action } = e.data || {}; - switch (action) { - case MSG_TRANS_GETRULE: - sendIframeMsg(MSG_TRANS_PUTRULE, rule); - break; - default: - } - }); - - // 浮球按钮 - const fab = await getFabWithDefault(); - const $action = document.createElement("div"); - $action.setAttribute("id", APP_LCNAME); - document.body.parentElement.appendChild($action); - const shadowContainer = $action.attachShadow({ mode: "closed" }); - const emotionRoot = document.createElement("style"); - const shadowRootElement = document.createElement("div"); - shadowContainer.appendChild(emotionRoot); - shadowContainer.appendChild(shadowRootElement); - const cache = createCache({ - key: APP_LCNAME, - prepend: true, - container: emotionRoot, - }); - ReactDOM.createRoot(shadowRootElement).render( - - - - - - ); - - // 同步订阅规则 - trySyncAllSubRules(setting); -}; - (async () => { try { - await init(); + // 设置页面 + if ( + document.location.href.includes(process.env.REACT_APP_OPTIONSPAGE_DEV) || + document.location.href.includes(process.env.REACT_APP_OPTIONSPAGE) || + document.location.href.includes(process.env.REACT_APP_OPTIONSPAGE2) + ) { + runSettingPage(); + return; + } + + // 读取设置信息 + const setting = await getSettingWithDefault(); + + // 适配iframe + if (isIframe) { + runIframe(setting); + return; + } + + // 不规范网页修复 + await runWebfix(setting); + + // 翻译网页 + const { translator, rule } = await runTranslator(setting); + + // 监听消息 + windowListener(rule); + + // 浮球按钮 + await showFab(translator); + + // 同步订阅规则 + await trySyncAllSubRules(setting); } catch (err) { - console.error("[KISS-Translator]", err); - const $err = document.createElement("div"); - $err.innerText = `KISS-Translator: ${err.message}`; - $err.style.cssText = "background:red; color:#fff;"; - document.body.prepend($err); + showErr(err); } })();