GitHub Diff File Toggle

A userscript that adds global diff file toggles

  1. // ==UserScript==
  2. // @name GitHub Diff File Toggle
  3. // @version 0.1.3
  4. // @description A userscript that adds global diff file toggles
  5. // @license MIT
  6. // @author Rob Garrison
  7. // @namespace https://github.com/Mottie
  8. // @match https://github.com/*
  9. // @run-at document-idle
  10. // @grant none
  11. // @require https://greatest.deepsurf.us/scripts/28721-mutations/code/mutations.js?version=1108163
  12. // @require https://greatest.deepsurf.us/scripts/398877-utils-js/code/utilsjs.js?version=1079637
  13. // @icon https://github.githubassets.com/pinned-octocat.svg
  14. // @supportURL https://github.com/Mottie/GitHub-userscripts/issues
  15.  
  16. // ==/UserScript==
  17.  
  18. /* global $ $$ on debounce make */
  19. (() => {
  20. "use strict";
  21.  
  22. let timer;
  23. let busy = false;
  24.  
  25. const setToggleStyle = state => {
  26. const mainToggle = $(".ghdt-toggle");
  27. mainToggle.classList.toggle("ghdt-selected", state);
  28. mainToggle.style = state
  29. ? "background-color: var(--color-btn-selected-bg);"
  30. : "";
  31. };
  32.  
  33. const buildButton = () => {
  34. if (!$(".ghdt-toggle")) {
  35. const button = make({
  36. el: "button",
  37. className: "btn btn-sm ghdt-toggle tooltipped tooltipped-s float-right",
  38. text: "Toggle viewed",
  39. attrs: {
  40. "aria-label": "Toggle all viewed files"
  41. }
  42. });
  43. on(button, "click", event => {
  44. toggle(document, !event.target.classList.contains("ghdt-selected"));
  45. });
  46. $("#files.diff-view")?.prepend(button);
  47. }
  48. // Update toggle button state after initialized; timer for progressive
  49. // loading
  50. clearTimeout(timer);
  51. timer = setTimeout(() => {
  52. if ($$(".js-reviewed-checkbox").every(el => el.checked)) {
  53. setToggleStyle(true);
  54. }
  55. }, 1000);
  56. };
  57.  
  58. const toggle = (target, state) => {
  59. $$(".js-reviewed-checkbox").forEach(checkbox => {
  60. if (target !== checkbox && checkbox.checked !== state) {
  61. checkbox.click();
  62. }
  63. });
  64. setToggleStyle(state);
  65. };
  66.  
  67. const handleChange = event => {
  68. const { target, altKey, shiftKey } = event;
  69. const anyModifier = altKey || shiftKey;
  70. if (!busy && anyModifier && target.matches(".js-reviewed-checkbox")) {
  71. busy = true;
  72. toggle(target, target.checked);
  73. setTimeout(() => {
  74. busy = false;
  75. });
  76. }
  77. };
  78.  
  79. const init = () => {
  80. if ($("#files.diff-view") || $(".pr-toolbar")) {
  81. buildButton();
  82. }
  83. };
  84.  
  85. on(document, "ghmo:container ghmo:diff", init);
  86. on(document, "click", debounce(handleChange));
  87. on(document, "keydown", debounce(handleChange));
  88. init();
  89. })();