GitHub Diff Links

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

Verze ze dne 14. 04. 2017. Zobrazit nejnovější verzi.

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