GitHub Diff Filename

A userscript that highlights filename & permission alterations

目前为 2017-08-27 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name GitHub Diff Filename
  3. // @version 0.1.0
  4. // @description A userscript that highlights filename & permission alterations
  5. // @license MIT
  6. // @author Rob Garrison
  7. // @namespace https://github.com/Mottie
  8. // @include https://github.com/*
  9. // @run-at document-end
  10. // @grant GM_getValue
  11. // @grant GM_setValue
  12. // @require https://greasyfork.org/scripts/28721-mutations/code/mutations.js?version=189706
  13. // @icon https://github.com/fluidicon.png
  14. // ==/UserScript==
  15. (() => {
  16. "use strict";
  17.  
  18. const arrow = "\u2192", // "→"
  19. regex = new RegExp(`\\s${arrow}\\s`);
  20.  
  21. function processFileInfo(el) {
  22. let node;
  23. if (!$(".ghdfn", el)) {
  24. const link = $("a", el);
  25. // A file can be moved AND include permission changes
  26. // e.g. main.js → scripts/main.js 100755 → 100644
  27. // with file name inside link and permission changes outside in a text node
  28. if (link && regex.test(link.textContent)) {
  29. node = findMatchingNode(link)[0];
  30. processNode(node);
  31. }
  32. node = findMatchingNode(el)[0];
  33. processNode(node);
  34. }
  35. }
  36.  
  37. function processNode(node) {
  38. if (node) {
  39. let txt = node.textContent,
  40. // modify right node first to maintain node text indexing
  41. middle = txt.indexOf(arrow);
  42. if (middle > -1) {
  43. wrapParts({
  44. start: middle + 2,
  45. end: txt.length,
  46. name: "ghdfn text-green",
  47. node
  48. });
  49. }
  50. middle = node.textContent.indexOf(arrow);
  51. if (middle > -1) {
  52. wrapParts({
  53. start: 0,
  54. end: middle - 1,
  55. name: "ghdfn text-red",
  56. node
  57. });
  58. }
  59. }
  60. }
  61.  
  62. function findMatchingNode(el) {
  63. return [...el.childNodes].filter(
  64. node => regex.test(node.textContent) && node.nodeType === 3
  65. );
  66. }
  67.  
  68. function wrapParts(data) {
  69. let newNode, tmpNode;
  70. const {start, end, name, node} = data;
  71. if (node && node.nodeType === 3) {
  72. tmpNode = node.splitText(start);
  73. tmpNode.splitText(end - start);
  74. newNode = document.createElement("span");
  75. newNode.className = name;
  76. newNode.textContent = tmpNode.textContent;
  77. tmpNode.parentNode.replaceChild(newNode, tmpNode);
  78. }
  79. }
  80.  
  81. function $(str, el = document) {
  82. return el.querySelector(str);
  83. }
  84.  
  85. function $$(str, el = document) {
  86. return [...el.querySelectorAll(str)];
  87. }
  88.  
  89. function init() {
  90. if ($("#files")) {
  91. $$("#files .file-info").forEach(el => {
  92. processFileInfo(el);
  93. });
  94. }
  95. }
  96.  
  97. document.addEventListener("ghmo:container", init);
  98. document.addEventListener("ghmo:diff", init);
  99. init();
  100.  
  101. })();