您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
Replaces GitHub's code language icons with Material Design Icons.
当前为
// ==UserScript== // @name GitHub Code Language Icons // @description Replaces GitHub's code language icons with Material Design Icons. // @icon https://github.githubassets.com/favicons/favicon-dark.svg // @version 1.0 // @author afkarxyz // @namespace https://github.com/afkarxyz/misc-scripts/ // @supportURL https://github.com/afkarxyz/misc-scripts/issues // @license MIT // @match https://github.com/* // @grant GM_setValue // @grant GM_getValue // ==/UserScript== (function() { 'use strict'; const ICON_BASE_URL = 'https://raw.githubusercontent.com/afkarxyz/misc-scripts/refs/heads/main/icons/'; function normalizeLanguageName(language) { const languageMappings = { 'csharp': ['c#'], 'docker': ['dockerfile'], 'console': ['batchfile', 'shell'] }; const normalizedLanguage = language.toLowerCase(); for (const [iconName, languageList] of Object.entries(languageMappings)) { if (languageList.includes(normalizedLanguage)) { return iconName; } } return normalizedLanguage; } async function fetchAvailableIcons() { const cacheKey = 'githubLanguageIconsCache'; const currentTime = Date.now(); const cachedData = JSON.parse(GM_getValue(cacheKey, '{}')); if (cachedData.timestamp && (currentTime - cachedData.timestamp < 7 * 24 * 60 * 60 * 1000)) { return cachedData.fileTypes; } try { const response = await fetch('https://raw.githubusercontent.com/afkarxyz/misc-scripts/refs/heads/main/icons.json'); const data = await response.json(); GM_setValue(cacheKey, JSON.stringify({ fileTypes: data.fileTypes, timestamp: currentTime })); return data.fileTypes; } catch (error) { console.error('Failed to fetch icon list:', error); return cachedData.fileTypes || []; } } async function replaceLanguageIcons() { let availableIcons; try { availableIcons = await fetchAvailableIcons(); } catch (error) { console.error('Error getting available icons:', error); return; } const elementsToProcess = [ ...document.querySelectorAll('.d-inline'), ...document.querySelectorAll('.f6.color-fg-muted .repo-language-color + span[itemprop="programmingLanguage"]'), ...document.querySelectorAll('.mb-3 .no-wrap span[itemprop="programmingLanguage"]') ]; elementsToProcess.forEach(element => { let langElement, language; if (element.closest('.d-inline')) { const parentItem = element.closest('.d-inline'); langElement = parentItem.querySelector('.text-bold'); if (!langElement || langElement.textContent.toLowerCase() === 'other' || parentItem.dataset.iconChecked) return; language = normalizeLanguageName(langElement.textContent); parentItem.dataset.iconChecked = 'true'; const svg = parentItem.querySelector('svg'); if (!svg || !availableIcons.includes(language)) return; const img = document.createElement('img'); img.src = `${ICON_BASE_URL}${language}.svg`; img.width = 16; img.height = 16; img.className = 'mr-2'; img.style.verticalAlign = 'middle'; svg.parentNode.replaceChild(img, svg); } else if (element.closest('.f6.color-fg-muted')) { language = normalizeLanguageName(element.textContent); if (!availableIcons.includes(language)) return; const parentSpan = element.parentElement; const colorSpan = parentSpan.querySelector('.repo-language-color'); const img = document.createElement('img'); img.src = `${ICON_BASE_URL}${language}.svg`; img.width = 16; img.height = 16; img.style.marginRight = '2px'; img.style.verticalAlign = 'sub'; if (colorSpan) { colorSpan.parentNode.insertBefore(img, colorSpan); colorSpan.remove(); } } else if (element.closest('.mb-3 .no-wrap')) { language = normalizeLanguageName(element.textContent); if (!availableIcons.includes(language)) return; const parentSpan = element.parentElement; const colorSpan = parentSpan.querySelector('.repo-language-color'); const img = document.createElement('img'); img.src = `${ICON_BASE_URL}${language}.svg`; img.width = 16; img.height = 16; img.style.marginRight = '4px'; const flexContainer = document.createElement('span'); flexContainer.style.display = 'inline-flex'; flexContainer.style.alignItems = 'center'; if (colorSpan) { colorSpan.remove(); flexContainer.appendChild(img); flexContainer.appendChild(element); parentSpan.parentNode.replaceChild(flexContainer, parentSpan); } } }); } let iconListPromise = null; function init() { const observer = new MutationObserver(() => { iconListPromise = iconListPromise ? iconListPromise.then(() => replaceLanguageIcons()) : replaceLanguageIcons(); }); observer.observe(document.body, { childList: true, subtree: true }); iconListPromise = replaceLanguageIcons(); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();