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

163 lines
3.6 KiB
JavaScript
Raw Normal View History

2023-08-05 15:32:51 +08:00
import { createRoot } from "react-dom/client";
import {
APP_LCNAME,
TRANS_MIN_LENGTH,
TRANS_MAX_LENGTH,
EVENT_KISS,
MSG_TRANS_CURRULE,
2023-08-21 16:06:21 +08:00
OPT_STYLE_DASHLINE,
OPT_STYLE_FUZZY,
} from "../config";
2023-08-05 15:32:51 +08:00
import { queryEls } from ".";
import Content from "../views/Content";
2023-08-11 16:48:09 +08:00
import { fetchUpdate, fetchClear } from "./fetch";
2023-08-05 15:32:51 +08:00
/**
* 翻译类
*/
export class Translator {
_rule = {};
2023-08-22 21:45:23 +08:00
_minLength = 0;
_maxLength = 0;
2023-08-05 15:32:51 +08:00
_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) => {
2023-08-05 15:32:51 +08:00
this._interseObserver.observe(el);
});
} catch (err) {
//
}
});
});
});
2023-08-22 21:45:23 +08:00
constructor(rule, { fetchInterval, fetchLimit, minLength, maxLength }) {
2023-08-10 13:41:55 +08:00
fetchUpdate(fetchInterval, fetchLimit);
2023-08-22 21:45:23 +08:00
this._minLength = minLength ?? TRANS_MIN_LENGTH;
this._maxLength = maxLength ?? TRANS_MAX_LENGTH;
this.rule = rule;
2023-08-08 13:29:15 +08:00
if (rule.transOpen === "true") {
2023-08-05 15:32:51 +08:00
this._register();
}
}
get rule() {
// console.log("get rule", this._rule);
2023-08-05 15:32:51 +08:00
return this._rule;
}
set rule(rule) {
// console.log("set rule", rule);
this._rule = rule;
// 广播消息
window.dispatchEvent(
new CustomEvent(EVENT_KISS, {
detail: {
action: MSG_TRANS_CURRULE,
args: rule,
},
})
);
}
2023-08-05 15:32:51 +08:00
updateRule = (obj) => {
this.rule = { ...this.rule, ...obj };
2023-08-05 15:32:51 +08:00
};
toggle = () => {
if (this.rule.transOpen === "true") {
this.rule = { ...this.rule, transOpen: "false" };
2023-08-05 15:32:51 +08:00
this._unRegister();
} else {
this.rule = { ...this.rule, transOpen: "true" };
2023-08-05 15:32:51 +08:00
this._register();
}
};
2023-08-21 16:06:21 +08:00
toggleStyle = () => {
const textStyle =
this.rule.textStyle === OPT_STYLE_FUZZY
? OPT_STYLE_DASHLINE
: OPT_STYLE_FUZZY;
this.rule = { ...this.rule, textStyle };
};
2023-08-05 15:32:51 +08:00
_register = () => {
// 监听节点变化
this._mutaObserver.observe(document, {
childList: true,
subtree: true,
});
// 监听节点显示
queryEls(this.rule.selector).forEach((el) => {
2023-08-05 15:32:51 +08:00
this._interseObserver.observe(el);
});
};
_unRegister = () => {
// 解除节点变化监听
this._mutaObserver.disconnect();
// 解除节点显示监听
queryEls(this.rule.selector).forEach((el) =>
2023-08-05 15:32:51 +08:00
this._interseObserver.unobserve(el)
);
// 移除已插入元素
queryEls(APP_LCNAME).forEach((el) => el.remove());
2023-08-11 16:48:09 +08:00
// 清空任务池
fetchClear();
2023-08-05 15:32:51 +08:00
};
_render = (el) => {
// 含子元素
if (el.querySelector(this.rule.selector)) {
return;
}
// 已翻译
2023-08-05 15:32:51 +08:00
if (el.querySelector(APP_LCNAME)) {
return;
}
// 太长或太短
2023-08-05 15:32:51 +08:00
const q = el.innerText.trim();
2023-08-22 21:45:23 +08:00
if (!q || q.length < this._minLength || q.length > this._maxLength) {
2023-08-05 15:32:51 +08:00
return;
}
// console.log("---> ", q);
const span = document.createElement(APP_LCNAME);
2023-08-10 17:03:37 +08:00
span.style.visibility = "visible";
2023-08-05 15:32:51 +08:00
el.appendChild(span);
2023-08-11 16:48:09 +08:00
el.style.cssText +=
"-webkit-line-clamp: unset; max-height: none; height: auto;";
el.parentElement.style.cssText +=
"-webkit-line-clamp: unset; max-height: none; height: auto;";
2023-08-05 15:32:51 +08:00
const root = createRoot(span);
2023-08-19 13:48:03 +08:00
root.render(<Content q={q} translator={this} />);
2023-08-05 15:32:51 +08:00
};
}