input box trans

This commit is contained in:
Gabe Yuan
2023-09-13 18:02:51 +08:00
committed by Gabe Yuan
parent 0ea97b73e3
commit a8002bba9f
3 changed files with 113 additions and 9 deletions

View File

@@ -84,6 +84,11 @@
> >
</p> </p>
</h2> </h2>
<hr />
<input id="input1" style="width: 80%;" />
<hr />
<textarea id="textarea1" style="width: 80%;">test</textarea>
<hr />
<div id="addtitle"></div> <div id="addtitle"></div>
<h2>Shadow 1</h2> <h2>Shadow 1</h2>
<div id="shadow1"></div> <div id="shadow1"></div>

View File

@@ -68,12 +68,12 @@ export const shortcutRegister = (targetKeys = [], fn, target = document) => {
/** /**
* 注册连续快捷键 * 注册连续快捷键
* @param {*} targetKeys * @param {*} targetKeys
* @param {*} fn * @param {*} fn
* @param {*} step * @param {*} step
* @param {*} timeout * @param {*} timeout
* @param {*} target * @param {*} target
* @returns * @returns
*/ */
export const stepShortcutRegister = ( export const stepShortcutRegister = (
targetKeys = [], targetKeys = [],
@@ -84,12 +84,19 @@ export const stepShortcutRegister = (
) => { ) => {
let count = 0; let count = 0;
let pre = Date.now(); let pre = Date.now();
return shortcutListener((curkeys) => { let timer;
if (targetKeys.length > 0) { return shortcutListener((curkeys, allkeys) => {
timer && clearTimeout(timer);
timer = setTimeout(() => {
clearTimeout(timer);
count = 0;
}, timeout);
if (targetKeys.length > 0 && curkeys.length === 0) {
const now = Date.now(); const now = Date.now();
if ( if (
(count === 0 || now - pre < timeout) && (count === 0 || now - pre < timeout) &&
isSameSet(new Set(targetKeys), new Set(curkeys)) isSameSet(new Set(targetKeys), new Set(allkeys))
) { ) {
count++; count++;
if (count === step) { if (count === step) {

View File

@@ -9,16 +9,22 @@ import {
SHADOW_KEY, SHADOW_KEY,
OPT_MOUSEKEY_DISABLE, OPT_MOUSEKEY_DISABLE,
OPT_MOUSEKEY_MOUSEOVER, OPT_MOUSEKEY_MOUSEOVER,
DEFAULT_INPUT_RULE,
DEFAULT_TRANS_APIS,
} from "../config"; } from "../config";
import Content from "../views/Content"; import Content from "../views/Content";
import { updateFetchPool, clearFetchPool } from "./fetch"; import { updateFetchPool, clearFetchPool } from "./fetch";
import { debounce, genEventName } from "./utils"; import { debounce, genEventName } from "./utils";
import { stepShortcutRegister } from "./shortcut";
import { apiTranslate } from "../apis";
import { tryDetectLang } from ".";
/** /**
* 翻译类 * 翻译类
*/ */
export class Translator { export class Translator {
_rule = {}; _rule = {};
_inputRule = {};
_setting = {}; _setting = {};
_rootNodes = new Set(); _rootNodes = new Set();
_tranNodes = new Map(); _tranNodes = new Map();
@@ -38,6 +44,7 @@ export class Translator {
"script", "script",
"iframe", "iframe",
]; ];
_inputNodeNames = ["INPUT", "TEXTAREA"];
_eventName = genEventName(); _eventName = genEventName();
// 显示 // 显示
@@ -101,6 +108,12 @@ export class Translator {
if (rule.transOpen === "true") { if (rule.transOpen === "true") {
this._register(); this._register();
} }
const inputRule = setting.inputRule || DEFAULT_INPUT_RULE;
this._inputRule = { ...inputRule, selector: rule.inputSelector };
if (inputRule.transOpen && rule.inputSelector) {
this._registerInput();
}
} }
get setting() { get setting() {
@@ -243,6 +256,85 @@ export class Translator {
}); });
}; };
_registerInput = () => {
const {
triggerShortcut,
translator,
fromLang,
toLang,
triggerCount,
selector,
} = this._inputRule;
const apiSetting = (this._setting.transApis || DEFAULT_TRANS_APIS)[
translator
];
stepShortcutRegister(
triggerShortcut,
() => {
document.querySelectorAll(selector).forEach(async (node) => {
let text = "";
let num = 0;
let timer;
if (this._inputNodeNames.includes(node.nodeName)) {
text = node.value?.trim() || "";
} else {
text = node.textContent?.trim() || "";
}
if (!text) {
return;
}
// console.log("input -->", text);
try {
const deLang = await tryDetectLang(text);
if (deLang && toLang.includes(deLang)) {
return;
}
timer = setInterval(() => {
if (this._inputNodeNames.includes(node.nodeName)) {
node.value = text + "-\\|/"[++num % 4];
} else {
node.textContent = text + "-\\|/"[++num % 4];
}
}, 200);
const [trText, isSame] = await apiTranslate({
translator,
text,
fromLang,
toLang,
apiSetting,
});
if (!trText || isSame) {
throw new Error("same lang or no res");
}
clearInterval(timer);
if (this._inputNodeNames.includes(node.nodeName)) {
node.value = trText;
} else {
node.textContent = trText;
}
} catch (err) {
console.log("[translate input]", err.message);
timer && clearInterval(timer);
if (this._inputNodeNames.includes(node.nodeName)) {
node.value = text;
} else {
node.textContent = text;
}
}
});
},
triggerCount
);
};
_handleMouseover = (e) => { _handleMouseover = (e) => {
const key = this._setting.mouseKey.slice(3); const key = this._setting.mouseKey.slice(3);
if (this._setting.mouseKey === OPT_MOUSEKEY_MOUSEOVER || e[key]) { if (this._setting.mouseKey === OPT_MOUSEKEY_MOUSEOVER || e[key]) {