diff --git a/public/content.html b/public/content.html
index c0b214f..0455678 100644
--- a/public/content.html
+++ b/public/content.html
@@ -84,6 +84,11 @@
>
+
+
+
+
+
Shadow 1
diff --git a/src/libs/shortcut.js b/src/libs/shortcut.js
index c29f98f..4d48603 100644
--- a/src/libs/shortcut.js
+++ b/src/libs/shortcut.js
@@ -68,12 +68,12 @@ export const shortcutRegister = (targetKeys = [], fn, target = document) => {
/**
* 注册连续快捷键
- * @param {*} targetKeys
- * @param {*} fn
- * @param {*} step
- * @param {*} timeout
- * @param {*} target
- * @returns
+ * @param {*} targetKeys
+ * @param {*} fn
+ * @param {*} step
+ * @param {*} timeout
+ * @param {*} target
+ * @returns
*/
export const stepShortcutRegister = (
targetKeys = [],
@@ -84,12 +84,19 @@ export const stepShortcutRegister = (
) => {
let count = 0;
let pre = Date.now();
- return shortcutListener((curkeys) => {
- if (targetKeys.length > 0) {
+ let timer;
+ 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();
if (
(count === 0 || now - pre < timeout) &&
- isSameSet(new Set(targetKeys), new Set(curkeys))
+ isSameSet(new Set(targetKeys), new Set(allkeys))
) {
count++;
if (count === step) {
diff --git a/src/libs/translator.js b/src/libs/translator.js
index 69789e1..277cbe7 100644
--- a/src/libs/translator.js
+++ b/src/libs/translator.js
@@ -9,16 +9,22 @@ import {
SHADOW_KEY,
OPT_MOUSEKEY_DISABLE,
OPT_MOUSEKEY_MOUSEOVER,
+ DEFAULT_INPUT_RULE,
+ DEFAULT_TRANS_APIS,
} from "../config";
import Content from "../views/Content";
import { updateFetchPool, clearFetchPool } from "./fetch";
import { debounce, genEventName } from "./utils";
+import { stepShortcutRegister } from "./shortcut";
+import { apiTranslate } from "../apis";
+import { tryDetectLang } from ".";
/**
* 翻译类
*/
export class Translator {
_rule = {};
+ _inputRule = {};
_setting = {};
_rootNodes = new Set();
_tranNodes = new Map();
@@ -38,6 +44,7 @@ export class Translator {
"script",
"iframe",
];
+ _inputNodeNames = ["INPUT", "TEXTAREA"];
_eventName = genEventName();
// 显示
@@ -101,6 +108,12 @@ export class Translator {
if (rule.transOpen === "true") {
this._register();
}
+
+ const inputRule = setting.inputRule || DEFAULT_INPUT_RULE;
+ this._inputRule = { ...inputRule, selector: rule.inputSelector };
+ if (inputRule.transOpen && rule.inputSelector) {
+ this._registerInput();
+ }
}
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) => {
const key = this._setting.mouseKey.slice(3);
if (this._setting.mouseKey === OPT_MOUSEKEY_MOUSEOVER || e[key]) {