(node)
| 821 | |
| 822 | // 返回最终应该翻译的父节点或 false |
| 823 | function getTransNode(node) { |
| 824 | let model = util.getValue('model') |
| 825 | // 1、全局节点与空节点、文字过多的节点、class="notranslate" 的节点不翻译 |
| 826 | if (!node || [document.documentElement, document.body].includes(node) |
| 827 | || node.tagName.toLowerCase() === "iframe" || node.classList.contains('notranslate') |
| 828 | || node.textContent.length > 8192 |
| 829 | ) return false; |
| 830 | // 2、特例适配标签,遇到这些标签则直接返回节点 |
| 831 | if (specialSet.has(node.tagName.toLowerCase())) return node; |
| 832 | // 3、特例适配函数,根据 host 适配、且支持匹配 class |
| 833 | let fn = getTransNodeCompat.get(url.host); |
| 834 | if (fn && fn(node)) return node; |
| 835 | // 4、检测当前节点是否满足翻译条件 |
| 836 | if (getTransNodeSet.has(node.tagName.toLowerCase()) || detectChildMeta(node)) { |
| 837 | return getTransNode(node.parentNode) || node; // 如果当前节点满足翻译条件,则向上寻找最终符合的父节点 |
| 838 | } |
| 839 | // 5、如果节点是div并且不符合一般翻译条件,可翻译首行文本 |
| 840 | if (node.tagName.toLowerCase() === 'div') { |
| 841 | // 遍历子节点,寻找首个文本节点或 a 标签节点 |
| 842 | let child = node.firstChild; |
| 843 | while (child) { |
| 844 | if (child.nodeType === Node.TEXT_NODE && child.textContent.trim() !== '') { |
| 845 | transModelFn[model](child.textContent).then(text => { |
| 846 | child.textContent = text; |
| 847 | }) |
| 848 | return false; // 只翻译首行文本 |
| 849 | } |
| 850 | child = child.nextSibling; |
| 851 | } |
| 852 | } |
| 853 | // 6、翻译文本节点 |
| 854 | if (node.nodeType === Node.TEXT_NODE && node.textContent.trim() !== '') { |
| 855 | transModelFn[model](node.textContent).then(text => { |
| 856 | node.textContent = text; |
| 857 | }) |
| 858 | return false; // 只翻译文本节点 |
| 859 | } |
| 860 | |
| 861 | // console.log('不翻译节点:', node); |
| 862 | return false |
| 863 | } |
| 864 | |
| 865 | // node 的 parentNode 只含有这些标签时,会向上翻译 parentNode |
| 866 | const detectChildMetaSet = new Set([ |
no test coverage detected