Files
kiss-translator/src/libs/rules.js

239 lines
6.9 KiB
JavaScript
Raw Normal View History

2023-08-30 18:05:37 +08:00
import { matchValue, type, isMatch } from "./utils";
2023-08-20 19:27:29 +08:00
import {
GLOBAL_KEY,
OPT_STYLE_ALL,
OPT_LANGS_FROM,
OPT_LANGS_TO,
// OPT_TIMING_ALL,
DEFAULT_RULE,
2023-08-30 18:05:37 +08:00
GLOBLA_RULE,
2023-08-20 19:27:29 +08:00
} from "../config";
2023-08-31 00:18:57 +08:00
import { loadOrFetchSubRules } from "./subRules";
2023-09-10 12:35:03 +08:00
import { getRulesWithDefault, setRules } from "./storage";
import { trySyncRules } from "./sync";
// import { FIXER_ALL } from "./webfix";
2024-03-19 18:07:18 +08:00
import { kissLog } from "./log";
2023-08-30 18:05:37 +08:00
/**
* 根据href匹配规则
* @param {*} rules
* @param {string} href
* @returns
*/
2025-09-30 00:51:31 +08:00
export const matchRule = async (href, { injectRules, subrulesList }) => {
2023-11-24 17:07:29 +08:00
const rules = await getRulesWithDefault();
2023-08-30 18:05:37 +08:00
if (injectRules) {
try {
const selectedSub = subrulesList.find((item) => item.selected);
if (selectedSub?.url) {
2025-09-30 00:51:31 +08:00
const subRules = await loadOrFetchSubRules(selectedSub.url);
2023-08-30 18:05:37 +08:00
rules.splice(-1, 0, ...subRules);
}
} catch (err) {
kissLog("load injectRules", err);
2023-08-30 18:05:37 +08:00
}
}
const rule = rules.find((r) =>
r.pattern.split(",").some((p) => isMatch(href, p.trim()))
);
2024-03-16 23:37:27 +08:00
const globalRule = {
...GLOBLA_RULE,
...(rules.find((r) => r.pattern === GLOBAL_KEY) || {}),
};
2023-08-30 18:05:37 +08:00
if (!rule) {
return globalRule;
}
2024-03-16 23:37:27 +08:00
[
"selector",
"keepSelector",
"rootsSelector",
"ignoreSelector",
2024-03-16 23:37:27 +08:00
"terms",
2025-10-01 16:18:19 +08:00
"aiTerms",
2025-10-16 20:16:03 +08:00
"termsStyle",
2024-03-16 23:37:27 +08:00
"selectStyle",
"parentStyle",
2025-10-10 15:05:47 +08:00
"grandStyle",
2024-03-16 23:37:27 +08:00
"injectJs",
"injectCss",
// "fixerSelector",
2024-05-15 11:07:13 +08:00
"transStartHook",
"transEndHook",
// "transRemoveHook",
2024-03-16 23:37:27 +08:00
].forEach((key) => {
if (!rule[key]?.trim()) {
rule[key] = globalRule[key];
}
});
[
"apiSlug",
2024-03-16 23:37:27 +08:00
"fromLang",
"toLang",
"transOpen",
"transOnly",
// "transTiming",
"autoScan",
"hasRichText",
"hasShadowroot",
2024-03-16 23:37:27 +08:00
"transTag",
"transTitle",
// "detectRemote",
// "fixerFunc",
2024-03-16 23:37:27 +08:00
].forEach((key) => {
2025-10-01 22:46:55 +08:00
if (!rule[key] || rule[key] === GLOBAL_KEY) {
2024-03-16 23:37:27 +08:00
rule[key] = globalRule[key];
}
});
// if (!rule.skipLangs || rule.skipLangs.length === 0) {
// rule.skipLangs = globalRule.skipLangs;
// }
2025-10-01 22:46:55 +08:00
if (!rule.textStyle || rule.textStyle === GLOBAL_KEY) {
2023-09-08 23:38:36 +08:00
rule.textStyle = globalRule.textStyle;
rule.bgColor = globalRule.bgColor;
rule.textDiyStyle = globalRule.textDiyStyle;
} else {
rule.bgColor = rule.bgColor?.trim() || globalRule.bgColor;
rule.textDiyStyle = rule.textDiyStyle?.trim() || globalRule.textDiyStyle;
}
2023-08-30 18:05:37 +08:00
return rule;
};
2023-08-20 19:27:29 +08:00
/**
* 检查过滤rules
* @param {*} rules
* @returns
*/
export const checkRules = (rules) => {
if (type(rules) === "string") {
rules = JSON.parse(rules);
}
if (type(rules) !== "array") {
throw new Error("data error");
}
2023-08-30 18:05:37 +08:00
const fromLangs = OPT_LANGS_FROM.map((item) => item[0]);
const toLangs = OPT_LANGS_TO.map((item) => item[0]);
2023-08-20 19:27:29 +08:00
const patternSet = new Set();
rules = rules
.filter((rule) => type(rule) === "object")
.filter(({ pattern }) => {
if (type(pattern) !== "string" || patternSet.has(pattern.trim())) {
return false;
}
patternSet.add(pattern.trim());
return true;
})
.map(
({
pattern,
selector,
2024-01-02 17:55:59 +08:00
keepSelector,
rootsSelector,
ignoreSelector,
2024-01-19 16:02:53 +08:00
terms,
2025-10-01 16:18:19 +08:00
aiTerms,
2025-10-16 20:16:03 +08:00
termsStyle,
2024-03-14 18:06:28 +08:00
selectStyle,
parentStyle,
2025-10-10 15:05:47 +08:00
grandStyle,
2024-03-14 18:06:28 +08:00
injectJs,
injectCss,
apiSlug,
2023-08-20 19:27:29 +08:00
fromLang,
toLang,
textStyle,
transOpen,
bgColor,
2023-09-01 15:57:05 +08:00
textDiyStyle,
2024-03-16 23:37:27 +08:00
transOnly,
autoScan,
hasRichText,
hasShadowroot,
// transTiming,
2024-03-16 23:37:27 +08:00
transTag,
transTitle,
// detectRemote,
// skipLangs,
// fixerSelector,
// fixerFunc,
2024-05-15 11:07:13 +08:00
transStartHook,
transEndHook,
// transRemoveHook,
2023-08-20 19:27:29 +08:00
}) => ({
pattern: pattern.trim(),
selector: type(selector) === "string" ? selector : "",
2024-01-02 17:55:59 +08:00
keepSelector: type(keepSelector) === "string" ? keepSelector : "",
rootsSelector: type(rootsSelector) === "string" ? rootsSelector : "",
ignoreSelector: type(ignoreSelector) === "string" ? ignoreSelector : "",
2024-01-19 16:02:53 +08:00
terms: type(terms) === "string" ? terms : "",
2025-10-01 16:18:19 +08:00
aiTerms: type(aiTerms) === "string" ? aiTerms : "",
2025-10-16 20:16:03 +08:00
termsStyle: type(termsStyle) === "string" ? termsStyle : "",
2024-03-14 18:06:28 +08:00
selectStyle: type(selectStyle) === "string" ? selectStyle : "",
parentStyle: type(parentStyle) === "string" ? parentStyle : "",
2025-10-10 15:05:47 +08:00
grandStyle: type(grandStyle) === "string" ? grandStyle : "",
2024-03-14 18:06:28 +08:00
injectJs: type(injectJs) === "string" ? injectJs : "",
injectCss: type(injectCss) === "string" ? injectCss : "",
2023-08-20 19:27:29 +08:00
bgColor: type(bgColor) === "string" ? bgColor : "",
2023-09-01 15:57:05 +08:00
textDiyStyle: type(textDiyStyle) === "string" ? textDiyStyle : "",
2025-10-13 23:26:29 +08:00
apiSlug:
type(apiSlug) === "string" && apiSlug.trim() !== ""
? apiSlug.trim()
: GLOBAL_KEY,
2023-08-20 19:27:29 +08:00
fromLang: matchValue([GLOBAL_KEY, ...fromLangs], fromLang),
toLang: matchValue([GLOBAL_KEY, ...toLangs], toLang),
textStyle: matchValue([GLOBAL_KEY, ...OPT_STYLE_ALL], textStyle),
transOpen: matchValue([GLOBAL_KEY, "true", "false"], transOpen),
2024-03-16 23:37:27 +08:00
transOnly: matchValue([GLOBAL_KEY, "true", "false"], transOnly),
autoScan: matchValue([GLOBAL_KEY, "true", "false"], autoScan),
hasRichText: matchValue([GLOBAL_KEY, "true", "false"], hasRichText),
hasShadowroot: matchValue([GLOBAL_KEY, "true", "false"], hasShadowroot),
// transTiming: matchValue([GLOBAL_KEY, ...OPT_TIMING_ALL], transTiming),
2024-03-19 10:00:00 +08:00
transTag: matchValue([GLOBAL_KEY, "span", "font"], transTag),
2024-03-16 23:37:27 +08:00
transTitle: matchValue([GLOBAL_KEY, "true", "false"], transTitle),
// detectRemote: matchValue([GLOBAL_KEY, "true", "false"], detectRemote),
// skipLangs: type(skipLangs) === "array" ? skipLangs : [],
// fixerSelector: type(fixerSelector) === "string" ? fixerSelector : "",
2024-05-15 11:07:13 +08:00
transStartHook: type(transStartHook) === "string" ? transStartHook : "",
transEndHook: type(transEndHook) === "string" ? transEndHook : "",
// transRemoveHook:
// type(transRemoveHook) === "string" ? transRemoveHook : "",
// fixerFunc: matchValue([GLOBAL_KEY, ...FIXER_ALL], fixerFunc),
2023-08-20 19:27:29 +08:00
})
);
return rules;
};
2023-09-10 12:35:03 +08:00
/**
* 保存或更新rule
* @param {*} curRule
2023-09-10 12:35:03 +08:00
*/
export const saveRule = async (curRule) => {
2023-09-10 12:35:03 +08:00
const rules = await getRulesWithDefault();
const index = rules.findIndex(
(item) =>
item.pattern !== GLOBAL_KEY && isMatch(curRule.pattern, item.pattern)
);
if (index !== -1) {
const rule = rules.splice(index, 1)[0];
curRule = { ...rule, ...curRule, pattern: rule.pattern };
2023-09-10 12:35:03 +08:00
}
const newRule = {};
Object.entries(GLOBLA_RULE).forEach(([key, val]) => {
newRule[key] =
!curRule[key] || curRule[key] === val ? DEFAULT_RULE[key] : curRule[key];
});
rules.unshift(newRule);
2023-09-10 12:35:03 +08:00
await setRules(rules);
2023-09-20 17:47:23 +08:00
trySyncRules();
2023-09-10 12:35:03 +08:00
};