feat: enhanced hook function functionality

This commit is contained in:
Gabe
2025-08-27 01:02:11 +08:00
parent fd2f0e513b
commit 5c44ba1da8
4 changed files with 38 additions and 33 deletions

View File

@@ -1184,9 +1184,9 @@ export const I18N = {
zh_TW: `翻譯開始 Hook`, zh_TW: `翻譯開始 Hook`,
}, },
translate_start_hook_helper: { translate_start_hook_helper: {
zh: `翻译开始时运行,入参为: 翻译节点,原文文本。`, zh: `翻译开始时运行,入参为: 翻译节点,原文文本,返回:待译文本`,
en: `Run when translation starts, the input parameters are: translation node, original text.`, en: `Run when translation starts, the input parameters are: translation node, original text, and returns: text to be translated.`,
zh_TW: `翻譯開始時執行,入參為:翻譯節點、原文文字。`, zh_TW: `翻譯開始時執行,入參為:翻譯節點、原文文字,回傳:待譯文本`,
}, },
translate_end_hook: { translate_end_hook: {
zh: `翻译完成钩子函数`, zh: `翻译完成钩子函数`,
@@ -1194,9 +1194,9 @@ export const I18N = {
zh_TW: `翻譯完成 Hook`, zh_TW: `翻譯完成 Hook`,
}, },
translate_end_hook_helper: { translate_end_hook_helper: {
zh: `翻译完成时运行,入参为: 翻译节点,原文文本,译文文本,保留元素。`, zh: `翻译完成时运行,入参为: 翻译节点,原文文本,译文文本,保留元素、术语列表,返回:译文文本`,
en: `Run when the translation is completed, the input parameters are: translation node, original text, translation text, retained elements.`, en: `Run when the translation is completed, the input parameters are: translation node, original text, translation text, retained elements, and returns: translation text.`,
zh_TW: `翻譯完成時執行,入參為:翻譯節點、原文文字、譯文文字、保留元素。`, zh_TW: `翻譯完成時執行,入參為:翻譯節點、原文文字、譯文文字、保留元素,返回:譯文文本`,
}, },
translate_remove_hook: { translate_remove_hook: {
zh: `翻译移除钩子函数`, zh: `翻译移除钩子函数`,

View File

@@ -14,7 +14,7 @@ import { kissLog } from "../libs/log";
*/ */
export function useTranslate(q, rule, setting) { export function useTranslate(q, rule, setting) {
const [text, setText] = useState(""); const [text, setText] = useState("");
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(true);
const [sameLang, setSamelang] = useState(false); const [sameLang, setSamelang] = useState(false);
const { translator, fromLang, toLang, detectRemote, skipLangs = [] } = rule; const { translator, fromLang, toLang, detectRemote, skipLangs = [] } = rule;
@@ -22,8 +22,6 @@ export function useTranslate(q, rule, setting) {
useEffect(() => { useEffect(() => {
(async () => { (async () => {
try { try {
setLoading(true);
if (!q.replace(/\[(\d+)\]/g, "").trim()) { if (!q.replace(/\[(\d+)\]/g, "").trim()) {
setText(q); setText(q);
setSamelang(false); setSamelang(false);

View File

@@ -495,13 +495,6 @@ export class Translator {
let q = el.innerText.trim(); let q = el.innerText.trim();
const keeps = []; const keeps = [];
// 翻译开始钩子函数
const { transStartHook } = this._rule;
if (transStartHook?.trim()) {
interpreter.run(`exports.transStartHook = ${transStartHook}`);
interpreter.exports.transStartHook(el, q);
}
// 保留元素 // 保留元素
const keepSelector = this._keepSelector.trim(); const keepSelector = this._keepSelector.trim();
if (keepSelector) { if (keepSelector) {
@@ -540,17 +533,22 @@ export class Translator {
const re = new RegExp(term[0], "g"); const re = new RegExp(term[0], "g");
q = q.replace(re, (t) => { q = q.replace(re, (t) => {
const text = `[${keeps.length}]`; const text = `[${keeps.length}]`;
keeps.push(`<i class="kiss-trem">${term[1] || t}</i>`); keeps.push(`<i class="kiss-term">${term[1] || t}</i>`);
return text; return text;
}); });
} }
} }
// 附加样式 // 翻译开始钩子函数
const { selectStyle, parentStyle } = this._rule; const { transStartHook } = this._rule;
el.style.cssText += selectStyle; if (transStartHook?.trim()) {
if (el.parentElement) { interpreter.run(`exports.transStartHook = ${transStartHook}`);
el.parentElement.style.cssText += parentStyle; q = interpreter.exports.transStartHook(el, q);
}
// 终止翻译
if (!q) {
return;
} }
// 插入译文节点 // 插入译文节点
@@ -564,5 +562,12 @@ export class Translator {
// 渲染译文节点 // 渲染译文节点
const root = createRoot(traEl); const root = createRoot(traEl);
root.render(<Content q={q} keeps={keeps} translator={this} $el={el} />); root.render(<Content q={q} keeps={keeps} translator={this} $el={el} />);
// 附加样式
const { selectStyle, parentStyle } = this._rule;
el.style.cssText += selectStyle;
if (el.parentElement) {
el.parentElement.style.cssText += parentStyle;
}
}; };
} }

View File

@@ -129,14 +129,6 @@ export default function Content({ q, keeps, translator, $el }) {
}; };
}, [translator.eventName]); }, [translator.eventName]);
useEffect(() => {
// 运行钩子函数
if (text && transEndHook?.trim()) {
interpreter.run(`exports.transEndHook = ${transEndHook}`);
interpreter.exports.transEndHook($el, q, text, keeps);
}
}, [$el, q, text, keeps, transEndHook]);
const gap = useMemo(() => { const gap = useMemo(() => {
if (transOnly === "true") { if (transOnly === "true") {
return ""; return "";
@@ -154,6 +146,16 @@ export default function Content({ q, keeps, translator, $el }) {
[textStyle, textDiyStyle, bgColor, transTag] [textStyle, textDiyStyle, bgColor, transTag]
); );
const trText = useMemo(() => {
if (loading || !transEndHook?.trim()) {
return text;
}
// 翻译完成钩子函数
interpreter.run(`exports.transEndHook = ${transEndHook}`);
return interpreter.exports.transEndHook($el, q, text, keeps);
}, [loading, $el, q, text, keeps, transEndHook]);
if (loading) { if (loading) {
return ( return (
<> <>
@@ -163,7 +165,7 @@ export default function Content({ q, keeps, translator, $el }) {
); );
} }
if (!text || sameLang) { if (!trText || sameLang) {
return; return;
} }
@@ -186,7 +188,7 @@ export default function Content({ q, keeps, translator, $el }) {
<StyledSpan <StyledSpan
{...styles} {...styles}
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: text.replace(/\[(\d+)\]/g, (_, p) => keeps[parseInt(p)]), __html: trText.replace(/\[(\d+)\]/g, (_, p) => keeps[parseInt(p)]),
}} }}
/> />
</> </>
@@ -196,7 +198,7 @@ export default function Content({ q, keeps, translator, $el }) {
return ( return (
<> <>
{gap} {gap}
<StyledSpan {...styles}>{text}</StyledSpan> <StyledSpan {...styles}>{trText}</StyledSpan>
</> </>
); );
} }