// ==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 // @updateURL https://raw.githubusercontent.com/Mottie/Github-userscripts/master/github-diff-filename.user.js // @downloadURL https://raw.githubusercontent.com/Mottie/Github-userscripts/master/github-diff-filename.user.js // @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 = ` ${oldFile} ${arrow} ${newFile}`; } } 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(); })();
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: