GitHub Diff File Toggle

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

目前為 2017-04-21 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name GitHub Diff File Toggle
  3. // @version 1.2.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. // @author StylishThemes
  7. // @namespace https://github.com/StylishThemes
  8. // @include https://github.com/*
  9. // @run-at document-end
  10. // @grant GM_addStyle
  11. // @grant GM_getValue
  12. // @grant GM_setValue
  13. // @grant GM_registerMenuCommand
  14. // @require https://greasyfork.org/scripts/28721-mutations/code/mutations.js?version=188090
  15. // @icon https://avatars3.githubusercontent.com/u/6145677?v=3&s=200
  16. // ==/UserScript==
  17. /* jshint esnext:true, unused:true */
  18. (() => {
  19. "use strict";
  20. /*
  21. This code is also part of the GitHub-Dark Script
  22. (https://github.com/StylishThemes/GitHub-Dark-Script)
  23. Extracted out into a separate userscript in case users only want to add this
  24. functionality
  25. */
  26. const icon =
  27. `<svg class="octicon" xmlns="http://www.w3.org/2000/svg" width="10" height="6.5" viewBox="0 0 10 6.5">
  28. <path d="M0 1.5L1.5 0l3.5 3.7L8.5.0 10 1.5 5 6.5 0 1.5z"/>
  29. </svg>`;
  30.  
  31. // Add file diffs toggle
  32. function addFileToggle() {
  33. const files = $$("#files .file-actions");
  34. let button = document.createElement("button");
  35. button.type = "button";
  36. button.className = "ghd-file-toggle btn btn-sm tooltipped tooltipped-n";
  37. button.setAttribute("aria-label", "Click to Expand or Collapse file");
  38. button.setAttribute("tabindex", "-1");
  39. button.innerHTML = icon;
  40. files.forEach(el => {
  41. if (!$(".ghd-file-toggle", el)) {
  42. // hide GitHub toggle view button
  43. el.querySelector(".js-details-target").style.display = "none";
  44. el.appendChild(button.cloneNode(true));
  45. }
  46. });
  47. // start with all but first entry collapsed
  48. if (files.length) {
  49. if (/^t/.test(GM_getValue("accordion"))) {
  50. toggleFile({
  51. target: $(".ghd-file-toggle")
  52. }, "init");
  53. }
  54. }
  55. }
  56.  
  57. function toggleSibs(target, state) {
  58. // oddly, when a "Details--on" class is applied, the content is hidden
  59. const isCollapsed = state || target.classList.contains("Details--on"),
  60. toggles = $$(".file");
  61. let el,
  62. indx = toggles.length;
  63. while (indx--) {
  64. el = toggles[indx];
  65. if (el !== target) {
  66. el.classList.toggle("Details--on", isCollapsed);
  67. }
  68. }
  69. }
  70.  
  71. function toggleFile(event, init) {
  72. const accordion = GM_getValue("accordion"),
  73. el = closest(".file", event.target);
  74. if (el && accordion) {
  75. if (!init) {
  76. el.classList.toggle("Details--on");
  77. }
  78. toggleSibs(el, true);
  79. } else if (el) {
  80. el.classList.toggle("Details--on");
  81. // shift+click toggle all files!
  82. if (event.shiftKey) {
  83. toggleSibs(el);
  84. }
  85. }
  86. document.activeElement.blur();
  87. // move current open panel to the top
  88. if (!el.classList.contains("Details--on")) {
  89. location.hash = el.id;
  90. }
  91. }
  92.  
  93. function addBindings() {
  94. $("body").addEventListener("click", event => {
  95. const target = event.target;
  96. if (target && target.classList.contains("ghd-file-toggle")) {
  97. toggleFile(event);
  98. return false;
  99. }
  100. });
  101. }
  102.  
  103. function $(str, el) {
  104. return (el || document).querySelector(str);
  105. }
  106.  
  107. function $$(str, el) {
  108. return Array.from((el || document).querySelectorAll(str));
  109. }
  110.  
  111. function closest(selector, el) {
  112. while (el && el.nodeType === 1) {
  113. if (el.matches(selector)) {
  114. return el;
  115. }
  116. el = el.parentNode;
  117. }
  118. return null;
  119. }
  120.  
  121. // Don't initialize if GitHub Dark Script is active
  122. if (!$("#ghd-menu")) {
  123. GM_addStyle(`
  124. .Details--on .ghd-file-toggle svg {
  125. -webkit-transform:rotate(90deg); transform:rotate(90deg);
  126. }
  127. .ghd-file-toggle svg.octicon {
  128. pointer-events: none;
  129. vertical-align: middle;
  130. }
  131. `);
  132.  
  133. document.addEventListener("ghmo:container", addFileToggle);
  134. document.addEventListener("ghmo:diff", addFileToggle);
  135.  
  136. // Add GM options
  137. GM_registerMenuCommand("GitHub Diff File Toggle", () => {
  138. let result = "" + (GM_getValue("accordion") || false);
  139. const val = prompt("Accordion Mode? (true/false):", result);
  140. if (val) {
  141. result = /^t/.test(val);
  142. GM_setValue("accordion", result);
  143. }
  144. });
  145.  
  146. addBindings();
  147. addFileToggle();
  148. }
  149.  
  150. })();