diff --git a/.env b/.env index 266b85f..277175f 100644 --- a/.env +++ b/.env @@ -17,8 +17,6 @@ REACT_APP_RULESURL=https://fishjar.github.io/kiss-rules/kiss-rules.json REACT_APP_RULESURL_ON=https://fishjar.github.io/kiss-rules/kiss-rules-on.json REACT_APP_RULESURL_OFF=https://fishjar.github.io/kiss-rules/kiss-rules-off.json -REACT_APP_WEBFIXURL=https://fishjar.github.io/kiss-rules/kiss-webfix.json - REACT_APP_VERSIONFILE=https://fishjar.github.io/kiss-translator/version.txt REACT_APP_VERSIONFILE2=https://kiss-translator.rayjar.com/version.txt diff --git a/README.en.md b/README.en.md index 3f75b31..a0d0f71 100644 --- a/README.en.md +++ b/README.en.md @@ -62,9 +62,6 @@ A simple, open source [bilingual translation extension & Greasemonkey script](ht - Community subscription rules: [https://github.com/fishjar/kiss-rules](https://github.com/fishjar/kiss-rules) - Provides the latest and most complete list of subscription rules maintained by the community. - Help with rules-related issues. -- Web page correction script: [https://github.com/fishjar/kiss-webfixer](https://github.com/fishjar/kiss-webfixer) - - Fixed scripts for some special sites. - - So that the translation software can get better display effect. - Translation interface agent: [https://github.com/fishjar/kiss-proxy](https://github.com/fishjar/kiss-proxy) - If you encounter network problems when accessing a certain translation interface, this proxy service may help you. - Deploy and manage by yourself. diff --git a/README.md b/README.md index 79cb46c..9f4c28e 100644 --- a/README.md +++ b/README.md @@ -62,9 +62,6 @@ - 社区订阅规则: [https://github.com/fishjar/kiss-rules](https://github.com/fishjar/kiss-rules) - 提供社区维护的,最新最全的订阅规则列表。 - 求助规则相关的问题。 -- 网页修正脚本: [https://github.com/fishjar/kiss-webfixer](https://github.com/fishjar/kiss-webfixer) - - 针对一些特殊网站的修正脚本。 - - 以便翻译软件得到更好的展示效果。 - 翻译接口代理: [https://github.com/fishjar/kiss-proxy](https://github.com/fishjar/kiss-proxy) - 如果访问某个翻译接口遇到网络问题,这个代理服务也许可以帮到你。 - 自己部署,自己管理。 diff --git a/src/common.js b/src/common.js index 34b6b85..28d795f 100644 --- a/src/common.js +++ b/src/common.js @@ -20,7 +20,6 @@ import { touchTapListener } from "./libs/touch"; import { debounce, genEventName } from "./libs/utils"; import { handlePing, injectScript } from "./libs/gm"; import { browser } from "./libs/browser"; -import { matchFixer } from "./libs/webfix"; import { matchRule } from "./libs/rules"; import { trySyncAllSubRules } from "./libs/subRules"; import { isInBlacklist } from "./libs/blacklist"; @@ -223,12 +222,9 @@ export async function run(isUserscript = false) { return; } - // 不规范网页修复 - const fixerSetting = await matchFixer(href, setting); - // 翻译网页 const rule = await matchRule(href, setting); - const translator = new Translator(rule, setting, fixerSetting); + const translator = new Translator(rule, setting); // 适配iframe if (isIframe) { diff --git a/src/config/i18n.js b/src/config/i18n.js index 8704d66..5ed7ab9 100644 --- a/src/config/i18n.js +++ b/src/config/i18n.js @@ -187,7 +187,7 @@ export const I18N = { zh: `翻译时机`, en: `Translate Timing`, }, - mk_disable: { + mk_pagescroll: { zh: `滚动加载翻译(推荐)`, en: `Rolling Loading (Suggested)`, }, @@ -408,11 +408,11 @@ export const I18N = { en: `0. Supports regular expression matching. 1. Separate multiple terms with newlines or semicolons ";". 2. Terms and translations are separated by English commas ",". 3. If there is no translation, the term will be deemed not to be translated. 4. Leave blank to adopt the global setting.`, }, selector_style: { - zh: `选择器样式`, + zh: `选择器节点样式`, en: `Selector Style`, }, selector_parent_style: { - zh: `选择器父样式`, + zh: `选择器父节点样式`, en: `Selector Parent Style`, }, inject_js: { @@ -787,4 +787,8 @@ export const I18N = { zh: `更多`, en: `More`, }, + fixer_selector: { + zh: `修复函数选择器`, + en: `Fixer Selector`, + }, }; diff --git a/src/config/index.js b/src/config/index.js index 3c478c6..aa5bfb6 100644 --- a/src/config/index.js +++ b/src/config/index.js @@ -24,12 +24,10 @@ export const STOKEY_MSAUTH = `${APP_NAME}_msauth`; export const STOKEY_BDAUTH = `${APP_NAME}_bdauth`; export const STOKEY_SETTING = `${APP_NAME}_setting`; export const STOKEY_RULES = `${APP_NAME}_rules`; -export const STOKEY_WFRULES = `${APP_NAME}_webfix_rules`; export const STOKEY_WORDS = `${APP_NAME}_words`; export const STOKEY_SYNC = `${APP_NAME}_sync`; export const STOKEY_FAB = `${APP_NAME}_fab`; export const STOKEY_RULESCACHE_PREFIX = `${APP_NAME}_rulescache_`; -export const STOKEY_WEBFIXCACHE_PREFIX = `${APP_NAME}_webfixcache_`; export const CMD_TOGGLE_TRANSLATE = "toggleTranslate"; export const CMD_TOGGLE_STYLE = "toggleStyle"; @@ -44,7 +42,6 @@ export const CLIENT_USERSCRIPT = "userscript"; export const CLIENT_EXTS = [CLIENT_CHROME, CLIENT_EDGE, CLIENT_FIREFOX]; export const KV_RULES_KEY = "kiss-rules.json"; -export const KV_WFRULES_KEY = "kiss-webfix.json"; export const KV_WORDS_KEY = "kiss-words.json"; export const KV_RULES_SHARE_KEY = "kiss-rules-share.json"; export const KV_SETTING_KEY = "kiss-setting.json"; @@ -300,19 +297,19 @@ export const OPT_STYLE_USE_COLOR = [ OPT_STYLE_BLOCKQUOTE, ]; -export const OPT_MOUSEKEY_DISABLE = "mk_disable"; // 滚动加载翻译 -export const OPT_MOUSEKEY_PAGEOPEN = "mk_pageopen"; // 直接翻译到底 -export const OPT_MOUSEKEY_MOUSEOVER = "mk_mouseover"; -export const OPT_MOUSEKEY_CONTROL = "mk_ctrlKey"; -export const OPT_MOUSEKEY_SHIFT = "mk_shiftKey"; -export const OPT_MOUSEKEY_ALT = "mk_altKey"; -export const OPT_MOUSEKEY_ALL = [ - OPT_MOUSEKEY_DISABLE, - OPT_MOUSEKEY_PAGEOPEN, - OPT_MOUSEKEY_MOUSEOVER, - OPT_MOUSEKEY_CONTROL, - OPT_MOUSEKEY_SHIFT, - OPT_MOUSEKEY_ALT, +export const OPT_TIMING_PAGESCROLL = "mk_pagescroll"; // 滚动加载翻译 +export const OPT_TIMING_PAGEOPEN = "mk_pageopen"; // 直接翻译到底 +export const OPT_TIMING_MOUSEOVER = "mk_mouseover"; +export const OPT_TIMING_CONTROL = "mk_ctrlKey"; +export const OPT_TIMING_SHIFT = "mk_shiftKey"; +export const OPT_TIMING_ALT = "mk_altKey"; +export const OPT_TIMING_ALL = [ + OPT_TIMING_PAGESCROLL, + OPT_TIMING_PAGEOPEN, + OPT_TIMING_MOUSEOVER, + OPT_TIMING_CONTROL, + OPT_TIMING_SHIFT, + OPT_TIMING_ALT, ]; export const DEFAULT_FETCH_LIMIT = 10; // 默认最大任务数量 @@ -325,24 +322,34 @@ export const PROMPT_PLACE_TEXT = "{{text}}"; // 占位符 export const DEFAULT_COLOR = "#209CEE"; // 默认高亮背景色/线条颜色 export const DEFAULT_TRANS_TAG = "font"; +export const DEFAULT_SELECT_STYLE = + "-webkit-line-clamp: unset; max-height: none; height: auto;"; // 全局规则 export const GLOBLA_RULE = { - pattern: "*", - selector: DEFAULT_SELECTOR, - keepSelector: DEFAULT_KEEP_SELECTOR, - terms: "", - translator: OPT_TRANS_MICROSOFT, - fromLang: "auto", - toLang: "zh-CN", - textStyle: OPT_STYLE_DASHLINE, - transOpen: "false", - bgColor: "", - textDiyStyle: "", - selectStyle: "-webkit-line-clamp: unset; max-height: none; height: auto;", - parentStyle: "-webkit-line-clamp: unset; max-height: none; height: auto;", - injectJs: "", - injectCss: "", + pattern: "*", // 匹配网址 + selector: DEFAULT_SELECTOR, // 选择器 + keepSelector: DEFAULT_KEEP_SELECTOR, // 保留元素选择器 + terms: "", // 专业术语 + translator: OPT_TRANS_MICROSOFT, // 翻译服务 + fromLang: "auto", // 源语言 + toLang: "zh-CN", // 目标语言 + textStyle: OPT_STYLE_DASHLINE, // 译文样式 + transOpen: "false", // 开启翻译 + bgColor: "", // 译文颜色 + textDiyStyle: "", // 自定义译文样式 + selectStyle: DEFAULT_SELECT_STYLE, // 选择器节点样式 + parentStyle: DEFAULT_SELECT_STYLE, // 选择器父节点样式 + injectJs: "", // 注入JS + injectCss: "", // 注入CSS + transOnly: "false", // 是否仅显示译文 + transTiming: OPT_TIMING_PAGESCROLL, // 翻译时机/鼠标悬停翻译 + transTag: DEFAULT_TRANS_TAG, // 译文元素标签 + transTitle: "false", // 是否同时翻译页面标题 + detectRemote: "false", // 是否使用远程语言检测 + skipLangs: [], // 不翻译的语言 + fixerSelector: "", // 修复函数选择器 + fixerFunc: "-", // 修复函数 }; // 输入框翻译 @@ -458,23 +465,24 @@ export const DEFAULT_SETTING = { newlineLength: TRANS_NEWLINE_LENGTH, clearCache: false, // 是否在浏览器下次启动时清除缓存 injectRules: true, // 是否注入订阅规则 - injectWebfix: true, // 是否注入修复补丁 - detectRemote: false, // 是否使用远程语言检测 - contextMenus: true, // 是否添加右键菜单(作废) + // injectWebfix: true, // 是否注入修复补丁(作废) + // detectRemote: false, // 是否使用远程语言检测(移至rule,作废) + // contextMenus: true, // 是否添加右键菜单(作废) contextMenuType: 1, // 右键菜单类型(0不显示,1简单菜单,2多级菜单) - transTag: DEFAULT_TRANS_TAG, // 译文元素标签 - transOnly: false, // 是否仅显示译文 - transTitle: false, // 是否同时翻译页面标题 + // transTag: DEFAULT_TRANS_TAG, // 译文元素标签(移至rule,作废) + // transOnly: false, // 是否仅显示译文(移至rule,作废) + // transTitle: false, // 是否同时翻译页面标题(移至rule,作废) subrulesList: DEFAULT_SUBRULES_LIST, // 订阅列表 owSubrule: DEFAULT_OW_RULE, // 覆写订阅规则 transApis: DEFAULT_TRANS_APIS, // 翻译接口 - mouseKey: OPT_MOUSEKEY_DISABLE, // 翻译时机/鼠标悬停翻译 + // mouseKey: OPT_TIMING_PAGESCROLL, // 翻译时机/鼠标悬停翻译(移至rule,作废) shortcuts: DEFAULT_SHORTCUTS, // 快捷键 inputRule: DEFAULT_INPUT_RULE, // 输入框设置 tranboxSetting: DEFAULT_TRANBOX_SETTING, // 划词翻译设置 touchTranslate: 2, // 触屏翻译 blacklist: DEFAULT_BLACKLIST.join(",\n"), // 禁用翻译名单 - disableLangs: [], // 不翻译的语言 + // disableLangs: [], // 不翻译的语言(移至rule,作废) + transInterval: 500, // 翻译间隔时间 }; export const DEFAULT_RULES = [GLOBLA_RULE]; diff --git a/src/config/rules.js b/src/config/rules.js index 8ca899d..ef08c89 100644 --- a/src/config/rules.js +++ b/src/config/rules.js @@ -7,21 +7,29 @@ export const REMAIN_KEY = "-"; export const SHADOW_KEY = ">>>"; export const DEFAULT_RULE = { - pattern: "", - selector: "", - keepSelector: "", - terms: "", - translator: GLOBAL_KEY, - fromLang: GLOBAL_KEY, - toLang: GLOBAL_KEY, - textStyle: GLOBAL_KEY, - transOpen: GLOBAL_KEY, - bgColor: "", - textDiyStyle: "", - selectStyle: "", - parentStyle: "", - injectJs: "", - injectCss: "", + pattern: "", // 匹配网址 + selector: "", // 选择器 + keepSelector: "", // 保留元素选择器 + terms: "", // 专业术语 + translator: GLOBAL_KEY, // 翻译服务 + fromLang: GLOBAL_KEY, // 源语言 + toLang: GLOBAL_KEY, // 目标语言 + textStyle: GLOBAL_KEY, // 译文样式 + transOpen: GLOBAL_KEY, // 开启翻译 + bgColor: "", // 译文颜色 + textDiyStyle: "", // 自定义译文样式 + selectStyle: "", // 选择器节点样式 + parentStyle: "", // 选择器父节点样式 + injectJs: "", // 注入JS + injectCss: "", // 注入CSS + transOnly: GLOBAL_KEY, // 是否仅显示译文 + transTiming: GLOBAL_KEY, // 翻译时机/鼠标悬停翻译 + transTag: GLOBAL_KEY, // 译文元素标签 + transTitle: GLOBAL_KEY, // 是否同时翻译页面标题 + detectRemote: GLOBAL_KEY, // 是否使用远程语言检测 + skipLangs: [], // 不翻译的语言 + fixerSelector: "", // 修复函数选择器 + fixerFunc: GLOBAL_KEY, // 修复函数 }; const DEFAULT_DIY_STYLE = `color: #666; @@ -251,9 +259,6 @@ const RULES_MAP = { "randomnerdtutorials.com": { selector: `article ${DEFAULT_SELECTOR}`, }, - "forum.arduino.cc": { - selector: `.top-row>.title, .featured-topic>.title, .link-top-line>.title, .category-description, .topic-excerpt, .fancy-title, .cooked ${DEFAULT_SELECTOR}`, - }, "notebooks.githubusercontent.com/view/ipynb": { selector: `#notebook-container ${DEFAULT_SELECTOR}`, keepSelector: `code, img, svg`, @@ -276,6 +281,8 @@ export const BUILTIN_RULES = Object.entries(RULES_MAP) selectStyle = "", parentStyle = "", injectCss = "", + fixerSelector = "", + fixerFunc = GLOBAL_KEY, }, ]) => ({ ...DEFAULT_RULE, @@ -286,5 +293,7 @@ export const BUILTIN_RULES = Object.entries(RULES_MAP) selectStyle, parentStyle, injectCss, + fixerSelector, + fixerFunc, }) ); diff --git a/src/hooks/Translate.js b/src/hooks/Translate.js index 5ef8c9f..f8a79ac 100644 --- a/src/hooks/Translate.js +++ b/src/hooks/Translate.js @@ -16,7 +16,7 @@ export function useTranslate(q, rule, setting) { const [loading, setLoading] = useState(false); const [sameLang, setSamelang] = useState(false); - const { translator, fromLang, toLang } = rule; + const { translator, fromLang, toLang, detectRemote, skipLangs = [] } = rule; useEffect(() => { (async () => { @@ -29,12 +29,8 @@ export function useTranslate(q, rule, setting) { return; } - const deLang = await tryDetectLang(q, setting.detectRemote); - const disableLangs = setting.disableLangs || []; - if ( - deLang && - (toLang.includes(deLang) || disableLangs.includes(deLang)) - ) { + const deLang = await tryDetectLang(q, detectRemote === "true"); + if (deLang && (toLang.includes(deLang) || skipLangs.includes(deLang))) { setSamelang(true); } else { const [trText, isSame] = await apiTranslate({ @@ -54,7 +50,7 @@ export function useTranslate(q, rule, setting) { setLoading(false); } })(); - }, [q, translator, fromLang, toLang, setting]); + }, [q, translator, fromLang, toLang, detectRemote, skipLangs, setting]); return { text, sameLang, loading }; } diff --git a/src/hooks/WebfixRules.js b/src/hooks/WebfixRules.js deleted file mode 100644 index cd91784..0000000 --- a/src/hooks/WebfixRules.js +++ /dev/null @@ -1,58 +0,0 @@ -import { STOKEY_WFRULES, KV_WFRULES_KEY } from "../config"; -import { useStorage } from "./Storage"; -import { trySyncWebfixRules } from "../libs/sync"; -import { useCallback } from "react"; -import { useSyncMeta } from "./Sync"; - -const DEFAULT_WFRULES = []; - -/** - * 修复规则 hook - * @returns - */ -export function useWebfixRules() { - const { data: list, save } = useStorage(STOKEY_WFRULES, DEFAULT_WFRULES); - const { updateSyncMeta } = useSyncMeta(); - - const updateRules = useCallback( - async (rules) => { - await save(rules); - await updateSyncMeta(KV_WFRULES_KEY); - trySyncWebfixRules(); - }, - [save, updateSyncMeta] - ); - - const add = useCallback( - async (rule) => { - const rules = [...list]; - if (rules.map((item) => item.pattern).includes(rule.pattern)) { - return; - } - rules.unshift(rule); - await updateRules(rules); - }, - [list, updateRules] - ); - - const del = useCallback( - async (pattern) => { - let rules = [...list]; - rules = rules.filter((item) => item.pattern !== pattern); - await updateRules(rules); - }, - [list, updateRules] - ); - - const put = useCallback( - async (pattern, obj) => { - const rules = [...list]; - const rule = rules.find((r) => r.pattern === pattern); - rule && Object.assign(rule, obj); - await updateRules(rules); - }, - [list, updateRules] - ); - - return { list, add, del, put }; -} diff --git a/src/libs/blacklist.js b/src/libs/blacklist.js index ae69da1..acafa54 100644 --- a/src/libs/blacklist.js +++ b/src/libs/blacklist.js @@ -1,5 +1,4 @@ import { isMatch } from "./utils"; -import { DEFAULT_BLACKLIST } from "../config"; /** * 检查是否在黑名单中 @@ -7,7 +6,5 @@ import { DEFAULT_BLACKLIST } from "../config"; * @param {*} param1 * @returns */ -export const isInBlacklist = ( - href, - { blacklist = DEFAULT_BLACKLIST.join(",\n") } -) => blacklist.split(/\n|,/).some((url) => isMatch(href, url.trim())); +export const isInBlacklist = (href, { blacklist }) => + blacklist.split(/\n|,/).some((url) => isMatch(href, url.trim())); diff --git a/src/libs/inputTranslate.js b/src/libs/inputTranslate.js index aaef6f7..44469ca 100644 --- a/src/libs/inputTranslate.js +++ b/src/libs/inputTranslate.js @@ -7,7 +7,6 @@ import { import { genEventName, removeEndchar, matchInputStr, sleep } from "./utils"; import { stepShortcutRegister } from "./shortcut"; import { apiTranslate } from "../apis"; -import { tryDetectLang } from "."; import { loadingSvg } from "./svg"; function isInputNode(node) { @@ -83,7 +82,7 @@ function removeLoading(node, loadingId) { /** * 输入框翻译 */ -export default function inputTranslate ({ +export default function inputTranslate({ inputRule: { transOpen, triggerShortcut, @@ -95,7 +94,6 @@ export default function inputTranslate ({ transSign, } = DEFAULT_INPUT_RULE, transApis, - detectRemote, }) { if (!transOpen) { return; @@ -156,11 +154,6 @@ export default function inputTranslate ({ try { addLoading(node, loadingId); - const deLang = await tryDetectLang(text, detectRemote); - if (deLang && toLang.includes(deLang)) { - return; - } - const [trText, isSame] = await apiTranslate({ translator, text, diff --git a/src/libs/rules.js b/src/libs/rules.js index ffaed13..065b4b8 100644 --- a/src/libs/rules.js +++ b/src/libs/rules.js @@ -6,13 +6,13 @@ import { OPT_STYLE_ALL, OPT_LANGS_FROM, OPT_LANGS_TO, + OPT_TIMING_ALL, GLOBLA_RULE, - DEFAULT_SUBRULES_LIST, - DEFAULT_OW_RULE, } from "../config"; import { loadOrFetchSubRules } from "./subRules"; import { getRulesWithDefault, setRules } from "./storage"; import { trySyncRules } from "./sync"; +import { FIXER_ALL } from "./webfix"; /** * 根据href匹配规则 @@ -22,11 +22,7 @@ import { trySyncRules } from "./sync"; */ export const matchRule = async ( href, - { - injectRules = true, - subrulesList = DEFAULT_SUBRULES_LIST, - owSubrule = DEFAULT_OW_RULE, - } + { injectRules, subrulesList, owSubrule } ) => { const rules = await getRulesWithDefault(); if (injectRules) { @@ -60,18 +56,49 @@ export const matchRule = async ( const rule = rules.find((r) => r.pattern.split(",").some((p) => isMatch(href, p.trim())) ); - const globalRule = rules.find((r) => r.pattern === GLOBAL_KEY) || GLOBLA_RULE; + const globalRule = { + ...GLOBLA_RULE, + ...(rules.find((r) => r.pattern === GLOBAL_KEY) || {}), + }; if (!rule) { return globalRule; } - rule.selector = rule.selector?.trim() || globalRule.selector; - rule.keepSelector = rule.keepSelector?.trim() || globalRule.keepSelector; - rule.terms = rule.terms?.trim() || globalRule.terms; - rule.selectStyle = rule.selectStyle?.trim() || globalRule.selectStyle; - rule.parentStyle = rule.parentStyle?.trim() || globalRule.parentStyle; - rule.injectJs = rule.injectJs?.trim() || globalRule.injectJs; - rule.injectCss = rule.injectCss?.trim() || globalRule.injectCss; + [ + "selector", + "keepSelector", + "terms", + "selectStyle", + "parentStyle", + "injectJs", + "injectCss", + "fixerSelector", + ].forEach((key) => { + if (!rule[key]?.trim()) { + rule[key] = globalRule[key]; + } + }); + + [ + "translator", + "fromLang", + "toLang", + "transOpen", + "transOnly", + "transTiming", + "transTag", + "transTitle", + "detectRemote", + "fixerFunc", + ].forEach((key) => { + if (rule[key] === undefined || rule[key] === GLOBAL_KEY) { + rule[key] = globalRule[key]; + } + }); + + if (!rule.skipLangs || rule.skipLangs.length === 0) { + rule.skipLangs = globalRule.skipLangs; + } if (rule.textStyle === GLOBAL_KEY) { rule.textStyle = globalRule.textStyle; rule.bgColor = globalRule.bgColor; @@ -80,11 +107,6 @@ export const matchRule = async ( rule.bgColor = rule.bgColor?.trim() || globalRule.bgColor; rule.textDiyStyle = rule.textDiyStyle?.trim() || globalRule.textDiyStyle; } - ["translator", "fromLang", "toLang", "transOpen"].forEach((key) => { - if (rule[key] === GLOBAL_KEY) { - rule[key] = globalRule[key]; - } - }); return rule; }; @@ -131,6 +153,14 @@ export const checkRules = (rules) => { transOpen, bgColor, textDiyStyle, + transOnly, + transTiming, + transTag, + transTitle, + detectRemote, + skipLangs, + fixerSelector, + fixerFunc, }) => ({ pattern: pattern.trim(), selector: type(selector) === "string" ? selector : "", @@ -147,6 +177,14 @@ export const checkRules = (rules) => { toLang: matchValue([GLOBAL_KEY, ...toLangs], toLang), textStyle: matchValue([GLOBAL_KEY, ...OPT_STYLE_ALL], textStyle), transOpen: matchValue([GLOBAL_KEY, "true", "false"], transOpen), + transOnly: matchValue([GLOBAL_KEY, "true", "false"], transOnly), + transTiming: matchValue([GLOBAL_KEY, ...OPT_TIMING_ALL], transTiming), + transTag: matchValue([GLOBAL_KEY, "font", "span"], transTag), + transTitle: matchValue([GLOBAL_KEY, "true", "false"], transTitle), + detectRemote: matchValue([GLOBAL_KEY, "true", "false"], detectRemote), + skipLangs: type(skipLangs) === "array" ? skipLangs : [], + fixerSelector: type(fixerSelector) === "string" ? fixerSelector : "", + fixerFunc: matchValue([GLOBAL_KEY, ...FIXER_ALL], fixerFunc), }) ); diff --git a/src/libs/storage.js b/src/libs/storage.js index 3e19c6b..a1b81fd 100644 --- a/src/libs/storage.js +++ b/src/libs/storage.js @@ -1,14 +1,12 @@ import { STOKEY_SETTING, STOKEY_RULES, - STOKEY_WFRULES, STOKEY_WORDS, STOKEY_FAB, STOKEY_SYNC, STOKEY_MSAUTH, STOKEY_BDAUTH, STOKEY_RULESCACHE_PREFIX, - STOKEY_WEBFIXCACHE_PREFIX, DEFAULT_SETTING, DEFAULT_RULES, DEFAULT_SYNC, @@ -86,8 +84,10 @@ export const storage = { * 设置信息 */ export const getSetting = () => getObj(STOKEY_SETTING); -export const getSettingWithDefault = async () => - (await getSetting()) || DEFAULT_SETTING; +export const getSettingWithDefault = async () => ({ + ...DEFAULT_SETTING, + ...((await getSetting()) || {}), +}); export const setSetting = (val) => setObj(STOKEY_SETTING, val); export const updateSetting = (obj) => putObj(STOKEY_SETTING, obj); @@ -99,14 +99,6 @@ export const getRulesWithDefault = async () => (await getRules()) || DEFAULT_RULES; export const setRules = (val) => setObj(STOKEY_RULES, val); -/** - * 修复规则列表 - */ -export const getWebfixRules = () => getObj(STOKEY_WFRULES); -export const getWebfixRulesWithDefault = async () => - (await getWebfixRules()) || []; -export const setWebfixRules = (val) => setObj(STOKEY_WFRULES, val); - /** * 词汇列表 */ @@ -123,14 +115,6 @@ export const delSubRules = (url) => del(STOKEY_RULESCACHE_PREFIX + url); export const setSubRules = (url, val) => setObj(STOKEY_RULESCACHE_PREFIX + url, val); -/** - * 修复站点 - */ -export const getWebfix = (url) => getObj(STOKEY_WEBFIXCACHE_PREFIX + url); -export const getWebfixWithDefault = async () => (await getWebfix()) || []; -export const setWebfix = (url, val) => - setObj(STOKEY_WEBFIXCACHE_PREFIX + url, val); - /** * fab位置 */ diff --git a/src/libs/subRules.js b/src/libs/subRules.js index 24e9ca7..3d75d2b 100644 --- a/src/libs/subRules.js +++ b/src/libs/subRules.js @@ -8,7 +8,6 @@ import { import { apiFetch } from "../apis"; import { checkRules } from "./rules"; import { isAllchar } from "./utils"; -import { syncWebfix } from "./webfix"; /** * 更新缓存同步时间 @@ -66,9 +65,6 @@ export const trySyncAllSubRules = async ({ subrulesList }) => { // 同步订阅规则 await syncAllSubRules(subrulesList); await updateSync({ subRulesSyncAt: now }); - - // 同步修复规则 - await syncWebfix(process.env.REACT_APP_WEBFIXURL); } } catch (err) { console.log("[try sync all subrules]", err); diff --git a/src/libs/sync.js b/src/libs/sync.js index 3e7b34a..7d9743a 100644 --- a/src/libs/sync.js +++ b/src/libs/sync.js @@ -2,7 +2,6 @@ import { APP_LCNAME, KV_SETTING_KEY, KV_RULES_KEY, - KV_WFRULES_KEY, KV_WORDS_KEY, KV_RULES_SHARE_KEY, KV_SALT_SHARE, @@ -14,10 +13,8 @@ import { getSettingWithDefault, getRulesWithDefault, getWordsWithDefault, - getWebfixRulesWithDefault, setSetting, setRules, - setWebfixRules, setWords, } from "./storage"; import { apiSyncData } from "../apis"; @@ -141,25 +138,6 @@ export const trySyncRules = async () => { } }; -/** - * 同步修复规则 - * @returns - */ -const syncWebfixRules = async () => { - const res = await syncData(KV_WFRULES_KEY, getWebfixRulesWithDefault); - if (res?.isNew) { - await setWebfixRules(res.value); - } -}; - -export const trySyncWebfixRules = async () => { - try { - await syncWebfixRules(); - } catch (err) { - console.log("[sync user webfix rules]", err); - } -}; - /** * 同步词汇 * @returns @@ -207,13 +185,11 @@ export const syncShareRules = async ({ rules, syncUrl, syncKey }) => { export const syncSettingAndRules = async () => { await syncSetting(); await syncRules(); - await syncWebfixRules(); await syncWords(); }; export const trySyncSettingAndRules = async () => { await trySyncSetting(); await trySyncRules(); - await trySyncWebfixRules(); await trySyncWords(); }; diff --git a/src/libs/translator.js b/src/libs/translator.js index b289b6b..6863f7b 100644 --- a/src/libs/translator.js +++ b/src/libs/translator.js @@ -9,9 +9,9 @@ import { OPT_STYLE_DASHLINE, OPT_STYLE_FUZZY, SHADOW_KEY, - OPT_MOUSEKEY_DISABLE, - OPT_MOUSEKEY_PAGEOPEN, - OPT_MOUSEKEY_MOUSEOVER, + OPT_TIMING_PAGESCROLL, + OPT_TIMING_PAGEOPEN, + OPT_TIMING_MOUSEOVER, DEFAULT_TRANS_APIS, } from "../config"; import Content from "../views/Content"; @@ -29,7 +29,6 @@ import { injectInlineJs, injectInternalCss } from "./injector"; export class Translator { _rule = {}; _setting = {}; - _fixerSetting = null; _rootNodes = new Set(); _tranNodes = new Map(); _skipNodeNames = [ @@ -104,14 +103,13 @@ export class Translator { }; }; - constructor(rule, setting, fixerSetting) { + constructor(rule, setting) { const { fetchInterval, fetchLimit } = setting; updateFetchPool(fetchInterval, fetchLimit); this._overrideAttachShadow(); this._setting = setting; this._rule = rule; - this._fixerSetting = fixerSetting; this._keepSelector = (rule.keepSelector || "") .split(SHADOW_KEY) @@ -267,14 +265,15 @@ export class Translator { }; _register = () => { - const { fromLang, toLang, injectJs, injectCss } = this._rule; + const { fromLang, toLang, injectJs, injectCss, fixerSelector, fixerFunc } = + this._rule; if (fromLang === toLang) { return; } // webfix - if (this._fixerSetting) { - runFixer(this._fixerSetting); + if (fixerSelector && fixerFunc !== "-") { + runFixer(fixerSelector, fixerFunc); } // 注入用户JS/CSS @@ -299,14 +298,14 @@ export class Translator { }); if ( - !this._setting.mouseKey || - this._setting.mouseKey === OPT_MOUSEKEY_DISABLE + !this._rule.transTiming || + this._rule.transTiming === OPT_TIMING_PAGESCROLL ) { // 监听节点显示 this._tranNodes.forEach((_, node) => { this._interseObserver.observe(node); }); - } else if (this._setting.mouseKey === OPT_MOUSEKEY_PAGEOPEN) { + } else if (this._rule.transTiming === OPT_TIMING_PAGEOPEN) { // 全文直接翻译 this._tranNodes.forEach((_, node) => { this._render(node); @@ -321,7 +320,7 @@ export class Translator { } // 翻译页面标题 - if (this._setting.transTitle && !this._docTitle) { + if (this._rule.transTitle === "true" && !this._docTitle) { const title = document.title; this._docTitle = title; this.translateText(title).then((trText) => { @@ -336,8 +335,8 @@ export class Translator { return; } - const key = this._setting.mouseKey.slice(3); - if (this._setting.mouseKey === OPT_MOUSEKEY_MOUSEOVER || e[key]) { + const key = this._rule.transTiming.slice(3); + if (this._rule.transTiming === OPT_TIMING_MOUSEOVER || e[key]) { e.target.removeEventListener("mouseenter", this._handleMouseover); e.target.removeEventListener("mouseleave", this._handleMouseout); this._render(e.target); @@ -357,7 +356,7 @@ export class Translator { _handleKeydown = (e) => { // console.log("keydown", e); - const key = this._setting.mouseKey.slice(3); + const key = this._rule.transTiming.slice(3); if (e[key] && this._mouseoverNode) { this._mouseoverNode.removeEventListener( "mouseenter", @@ -392,12 +391,12 @@ export class Translator { this._tranNodes.forEach((innerHTML, node) => { if ( - !this._setting.mouseKey || - this._setting.mouseKey === OPT_MOUSEKEY_DISABLE + !this._rule.transTiming || + this._rule.transTiming === OPT_TIMING_PAGESCROLL ) { // 解除节点显示监听 this._interseObserver.unobserve(node); - } else if (this._setting.mouseKey !== OPT_MOUSEKEY_PAGEOPEN) { + } else if (this._rule.transTiming !== OPT_TIMING_PAGEOPEN) { // 移除鼠标悬停监听 // node.style.pointerEvents = "none"; node.removeEventListener("mouseenter", this._handleMouseover); @@ -405,7 +404,7 @@ export class Translator { } // 移除/恢复元素 - if (innerHTML && this._setting.transOnly) { + if (innerHTML && this._rule.transOnly === "true") { node.innerHTML = innerHTML; } else { node.querySelector(APP_LCNAME)?.remove(); @@ -446,7 +445,7 @@ export class Translator { // 已翻译 if (traEl) { - if (this._setting.transOnly) { + if (this._rule.transOnly === "true") { return; } @@ -465,7 +464,7 @@ export class Translator { } let q = el.innerText.trim(); - if (this._setting.transOnly) { + if (this._rule.transOnly === "true") { this._tranNodes.set(el, el.innerHTML); } else { this._tranNodes.set(el, q); @@ -522,7 +521,7 @@ export class Translator { traEl = document.createElement(APP_LCNAME); traEl.style.visibility = "visible"; - // if (this._setting.transOnly) { + // if (this._rule.transOnly === "true") { // el.innerHTML = ""; // } const { selectStyle, parentStyle } = this._rule; @@ -532,8 +531,6 @@ export class Translator { el.parentElement.style.cssText += parentStyle; } - // console.log({ q, keeps }); - const root = createRoot(traEl); root.render(); }; diff --git a/src/libs/webfix.js b/src/libs/webfix.js index b38787d..a1c3d3f 100644 --- a/src/libs/webfix.js +++ b/src/libs/webfix.js @@ -1,55 +1,18 @@ -import { isMatch } from "./utils"; -import { getWebfix, setWebfix, getWebfixRulesWithDefault } from "./storage"; -import { apiFetch } from "../apis"; - /** * 修复程序类型 */ +const FIXER_NONE = "-"; const FIXER_BR = "br"; const FIXER_BN = "bn"; const FIXER_BR_DIV = "brToDiv"; const FIXER_BN_DIV = "bnToDiv"; -const FIXER_FONTSIZE = "fontSize"; + export const FIXER_ALL = [ + FIXER_NONE, FIXER_BR, FIXER_BN, FIXER_BR_DIV, FIXER_BN_DIV, - // FIXER_FONTSIZE, -]; - -/** - * 需要修复的站点列表 - * - pattern 匹配网址 - * - selector 需要修复的选择器 - * - rootSelector 需要监听的选择器,可留空 - * - fixer 修复函数,可针对不同网址,选用不同修复函数 - */ -const DEFAULT_SITES = [ - { - pattern: "www.phoronix.com", - selector: ".content", - rootSelector: "", - fixer: FIXER_BR, - }, - { - pattern: "t.me/s/", - selector: ".tgme_widget_message_text", - rootSelector: ".tgme_channel_history", - fixer: FIXER_BR, - }, - { - pattern: "baidu.com", - selector: "html", - rootSelector: "", - fixer: FIXER_FONTSIZE, - }, - { - pattern: "chat.openai.com", - selector: "div[data-testid^=conversation-turn] .items-start > div", - rootSelector: "", - fixer: FIXER_BN, - }, ]; /** @@ -135,14 +98,6 @@ function bnDivFixer(node) { return bnFixer(node, "div"); } -/** - * 修复字体大小问题,如 baidu.com - * @param {*} node - */ -function fontSizeFixer(node) { - node.style.cssText += "font-size:1em;"; -} - /** * 修复程序映射 */ @@ -151,7 +106,6 @@ const fixerMap = { [FIXER_BN]: bnFixer, [FIXER_BR_DIV]: brDivFixer, [FIXER_BN_DIV]: bnDivFixer, - [FIXER_FONTSIZE]: fontSizeFixer, }; /** @@ -189,68 +143,16 @@ function run(selector, fixer, rootSelector) { }); } -/** - * 同步远程数据 - * @param {*} url - * @returns - */ -export const syncWebfix = async (url) => { - const sites = await apiFetch(url); - await setWebfix(url, sites); - return sites; -}; - -/** - * 从缓存或远程加载修复站点 - * @param {*} url - * @returns - */ -export const loadOrFetchWebfix = async (url) => { - try { - let sites = await getWebfix(url); - if (sites?.length) { - return sites; - } - return syncWebfix(url); - } catch (err) { - console.log("[load webfix]", err.message); - return DEFAULT_SITES; - } -}; - /** * 执行fixer * @param {*} param0 */ -export async function runFixer({ selector, fixer, rootSelector }) { +export async function runFixer(selector, fixer = "-", rootSelector) { try { - run(selector, fixerMap[fixer], rootSelector); + if (Object.keys(fixerMap).includes(fixer)) { + run(selector, fixerMap[fixer], rootSelector); + } } catch (err) { console.error(`[kiss-webfix run]: ${err.message}`); } } - -/** - * 匹配fixer配置 - */ -export async function matchFixer(href, { injectWebfix }) { - if (!injectWebfix) { - return null; - } - - try { - const userSites = await getWebfixRulesWithDefault(); - const subSites = await loadOrFetchWebfix(process.env.REACT_APP_WEBFIXURL); - const sites = [...userSites, ...subSites]; - for (let i = 0; i < sites.length; i++) { - const site = sites[i]; - if (isMatch(href, site.pattern) && fixerMap[site.fixer]) { - return site; - } - } - } catch (err) { - console.error(`[kiss-webfix match]: ${err.message}`); - } - - return null; -} diff --git a/src/views/Content/index.js b/src/views/Content/index.js index 4f5039f..16ae905 100644 --- a/src/views/Content/index.js +++ b/src/views/Content/index.js @@ -11,8 +11,6 @@ import { OPT_STYLE_DIY, DEFAULT_COLOR, MSG_TRANS_CURRULE, - TRANS_NEWLINE_LENGTH, - DEFAULT_TRANS_TAG, } from "../../config"; import { useTranslate } from "../../hooks/Translate"; import { styled, css } from "@mui/material/styles"; @@ -87,13 +85,10 @@ const StyledSpan = styled("span")` export default function Content({ q, keeps, translator, $el }) { const [rule, setRule] = useState(translator.rule); const { text, sameLang, loading } = useTranslate(q, rule, translator.setting); - const { transOpen, textStyle, bgColor = "", textDiyStyle = "" } = rule; + const { transOpen, textStyle, bgColor, textDiyStyle, transOnly, transTag } = + rule; - const { - newlineLength = TRANS_NEWLINE_LENGTH, - transTag = DEFAULT_TRANS_TAG, - transOnly = false, - } = translator.setting; + const { newlineLength } = translator.setting; const handleKissEvent = (e) => { const { action, args } = e.detail; @@ -113,7 +108,7 @@ export default function Content({ q, keeps, translator, $el }) { }, [translator.eventName]); const gap = useMemo(() => { - if (transOnly) { + if (transOnly === "true") { return ""; } return q.length >= newlineLength ?
: " "; @@ -142,7 +137,11 @@ export default function Content({ q, keeps, translator, $el }) { return; } - if (transOnly && transOpen === "true" && $el.querySelector(APP_LCNAME)) { + if ( + transOnly === "true" && + transOpen === "true" && + $el.querySelector(APP_LCNAME) + ) { Array.from($el.childNodes).forEach((el) => { if (el.localName !== APP_LCNAME) { el.remove(); diff --git a/src/views/Options/Navigator.js b/src/views/Options/Navigator.js index 0b07f92..efa9336 100644 --- a/src/views/Options/Navigator.js +++ b/src/views/Options/Navigator.js @@ -11,7 +11,6 @@ import DesignServicesIcon from "@mui/icons-material/DesignServices"; import { useI18n } from "../../hooks/I18n"; import SyncIcon from "@mui/icons-material/Sync"; import ApiIcon from "@mui/icons-material/Api"; -import SendTimeExtensionIcon from "@mui/icons-material/SendTimeExtension"; import InputIcon from "@mui/icons-material/Input"; import SelectAllIcon from "@mui/icons-material/SelectAll"; import EventNoteIcon from "@mui/icons-material/EventNote"; @@ -65,12 +64,6 @@ export default function Navigator(props) { url: "/sync", icon: , }, - { - id: "webfix", - label: i18n("patch_setting"), - url: "/webfix", - icon: , - }, { id: "words", label: i18n("favorite_words"), diff --git a/src/views/Options/Rules.js b/src/views/Options/Rules.js index bc12bef..6edf61e 100644 --- a/src/views/Options/Rules.js +++ b/src/views/Options/Rules.js @@ -15,6 +15,9 @@ import { OPT_STYLE_USE_COLOR, URL_KISS_RULES_NEW_ISSUE, OPT_SYNCTYPE_WORKER, + OPT_TIMING_PAGESCROLL, + DEFAULT_TRANS_TAG, + OPT_TIMING_ALL, } from "../../config"; import { useState, useEffect, useMemo } from "react"; import { useI18n } from "../../hooks/I18n"; @@ -50,12 +53,10 @@ import HelpButton from "./HelpButton"; import { useSyncCaches } from "../../hooks/Sync"; import DownloadButton from "./DownloadButton"; import UploadButton from "./UploadButton"; +import { FIXER_ALL } from "../../libs/webfix"; function RuleFields({ rule, rules, setShow, setKeyword }) { - const initFormValues = rule || { - ...DEFAULT_RULE, - transOpen: "true", - }; + const initFormValues = { ...DEFAULT_RULE, ...(rule || {}) }; const editMode = !!rule; const i18n = useI18n(); @@ -79,6 +80,14 @@ function RuleFields({ rule, rules, setShow, setKeyword }) { transOpen, bgColor, textDiyStyle, + transOnly = "false", + transTiming = OPT_TIMING_PAGESCROLL, + transTag = DEFAULT_TRANS_TAG, + transTitle = "false", + detectRemote = "false", + skipLangs = [], + fixerSelector = "", + fixerFunc = "-", } = formValues; const hasSamePattern = (str) => { @@ -323,6 +332,141 @@ function RuleFields({ rule, rules, setShow, setKeyword }) { {showMore && ( <> + + + + + {GlobalItem} + {i18n("disable")} + {i18n("enable")} + + + + + {GlobalItem} + {OPT_TIMING_ALL.map((item) => ( + + {i18n(item)} + + ))} + + + + + {GlobalItem} + {``} + {``} + + + + + {GlobalItem} + {i18n("disable")} + {i18n("enable")} + + + + + {GlobalItem} + {i18n("disable")} + {i18n("enable")} + + + + + + + {OPT_LANGS_TO.map(([langKey, langName]) => ( + + {langName} + + ))} + + + + + {GlobalItem} + {FIXER_ALL.map((item) => ( + + {item} + + ))} + + - - {i18n("translate_timing")} - - - - - {i18n("translation_element_tag")} - - - - - {i18n("show_only_translations")} - - {i18n("show_only_translations_help")} - - - - {i18n("translate_page_title")} - - - {i18n("touch_translate_shortcut")} - {i18n("disable")} - {i18n("enable")} - - {i18n("detect_lang_remote_help")} - - - - {i18n("disable_langs")} - - {i18n("disable_langs_helper")} - - {isExt ? ( <> diff --git a/src/views/Options/Webfix.js b/src/views/Options/Webfix.js deleted file mode 100644 index 0c98eed..0000000 --- a/src/views/Options/Webfix.js +++ /dev/null @@ -1,358 +0,0 @@ -import Stack from "@mui/material/Stack"; -import TextField from "@mui/material/TextField"; -import { useCallback, useEffect, useState } from "react"; -import { useI18n } from "../../hooks/I18n"; -import Typography from "@mui/material/Typography"; -import Accordion from "@mui/material/Accordion"; -import AccordionSummary from "@mui/material/AccordionSummary"; -import AccordionDetails from "@mui/material/AccordionDetails"; -import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; -import Alert from "@mui/material/Alert"; -import Box from "@mui/material/Box"; -import FormControlLabel from "@mui/material/FormControlLabel"; -import Switch from "@mui/material/Switch"; -import { useSetting } from "../../hooks/Setting"; -import CircularProgress from "@mui/material/CircularProgress"; -import { syncWebfix, loadOrFetchWebfix, FIXER_ALL } from "../../libs/webfix"; -import Button from "@mui/material/Button"; -import SyncIcon from "@mui/icons-material/Sync"; -import { useAlert } from "../../hooks/Alert"; -import HelpButton from "./HelpButton"; -import { URL_KISS_RULES_NEW_ISSUE } from "../../config"; -import MenuItem from "@mui/material/MenuItem"; -import { useWebfixRules } from "../../hooks/WebfixRules"; - -function WebfixFields({ rule, webfix, setShow }) { - const editMode = !!rule; - const initFormValues = rule || { - pattern: "", - selector: "", - rootSelector: "", - fixer: FIXER_ALL[0], - }; - const i18n = useI18n(); - const [disabled, setDisabled] = useState(editMode); - const [errors, setErrors] = useState({}); - const [formValues, setFormValues] = useState(initFormValues); - - const { pattern, selector, rootSelector, fixer } = formValues; - - const hasSamePattern = (str) => { - for (const item of webfix.list || []) { - if (item.pattern === str && rule?.pattern !== str) { - return true; - } - } - return false; - }; - - const handleFocus = (e) => { - e.preventDefault(); - const { name } = e.target; - setErrors((pre) => ({ ...pre, [name]: "" })); - }; - - const handleChange = (e) => { - e.preventDefault(); - const { name, value } = e.target; - setFormValues((pre) => ({ ...pre, [name]: value })); - }; - - const handleCancel = (e) => { - e.preventDefault(); - if (editMode) { - setDisabled(true); - } else { - setShow(false); - } - setFormValues(initFormValues); - }; - - const handleSubmit = (e) => { - e.preventDefault(); - const errors = {}; - if (!pattern.trim()) { - errors.pattern = i18n("error_cant_be_blank"); - } - if (hasSamePattern(pattern)) { - errors.pattern = i18n("error_duplicate_values"); - } - if (!selector.trim()) { - errors.selector = i18n("error_cant_be_blank"); - } - if (Object.keys(errors).length > 0) { - setErrors(errors); - return; - } - - if (editMode) { - // 编辑 - setDisabled(true); - webfix.put(rule.pattern, formValues); - } else { - // 添加 - webfix.add(formValues); - setShow(false); - setFormValues(initFormValues); - } - }; - - return ( -
- - - - - - {FIXER_ALL.map((item) => ( - - {item} - - ))} - - - {webfix && - (editMode ? ( - // 编辑 - - {disabled ? ( - <> - - - - ) : ( - <> - - - - )} - - ) : ( - // 添加 - - - - - ))} - -
- ); -} - -function WebfixAccordion({ rule, webfix }) { - const [expanded, setExpanded] = useState(false); - - const handleChange = (e) => { - setExpanded((pre) => !pre); - }; - - return ( - - }> - - {rule.pattern} - - - - {expanded && } - - - ); -} - -export default function Webfix() { - const [loading, setLoading] = useState(false); - const [sites, setSites] = useState([]); - const i18n = useI18n(); - const alert = useAlert(); - const { setting, updateSetting } = useSetting(); - const [showAdd, setShowAdd] = useState(false); - const webfix = useWebfixRules(); - - const loadSites = useCallback(async () => { - const sites = await loadOrFetchWebfix(process.env.REACT_APP_WEBFIXURL); - setSites(sites); - }, []); - - const handleSyncTest = async (e) => { - e.preventDefault(); - try { - setLoading(true); - await syncWebfix(process.env.REACT_APP_WEBFIXURL); - await loadSites(); - alert.success(i18n("sync_success")); - } catch (err) { - console.log("[sync webfix]", err); - alert.error(i18n("sync_failed")); - } finally { - setLoading(false); - } - }; - - useEffect(() => { - (async () => { - try { - setLoading(true); - await loadSites(); - } catch (err) { - console.log("[load webfix]", err.message); - } finally { - setLoading(false); - } - })(); - }, [loadSites]); - - return ( - - - {i18n("patch_setting_help")} - - - - - - - { - updateSetting({ - injectWebfix: !setting.injectWebfix, - }); - }} - /> - } - label={i18n("inject_webfix")} - /> - - - {showAdd && } - - {webfix.list?.length > 0 && ( - - {webfix.list.map((rule) => ( - - ))} - - )} - - {setting.injectWebfix && ( - - {loading ? ( -
- -
- ) : ( - sites.map((rule) => ( - - )) - )} -
- )} -
-
- ); -} diff --git a/src/views/Options/index.js b/src/views/Options/index.js index 6170369..130b7ef 100644 --- a/src/views/Options/index.js +++ b/src/views/Options/index.js @@ -18,7 +18,6 @@ import Stack from "@mui/material/Stack"; import { adaptScript } from "../../libs/gm"; import Alert from "@mui/material/Alert"; import Apis from "./Apis"; -import Webfix from "./Webfix"; import InputSetting from "./InputSetting"; import Tranbox from "./Tranbox"; import FavWords from "./FavWords"; @@ -125,7 +124,6 @@ export default function Options() { } /> } /> } /> - } /> } /> } />