您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在 GitHub 仓库页面添加按钮,以快速打开对应的 DeepWiki 页面。
// ==UserScript== // @name GitHub to DeepWiki // @namespace http://tampermonkey.net/ // @version 0.1 // @description Adds a button to GitHub repo pages to open the corresponding DeepWiki page. // @description:zh-CN 在 GitHub 仓库页面添加按钮,以快速打开对应的 DeepWiki 页面。 // @author Leihao Zhou // @match https://github.com/*/* // @grant GM_addStyle // @grant window.open // @run-at document-idle // @name:zh-CN GitHub 跳转 DeepWiki // @license MIT // ==/UserScript== (function() { 'use strict'; const BUTTON_ID = 'deepwiki-button-userscript'; // Unique ID const addDeepWikiButton = () => { // 1. Check if already added if (document.getElementById(BUTTON_ID)) { return; } // 2. Check if on a valid repo page (path needs at least user/repo) const pathParts = location.pathname.split('/').filter(Boolean); // Ensure it's a repo page, not settings, issues, PRs etc. within the repo for simplicity // A more robust check might involve looking for specific page elements. if (pathParts.length !== 2) { // console.log('DeepWiki Button: Not on a main repo page.'); return; // Only target the main repo page for now } // 3. Find insertion point (try a few common selectors for GitHub's layout) const potentialTargets = [ '.gh-header-actions', // Newer layout '.pagehead-actions', // Older layout '#repository-container-header > div > div > div > ul' // Fallback selector observed ]; let targetElement = null; for (const selector of potentialTargets) { targetElement = document.querySelector(selector); if (targetElement) break; } if (!targetElement) { // console.log('DeepWiki Button: Target element not found using selectors:', potentialTargets); // Try again after a short delay in case the element is slow to render setTimeout(() => { if (!document.getElementById(BUTTON_ID)) { // Check again before retrying targetElement = document.querySelector(potentialTargets.join(', ')); // Try all at once if (targetElement) { insertButton(targetElement); } else { console.warn('DeepWiki Button: Target element still not found after delay.'); } } }, 1000); // Wait 1 second return; } insertButton(targetElement); }; const insertButton = (targetElement) => { // 4. Create button const button = document.createElement('a'); button.id = BUTTON_ID; button.textContent = '🚀 Open in DeepWiki'; button.target = '_blank'; button.rel = 'noopener noreferrer'; button.href = '#'; // Set href to '#' initially to make it behave like a link button.setAttribute('aria-label', 'Open this repository in DeepWiki'); button.setAttribute('role', 'button'); button.setAttribute('tabindex', '0'); // Make it focusable // Apply styles using GM_addStyle for better management or inline styles // Using inline styles for simplicity here button.style.marginLeft = '8px'; button.style.padding = '5px 16px'; // Adjusted padding like GitHub buttons button.style.border = '1px solid rgba(240, 246, 252, 0.1)'; // GitHub's border color button.style.borderRadius = '6px'; button.style.backgroundColor = '#21262d'; // GitHub's dark button background button.style.color = '#c9d1d9'; // GitHub's dark button text color button.style.fontWeight = '500'; button.style.fontSize = '14px'; // Match GitHub button font size button.style.lineHeight = '20px'; button.style.cursor = 'pointer'; button.style.textDecoration = 'none'; button.style.display = 'inline-flex'; button.style.alignItems = 'center'; button.style.verticalAlign = 'middle'; // Ensure vertical alignment // Add hover/focus effect mimicking GitHub const hoverBg = '#30363d'; const hoverBorder = '#8b949e'; const defaultBg = '#21262d'; const defaultBorder = 'rgba(240, 246, 252, 0.1)'; button.onmouseover = () => { button.style.backgroundColor = hoverBg; button.style.borderColor = hoverBorder; }; button.onmouseout = () => { button.style.backgroundColor = defaultBg; button.style.borderColor = defaultBorder; }; button.onfocus = () => { button.style.outline = '2px solid #58a6ff'; button.style.outlineOffset = '2px'; }; // Accessibility focus ring button.onblur = () => { button.style.outline = 'none'; }; const handleClick = (event) => { event.preventDefault(); // Prevent default link navigation event.stopPropagation(); // Stop event bubbling const currentUrl = location.href; // More robust replacement: ensure we only replace the domain and the base path const urlObject = new URL(currentUrl); const pathParts = urlObject.pathname.split('/').filter(Boolean); if (pathParts.length >= 2) { const user = pathParts[0]; const repo = pathParts[1]; const deepwikiUrl = `https://deepwiki.com/${user}/${repo}`; window.open(deepwikiUrl, '_blank'); } else { console.error('DeepWiki Button: Could not extract user/repo from URL:', currentUrl); } }; // 5. Add click handler button.addEventListener('click', handleClick); // Add keydown handler for accessibility (Enter/Space) button.addEventListener('keydown', (event) => { if (event.key === 'Enter' || event.key === ' ') { handleClick(event); } }); // 6. Insert button (prepend to appear first in the actions list, or append if prepend not suitable) // Using prepend is generally better for visibility if (targetElement.prepend) { targetElement.prepend(button); } else { targetElement.insertBefore(button, targetElement.firstChild); // Fallback for older browsers } console.log('DeepWiki Button added.'); } // --- Handling SPA Navigation --- // GitHub uses Turbo (formerly Turbolinks) for navigation. Observe changes to the body or a specific container. let previousUrl = location.href; const observer = new MutationObserver((mutationsList) => { // Check if URL changed - simple way to detect SPA navigation if (location.href !== previousUrl) { previousUrl = location.href; // Wait a bit for the new page elements to likely render after URL change setTimeout(addDeepWikiButton, 300); } else { // If URL didn't change, check if the button is missing and the target exists (e.g., partial DOM update) if (!document.getElementById(BUTTON_ID)) { const target = document.querySelector('.gh-header-actions, .pagehead-actions, #repository-container-header > div > div > div > ul'); if (target) { addDeepWikiButton(); // Try adding if target exists but button doesn't } } } }); // Start observing the body for subtree modifications and child list changes. // Observing 'body' is broad but reliable for catching SPA navigations. observer.observe(document.body, { childList: true, subtree: true }); // Initial run in case the page is already loaded // Use requestIdleCallback or setTimeout for potentially better timing if (document.readyState === 'complete' || document.readyState === 'interactive') { setTimeout(addDeepWikiButton, 500); // Delay slightly } else { document.addEventListener('DOMContentLoaded', () => setTimeout(addDeepWikiButton, 500)); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址