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]) {