🏠 返回首頁 

GitHub Diff Filename

A userscript that highlights filename & permission alterations

// ==UserScript==
// @name        GitHub Diff Filename
// @version     1.1.6
// @description A userscript that highlights filename & permission alterations
// @license     MIT
// @author      Rob Garrison
// @namespace   https://github.com/Mottie
// @match       https://github.com/*
// @run-at      document-end
// @grant       GM_getValue
// @grant       GM_setValue
// @require     https://greasyfork.org/scripts/28721-mutations/code/mutations.js?version=1108163
// @require     https://greasyfork.org/scripts/398877-utils-js/code/utilsjs.js?version=1079637
// @icon        https://github.githubassets.com/pinned-octocat.svg
// @supportURL  https://github.com/Mottie/GitHub-userscripts/issues
// ==/UserScript==
/* global $ $$ on */
(() => {
"use strict";
const arrow = "\u2192"; // "→"
const regex = new RegExp(`\\s${arrow}\\s`);
function processFileInfo(el) {
if (!$(".ghdfn", el)) {
// A file can be moved AND include permission changes
// e.g. main.js → scripts/main.js 100755 → 100644
// see https://github.com/openstyles/stylus/pull/110/files#diff-5186ece9a52b5e8b0d2e221fdf139ae963ae774267b2f52653c7e45e2a0bda52
const link = $("a[title]", el);
// file name/location changes are inside the link
if (link && regex.test(link.textContent)) {
modifyLinkText(link);
}
// permission changes in a text node as a direct child of the wrapper
// process permission change (if it exists)
const node = findTextNode(el)[0];
processNode(node);
}
}
function modifyLinkText(link) {
if (link) {
const [oldFile, newFile] = (link.title || "").split(regex);
link.innerHTML = `
<span class="ghdfn color-fg-danger">${oldFile}</span> ${arrow}
<span class="ghdfn color-fg-success">${newFile}</span>`;
}
}
function processNode(node) {
if (node) {
let txt = node.textContent,
// modify right node first to maintain node text indexing
middle = txt.indexOf(arrow);
if (middle > -1) {
wrapParts({
start: middle + 2,
end: txt.length,
name: "ghdfn color-fg-success",
node
});
}
middle = node.textContent.indexOf(arrow);
if (middle > -1) {
wrapParts({
start: 0,
end: middle - 1,
name: "ghdfn color-fg-danger",
node
});
}
}
}
function findTextNode(el) {
return [...el.childNodes].filter(
node => regex.test(node.textContent) && node.nodeType === 3
);
}
function wrapParts(data) {
let newNode, tmpNode;
const {start, end, name, node} = data;
if (node && node.nodeType === 3) {
tmpNode = node.splitText(start);
tmpNode.splitText(end - start);
newNode = document.createElement("span");
newNode.className = name;
newNode.textContent = tmpNode.textContent;
tmpNode.parentNode.replaceChild(newNode, tmpNode);
}
}
function init() {
if ($("#files")) {
$$("#files .file-info").forEach(processFileInfo);
}
}
on(document, "ghmo:container ghmo:diff", init);
init();
})();