您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Display repository size on GitHub repo pages
当前为
您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
- // ==UserScript==
- // @name GitHub Repo Size Display
- // @namespace http://tampermonkey.net/
- // @version 1.0
- // @description Display repository size on GitHub repo pages
- // @license MIT
- // @author Lainbo
- // @match https://github.com/*
- // @grant GM_getValue
- // @grant GM_setValue
- // @grant GM_registerMenuCommand
- // @grant GM_addStyle
- // @icon data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMTQgMTQiPjxnIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxyZWN0IHdpZHRoPSIxMSIgaGVpZ2h0PSIxMyIgeD0iMS41IiB5PSIuNSIgcng9IjEiLz48cGF0aCBkPSJtNC41IDEwLjVsMS43NS0yLjc1TTQuMDkgN0EyLjkzIDIuOTMgMCAwIDEgNCA1LjE2YTMgMyAwIDEgMSA0LjY3IDMuMjdNNy41IDExSDEwIi8+PC9nPjwvc3ZnPg==
- // ==/UserScript==
- (function () {
- 'use strict'
- let observer
- let repoTitleComponent
- GM_addStyle(`
- .modal-overlay {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background-color: rgba(0, 0, 0, 0.5);
- display: flex;
- justify-content: center;
- align-items: center;
- z-index: 9999;
- }
- .modal-content {
- background-color: #f6f8fa;
- padding: 24px;
- border-radius: 6px;
- width: 340px;
- box-shadow: 0 8px 24px rgba(140,149,159,0.2);
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
- }
- .modal-title {
- font-size: 20px;
- font-weight: 600;
- margin-bottom: 16px;
- color: #24292f;
- }
- .modal-description {
- font-size: 14px;
- color: #57606a;
- margin-bottom: 16px;
- line-height: 1.5;
- }
- .modal-content input {
- width: 100%;
- margin-bottom: 16px;
- padding: 5px 12px;
- font-size: 14px;
- line-height: 20px;
- color: #24292f;
- vertical-align: middle;
- background-color: #ffffff;
- background-repeat: no-repeat;
- background-position: right 8px center;
- border: 1px solid #d0d7de;
- border-radius: 6px;
- box-shadow: inset 0 1px 0 rgba(208,215,222,0.2);
- }
- .modal-content button {
- color: #ffffff;
- background-color: #2da44e;
- padding: 5px 16px;
- font-size: 14px;
- font-weight: 500;
- line-height: 20px;
- white-space: nowrap;
- vertical-align: middle;
- cursor: pointer;
- border: 1px solid;
- border-radius: 6px;
- appearance: none;
- user-select: none;
- margin-right: 8px;
- }
- .modal-content button.cancel {
- color: #24292f;
- background-color: #f6f8fa;
- border-color: rgba(27,31,36,0.15);
- }
- .modal-content button:hover {
- background-color: #2c974b;
- }
- .modal-content button.cancel:hover {
- background-color: #f3f4f6;
- }
- .repo-size-label.error {
- background-color: #ffdce0;
- color: #cf222e;
- }
- `)
- function formatSize(sizeInKB) {
- if (sizeInKB >= 1024 * 1024) {
- return `${(sizeInKB / (1024 * 1024)).toFixed(2)} GB`
- }
- else if (sizeInKB >= 1024) {
- return `${(sizeInKB / 1024).toFixed(2)} MB`
- }
- else {
- return `${sizeInKB} KB`
- }
- }
- function updateRepoSize(content, isError = false) {
- if (!repoTitleComponent) {
- repoTitleComponent = document.querySelector('#repo-title-component')
- if (!repoTitleComponent) { return }
- }
- let sizeElement = repoTitleComponent.querySelector('.repo-size-label')
- if (!sizeElement) {
- sizeElement = document.createElement('span')
- sizeElement.className = 'Label Label--secondary v-align-middle ml-1 repo-size-label'
- repoTitleComponent.appendChild(sizeElement)
- }
- sizeElement.textContent = content
- sizeElement.classList.toggle('error', isError)
- }
- function fetchRepoSize() {
- const repoRegex = /^https?:\/\/github\.com\/([^/]+)\/([^/]+)\/?$/
- const match = location.href.match(repoRegex)
- if (!match) { return }
- const [, owner, repo] = match
- const apiUrl = `https://api.github.com/repos/${owner}/${repo}`
- const token = GM_getValue('github_token', '')
- if (!token) {
- updateRepoSize('Token not set', true)
- return
- }
- fetch(apiUrl, {
- headers: { Authorization: `token ${token}` },
- })
- .then((response) => {
- if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) }
- return response.json()
- })
- .then((data) => {
- if (data.size !== undefined) {
- updateRepoSize(formatSize(data.size))
- }
- else {
- throw new Error('Size information not available')
- }
- })
- .catch((error) => {
- console.error('Error fetching repo size:', error)
- updateRepoSize('Size fetch failed', true)
- })
- }
- function createModal() {
- const modalHTML = `
- <div class="modal-overlay">
- <div class="modal-content">
- <h2 class="modal-title">Set GitHub Token</h2>
- <p class="modal-description">Enter your GitHub personal access token with "repo" scope.</p>
- <input type="text" id="github-token-input" placeholder="Enter your GitHub personal access token">
- <button id="save-token">Save</button>
- <button id="cancel-token" class="cancel">Cancel</button>
- </div>
- </div>
- `
- const modalContainer = document.createElement('div')
- modalContainer.innerHTML = modalHTML
- document.body.appendChild(modalContainer)
- const input = document.getElementById('github-token-input')
- input.value = GM_getValue('github_token', '')
- document.getElementById('save-token').addEventListener('click', () => {
- const token = input.value.trim()
- if (token) {
- GM_setValue('github_token', token)
- modalContainer.remove()
- location.reload()
- }
- })
- document.getElementById('cancel-token').addEventListener('click', () => modalContainer.remove())
- }
- function observePageChanges() {
- if (observer) {
- observer.disconnect()
- }
- const targetNode = document.body
- const config = { childList: true, subtree: true }
- observer = new MutationObserver((mutationsList, observer) => {
- for (const mutation of mutationsList) {
- if (mutation.type === 'childList') {
- repoTitleComponent = document.querySelector('#repo-title-component')
- if (repoTitleComponent && !repoTitleComponent.querySelector('.repo-size-label')) {
- fetchRepoSize()
- observer.disconnect()
- break
- }
- }
- }
- })
- observer.observe(targetNode, config)
- }
- function init() {
- fetchRepoSize()
- observePageChanges()
- }
- // Register the menu command to set the GitHub token
- GM_registerMenuCommand('Set GitHub Token', createModal)
- // Execute on page load
- window.addEventListener('load', init)
- // Listen for GitHub's pjax:end event to handle updates during internal navigation
- document.addEventListener('pjax:end', init)
- })()