Spaces:
Configuration error
Configuration error
| class TExe { | |
| static T = null; | |
| constructor() { | |
| this.excludeClass = ["lite-search-item-type"]; | |
| } | |
| tSkip(node) { | |
| // 是否需要跳过翻译? | |
| // 判断node.classList 是否包含 excludeClass中的一个 | |
| return this.excludeClass.some((cls) => node.classList?.contains(cls)); | |
| } | |
| translateKjPopDesc(node) { | |
| let T = this.T; | |
| if (!T) return false; | |
| if (!node || !node.querySelectorAll) return false; | |
| if (!node?.classList?.contains("kj-documentation-popup")) return false; | |
| const allElements = node.querySelectorAll("*"); | |
| for (const ele of allElements) { | |
| this.replaceText(ele); | |
| } | |
| return true; | |
| } | |
| translateAllText(node) { | |
| let T = this.T; | |
| if (!T) return; | |
| if (!node || !node.querySelectorAll) return; | |
| const allElements = node.querySelectorAll("*"); | |
| for (const ele of allElements) { | |
| let targetLangText = T.Menu[ele.innerText]; | |
| if (!targetLangText) { | |
| if (ele.nodeName === "INPUT" && ele.type === "button") { | |
| targetLangText = T.Menu[ele.value]; | |
| if (!targetLangText) continue; | |
| ele.value = targetLangText; | |
| } | |
| continue; | |
| } | |
| this.replaceText(ele); | |
| } | |
| } | |
| replaceText(target) { | |
| let T = this.T; | |
| if (!T) return; | |
| if (this.tSkip(target)) return; | |
| if (target?.childNodes.length > 1) { | |
| for (const childNode of target.childNodes) { | |
| this.replaceText(childNode); | |
| const targetLangText = childNode?.nodeType === Node.ELEMENT_NODE ? T.Menu[childNode.innerText] : T.Menu[childNode.nodeValue]; | |
| if (!targetLangText) continue; | |
| if (childNode?.nodeType === Node.TEXT_NODE) { | |
| childNode.nodeValue = targetLangText; | |
| } | |
| if (childNode?.nodeType === Node.ELEMENT_NODE) { | |
| childNode.innerText = targetLangText; | |
| } | |
| } | |
| } else { | |
| if (target?.firstChild) { | |
| this.replaceText(target.firstChild); | |
| } | |
| if (target?.firstChild?.nodeType === Node.TEXT_NODE) { | |
| const targetLangText = T.Menu[target.firstChild.nodeValue]; | |
| if (!targetLangText) return; | |
| target.innerText = targetLangText; | |
| } | |
| } | |
| } | |
| } | |
| let texe = new TExe(); | |
| export function applyMenuTranslation(T) { | |
| texe.T = T; | |
| texe.translateAllText(document.querySelector(".litegraph")); | |
| for (let node of document.querySelectorAll(".comfy-modal")) | |
| observeFactory(node, (mutationsList, observer) => { | |
| for (let mutation of mutationsList) { | |
| texe.translateAllText(mutation.target); | |
| } | |
| }); | |
| const viewHistoryButton = document.getElementById("comfy-view-history-button"); | |
| const viewQueueButton = document.getElementById("comfy-view-queue-button"); | |
| [viewHistoryButton, viewQueueButton].map((btn) => { | |
| observeFactory(btn, (mutationsList, observer) => { | |
| observer.disconnect(); | |
| for (let mutation of mutationsList) { | |
| if (mutation.type === "childList") { | |
| const translatedValue = T.Menu[mutation.target.textContent]; | |
| if (!translatedValue) continue; | |
| mutation.target.innerText = translatedValue; | |
| } | |
| } | |
| observer.observe(btn, { childList: true, attributes: true }); | |
| }); | |
| }); | |
| const comfySettingDialog = document.querySelector("#comfy-settings-dialog"); | |
| observeFactory(comfySettingDialog.querySelector("tbody"), handleComfySettingDialogObserver); | |
| observeFactory(document.querySelector(".comfy-menu"), handleViewQueueComfyListObserver); | |
| observeFactory(document.querySelector(".comfy-menu").querySelectorAll(".comfy-list")[0], handleViewQueueComfyListObserver); | |
| observeFactory(document.querySelector(".comfy-menu").querySelectorAll(".comfy-list")[1], handleViewQueueComfyListObserver); | |
| observeFactory(document.querySelector("body.litegraph"), (mutationsList, observer) => { | |
| for (let mutation of mutationsList) { | |
| for (const node of mutation.addedNodes) { | |
| // if (texe.translateKjPopDesc(node)) continue; | |
| texe.translateAllText(node); | |
| if (node.classList.contains("comfy-modal")) { | |
| observeFactory(node, (mutationsList, observer) => { | |
| for (let mutation of mutationsList) { | |
| texe.translateAllText(mutation.target); | |
| } | |
| }); | |
| } | |
| } | |
| } | |
| }); | |
| // search box | |
| observeFactory(document.querySelector(".litegraph"), (mutationsList, observer) => { | |
| if (observer.ob == undefined) { | |
| observer.ob = []; | |
| } | |
| for (let mutation of mutationsList) { | |
| if (mutation.removedNodes.length > 0 && observer.ob != undefined) { | |
| for (let ob of observer.ob) ob.disconnect(); | |
| observer.ob = []; | |
| break; | |
| } | |
| for (const sb of mutation.addedNodes) { | |
| if (!sb || !sb.querySelector) continue | |
| var helper = sb.querySelector(".helper"); | |
| if (!helper) continue; | |
| var ob = observeFactory(helper, (mutationsList, observer) => { | |
| for (let mutation of mutationsList) { | |
| for (const item of mutation.addedNodes) { | |
| if (item.innerText in T.Nodes) { | |
| item.innerText = T.Nodes[item.innerText]["title"]; | |
| } | |
| } | |
| } | |
| }); | |
| for (let item of helper.querySelectorAll(".lite-search-item")) { | |
| if (item.innerText in T.Nodes) { | |
| item.innerText = T.Nodes[item.innerText]["title"]; | |
| } | |
| } | |
| observer.ob.push(ob); | |
| } | |
| } | |
| }); | |
| function handleViewQueueComfyListObserver(mutationsList) { | |
| for (let mutation of mutationsList) { | |
| texe.replaceText(mutation.target); | |
| if (mutation.type === "childList" && mutation.addedNodes.length > 0) { | |
| for (const node of mutation.addedNodes) { | |
| texe.replaceText(node); | |
| } | |
| } | |
| } | |
| } | |
| const translateSettingDialog = () => { | |
| const comfySettingDialogAllElements = comfySettingDialog.querySelectorAll("*"); | |
| for (const ele of comfySettingDialogAllElements) { | |
| let targetLangText = T.Menu[ele.innerText]; | |
| let titleText = T.Menu[ele.title]; | |
| if(titleText) ele.title = titleText; | |
| if (!targetLangText) { | |
| if (ele.nodeName === "INPUT" && ele.type === "button") { | |
| targetLangText = T.Menu[ele.value]; | |
| if (!targetLangText) continue; | |
| ele.value = targetLangText; | |
| } | |
| continue; | |
| } | |
| texe.replaceText(ele); | |
| } | |
| }; | |
| function handleComfySettingDialogObserver(mutationsList) { | |
| for (let mutation of mutationsList) { | |
| if (mutation.type === "childList" && mutation.addedNodes.length > 0) { | |
| translateSettingDialog(); | |
| } | |
| } | |
| } | |
| } | |
| export function observeFactory(observeTarget, fn) { | |
| const observer = new MutationObserver(function (mutationsList, observer) { | |
| fn(mutationsList, observer); | |
| }); | |
| observer.observe(observeTarget, { | |
| childList: true, | |
| attributes: true, | |
| }); | |
| return observer; | |
| } | |