// ==UserScript== // @name Github copy clone command button // @namespace http://tampermonkey.net/ // @version 1.0 // @description Add a 1-click copy button with the "git clone --recurse-submodules ..." command, after the Code button on the GitHub repository page // @author Poker powered by Copilot // @match https://github.com/*/* // @grant GM_setClipboard // ==/UserScript== (function() { 'use strict'; function getCloneCmd() { const match = location.pathname.match(/^\/([^\/]+)\/([^\/]+)(\/|$)/); if (!match) return null; return `git clone --recurse-submodules https://github.com/${match[1]}/${match[2]}.git`; } function copyCloneCmd(cmd) { if (!cmd) return; if (typeof GM_setClipboard === 'function') { GM_setClipboard(cmd); } else if (navigator.clipboard) { navigator.clipboard.writeText(cmd); } showTip(`Copied:${cmd}`); } function showTip(msg) { const tip = document.createElement('div'); tip.textContent = msg; tip.style.position = 'fixed'; tip.style.top = '20px'; tip.style.right = '20px'; tip.style.background = '#28a745'; tip.style.color = '#fff'; tip.style.padding = '8px 16px'; tip.style.borderRadius = '6px'; tip.style.zIndex = 9999; tip.style.fontSize = '16px'; tip.style.boxShadow = '0 2px 8px rgba(0,0,0,0.15)'; document.body.appendChild(tip); setTimeout(() => tip.remove(), 1800); } function addCopyButton() { const cmd = getCloneCmd(); if (!cmd) return; const codeBtn = Array.from(document.querySelectorAll('button')).find( btn => btn.textContent.trim() === 'Code' ); if (!codeBtn) return; if (document.getElementById('copy-clone-submodules-btn')) return; // SVG字符串多行可读 const svg = ` `.trim(); // 克隆Code按钮 const copyBtn = codeBtn.cloneNode(true); copyBtn.id = 'copy-clone-submodules-btn'; // 替换内容为SVG const contentSpan = copyBtn.querySelector('[data-component="buttonContent"]'); if (contentSpan) { contentSpan.innerHTML = svg; } else { copyBtn.innerHTML = svg; } // 设置title为命令内容 copyBtn.title = cmd; // 移除aria-haspopup等下拉相关属性 copyBtn.removeAttribute('aria-haspopup'); copyBtn.removeAttribute('aria-expanded'); copyBtn.removeAttribute('aria-describedby'); // 绑定复制事件 copyBtn.addEventListener('click', function(e) { e.preventDefault(); e.stopPropagation(); copyCloneCmd(cmd); }); // 插入到Code按钮后 codeBtn.parentNode.insertBefore(copyBtn, codeBtn.nextSibling); } // 监听页面变化(支持pjax和动态加载) const observer = new MutationObserver(addCopyButton); observer.observe(document.body, { childList: true, subtree: true }); addCopyButton(); })();