Gist Raw Links

Add a button that contains a list of gist raw file links

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

  1. // ==UserScript==
  2. // @name Gist Raw Links
  3. // @version 0.1.4
  4. // @description Add a button that contains a list of gist raw file links
  5. // @license MIT
  6. // @author Rob Garrison
  7. // @namespace https://github.com/Mottie
  8. // @include https://gist.github.com/*
  9. // @run-at document-idle
  10. // @grant GM_addStyle
  11. // @grant GM_xmlhttpRequest
  12. // @connect api.github.com
  13. // @icon https://github.com/fluidicon.png
  14. // ==/UserScript==
  15. (() => {
  16. "use strict";
  17.  
  18. GM_addStyle(`
  19. .ghrl-get-list * { pointer-events:none; }
  20. .ghrl-files > div { text-align:center; pointer-events:none; }
  21. .ghrl-files a { cursor:pointer; }
  22. .gist-count-links { z-index: 20; }
  23. `);
  24.  
  25. const item = document.createElement("li");
  26. item.className = "dropdown js-menu-container";
  27.  
  28. function addButton(node) {
  29. const button = item.cloneNode();
  30. button.innerHTML = `
  31. <a href="#" class="js-menu-target tooltipped tooltipped-n ghrl-get-list" aria-label="Open list of raw urls">
  32. ? Raw urls <span class="dropdown-caret"></span>
  33. </a>
  34. <div class="dropdown-menu-content">
  35. <ul class="dropdown-menu dropdown-menu-sw ghrl-files">
  36. <div>
  37. <img src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="32" alt="">
  38. </div>
  39. </ul>
  40. </div>`;
  41. node.insertBefore(button, node.childNodes[0]);
  42. }
  43.  
  44. function update() {
  45. const gists = $$(".gist-snippet");
  46. let indx = gists.length;
  47. if (indx) {
  48. while (indx--) {
  49. // only save dabblet files from list
  50. if (!$(".ghrl-get-list", gists[indx])) {
  51. addButton($(".gist-count-links", gists[indx]));
  52. }
  53. }
  54. }
  55. }
  56.  
  57. function addList(link, files) {
  58. let url,
  59. html = "";
  60. Object.keys(files).forEach(file => {
  61. // remove version sha from raw_url to always point at
  62. // the latest version of the file - see #18
  63. url = files[file].raw_url.replace(/raw\/\w+\//, "raw/");
  64. html += `
  65. <a class="dropdown-item ghrl-file" href="${url}">
  66. ${file}
  67. </a>`;
  68. });
  69. $(".ghrl-files", link.parentNode).innerHTML = html;
  70. }
  71.  
  72. function loadFileList(link) {
  73. let url,
  74. el = closest(".dropdown", link);
  75. el = $("a", el.nextElementSibling);
  76. if (el) {
  77. url = el.href.split("/");
  78. GM_xmlhttpRequest({
  79. method : "GET",
  80. url : `https://api.github.com/gists/${url.pop()}`,
  81. onload : function(response) {
  82. let json = false;
  83. try {
  84. json = JSON.parse(response.responseText);
  85. } catch (err) {
  86. console.error(`Invalid JSON for gist ${gistid}`);
  87. return false;
  88. }
  89. if (json && json.files) {
  90. addList(link, json.files);
  91. }
  92. }
  93. });
  94. }
  95. }
  96.  
  97. function removeBackdrop(event) {
  98. event.preventDefault();
  99. const el = $(".modal-backdrop");
  100. if (el) {
  101. el.removeEventListener("click", removeBackdrop);
  102. el.parentNode.removeChild(el);
  103. $$(".ghrl-get-list").forEach(el => {
  104. el.classList.remove("selected");
  105. el.parentNode.classList.remove("active");
  106. });
  107. }
  108. }
  109.  
  110. function addBindings() {
  111. document.addEventListener("click", function(event) {
  112. const target = event.target;
  113. if (target.classList.contains("ghrl-get-list")) {
  114. event.preventDefault();
  115. if (!$(".dropdown-item", target.parentNode)) {
  116. loadFileList(target);
  117. }
  118. // let GitHub process the elements
  119. setTimeout(() => {
  120. const el = $(".modal-backdrop");
  121. if (el) {
  122. el.addEventListener("click", removeBackdrop);
  123. }
  124. }, 100);
  125. } else if (
  126. target.classList.contains("ghrl-file") &&
  127. // left mouse click only
  128. event.button === 0 &&
  129. // check for keyboard modifier + left click - the browser handles these
  130. // clicks differently
  131. !(event.shiftKey || event.ctrlKey || event.metaKey)
  132. ) {
  133. // allow left click to pass through
  134. window.location.href = target.href;
  135. }
  136. }, false);
  137. }
  138.  
  139. function $(str, el) {
  140. return (el || document).querySelector(str);
  141. }
  142.  
  143. function $$(str, el) {
  144. return Array.from((el || document).querySelectorAll(str));
  145. }
  146.  
  147. function closest(selector, el) {
  148. while (el && el.nodeType === 1) {
  149. if (el.matches(selector)) {
  150. return el;
  151. }
  152. el = el.parentNode;
  153. }
  154. return null;
  155. }
  156.  
  157. document.addEventListener("pjax:end", update);
  158. update();
  159. addBindings();
  160. })();