繁体转简体(使用繁化姬API)

使用繁化姬API自动将网页繁体中文转换为简体中文

// ==UserScript==
// @name         繁体转简体(使用繁化姬API)
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  使用繁化姬API自动将网页繁体中文转换为简体中文
// @author       Claude
// @match        *://*/*
// @grant        GM_xmlhttpRequest
// @connect      api.zhconvert.org
// @run-at       document-end
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // 声明使用繁化姬API的提示信息
    console.log("本程序使用了繁化姬的API服务 - 繁化姬商用必须付费 - https://zhconvert.org");

    // 创建一个按钮,用于控制转换功能
    const createControlButton = () => {
        const controlButton = document.createElement('div');
        controlButton.style.position = 'fixed';
        controlButton.style.bottom = '20px';
        controlButton.style.right = '20px';
        controlButton.style.padding = '10px';
        controlButton.style.backgroundColor = '#f0f0f0';
        controlButton.style.border = '1px solid #ccc';
        controlButton.style.borderRadius = '5px';
        controlButton.style.cursor = 'pointer';
        controlButton.style.zIndex = '9999';
        controlButton.style.fontSize = '14px';
        controlButton.style.fontFamily = 'Arial, sans-serif';
        controlButton.style.boxShadow = '0 2px 5px rgba(0,0,0,0.2)';
        controlButton.innerHTML = '繁→简 <small>by 繁化姬</small>';
        controlButton.title = "本程序使用了繁化姬的API服务 - 繁化姬商用必须付费";
        
        // 添加繁化姬链接
        controlButton.addEventListener('click', function() {
            convertPage();
            controlButton.style.backgroundColor = '#e0e0e0';
            setTimeout(() => {
                controlButton.style.backgroundColor = '#f0f0f0';
            }, 300);
        });
        
        // 添加繁化姬官网链接
        const linkElement = document.createElement('a');
        linkElement.href = 'https://zhconvert.org';
        linkElement.target = '_blank';
        linkElement.style.position = 'fixed';
        linkElement.style.bottom = '10px';
        linkElement.style.right = '20px';
        linkElement.style.fontSize = '10px';
        linkElement.style.color = '#999';
        linkElement.style.textDecoration = 'none';
        linkElement.style.zIndex = '9999';
        linkElement.textContent = '繁化姬官网';
        
        document.body.appendChild(controlButton);
        document.body.appendChild(linkElement);
        
        return controlButton;
    };

    // 使用繁化姬API转换文本
    const convertTextViaAPI = (text, callback) => {
        if (!text || text.trim() === '') {
            callback('');
            return;
        }
        
        GM_xmlhttpRequest({
            method: 'POST',
            url: 'https://api.zhconvert.org/convert',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            data: 'text=' + encodeURIComponent(text) + '&converter=Simplified',
            onload: function(response) {
                try {
                    const result = JSON.parse(response.responseText);
                    if (result.code === 0) {
                        callback(result.data.text);
                    } else {
                        console.error('繁化姬API错误:', result.msg);
                        callback(text);
                    }
                } catch (e) {
                    console.error('解析API响应出错:', e);
                    callback(text);
                }
            },
            onerror: function(error) {
                console.error('API请求失败:', error);
                callback(text);
            }
        });
    };

    // 获取页面所有文本内容
    const getPageText = () => {
        // 获取body中的所有文本节点内容
        const walker = document.createTreeWalker(
            document.body,
            NodeFilter.SHOW_TEXT,
            {
                acceptNode: function(node) {
                    // 排除script和style标签中的内容
                    if (node.parentNode.tagName === 'SCRIPT' || 
                        node.parentNode.tagName === 'STYLE' || 
                        node.parentNode.tagName === 'NOSCRIPT') {
                        return NodeFilter.FILTER_REJECT;
                    }
                    // 如果节点内容不为空,接受该节点
                    if (node.nodeValue.trim() !== '') {
                        return NodeFilter.FILTER_ACCEPT;
                    }
                    return NodeFilter.FILTER_SKIP;
                }
            }
        );

        const textNodes = [];
        let currentNode;
        
        while (currentNode = walker.nextNode()) {
            textNodes.push(currentNode);
        }
        
        return textNodes;
    };

    // 批量处理文本节点以减少API调用次数
    const processTextNodesInBatches = (textNodes, batchSize = 20) => {
        if (textNodes.length === 0) return;
        
        // 将文本节点分组
        for (let i = 0; i < textNodes.length; i += batchSize) {
            const batch = textNodes.slice(i, i + batchSize);
            
            // 合并批次中的文本内容,使用特殊分隔符
            const separator = '|||||';
            const combinedText = batch.map(node => node.nodeValue).join(separator);
            
            // 调用API转换组合文本
            convertTextViaAPI(combinedText, (convertedText) => {
                // 分割转换后的文本
                const convertedParts = convertedText.split(separator);
                
                // 更新各个节点的文本内容
                for (let j = 0; j < batch.length && j < convertedParts.length; j++) {
                    batch[j].nodeValue = convertedParts[j];
                }
            });
        }
    };

    // 转换页面内容
    const convertPage = () => {
        const textNodes = getPageText();
        processTextNodesInBatches(textNodes);
    };

    // 初始化
    const init = () => {
        createControlButton();
    };

    // 当页面加载完成后初始化
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();