Gist Raw Links

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

当前为 2017-05-20 提交的版本,查看 最新版本

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