| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- // text-processor.js
- import axios from 'axios'
- import { delayPerform } from 'js-perform-lock'
- const WindowsTranslateApi = 'https://jiasm.zfire.top/translate'
- // 数据过滤校验
- function isNumberRegex(str) {
- const regexPatterns = [
- /^\d+$/, // 纯数字
- /^\d*\.\d+$/, // 浮点数
- /^([01]\d|2[0-3]):([0-5]\d)$/, // 时间 (HH:MM)
- /^([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$/, // 时间 (HH:MM:SS)
- /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/, // 完整时间戳
- /^[A-Za-z]+$/, // 纯字母
- /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]+$/, // 字母和数字
- /^(?=.*[A-Za-z])(?=.*[\p{P}\p{S}])[\p{L}\p{P}\p{S}]+$/u, // 字母和标点符号
- /^(?=.*\d)(?=.*[\p{P}\p{S}])[\d\p{P}\p{S}]+$/u, // 数字和标点符号
- /^[\p{P}\s\dA-Za-z]+$/u // 字母、数字和标点符号
- ]
- return regexPatterns.some(pattern => pattern.test(str)) || !!window.Vue_Translation_Of_Text_Old_Data?.[str]
- }
- // 文本转译请求
- function pushNewText(data) {
- return new Promise(function (resolve, reject) {
- axios
- .post(`${WindowsTranslateApi}/api/v1/common/translationOfText`, data)
- .then(response => {
- if (response.data.code === 0) {
- const obj = {}
- const obj2 = {}
- response.data.data.forEach(val => {
- obj[val[0]] = val[1]
- obj2[val[1]] = true
- })
- window.Vue_Translation_Of_Text_Old_Data = {
- ...(window.Vue_Translation_Of_Text_Old_Data || {}),
- ...obj2
- }
- window.Vue_Translation_Of_Text_Data = {
- ...(window.Vue_Translation_Of_Text_Data || {}),
- ...obj
- }
- resolve(obj)
- } else {
- reject(new Error('API returned non-zero code'))
- }
- })
- .catch(reject)
- })
- }
- // 延迟替换处理器
- const deferredReplacement = (function () {
- const allKeywords = []
- const keywords = []
- const callbacks = []
- let keywordIndex = 0
- let callbackIndex = 0
- const delayProcessor = new delayPerform(250).refactor(function () {
- const currentKeywords = keywords.splice(0, keywordIndex)
- const currentCallbacks = callbacks.splice(0, callbackIndex)
- keywordIndex -= currentKeywords.length
- callbackIndex -= currentCallbacks.length
-
- if (currentKeywords.length > 0) {
- pushNewText({
- keywords: currentKeywords,
- targetLanguage: window?.Vue_Translation_Of_Text_Type
- }).then(() => {
- currentCallbacks.forEach(cb => cb?.())
- }).catch(error => {
- console.error('Translation failed:', error)
- currentCallbacks.forEach(cb => cb?.())
- })
- } else if (currentCallbacks.length > 0) {
- setTimeout(() => {
- currentCallbacks.forEach(cb => cb?.())
- }, 250)
- }
- })
- return function (text, callback) {
- delayProcessor()
- if (!allKeywords.includes(text)) {
- keywordIndex++
- allKeywords.push(text)
- keywords.push(text)
- }
- callbackIndex++
- callbacks.push(callback)
- }
- })()
- // DOM 处理器
- export const domProcessor = {
- // 处理文本节点
- processTextNode(node) {
- const text = node.textContent?.trim()
- if (!text || isNumberRegex(text)) return
- try {
- if (window.Vue_Translation_Of_Text_Data?.[text]) {
- node.textContent = window.Vue_Translation_Of_Text_Data[text]
- } else {
- deferredReplacement(text, () => {
- if (window.Vue_Translation_Of_Text_Data?.[text]) {
- node.textContent = window.Vue_Translation_Of_Text_Data[text]
- }
- })
- }
- } catch (error) {
- console.error('Text processing error:', error)
- }
- },
- // 处理输入框 placeholder
- processInputPlaceholder(element) {
- const placeholder = element.getAttribute('placeholder')?.trim()
- if (!placeholder || isNumberRegex(placeholder)) return
- try {
- if (window.Vue_Translation_Of_Text_Data?.[placeholder]) {
- element.setAttribute('placeholder', window.Vue_Translation_Of_Text_Data[placeholder])
- } else {
- deferredReplacement(placeholder, () => {
- if (window.Vue_Translation_Of_Text_Data?.[placeholder]) {
- element.setAttribute('placeholder', window.Vue_Translation_Of_Text_Data[placeholder])
- }
- })
- }
- } catch (error) {
- console.error('Placeholder processing error:', error)
- }
- },
- // 处理输入框值
- processInputValue(element) {
- const value = element.value?.trim()
- if (!value || isNumberRegex(value)) return
- try {
- if (window.Vue_Translation_Of_Text_Data?.[value]) {
- element.value = window.Vue_Translation_Of_Text_Data[value]
- } else {
- deferredReplacement(value, () => {
- if (window.Vue_Translation_Of_Text_Data?.[value]) {
- element.value = window.Vue_Translation_Of_Text_Data[value]
- }
- })
- }
- } catch (error) {
- console.error('Input value processing error:', error)
- }
- },
- // 处理属性文本
- processAttributeText(element, attributeName) {
- const value = element.getAttribute(attributeName)?.trim()
- if (!value || isNumberRegex(value)) return
- try {
- if (window.Vue_Translation_Of_Text_Data?.[value]) {
- element.setAttribute(attributeName, window.Vue_Translation_Of_Text_Data[value])
- } else {
- deferredReplacement(value, () => {
- if (window.Vue_Translation_Of_Text_Data?.[value]) {
- element.setAttribute(attributeName, window.Vue_Translation_Of_Text_Data[value])
- }
- })
- }
- } catch (error) {
- console.error(`Attribute ${attributeName} processing error:`, error)
- }
- },
- // 递归处理 DOM 元素
- processElement(element) {
- if (element && element.nodeType === Node.ELEMENT_NODE) {
- // 跳过 table 中的 td 元素
- // if (element.nodeName.toLowerCase() === 'td') {
- // return
- // }
- // 处理输入框和文本域
- if (['INPUT', 'TEXTAREA', 'SELECT'].includes(element.nodeName)) {
- this.processInputPlaceholder(element)
- if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {
- this.processInputValue(element)
- }
- }
- // 处理 Ant Design 组件属性
- this.processAttributeText(element, 'title')
- this.processAttributeText(element, 'aria-label')
- this.processAttributeText(element, 'alt')
- // 处理子节点
- Array.from(element.childNodes).forEach(child => {
- if (child.nodeType === Node.TEXT_NODE) {
- this.processTextNode(child)
- } else {
- this.processElement(child)
- }
- })
- }
- },
- // 处理特定选择器元素
- processSelector(selector) {
- Array.from(document.querySelectorAll(selector)).forEach(element => {
- this.processElement(element)
- })
- },
- // 处理标签名元素
- processTagName(tagName) {
- Array.from(document.getElementsByTagName(tagName)).forEach(element => {
- this.processElement(element)
- })
- }
- }
|