GitHub Diff Links

A userscript that adds links to diff and pull request headers to jump back & forth between files

От 31.01.2021. Виж последната версия.

  1. // ==UserScript==
  2. // @name GitHub Diff Links
  3. // @version 1.2.16
  4. // @description A userscript that adds links to diff and pull request headers to jump back & forth between files
  5. // @license MIT
  6. // @author Rob Garrison
  7. // @namespace https://github.com/Mottie
  8. // @include https://github.com/*
  9. // @run-at document-idle
  10. // @grant GM_addStyle
  11. // @require https://greasyfork.org/scripts/28721-mutations/code/mutations.js?version=882023
  12. // @icon https://github.githubassets.com/pinned-octocat.svg
  13. // ==/UserScript==
  14. (() => {
  15. "use strict";
  16.  
  17. // sometimes tooltips are too narrow...
  18. // and move diff anchors below sticky header
  19. GM_addStyle(`
  20. .gh-diff-links:after { min-width: 120px; }
  21. a[name*="diff-"]:before {
  22. padding-top: 60px !important;
  23. margin-top: -60px !important;
  24. content: "";
  25. position: absolute;
  26. }
  27. div.file-actions > div {
  28. display: inline;
  29. }`
  30. );
  31.  
  32. const button = document.createElement("a"),
  33. // button [ InnerHTML, tooltip ]
  34. nextBtn = ["Next", "Jump to next file\n("],
  35. prevBtn = ["Prev", "Jump to previous file\n(" ];
  36.  
  37. button.className = "btn btn-sm tooltipped tooltipped-s tooltipped-multiline gh-diff-links";
  38. button.setAttribute("rel", "nofollow");
  39.  
  40. function addButton(el, content, link) {
  41. let btn = button.cloneNode(),
  42. txt = el.classList.contains("select-menu-item") ?
  43. $(".description", el).textContent :
  44. link.textContent || "";
  45. // clean up whitespace
  46. txt = txt.replace(/\s+/g, " ").trim();
  47. // only add file name to tooltip
  48. txt = txt.substring(txt.lastIndexOf("/") + 1, txt.length);
  49. btn.innerHTML = content[0];
  50. btn.setAttribute("aria-label", content[1] + txt + ")" );
  51. btn.href = link.hash;
  52. // prepend button
  53. el.insertBefore(btn, el.childNodes[0]);
  54. }
  55.  
  56. function addSpace(el, content) {
  57. let btn = button.cloneNode();
  58. btn.disabled = true;
  59. btn.className = "btn btn-sm gh-diff-links disabled";
  60. btn.innerHTML = content[0];
  61. el.insertBefore(btn, el.childNodes[0]);
  62. }
  63.  
  64. function addLinks() {
  65. let last, temp,
  66. links = $$(".file-header .file-info a");
  67. if (links.length) {
  68. // links & file-actions "should" be the same length
  69. last = links.length - 1;
  70. $$(".file-actions").forEach((el, indx) => {
  71. // remove disabled buttons added before progressive
  72. // content has completed loading
  73. temp = $(".gh-diff-links.disabled", el);
  74. if (temp) {
  75. temp.parentNode.removeChild(temp);
  76. // remove both buttons to allow updating
  77. temp = $(".gh-diff-links", el);
  78. temp.parentNode.removeChild(temp);
  79. }
  80. if (!$(".gh-diff-links", el)) {
  81. if (indx === 0) {
  82. addButton(el, nextBtn, links[indx + 1]);
  83. addSpace(el, prevBtn);
  84. } else if (indx === last) {
  85. // add dummy "next" button to keep spacing
  86. addSpace(el, nextBtn);
  87. addButton(el, prevBtn, links[indx - 1]);
  88. } else {
  89. addButton(el, nextBtn, links[indx + 1]);
  90. addButton(el, prevBtn, links[indx - 1]);
  91. }
  92. }
  93. });
  94. }
  95. }
  96.  
  97. function init() {
  98. if ($("#files.diff-view") || $(".pr-toolbar")) {
  99. addLinks();
  100. }
  101. }
  102.  
  103. function $(selector, el) {
  104. return (el || document).querySelector(selector);
  105. }
  106.  
  107. function $$(selector, el) {
  108. return Array.from((el || document).querySelectorAll(selector));
  109. }
  110.  
  111. // DOM targets - to detect GitHub dynamic ajax page loading
  112. document.addEventListener("ghmo:container", init);
  113. document.addEventListener("ghmo:diff", addLinks);
  114. init();
  115.  
  116. })();