Greasy Fork is available in English.

GitHub Diff File Toggle

A userscript that adds a toggle to show or hide diff files

Verze ze dne 15. 04. 2016. Zobrazit nejnovější verzi.

  1. // ==UserScript==
  2. // @name GitHub Diff File Toggle
  3. // @version 1.0.0
  4. // @description A userscript that adds a toggle to show or hide diff files
  5. // @license https://creativecommons.org/licenses/by-sa/4.0/
  6. // @namespace https://github.com/StylishThemes
  7. // @include https://github.com/*
  8. // @grant GM_addStyle
  9. // @run-at document-end
  10. // @author StylishThemes
  11. // ==/UserScript==
  12. /* global GM_addStyle */
  13. (function() {
  14. "use strict";
  15. /*
  16. This code is also part of the GitHub-Dark Script (https://github.com/StylishThemes/GitHub-Dark-Script)
  17. Extracted out into a separate userscript in case users only want to add this functionality
  18. */
  19. var busy = false,
  20.  
  21. icon = [
  22. "<svg class='octicon' xmlns='http://www.w3.org/2000/svg' width='10' height='6.5' viewBox='0 0 10 6.5'>",
  23. "<path d='M0 1.497L1.504 0l3.49 3.76L8.505.016 10 1.52 4.988 6.51 0 1.496z'/>",
  24. "</svg>",
  25. ].join(""),
  26.  
  27. // Add file diffs toggle
  28. addFileToggle = function() {
  29. busy = true;
  30. var el, button,
  31. files = document.querySelectorAll("#files .file-actions"),
  32. indx = files.length;
  33. while (indx--) {
  34. el = files[indx];
  35. if (!el.querySelector(".ghd-file-toggle")) {
  36. button = document.querySelector("button");
  37. button.type = "button";
  38. button.className = "ghd-file-toggle btn btn-sm tooltipped tooltipped-n";
  39. button.setAttribute("aria-label", "Click to Expand or Collapse file");
  40. button.setAttribute("tabindex", "-1");
  41. button.innerHTML = icon;
  42. el.appendChild(button);
  43. }
  44. }
  45. busy = false;
  46. },
  47.  
  48. matches = function(el, selector) {
  49. // https://developer.mozilla.org/en-US/docs/Web/API/Element/matches
  50. var matches = document.querySelectorAll(selector),
  51. i = matches.length;
  52. while (--i >= 0 && matches.item(i) !== el) {}
  53. return i > -1;
  54. },
  55.  
  56. closest = function(el, selector) {
  57. while (el && !matches(el, selector)) {
  58. el = el.parentNode;
  59. }
  60. return matches(el, selector) ? el : null;
  61. },
  62.  
  63. nextSiblings = function(el, selector) {
  64. var siblings = [];
  65. while ((el = el.nextSibling)) {
  66. if (el && el.nodeType === 1 && matches(el, selector)) {
  67. siblings.push(el);
  68. }
  69. }
  70. return siblings;
  71. },
  72.  
  73. toggleFile = function(event) {
  74. busy = true;
  75. var el, sibs, indx,
  76. target = event.target;
  77. target.classList.toggle("ghd-file-collapsed");
  78. // find header
  79. el = closest(target, ".file-header");
  80. // toggle view of file or image; "image" class added to "Diff suppressed..."
  81. sibs = nextSiblings(el, ".blob-wrapper, .render-wrapper, .image, .rich-diff");
  82. indx = sibs && sibs.length || 0;
  83. while (indx--) {
  84. if (sibs[indx]) {
  85. sibs[indx].classList.toggle("ghd-collapsed-file");
  86. }
  87. }
  88.  
  89. // shift+click toggle all files!
  90. if (event.shiftKey) {
  91. var loop,
  92. isCollapsed = target.classList.contains("ghd-file-collapsed"),
  93. toggles = document.querySelectorAll(".ghd-file-toggle");
  94. indx = toggles.length;
  95. while (indx--) {
  96. el = toggles[indx];
  97. if (el !== target) {
  98. el.classList[isCollapsed ? "add" : "remove"]("ghd-file-collapsed");
  99. el = closest(el, ".file-header");
  100. sibs = nextSiblings(el, ".blob-wrapper, .render-wrapper, .image, .rich-diff");
  101. loop = sibs && sibs.length || 0;
  102. while (loop--) {
  103. if (sibs[loop]) {
  104. sibs[loop].classList[isCollapsed ? "add" : "remove"]("ghd-collapsed-file");
  105. }
  106. }
  107. }
  108. }
  109. }
  110. document.activeElement.blur();
  111. busy = false;
  112. },
  113.  
  114. addBindings = function() {
  115. document.querySelector("body").addEventListener("click", function(event) {
  116. var target = event.target;
  117. if (target && target.classList.contains("ghd-file-toggle")) {
  118. toggleFile(event);
  119. return false;
  120. }
  121. });
  122. },
  123.  
  124. targets = document.querySelectorAll([
  125. "#js-repo-pjax-container",
  126. "#js-pjax-container",
  127. ".js-preview-body"
  128. ].join(","));
  129.  
  130. // don't initialize if GitHub Dark Script is active
  131. if (!document.querySelector("#ghd-menu")) {
  132. GM_addStyle([
  133. ".ghd-collapsed-file, .file.open .data.ghd-collapsed-file { display: none; }",
  134. // file collapsed icon
  135. ".ghd-file-collapsed svg { -webkit-transform:rotate(90deg); transform:rotate(90deg); }",
  136. ".ghd-file-toggle svg.octicon { pointer-events: none; vertical-align: middle; }"
  137. ].join(""));
  138.  
  139. Array.prototype.forEach.call(targets, function(target) {
  140. new MutationObserver(function(mutations) {
  141. mutations.forEach(function(mutation) {
  142. // preform checks before adding code wrap to minimize function calls
  143. if (!busy && mutation.target === target) {
  144. addFileToggle();
  145. }
  146. });
  147. }).observe(target, {
  148. childList: true,
  149. subtree: true
  150. });
  151. });
  152.  
  153. addBindings();
  154. addFileToggle();
  155. }
  156.  
  157. })();