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.0
  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 class="dots" 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. console.log(link);
  75. addList(link, json.files);
  76. }
  77. }
  78. });
  79. }
  80. }
  81.  
  82. function addList(link, files) {
  83. let html = "";
  84. Object.keys(files).forEach(file => {
  85. html += `<a class="dropdown-item" href="${files[file].raw_url}">${file}</a>`;
  86. });
  87. console.log('updating list', link);
  88. $(".ghrl-files", link.parentNode).innerHTML = html;
  89. }
  90.  
  91. function removeBackdrop(event) {
  92. event.preventDefault();
  93. const el = $(".modal-backdrop");
  94. if (el) {
  95. el.removeEventListener("click", removeBackdrop);
  96. el.parentNode.removeChild(el);
  97. $$(".ghrl-get-list").forEach(el => {
  98. el.classList.remove("selected");
  99. el.parentNode.classList.remove("active");
  100. });
  101. }
  102. }
  103.  
  104. function addBindings() {
  105. document.addEventListener("click", function(event) {
  106. let flag;
  107. const target = event.target;
  108. if (target.classList.contains("ghrl-get-list")) {
  109. event.preventDefault();
  110. if (!$(".dropdown-item", target.parentNode)) {
  111. loadFileList(target);
  112. }
  113. // let GitHub process the elements
  114. setTimeout(() => {
  115. flag = !target.classList.contains("selected");
  116. const el = $(".modal-backdrop");
  117. if (el) {
  118. el.addEventListener("click", removeBackdrop);
  119. }
  120. }, 100);
  121. }
  122. }, false);
  123. }
  124.  
  125. function $(str, el) {
  126. return (el || document).querySelector(str);
  127. }
  128.  
  129. function $$(str, el) {
  130. return Array.from((el || document).querySelectorAll(str));
  131. }
  132.  
  133. function closest(selector, el) {
  134. while (el && el.nodeType === 1) {
  135. if (el.matches(selector)) {
  136. return el;
  137. }
  138. el = el.parentNode;
  139. }
  140. return null;
  141. }
  142.  
  143. document.addEventListener("pjax:end", update);
  144. update();
  145. addBindings();
  146. })();