标签 文件夹下载 下的文章

分享下 Gemini 搓的一个 Github 文件夹下载器,妈妈再也不用担心我为了一个文件夹下载整个仓库啦

精修样式,完美融入原生页面:

脚本源码:

// ==UserScript==
// @name                GitHub Folder Downloader
// @name:zh-CN          GitHub 文件夹下载器
// @version             0.7.0.33
// @author              叁月柒
// @match               *://github.com/*
// @grant               none
// @run-at              document-idle
// ==/UserScript==

(function () {
    'use strict';

    const isFolder = () => {
        const path = window.location.pathname.split('/').filter(Boolean);
        return path.length >= 2 && (path.length === 2 || path[2] === 'tree');
    };

    const injectToMenu = () => {
        const portalRoot = document.querySelector('#__primerPortalRoot__');
        if (!portalRoot) return;

        const menu = portalRoot.querySelector('ul[role="menu"]');
        if (!menu || menu.querySelector('.gh-download-integrated')) return;

        const menuText = menu.innerText;
        // 确保是操作菜单
        if (!menuText.includes('Copy path') && !menuText.includes('Delete directory')) return;

        // 1. 分割线
        const dividerHtml = `<li role="none" class="ActionList-sectionDivider gh-download-integrated"></li>`;

        // 2. 标题
        const headerHtml = `
            <li class="ActionList-sectionHeader gh-download-integrated" style="padding: 8px 16px 4px 16px;">
                <span class="ActionList-sectionHeader-label" style="color: #9198a1; font-size: 12px; font-weight: 500; display: block; line-height: 1.5;">
                    Download folder
                </span>
            </li>`;

        // 3. 子选项
        const createItem = (text, url) => `
            <li role="none" class="ActionList-item gh-download-integrated">
                <a role="menuitem" class="ActionList-content ActionList-content--visual16" target="_blank" rel="noopener noreferrer" href="${url}" style="text-decoration: none; padding-left: 16px;">
                    <span class="ActionList-item-label" style="padding-left: 24px; font-weight: 400; font-size: 14px; color: var(--fgColor-default, #adbac7);">
                        ${text}
                    </span>
                </a>
            </li>`;

        const downloadDirUrl = `https://download-directory.github.io?url=${window.location.href}`;
        const downGitUrl = `https://downgit.github.io/#/home?url=${window.location.href}`;

        const fragment = dividerHtml +
                         headerHtml +
                         createItem('by Download-Directory', downloadDirUrl) +
                         createItem('by DownGit', downGitUrl);

        menu.insertAdjacentHTML('beforeend', fragment);
    };

    const observer = new MutationObserver((mutations) => {
        if (!isFolder()) return;
        for (const mutation of mutations) {
            if (mutation.addedNodes.length > 0) {
                injectToMenu();
            }
        }
    });

    observer.observe(document.body, { childList: true, subtree: true });
})();

📌 转载信息
原作者:
MarSeventh
转载时间:
2026/1/24 16:04:58