您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds colors to files by type, displays small images in place of file-type icons in a repository source tree
当前为
- // ==UserScript==
- // @name GitHub file list beautifier
- // @description Adds colors to files by type, displays small images in place of file-type icons in a repository source tree
- // @license MIT License
- // @version 3.0.7
- // @match https://github.com/*
- // @grant none
- // @run-at document-end
- // @author wOxxOm
- // @namespace wOxxOm.scripts
- // @icon https://octodex.github.com/images/murakamicat.png
- // ==/UserScript==
- 'use strict';
- let savedConfig = {};
- try { savedConfig = JSON.parse(localStorage.FileListBeautifier) || {}; }
- catch (e) {}
- const config = Object.assign({},
- ...Object.entries({
- iconSize: 24,
- colorSeed1: 2,
- colorSeed2: 1299721,
- colorSeed3: 179426453,
- }).map(([k, v]) => ({[k]: +savedConfig[k] || v})));
- const styleQueue = [];
- const {sheet} = document.head.appendChild(Object.assign(document.createElement('style'), {
- textContent: `
- .wOxxOm-image-icon:not(#foo) {
- max-width: ${config.iconSize}px;
- max-height: ${config.iconSize}px;
- width: auto;
- height: auto;
- margin: auto;
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- }
- .wOxxOm-image-td:not(#foo) {
- position: relative;
- padding: 0;
- min-width: ${config.iconSize + 4}px;
- line-height: inherit;
- }
- a[file-type=":folder"]:not(#foo) {
- font-weight: bold;
- }
- `
- }));
- const filetypes = {};
- const tables = document.getElementsByTagName('table');
- const ME = Symbol(GM_info.script.name);
- const ob = new MutationObserver(() => {
- ob.disconnect();
- requestAnimationFrame(start);
- });
- const {pushState} = unsafeWindow.History.prototype;
- unsafeWindow.History.prototype.pushState = function() {
- const res = pushState.apply(this, arguments);
- start();
- return res;
- };
- let lumaBias, lumaFix, lumaAmp;
- addEventListener('popstate', start);
- if (document.body) start();
- else document.addEventListener('DOMContentLoaded', start, {once: true});
- function start() {
- beautify();
- ob.observe(document, {subtree: true, childList: true});
- }
- // postpone observing until the parser can breathe after the initial burst of activity during page load
- function beautify() {
- const table = tables[0];
- if (!table || !table.classList.contains('files'))
- return;
- let didSomeWork = false;
- for (const a of table.getElementsByClassName('js-navigation-open')) {
- if (!a.hasAttribute('href') || ME in a)
- continue;
- a[ME] = true;
- const tr = a.closest('tr');
- if (tr && tr.querySelector('.octicon-file-directory')) {
- a.setAttribute('file-type', ':folder');
- continue;
- }
- didSomeWork = true;
- const ext = a.href.match(/\.(\w+)$|$/)[1] || ':empty';
- a.setAttribute('file-type', ext);
- if (!filetypes[ext])
- addFileTypeStyle(ext);
- if (/^(png|jpe?g|bmp|gif|cur|ico)$/.test(ext)) {
- const m = a.href.match(/github\.com\/(.+?\/)blob\/(.*)$/);
- if (!m) continue;
- const iconCell = a.closest('.js-navigation-item').querySelector('.icon');
- const icon = iconCell.querySelector('.octicon-file, .octicon-file-text');
- if (!icon || icon.style.display === 'none') continue;
- icon.style.display = 'none';
- icon.insertAdjacentElement('afterend', Object.assign(
- document.createElement('img'), {
- className: 'wOxxOm-image-icon',
- src: `https://raw.githubusercontent.com/${m[1]}${m[2]}`,
- }));
- iconCell.classList.add('wOxxOm-image-td');
- }
- }
- }
- function addFileTypeStyle(type) {
- filetypes[type] = true;
- if (!styleQueue.length)
- requestAnimationFrame(commitStyleQueue);
- styleQueue.push(type);
- }
- function commitStyleQueue() {
- if (!lumaAmp) initLumaScale();
- for (const type of styleQueue) {
- const hash = calcSimpleHash(type);
- const H = hash % 360;
- const Hq = H / 60;
- const S = hash * config.colorSeed2 % 50 + 50 | 0;
- const redFix = (Hq < 1 ? 1 - Hq : Hq > 4 ? (Hq - 4) / 2 : 0);
- const blueFix = (Hq < 3 || Hq > 5 ? 0 : Hq < 4 ? Hq - 3 : 5 - Hq) * 3;
- const L = hash * config.colorSeed3 % lumaAmp + lumaBias + (redFix + blueFix) * lumaFix * S / 100 | 0;
- sheet.insertRule(`a[file-type="${type}"]:not(#foo) { color: hsl(${H},${S}%,${L}%) !important }`);
- }
- styleQueue.length = 0;
- }
- function calcSimpleHash(text) {
- let hash = 0;
- for (let i = 0, len = text.length; i < len; i++)
- hash = ((hash << 5) - hash) + text.charCodeAt(i);
- return Math.abs(hash * config.colorSeed1 | 0);
- }
- function initLumaScale() {
- const [, r, g, b] = getComputedStyle(document.body).backgroundColor.split(/[^\d.]+/).map(parseFloat);
- const isDark = (r * .2126 + g * .7152 + b * .0722) < 128;
- [lumaBias, lumaAmp, lumaFix] = isDark ? [30, 50, 12] : [25, 15, 0];
- }