GitHub Files Icon Replacement

Replace GitHub file icons with Material icons

当前为 2024-12-29 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name GitHub Files Icon Replacement
  3. // @name:vi Thay thế biểu tượng tệp GitHub
  4. // @name:zh-cn GitHub 文件图标替换
  5. // @name:zh-tw GitHub 文件圖標替換
  6. // @name:ru Замена иконок файлов GitHub
  7. // @namespace http://tampermonkey.net/
  8. // @version 2024.12.29.1
  9. // @description Replace GitHub file icons with Material icons
  10. // @description:vi Thay thế icon file trên GitHub bằng icon Material
  11. // @description:zh-cn 用更漂亮的图标替换 GitHub 文件图标
  12. // @description:zh-tw 用更漂亮的圖標替換 GitHub 文件圖標
  13. // @description:ru Замена иконок файлов GitHub на более красивые
  14. // @author Yuusei
  15. // @match https://github.com/*
  16. // @icon https://github.githubassets.com/favicon.ico
  17. // @grant GM_addStyle
  18. // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js
  19. // @run-at document-start
  20. // @license GPL-3.0-only
  21. // @compatible chrome
  22. // @compatible firefox
  23. // @compatible edge
  24. // @compatible safari
  25. // ==/UserScript==
  26.  
  27. (function ($) {
  28. 'use strict';
  29.  
  30. // Add custom styles
  31. GM_addStyle(`
  32. .material-icon {
  33. width: 20px;
  34. height: 20px;
  35. vertical-align: text-bottom;
  36. margin-right: 4px;
  37. transition: transform 0.2s ease;
  38. }
  39. .material-icon:hover {
  40. transform: scale(1.2);
  41. }
  42. `);
  43.  
  44. const iconMap = {
  45. // Development
  46. '.ts': 'typescript',
  47. '.tsx': 'react_ts',
  48. '.js': 'javascript',
  49. '.jsx': 'react',
  50. '.py': 'python',
  51. '.java': 'java',
  52. '.cpp': 'cpp',
  53. '.c': 'c',
  54. '.cs': 'csharp',
  55. '.go': 'go',
  56. '.rb': 'ruby',
  57. '.php': 'php',
  58. '.rs': 'rust',
  59. '.swift': 'swift',
  60. '.kt': 'kotlin',
  61. '.scala': 'scala',
  62. '.dart': 'dart',
  63. '.lua': 'lua',
  64. '.r': 'r',
  65. '.sh': 'console',
  66. '.ps1': 'powershell',
  67. '.bat': 'console',
  68. '.cmd': 'console',
  69. '.wasm': 'assembly',
  70. '.code-workspace': 'vscode',
  71. '.sln': 'visualstudio',
  72.  
  73. // Web
  74. '.html': 'html',
  75. '.htm': 'html',
  76. '.css': 'css',
  77. '.scss': 'sass',
  78. '.sass': 'sass',
  79.  
  80. '.less': 'less',
  81. '.styl': 'stylus',
  82. '.vue': 'vue',
  83. '.svelte': 'svelte',
  84. '.angular': 'angular',
  85.  
  86. // Data & Config
  87. '.json': 'json',
  88. '.yml': 'yaml',
  89. '.yaml': 'yaml',
  90. '.xml': 'xml',
  91. '.toml': 'settings',
  92. '.ini': 'settings',
  93. '.env': 'tune',
  94. '.conf': 'settings',
  95. '.sql': 'database',
  96. '.db': 'database',
  97. '.sqlite': 'database',
  98. '.graphql': 'graphql',
  99. '.proto': 'protobuf',
  100.  
  101. // Documentation
  102. '.md': 'markdown',
  103. '.mdx': 'markdown',
  104. '.txt': 'document',
  105. '.pdf': 'pdf',
  106. '.doc': 'word',
  107. '.docx': 'word',
  108. '.odt': 'document',
  109. '.rtf': 'document',
  110.  
  111. // Images
  112. '.svg': 'svg',
  113. '.png': 'image',
  114. '.jpg': 'image',
  115. '.jpeg': 'image',
  116. '.gif': 'image',
  117. '.ico': 'image',
  118. '.webp': 'image',
  119. '.bmp': 'image',
  120.  
  121. // Media
  122. '.mp3': 'audio',
  123. '.wav': 'audio',
  124. '.ogg': 'audio',
  125. '.mp4': 'video',
  126. '.webm': 'video',
  127. '.avi': 'video',
  128. '.mov': 'video',
  129.  
  130. // Archives
  131. '.zip': 'zip',
  132. '.rar': 'zip',
  133. '.7z': 'zip',
  134. '.tar': 'zip',
  135. '.gz': 'zip',
  136. '.bz2': 'zip',
  137.  
  138. // System
  139. '.exe': 'exe',
  140. '.dll': 'dll',
  141. '.so': 'lib',
  142. '.dylib': 'lib',
  143. '.sys': 'windows',
  144. '.reg': 'windows',
  145.  
  146. // Design
  147. '.fig': 'figma',
  148. '.sketch': 'sketch',
  149. '.ai': 'illustrator',
  150. '.psd': 'photoshop',
  151. '.xd': 'xd',
  152.  
  153. // 3D & Game
  154. '.unity': 'unity',
  155. '.blend': 'blender',
  156. '.fbx': '3d',
  157. '.obj': '3d',
  158. '.gltf': '3d',
  159. '.uasset': 'unreal',
  160. '.upk': 'unreal',
  161.  
  162. // Mobile
  163. '.apk': 'android',
  164. '.ipa': 'apple',
  165. '.xcodeproj': 'xcode',
  166. '.pbxproj': 'xcode',
  167.  
  168. // Container & Cloud
  169. Dockerfile: 'docker',
  170. '.dockerignore': 'docker',
  171. '.tf': 'terraform',
  172. '.tfvars': 'terraform',
  173. '.vagrant': 'vagrant',
  174. '.helm': 'kubernetes',
  175. };
  176.  
  177. const specialFiles = {
  178. // Package managers
  179. 'package.json': 'nodejs',
  180. 'package-lock.json': 'nodejs',
  181. 'yarn.lock': 'yarn',
  182. 'pnpm-lock.yaml': 'pnpm',
  183. 'bun.lockb': 'bun',
  184. 'composer.json': 'composer',
  185. 'composer.lock': 'composer',
  186. Gemfile: 'ruby',
  187. 'Gemfile.lock': 'ruby',
  188. 'requirements.txt': 'python',
  189. 'poetry.lock': 'python',
  190. 'Cargo.toml': 'rust',
  191. 'Cargo.lock': 'rust',
  192.  
  193. // Config files
  194. 'tsconfig.json': 'typescript',
  195. '.eslintrc': 'eslint',
  196. '.prettierrc': 'prettier',
  197. '.editorconfig': 'editorconfig',
  198. 'webpack.config.js': 'webpack',
  199. 'vite.config.js': 'vite',
  200. 'rollup.config.js': 'rollup',
  201. 'babel.config.js': 'babel',
  202. 'jest.config.js': 'jest',
  203. 'karma.conf.js': 'karma',
  204. 'cypress.config.js': 'cypress',
  205. 'playwright.config.js': 'playwright',
  206.  
  207. // Documentation
  208. 'README.md': 'markdown',
  209. LICENSE: 'certificate',
  210. 'CHANGELOG.md': 'markdown',
  211. 'CONTRIBUTING.md': 'markdown',
  212.  
  213. // Git
  214. '.gitignore': 'git',
  215. '.gitattributes': 'git',
  216. '.gitmodules': 'git',
  217. '.gitmessage': 'git',
  218. '.gitkeep': 'git',
  219.  
  220. // CI/CD
  221. '.travis.yml': 'travis',
  222. '.gitlab-ci.yml': 'gitlab',
  223. Jenkinsfile: 'jenkins',
  224. 'azure-pipelines.yml': 'azure',
  225. 'bitbucket-pipelines.yml': 'bitbucket',
  226.  
  227. // Docker
  228. Dockerfile: 'docker',
  229. 'docker-compose.yml': 'docker',
  230. 'docker-compose.yaml': 'docker',
  231. 'docker-compose.override.yml': 'docker',
  232.  
  233. // Framework configs
  234. 'angular.json': 'angular',
  235. 'next.config.js': 'next',
  236. 'nuxt.config.js': 'nuxt',
  237. 'svelte.config.js': 'svelte',
  238. 'capacitor.config.json': 'capacitor',
  239. 'ionic.config.json': 'ionic',
  240.  
  241. // Build tools
  242. Makefile: 'makefile',
  243. 'CMakeLists.txt': 'cmake',
  244. 'build.gradle': 'gradle',
  245. 'pom.xml': 'maven',
  246. 'build.sbt': 'sbt',
  247.  
  248. // Environment
  249. '.env': 'tune',
  250. '.env.local': 'tune',
  251. '.env.development': 'tune',
  252. '.env.production': 'tune',
  253. '.env.test': 'tune',
  254.  
  255. // Version managers
  256. '.nvmrc': 'nodejs',
  257. '.node-version': 'nodejs',
  258. '.ruby-version': 'ruby',
  259. '.python-version': 'python',
  260. '.java-version': 'java',
  261. };
  262.  
  263. function replaceIcons() {
  264. $('.react-directory-row-name-cell-large-screen').each(function () {
  265. const $filenameElement = $(this).find('.react-directory-filename-cell');
  266.  
  267. if ($filenameElement.length) {
  268. const filename = $filenameElement.text();
  269. let iconName = specialFiles[filename];
  270.  
  271. if (!iconName) {
  272. const extension = Object.keys(iconMap).find(ext => filename.toLowerCase().endsWith(ext));
  273. iconName = extension ? iconMap[extension] : null;
  274. }
  275.  
  276. if (iconName) {
  277. const $oldSvg = $(this).find('svg');
  278. if ($oldSvg.length) {
  279. const $newIcon = $('<img>', {
  280. src: `https://raw.githubusercontent.com/material-extensions/vscode-material-icon-theme/refs/heads/main/icons/${iconName}.svg`,
  281. class: 'material-icon',
  282. alt: iconName,
  283. });
  284. $oldSvg.replaceWith($newIcon);
  285. }
  286. }
  287. }
  288. });
  289. }
  290.  
  291. // Initial replacement
  292. $(document).ready(replaceIcons);
  293.  
  294. // Watch for DOM changes
  295. const observer = new MutationObserver(replaceIcons);
  296. observer.observe(document.body, {
  297. childList: true,
  298. subtree: true,
  299. });
  300. })(jQuery);