您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
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();
- }
- })();