GitCode 页面优化

优化GitCode页面显示,删除广告,修改git命令,添加暗黑模式和返回顶部

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         GitCode 页面优化
// @namespace    http://tampermonkey.net/
// @version      0.0.1
// @description  优化GitCode页面显示,删除广告,修改git命令,添加暗黑模式和返回顶部
// @author 小明
// @license MIT
// @icon         chrome://favicon/https://www.gitcode.com/
// @match        https://gitcode.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // 存储暗黑模式状态
    let darkModeEnabled = false;

    // 在DOM加载完成后执行
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', function() {
            setTimeout(initScript, 4000); // DOM加载完成后4秒执行
        });
    } else {
        setTimeout(initScript, 4000); // 页面已加载,直接延迟4秒执行
    }

    function initScript() {
        console.log('GitCode优化脚本开始执行');

        // 添加控制按钮
        addControlButtons();

        // 第一:删除广告元素(如果没有找到也不报错)
        removeAds();

        // 判断页面类型并执行相应操作
        if (isRepoPage1()) {
            console.log('检测到仓库页面1');
            handleRepoPage1();
        } else if (isRepoPage2()) {
            console.log('检测到仓库页面2');
            handleRepoPage2();
        } else {
            console.log('未检测到特定仓库页面');
        }

        // 通用处理:在整个页面中查找并替换global和main
        replaceGlobalAndMainInPage();
    }

    // 添加控制按钮(返回顶部和暗黑模式)
    function addControlButtons() {
        // 创建按钮容器
        const buttonContainer = document.createElement('div');
        buttonContainer.id = 'gitcode-controls';
        buttonContainer.style.cssText = `
            position: fixed;
            bottom: 20px;
            right: 20px;
            z-index: 9999;
            display: flex;
            flex-direction: column;
            gap: 10px;
        `;

        // 创建暗黑模式按钮
        const darkModeButton = document.createElement('button');
        darkModeButton.id = 'gitcode-dark-mode-btn';
        darkModeButton.textContent = '🌙 暗黑模式';
        darkModeButton.style.cssText = `
            padding: 10px 16px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            border-radius: 25px;
            cursor: pointer;
            font-weight: bold;
            box-shadow: 0 4px 12px rgba(0,0,0,0.15);
            transition: all 0.3s ease;
            font-family: 'Segoe UI', Arial, sans-serif;
            font-size: 14px;
        `;

        // 添加悬停效果
        darkModeButton.onmouseover = function() {
            this.style.transform = 'translateY(-2px)';
            this.style.boxShadow = '0 6px 16px rgba(0,0,0,0.2)';
        };
        darkModeButton.onmouseout = function() {
            this.style.transform = 'translateY(0)';
            this.style.boxShadow = '0 4px 12px rgba(0,0,0,0.15)';
        };

        // 暗黑模式切换功能
        darkModeButton.onclick = function() {
            darkModeEnabled = !darkModeEnabled;
            toggleDarkMode(darkModeEnabled);

            // 更新按钮文本
            this.textContent = darkModeEnabled ? '☀️ 明亮模式' : '🌙 暗黑模式';

            // 保存状态到localStorage
            localStorage.setItem('gitcode_dark_mode', darkModeEnabled ? 'enabled' : 'disabled');
        };

        // 创建返回顶部按钮
        const backToTopButton = document.createElement('button');
        backToTopButton.id = 'gitcode-back-to-top';
        backToTopButton.textContent = '⬆️ 返回顶部';
        backToTopButton.style.cssText = `
            padding: 10px 16px;
            background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
            color: white;
            border: none;
            border-radius: 25px;
            cursor: pointer;
            font-weight: bold;
            box-shadow: 0 4px 12px rgba(0,0,0,0.15);
            transition: all 0.3s ease;
            font-family: 'Segoe UI', Arial, sans-serif;
            font-size: 14px;
            opacity: 0;
            transform: translateY(20px);
        `;

        // 添加悬停效果
        backToTopButton.onmouseover = function() {
            this.style.transform = 'translateY(-2px)';
            this.style.boxShadow = '0 6px 16px rgba(0,0,0,0.2)';
        };
        backToTopButton.onmouseout = function() {
            this.style.transform = 'translateY(0)';
            this.style.boxShadow = '0 4px 12px rgba(0,0,0,0.15)';
        };

        // 返回顶部功能
        backToTopButton.onclick = function() {
            window.scrollTo({
                top: 0,
                behavior: 'smooth'
            });
        };

        // 添加按钮到容器
        buttonContainer.appendChild(darkModeButton);
        buttonContainer.appendChild(backToTopButton);
        document.body.appendChild(buttonContainer);

        // 检查并恢复暗黑模式状态
        const savedDarkMode = localStorage.getItem('gitcode_dark_mode');
        if (savedDarkMode === 'enabled') {
            darkModeEnabled = true;
            toggleDarkMode(true);
            darkModeButton.textContent = '☀️ 明亮模式';
        }

        // 监听滚动事件,显示/隐藏返回顶部按钮
        window.addEventListener('scroll', function() {
            if (window.scrollY > 300) {
                backToTopButton.style.opacity = '1';
                backToTopButton.style.transform = 'translateY(0)';
            } else {
                backToTopButton.style.opacity = '0';
                backToTopButton.style.transform = 'translateY(20px)';
            }
        });

        // 添加暗黑模式样式
        addDarkModeStyles();
    }

    // 切换暗黑模式
    function toggleDarkMode(enabled) {
        const appElement = document.getElementById('app');
        if (!appElement) return;

        if (enabled) {
            appElement.classList.add('gitcode-dark-mode');
            document.body.classList.add('gitcode-dark-mode-body');
        } else {
            appElement.classList.remove('gitcode-dark-mode');
            document.body.classList.remove('gitcode-dark-mode-body');
        }
    }

    // 添加暗黑模式样式
    function addDarkModeStyles() {
        const style = document.createElement('style');
        style.id = 'gitcode-dark-mode-styles';
        style.textContent = `
            /* 暗黑模式样式 */
            #app.gitcode-dark-mode {
                background-color: #1a1a1a !important;
                color: #e0e0e0 !important;
                filter: brightness(0.9) contrast(1.1);
            }

            .gitcode-dark-mode-body {
                background-color: #121212 !important;
            }

            #app.gitcode-dark-mode * {
                background-color: inherit !important;
                color: inherit !important;
                border-color: #444 !important;
            }

            #app.gitcode-dark-mode a {
                color: #4dabf7 !important;
            }

            #app.gitcode-dark-mode code,
            #app.gitcode-dark-mode pre {
                background-color: #2d2d2d !important;
                border-color: #444 !important;
            }

            #app.gitcode-dark-mode .devui-modal,
            #app.gitcode-dark-mode .devui-modal__body {
                background-color: #2d2d2d !important;
                border-color: #444 !important;
            }

            #app.gitcode-dark-mode input,
            #app.gitcode-dark-mode textarea,
            #app.gitcode-dark-mode select {
                background-color: #2d2d2d !important;
                color: #e0e0e0 !important;
                border-color: #555 !important;
            }

            #app.gitcode-dark-mode button {
                background-color: #333 !important;
                color: #e0e0e0 !important;
                border-color: #555 !important;
            }

            #app.gitcode-dark-mode .gitcode-dark-mode-btn {
                background: linear-gradient(135deg, #ff9a9e 0%, #fad0c4 100%) !important;
                color: #333 !important;
            }
        `;
        document.head.appendChild(style);
    }

    // 删除广告元素的函数
    function removeAds() {
        const selectors = [
            '#app > div > div.home-nav-right',
            '.announce-wrapper',
            '.devui-badge--count',
            '.g-header-search-recommend-placeholder'
        ];

        selectors.forEach(selector => {
            try {
                const element = document.querySelector(selector);
                if (element) {
                    element.remove();
                    console.log(`已删除: ${selector}`);
                }
            } catch (error) {
                // 静默失败,不报错
            }
        });
    }

    // 判断是否为仓库页面1
    function isRepoPage1() {
        return document.getElementById('readme') !== null;
    }

    // 判断是否为仓库页面2
    function isRepoPage2() {
        const hasCreateRepoWrapper = document.querySelector('.create-repo-wrapper') !== null;
        const hasEmptyRepoText = document.body.innerText.includes('当前项目代码仓是空仓库');
        return hasCreateRepoWrapper || hasEmptyRepoText;
    }

    // 处理仓库页面1
    function handleRepoPage1() {
        // 监听Clone按钮点击
        const cloneButton = document.querySelector('.cus-button-clone');
        if (cloneButton) {
            cloneButton.addEventListener('click', function() {
                // 等待弹窗出现
                setTimeout(() => {
                    handleCloneModal();
                }, 500);
            });
        }

        // 初始检查(如果弹窗已经存在)
        if (document.querySelector('.devui-modal__body')) {
            handleCloneModal();
        }
    }

    // 处理Clone弹窗
    function handleCloneModal() {
        const modalBody = document.querySelector('.devui-modal__body');
        if (!modalBody) return;

        // 1. 删除global
        replaceGlobalInElement(modalBody);

        // 2. 自动切换SSH
        autoSwitchToSSH();

        // 3. 修改复制按钮行为
        modifyCopyButtons(modalBody);
    }

    // 自动切换SSH
    function autoSwitchToSSH() {
        // 页面1的SSH切换
        const sshTabs = document.querySelectorAll('.repo-clone-tab-item');
        if (sshTabs.length >= 2) {
            // 点击第二个tab(SSH)
            sshTabs[1].click();
            console.log('已切换到SSH');
        }

        // 页面2的SSH切换
        const sshRadio = document.querySelector('input[value="SSH"]');
        if (sshRadio) {
            sshRadio.click();
            console.log('已切换到SSH(页面2)');
        }
    }

    // 修改复制按钮行为
    function modifyCopyButtons(container) {
        const copyButtons = container.querySelectorAll('.custom-icon-container, [xlink\\:href="#gt-line-copy"]');

        copyButtons.forEach(button => {
            // 移除旧的事件监听器
            const newButton = button.cloneNode(true);
            button.parentNode.replaceChild(newButton, button);

            // 添加新的事件监听器
            newButton.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();

                // 找到要复制的文本
                const textContainer = this.closest('.devui-row')?.querySelector('.whitespace-pre-wrap');
                if (textContainer) {
                    let text = textContainer.textContent;

                    // 删除global
                    text = text.replace(/--global /g, '');

                    // 复制到剪贴板
                    navigator.clipboard.writeText(text).then(() => {
                        console.log('已复制修改后的命令:', text);

                        // 显示复制成功的提示
                        showToast('命令已复制(已移除global)');
                    }).catch(err => {
                        console.error('复制失败:', err);
                    });
                }
            });
        });
    }

    // 处理仓库页面2
    function handleRepoPage2() {
        // 1. 自动切换SSH
        autoSwitchToSSH();

        // 2. 删除global
        replaceGlobalInElement(document.body);

        // 3. 把main改为master
        replaceMainToMasterInElement(document.body);
    }

    // 在整个页面中替换global和main
    function replaceGlobalAndMainInPage() {
        replaceGlobalInElement(document.body);
        replaceMainToMasterInElement(document.body);
    }

    // 在指定元素中删除global
    function replaceGlobalInElement(element) {
        const textNodes = getTextNodes(element);

        textNodes.forEach(node => {
            if (node.nodeType === Node.TEXT_NODE && node.textContent.includes('--global')) {
                const newText = node.textContent.replace(/--global /g, '');
                if (newText !== node.textContent) {
                    node.textContent = newText;
                    console.log('已删除global:', newText);
                }
            }
        });
    }

    // 在指定元素中将main替换为master
    function replaceMainToMasterInElement(element) {
        const textNodes = getTextNodes(element);

        textNodes.forEach(node => {
            if (node.nodeType === Node.TEXT_NODE) {
                let newText = node.textContent;

                // 替换 git branch -m main 为 git branch -m master
                newText = newText.replace(/git branch -m main/g, 'git branch -m master');

                // 替换 git push -u origin main 为 git push -u origin master
                newText = newText.replace(/git push -u origin main/g, 'git push -u origin master');

                // 替换其他可能的main引用(但确保是git命令中的)
                newText = newText.replace(/origin main(\s|$)/g, 'origin master$1');

                if (newText !== node.textContent) {
                    node.textContent = newText;
                    console.log('已将main替换为master');
                }
            }
        });
    }

    // 获取元素中的所有文本节点
    function getTextNodes(element) {
        const textNodes = [];
        const walker = document.createTreeWalker(
            element,
            NodeFilter.SHOW_TEXT,
            null,
            false
        );

        let node;
        while (node = walker.nextNode()) {
            textNodes.push(node);
        }

        return textNodes;
    }

    // 显示提示消息
    function showToast(message) {
        // 移除现有的提示
        const existingToast = document.querySelector('.gitcode-optimizer-toast');
        if (existingToast) {
            existingToast.remove();
        }

        // 创建新的提示
        const toast = document.createElement('div');
        toast.className = 'gitcode-optimizer-toast';
        toast.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            background: ${darkModeEnabled ? '#333' : '#4CAF50'};
            color: white;
            padding: 10px 20px;
            border-radius: 4px;
            z-index: 9999;
            font-family: Arial, sans-serif;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
            animation: fadeInOut 3s ease-in-out;
        `;

        // 添加动画样式
        const style = document.createElement('style');
        style.textContent = `
            @keyframes fadeInOut {
                0% { opacity: 0; transform: translateY(-20px); }
                10% { opacity: 1; transform: translateY(0); }
                90% { opacity: 1; transform: translateY(0); }
                100% { opacity: 0; transform: translateY(-20px); }
            }
        `;
        document.head.appendChild(style);

        toast.textContent = message;
        document.body.appendChild(toast);

        // 3秒后自动移除
        setTimeout(() => {
            if (toast.parentNode) {
                toast.remove();
            }
        }, 3000);
    }

    // 使用MutationObserver监听DOM变化
    const observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            if (mutation.addedNodes.length) {
                // 检查新添加的节点中是否有弹窗
                mutation.addedNodes.forEach(function(node) {
                    if (node.nodeType === Node.ELEMENT_NODE) {
                        if (node.classList && node.classList.contains('devui-modal__body')) {
                            setTimeout(() => {
                                handleCloneModal();
                            }, 100);
                        }

                        // 检查是否包含需要处理的元素
                        if (node.querySelector && (
                            node.querySelector('.devui-modal__body') ||
                            node.querySelector('.create-repo-wrapper') ||
                            node.querySelector('.repo-clone-tab')
                        )) {
                            replaceGlobalInElement(node);
                            replaceMainToMasterInElement(node);
                        }
                    }
                });
            }
        });
    });

    // 开始观察DOM变化(在脚本初始化后开始观察)
    setTimeout(() => {
        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
        console.log('开始监听DOM变化');
    }, 5000); // 延迟一点开始观察,确保脚本主体已执行

    console.log('GitCode优化脚本已加载,将在页面加载完成后4秒执行');
})();