兼容 GitHub 2026 最新 UI,添加分割线并优化视觉效果
// ==UserScript==
// @name GitHub RSS & Inoreader Helper
// @namespace http://tampermonkey.net/
// @version 1.1
// @description 兼容 GitHub 2026 最新 UI,添加分割线并优化视觉效果
// @author GeBron
// @match https://github.com/*/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand
// @grant GM_addStyle
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
// 优化样式:增加分割线和原生字体间距
GM_addStyle(`
#github-rss-helper {
padding-top: 16px;
margin-top: 16px;
border-top: 1px solid var(--color-border-muted, #d0d7de);
}
.rss-title {
font-size: 14px;
font-weight: 600;
margin-bottom: 12px;
color: var(--color-fg-default, #1f2328);
}
.rss-item {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.rss-label {
font-size: 12px;
font-weight: 500;
color: var(--color-fg-default);
}
.rss-btns {
display: flex;
gap: 6px;
}
.rss-btn {
padding: 3px 10px;
font-size: 11px;
font-weight: 500;
border-radius: 6px;
background-color: var(--color-btn-bg, #f6f8fa);
border: 1px solid var(--color-btn-border, rgba(31,35,40,0.15));
color: var(--color-btn-text, #24292f);
cursor: pointer;
text-decoration: none;
line-height: 1.2;
box-shadow: var(--color-calendar-graph-day-L1-shadow, 0 1px 0 rgba(27,31,36,0.04));
}
.rss-btn:hover {
background-color: var(--color-btn-hover-bg, #f3f4f6);
border-color: var(--color-btn-hover-border, rgba(31,35,40,0.15));
text-decoration: none;
}
`);
const FEED_TYPES = [
{ id: 'show_tags', label: 'Tags', suffix: 'tags.atom' },
{ id: 'show_releases', label: 'Releases', suffix: 'releases.atom' },
{ id: 'show_issues', label: 'Issues', suffix: 'issues.atom' },
{ id: 'show_commits', label: 'Commits', suffix: 'commits.atom' }
];
function inject() {
if (document.getElementById('github-rss-helper')) return;
const pathParts = window.location.pathname.split('/').filter(Boolean);
if (pathParts.length < 2) return;
const [owner, repo] = pathParts;
// 过滤非项目主页逻辑
if (['settings','pulls','issues','actions','projects','security','insights'].includes(repo)) return;
// 定位侧边栏
const sidebar =
document.querySelector('aside[aria-label="Repository sidebar"]') ||
document.querySelector('.Layout-sidebar') ||
document.querySelector('.BorderGrid')?.parentElement ||
document.querySelector('div[data-testid="sidebar"]');
if (!sidebar) return;
// 创建容器
const container = document.createElement('div');
container.id = 'github-rss-helper';
let html = `<div class="rss-title">RSS Feeds</div>`;
let hasActive = false;
FEED_TYPES.forEach(feed => {
if (GM_getValue(feed.id) === false) return;
hasActive = true;
const url = `https://github.com/${owner}/${repo}/${feed.suffix}`;
html += `
<div class="rss-item">
<span class="rss-label">${feed.label}</span>
<div class="rss-btns">
<a href="https://www.inoreader.com/?add_feed=${encodeURIComponent(url)}" target="_blank" class="rss-btn">Inoreader</a>
<button class="rss-btn copy-rss" data-url="${url}">Copy</button>
</div>
</div>`;
});
if (!hasActive) return;
container.innerHTML = html;
// 插入到侧边栏最后
sidebar.appendChild(container);
// 绑定复制事件
container.querySelectorAll('.copy-rss').forEach(btn => {
btn.onclick = (e) => {
e.preventDefault();
navigator.clipboard.writeText(btn.dataset.url);
const old = btn.innerText;
btn.innerText = 'OK!';
setTimeout(() => btn.innerText = old, 1000);
};
});
}
// 菜单管理
FEED_TYPES.forEach(type => {
if (GM_getValue(type.id) === undefined) GM_setValue(type.id, type.id !== 'show_commits');
GM_registerMenuCommand(`${GM_getValue(type.id) ? '✅' : '❌'} ${type.label}`, () => {
GM_setValue(type.id, !GM_getValue(type.id));
location.reload();
});
});
// 监控页面动态变化
let timer = null;
const observer = new MutationObserver(() => {
clearTimeout(timer);
timer = setTimeout(inject, 500);
});
observer.observe(document.body, { childList: true, subtree: true });
inject();
})();