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

159 lines
4.4 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,
2023-09-01 22:27:25 +08:00
REMAIN_KEY,
2023-08-20 19:27:29 +08:00
OPT_TRANS_ALL,
OPT_STYLE_ALL,
OPT_LANGS_FROM,
OPT_LANGS_TO,
2023-08-30 18:05:37 +08:00
GLOBLA_RULE,
DEFAULT_SUBRULES_LIST,
2023-09-01 22:27:25 +08:00
DEFAULT_OW_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";
2023-08-30 18:05:37 +08:00
/**
* 根据href匹配规则
* @param {*} rules
* @param {string} href
* @returns
*/
export const matchRule = async (
href,
2023-09-01 22:27:25 +08:00
{
injectRules = true,
subrulesList = DEFAULT_SUBRULES_LIST,
owSubrule = DEFAULT_OW_RULE,
}
2023-08-30 18:05:37 +08:00
) => {
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) {
2023-09-01 22:27:25 +08:00
const mixRule = {};
Object.entries(owSubrule)
.filter(([key, val]) => {
if (
owSubrule.textStyle === REMAIN_KEY &&
(key === "bgColor" || key === "textDiyStyle")
) {
return false;
}
return val !== REMAIN_KEY;
})
.forEach(([key, val]) => {
mixRule[key] = val;
});
2023-09-11 22:53:04 +08:00
let subRules = await loadOrFetchSubRules(selectedSub.url);
subRules = subRules.map((item) => ({ ...item, ...mixRule }));
2023-08-30 18:05:37 +08:00
rules.splice(-1, 0, ...subRules);
}
} catch (err) {
console.log("[load injectRules]", err);
}
}
const rule = rules.find((r) =>
r.pattern.split(",").some((p) => isMatch(href, p.trim()))
);
2023-09-08 23:38:36 +08:00
const globalRule = rules.find((r) => r.pattern === GLOBAL_KEY) || GLOBLA_RULE;
2023-08-30 18:05:37 +08:00
if (!rule) {
return globalRule;
}
2023-09-08 23:38:36 +08:00
rule.selector = rule.selector?.trim() || globalRule.selector;
2024-01-02 17:55:59 +08:00
rule.keepSelector = rule.keepSelector?.trim() || globalRule.keepSelector;
2024-01-19 16:02:53 +08:00
rule.terms = rule.terms?.trim() || globalRule.terms;
2023-09-08 23:38:36 +08:00
if (rule.textStyle === GLOBAL_KEY) {
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;
}
["translator", "fromLang", "toLang", "transOpen"].forEach((key) => {
if (rule[key] === GLOBAL_KEY) {
rule[key] = globalRule[key];
2023-08-30 18:05:37 +08:00
}
2023-09-08 23:38:36 +08:00
});
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,
2024-01-19 16:02:53 +08:00
terms,
2023-08-20 19:27:29 +08:00
translator,
fromLang,
toLang,
textStyle,
transOpen,
bgColor,
2023-09-01 15:57:05 +08:00
textDiyStyle,
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 : "",
2024-01-19 16:02:53 +08:00
terms: type(terms) === "string" ? terms : "",
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 : "",
2023-08-20 19:27:29 +08:00
translator: matchValue([GLOBAL_KEY, ...OPT_TRANS_ALL], translator),
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),
})
);
return rules;
};
2023-09-10 12:35:03 +08:00
/**
* 保存或更新rule
* @param {*} newRule
*/
export const saveRule = async (newRule) => {
const rules = await getRulesWithDefault();
2023-09-10 13:09:19 +08:00
const rule = rules.find((item) => isMatch(newRule.pattern, item.pattern));
2023-09-10 13:44:34 +08:00
if (rule && rule.pattern !== GLOBAL_KEY) {
2023-09-10 12:35:03 +08:00
Object.assign(rule, { ...newRule, pattern: rule.pattern });
} else {
rules.unshift(newRule);
}
await setRules(rules);
2023-09-20 17:47:23 +08:00
trySyncRules();
2023-09-10 12:35:03 +08:00
};