GitHub Files Icon Replacement

Replace GitHub file icons with material icons

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

  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.23.3
  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 none
  18. // @run-at document-start
  19. // @license GPL-3.0-only
  20. // @compatible chrome
  21. // @compatible firefox
  22. // @compatible edge
  23. // ==/UserScript==
  24.  
  25. (function () {
  26. 'use strict';
  27.  
  28. function replaceIcons() {
  29. const fileElements = document.querySelectorAll('.react-directory-row-name-cell-large-screen');
  30.  
  31. fileElements.forEach(element => {
  32. const filenameElement = element.querySelector('.react-directory-filename-cell');
  33. if (filenameElement) {
  34. const filename = filenameElement.textContent;
  35. let iconName = '';
  36.  
  37. const iconMap = {
  38. '.ts': 'typescript',
  39. '.json': 'json',
  40. '.yml': 'yaml',
  41. '.yaml': 'yaml',
  42. '.js': 'javascript',
  43. '.html': 'html',
  44. '.css': 'css',
  45. '.py': 'python',
  46. '.php': 'php',
  47. '.md': 'markdown',
  48. '.lua': 'lua',
  49. '.npm': 'npm',
  50. '.lock': 'npm',
  51. '.svg': 'svg',
  52. '.xml': 'xml',
  53. '.txt': 'document',
  54. '.vue': 'vue',
  55. '.angular': 'angular',
  56. '.gitignore': 'git',
  57. '.git': 'git',
  58. '.jsx': 'react',
  59. '.tsx': 'react_ts',
  60. '.scss': 'sass',
  61. '.sass': 'sass',
  62. '.less': 'less',
  63. '.sh': 'shell',
  64. '.bash': 'shell',
  65. '.zsh': 'shell',
  66. '.fish': 'shell',
  67. '.c': 'c',
  68. '.cpp': 'cpp',
  69. '.cs': 'csharp',
  70. '.go': 'go',
  71. '.rs': 'rust',
  72. '.rb': 'ruby',
  73. '.java': 'java',
  74. '.kt': 'kotlin',
  75. '.swift': 'swift',
  76. '.dart': 'dart',
  77. '.sql': 'database',
  78. '.db': 'database',
  79. '.env': 'tune',
  80. '.docker': 'docker',
  81. '.dockerfile': 'docker',
  82. '.exe': 'exe',
  83. '.png': 'image',
  84. '.jpg': 'image',
  85. '.jpeg': 'image',
  86. '.gif': 'image',
  87. '.ico': 'image',
  88. '.webp': 'image',
  89. '.bmp': 'image',
  90. '.tiff': 'image',
  91. '.mp3': 'audio',
  92. '.wav': 'audio',
  93. '.mp4': 'video',
  94. '.mov': 'video',
  95. '.avi': 'video',
  96. '.ini': 'settings',
  97. '.config': 'settings',
  98. '.toml': 'settings',
  99. '.gradle': 'gradle',
  100. '.jar': 'java',
  101. '.class': 'java',
  102. '.properties': 'settings',
  103. '.r': 'r',
  104. '.rmd': 'r',
  105. '.scala': 'scala',
  106. '.groovy': 'groovy',
  107. '.pl': 'perl',
  108. '.pm': 'perl',
  109. '.h': 'c',
  110. '.hpp': 'cpp',
  111. '.hxx': 'cpp',
  112. '.m': 'objectivec',
  113. '.mm': 'objectivec',
  114. '.swift': 'swift',
  115. '.f': 'fortran',
  116. '.f90': 'fortran',
  117. '.f95': 'fortran',
  118. '.mat': 'matlab',
  119. '.coffee': 'coffeescript',
  120. '.litcoffee': 'coffeescript',
  121. '.elm': 'elm',
  122. '.ex': 'elixir',
  123. '.exs': 'elixir',
  124. '.erl': 'erlang',
  125. '.hrl': 'erlang',
  126. '.clj': 'clojure',
  127. '.cljs': 'clojure',
  128. '.fs': 'fsharp',
  129. '.fsx': 'fsharp',
  130. '.hs': 'haskell',
  131. '.lhs': 'haskell',
  132. '.ml': 'ocaml',
  133. '.mli': 'ocaml',
  134. '.pp': 'puppet',
  135. '.tf': 'terraform',
  136. '.tfvars': 'terraform',
  137. '.sol': 'solidity',
  138. '.proto': 'protobuf',
  139. '.graphql': 'graphql',
  140. '.haml': 'haml',
  141. '.slim': 'slim',
  142. '.erb': 'erb',
  143. '.jade': 'pug',
  144. '.pug': 'pug',
  145. '.styl': 'stylus',
  146. '.nix': 'nix',
  147. '.vim': 'vim',
  148. '.bat': 'console',
  149. '.cmd': 'console',
  150. '.dll': 'dll',
  151. '.so': 'lib',
  152. '.a': 'lib',
  153. '.dylib': 'lib',
  154. '.zip': 'zip',
  155. '.rar': 'zip',
  156. '.7z': 'zip',
  157. '.tar': 'zip',
  158. '.gz': 'zip',
  159. '.bz2': 'zip',
  160. '.xz': 'zip',
  161. '.pdf': 'pdf',
  162. '.doc': 'word',
  163. '.docx': 'word',
  164. '.ppt': 'powerpoint',
  165. '.pptx': 'powerpoint',
  166. '.odt': 'document',
  167. '.fig': 'figma',
  168. '.xd': 'xd',
  169. '.ai': 'illustrator',
  170. '.psd': 'photoshop',
  171. '.blend': 'blender',
  172. '.fbx': '3d',
  173. '.obj': '3d',
  174. '.stl': '3d',
  175. '.3ds': '3d',
  176. '.max': '3d',
  177. '.maya': '3d',
  178. '.shader': 'shader',
  179. '.glsl': 'shader',
  180. '.vert': 'shader',
  181. '.frag': 'shader',
  182. '.wasm': 'assembly',
  183. '.wat': 'assembly',
  184. '.asm': 'assembly',
  185. '.s': 'assembly',
  186. '.ko': 'linux',
  187. '.deb': 'debian',
  188. '.rpm': 'redhat',
  189. '.apk': 'android',
  190. '.ipa': 'apple',
  191. '.dmg': 'apple',
  192. '.pkg': 'apple',
  193. '.app': 'apple',
  194. '.pas': 'pascal',
  195. '.cobol': 'cobol',
  196. '.ada': 'ada',
  197. '.lisp': 'lisp',
  198. '.scm': 'scheme',
  199. '.rkt': 'racket',
  200. '.prolog': 'prolog',
  201. '.forth': 'forth',
  202. '.apl': 'apl',
  203. '.basic': 'basic',
  204. '.d': 'd',
  205. '.nim': 'nim',
  206. '.crystal': 'crystal',
  207. '.julia': 'julia',
  208. '.io': 'io',
  209. '.tcl': 'tcl',
  210. '.zig': 'zig',
  211. '.v': 'v',
  212. '.odin': 'odin',
  213. '.haxe': 'haxe',
  214. '.idl': 'idl',
  215. '.hack': 'hack',
  216. '.pike': 'pike',
  217. '.eiffel': 'eiffel',
  218. '.smalltalk': 'smalltalk',
  219. '.modula': 'modula',
  220. '.algol': 'algol'
  221. };
  222.  
  223. const specialFiles = {
  224. 'package.json': 'nodejs',
  225. 'README.md': 'markdown',
  226. 'LICENSE': 'certificate',
  227. '.prettierignore': 'prettier',
  228. '.prettierrc': 'prettier',
  229. '.eslintignore': 'eslint',
  230. '.eslintrc.cjs': 'eslint',
  231. '.eslintrc.js': 'eslint',
  232. '.eslintrc.json': 'eslint',
  233. '.eslintrc.yml': 'eslint',
  234. 'docker-compose.yml': 'docker',
  235. 'Dockerfile': 'docker',
  236. '.dockerignore': 'docker',
  237. '.env.local': 'tune',
  238. '.env.development': 'tune',
  239. '.env.production': 'tune',
  240. '.env.test': 'tune',
  241. '.env.staging': 'tune',
  242. 'tsconfig.json': 'typescript',
  243. 'webpack.config.js': 'webpack',
  244. 'babel.config.js': 'babel',
  245. 'jest.config.js': 'jest',
  246. 'angular.json': 'angular',
  247. 'next.config.js': 'next',
  248. 'nuxt.config.js': 'nuxt',
  249. 'vite.config.js': 'vite',
  250. 'rollup.config.js': 'rollup',
  251. 'svelte.config.js': 'svelte',
  252. 'tailwind.config.js': 'tailwind',
  253. 'postcss.config.js': 'postcss',
  254. 'composer.json': 'composer',
  255. 'composer.lock': 'composer',
  256. 'Gemfile': 'ruby',
  257. 'Gemfile.lock': 'ruby',
  258. 'requirements.txt': 'python',
  259. 'poetry.lock': 'python',
  260. 'pyproject.toml': 'python',
  261. 'Cargo.toml': 'rust',
  262. 'Cargo.lock': 'rust',
  263. 'go.mod': 'go',
  264. 'go.sum': 'go',
  265. 'mix.exs': 'elixir',
  266. 'rebar.config': 'erlang',
  267. 'stack.yaml': 'haskell',
  268. 'cabal.project': 'haskell',
  269. 'dune-project': 'ocaml',
  270. 'opam': 'ocaml',
  271. 'Rakefile': 'ruby',
  272. 'Makefile': 'makefile',
  273. 'CMakeLists.txt': 'cmake',
  274. 'build.gradle': 'gradle',
  275. 'pom.xml': 'maven',
  276. 'build.sbt': 'sbt',
  277. 'mix.lock': 'elixir',
  278. 'elm.json': 'elm',
  279. 'browserslist': 'browserslist',
  280. '.babelrc': 'babel',
  281. '.travis.yml': 'travis',
  282. 'circle.yml': 'circleci',
  283. 'jenkins.yml': 'jenkins',
  284. 'kubernetes.yml': 'kubernetes',
  285. 'nginx.conf': 'nginx',
  286. 'apache.conf': 'apache',
  287. '.gitattributes': 'git',
  288. '.gitmodules': 'git',
  289. '.gitlab-ci.yml': 'gitlab',
  290. 'bitbucket-pipelines.yml': 'bitbucket',
  291. 'azure-pipelines.yml': 'azure',
  292. 'Jenkinsfile': 'jenkins',
  293. 'sonar-project.properties': 'sonarqube',
  294. 'phpunit.xml': 'phpunit',
  295. 'karma.conf.js': 'karma',
  296. 'cypress.json': 'cypress',
  297. 'playwright.config.js': 'playwright',
  298. 'selenium.config.js': 'selenium',
  299. 'docker-compose.override.yml': 'docker',
  300. 'docker-compose.prod.yml': 'docker',
  301. 'docker-compose.dev.yml': 'docker',
  302. 'Procfile': 'heroku',
  303. 'vercel.json': 'vercel',
  304. 'netlify.toml': 'netlify',
  305. 'firebase.json': 'firebase',
  306. 'now.json': 'zeit',
  307. 'pm2.config.js': 'pm2',
  308. 'nodemon.json': 'nodemon',
  309. 'lerna.json': 'lerna',
  310. 'nx.json': 'nx',
  311. 'rush.json': 'rush',
  312. 'yarn.lock': 'yarn',
  313. 'pnpm-lock.yaml': 'pnpm',
  314. 'bun.lockb': 'bun',
  315. 'deno.json': 'deno',
  316. 'rome.json': 'rome',
  317. 'prettier.config.js': 'prettier',
  318. 'stylelint.config.js': 'stylelint',
  319. 'commitlint.config.js': 'commitlint',
  320. 'lint-staged.config.js': 'lint-staged',
  321. 'husky.config.js': 'husky',
  322. '.huskyrc': 'husky',
  323. '.lintstagedrc': 'lint-staged',
  324. '.commitlintrc': 'commitlint',
  325. '.stylelintrc': 'stylelint',
  326. '.prettierrc.js': 'prettier',
  327. '.eslintrc': 'eslint',
  328. '.browserslistrc': 'browserslist',
  329. '.npmrc': 'npm',
  330. '.yarnrc': 'yarn',
  331. '.nvmrc': 'nodejs',
  332. '.node-version': 'nodejs',
  333. '.ruby-version': 'ruby',
  334. '.python-version': 'python',
  335. '.tool-versions': 'asdf',
  336. '.editorconfig': 'editorconfig',
  337. '.mailmap': 'email',
  338. '.gitmessage': 'git',
  339. '.gitkeep': 'git',
  340. 'pascal.config': 'pascal',
  341. 'cobol.config': 'cobol',
  342. 'ada.config': 'ada',
  343. 'lisp.config': 'lisp',
  344. 'scheme.config': 'scheme',
  345. 'racket.config': 'racket',
  346. 'prolog.config': 'prolog',
  347. 'forth.config': 'forth',
  348. 'apl.config': 'apl',
  349. 'basic.config': 'basic',
  350. 'd.config': 'd',
  351. 'nim.config': 'nim',
  352. 'crystal.config': 'crystal',
  353. 'julia.config': 'julia',
  354. 'io.config': 'io',
  355. 'tcl.config': 'tcl',
  356. 'zig.config': 'zig',
  357. 'v.config': 'v',
  358. 'odin.config': 'odin',
  359. 'haxe.config': 'haxe',
  360. 'idl.config': 'idl',
  361. 'hack.config': 'hack',
  362. 'pike.config': 'pike',
  363. 'eiffel.config': 'eiffel',
  364. 'smalltalk.config': 'smalltalk',
  365. 'modula.config': 'modula',
  366. 'algol.config': 'algol'
  367. };
  368.  
  369. iconName = specialFiles[filename] || Object.entries(iconMap).find(([ext]) => filename.toLowerCase().endsWith(ext))?.[1];
  370.  
  371. if (iconName) {
  372. const oldSvg = element.querySelector('svg');
  373. if (oldSvg) {
  374. const newIcon = document.createElement('img');
  375. newIcon.src = `https://raw.githubusercontent.com/material-extensions/vscode-material-icon-theme/refs/heads/main/icons/${iconName}.svg`;
  376. newIcon.style.cssText = 'width:20px;height:20px;vertical-align:text-bottom;margin-right:4px';
  377. oldSvg.parentNode.replaceChild(newIcon, oldSvg);
  378. }
  379. }
  380. }
  381. });
  382. }
  383.  
  384. replaceIcons();
  385.  
  386. const observer = new MutationObserver(replaceIcons);
  387. observer.observe(document.body, {
  388. childList: true,
  389. subtree: true,
  390. });
  391. })();