Files
kiss-translator/src/content.js

156 lines
3.4 KiB
JavaScript
Raw Normal View History

2023-08-04 16:48:40 +08:00
import { browser } from "./libs/browser";
2023-07-20 13:45:41 +08:00
import { createRoot } from "react-dom/client";
import {
APP_LCNAME,
MSG_TRANS_TOGGLE,
MSG_TRANS_GETRULE,
MSG_TRANS_PUTRULE,
2023-08-03 10:23:40 +08:00
TRANS_MIN_LENGTH,
TRANS_MAX_LENGTH,
2023-07-20 13:45:41 +08:00
} from "./config";
import Content from "./views/Content";
import { StoragesProvider } from "./hooks/Storage";
import { queryEls, getRules, matchRule } from "./libs";
2023-08-04 16:05:14 +08:00
import { getSetting } from "./libs";
import { transPool } from "./libs/pool";
2023-07-20 13:45:41 +08:00
/**
* 翻译类
*/
class Translator {
_rule = {};
_interseObserver = new IntersectionObserver(
(intersections) => {
intersections.forEach((intersection) => {
if (intersection.isIntersecting) {
this._render(intersection.target);
this._interseObserver.unobserve(intersection.target);
}
});
},
{
threshold: 0.1,
}
);
_mutaObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
try {
queryEls(this._rule.selector, node).forEach((el) => {
this._interseObserver.observe(el);
});
} catch (err) {
//
}
});
});
});
constructor(rule) {
this._rule = rule;
if (rule.transOpen) {
this._register();
}
}
get rule() {
return this._rule;
}
updateRule = (obj) => {
this._rule = { ...this._rule, ...obj };
};
toggle = () => {
if (this._rule.transOpen) {
this._rule.transOpen = false;
this._unRegister();
} else {
this._rule.transOpen = true;
this._register();
}
};
_register = () => {
// 监听节点变化
this._mutaObserver.observe(document, {
childList: true,
subtree: true,
});
// 监听节点显示
queryEls(this._rule.selector).forEach((el) => {
this._interseObserver.observe(el);
});
};
_unRegister = () => {
// 解除节点变化监听
this._mutaObserver.disconnect();
// 解除节点显示监听
queryEls(this._rule.selector).forEach((el) =>
this._interseObserver.unobserve(el)
);
// 移除已插入元素
queryEls(APP_LCNAME).forEach((el) => el.remove());
};
_render = (el) => {
if (el.querySelector(APP_LCNAME)) {
return;
}
2023-08-03 10:23:40 +08:00
// 除openai外保留code和a标签
2023-08-03 15:42:59 +08:00
const q = el.innerText.trim();
2023-08-03 10:23:40 +08:00
if (!q || q.length < TRANS_MIN_LENGTH || q.length > TRANS_MAX_LENGTH) {
// 太长或太短不翻译
2023-07-20 13:45:41 +08:00
return;
}
// console.log("---> ", q);
const span = document.createElement(APP_LCNAME);
el.appendChild(span);
const root = createRoot(span);
root.render(
<StoragesProvider>
<Content q={q} rule={this._rule} />
</StoragesProvider>
);
};
}
/**
* 入口函数
*/
(async () => {
2023-08-04 16:05:14 +08:00
const { fetchInterval, fetchLimit } = await getSetting();
transPool.update(fetchInterval, fetchLimit);
2023-07-20 13:45:41 +08:00
const rules = await getRules();
const rule = matchRule(rules, document.location.href);
const translator = new Translator(rule);
// 监听消息
browser?.runtime.onMessage.addListener(async ({ action, args }) => {
switch (action) {
case MSG_TRANS_TOGGLE:
translator.toggle();
break;
case MSG_TRANS_GETRULE:
break;
case MSG_TRANS_PUTRULE:
translator.updateRule(args);
break;
default:
return { error: `message action is unavailable: ${action}` };
}
return { data: translator.rule };
});
})();