Greasy Fork 支持简体中文。

GitHub - Linkify package.json dependencies

Turns the names of packages into links to their homepages when looking at a package.json file

  1. // ==UserScript==
  2. // @name GitHub - Linkify package.json dependencies
  3. // @description Turns the names of packages into links to their homepages when looking at a package.json file
  4. // @author James Skinner <spiralx@gmail.com> (http://github.com/spiralx)
  5. // @namespace http://spiralx.org/
  6. // @version 0.3.1
  7. // @match *://github.com/*/package.json
  8. // @match *://github.com/*%2Fpackage.json
  9. // @grant GM_xmlhttpRequest
  10. // @grant GM_getValue
  11. // @grant GM_setValue
  12. // @grant GM_registerMenuCommand
  13. // @require https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.js
  14. // ==/UserScript==
  15.  
  16.  
  17. (function($) {
  18. 'use strict';
  19. function Cache(key) {
  20. this._key = key;
  21. this._data = {};
  22. this.load();
  23. }
  24. Cache.prototype = {
  25. getValue: function(k) {
  26. return this._data[k];
  27. },
  28. setValue: function(k, v) {
  29. this._data[k] = v;
  30. this.save();
  31. },
  32. deleteValue: function(k) {
  33. if (k in this._data) {
  34. delete this._data[k];
  35. this.save();
  36. }
  37. },
  38. hasValue: function(k) {
  39. return k in this._data;
  40. },
  41. listValues: function() {
  42. return Object.keys(this._data).sort();
  43. },
  44. clear: function() {
  45. this._data = {};
  46. this.save();
  47. },
  48. save: function() {
  49. var s = JSON.stringify(this._data);
  50. GM_setValue(this._key, s);
  51. console.info('Cache(' + this._key + ') saved: ' + s);
  52. },
  53. load: function(s) {
  54. try {
  55. this._data = JSON.parse(s || GM_getValue(this._key));
  56. }
  57. catch (ex) {
  58. this.clear();
  59. }
  60. },
  61. edit: function() {
  62. var res = window.prompt('Edit cached package URLs', JSON.stringify(this._data, null, 2));
  63. if (res !== null) {
  64. try {
  65. this._data = res ? JSON.parse(res) : {};
  66. this.save();
  67. }
  68. catch (ex) {
  69. console.warn('Failed to update cache data: %s %o', ex.toString(), ex);
  70. }
  71. }
  72. },
  73. toString: function() {
  74. return 'Cache(' + this._key + '): [' + this.listValues.join('\n') + ']';
  75. },
  76. dump: function() {
  77. console.log('Cache(' + this._key + '):\n' + JSON.stringify(this._data, null, 2));
  78. }
  79. };
  80.  
  81.  
  82. // --------------------------------------------------------------------------
  83. function extractWebUrl(j) {
  84. if (!j) {
  85. return;
  86. }
  87.  
  88. return (typeof j === 'string' ? j : j.url)
  89. .replace(/^gitlab:(\S+)\/(\S+)$/, 'https://gitlab.com/$1/$2')
  90. .replace(/^bitbucket:(\S+)\/(\S+)$/, 'https://bitbucket.com/$1/$2')
  91. .replace(/^gist:(\S+?)$/, 'https://gist.github.com/$1')
  92. .replace(/^([^\/\s]+)\/([^\/\s]+)$/, 'https://github.com/$1/$2')
  93. .replace(/^git(\+https)?:\/\//, 'https://')
  94. .replace(/(\/svn\/trunk|\.git|\/issues)$/, '');
  95. }
  96.  
  97.  
  98. // --------------------------------------------------------------------------
  99. function getPackageLink(packageName, url, background) {
  100. return $('<a>')
  101. .text(packageName)
  102. .attr('href', url)
  103. .css('background-color', background || 'white');
  104. }
  105.  
  106.  
  107. // --------------------------------------------------------------------------
  108.  
  109. function getPackageData(packageName, $a) {
  110. var url = 'http://registry.npmjs.com/' + packageName;
  111.  
  112. GM_xmlhttpRequest({
  113. url: url,
  114. method: 'GET',
  115. onload: function(response) {
  116. var data = JSON.parse(response.responseText),
  117. homepage = extractWebUrl(data.repository) || extractWebUrl(data.homepage) || extractWebUrl(data.bugs);
  118. if (homepage) {
  119. $a
  120. .attr('href', homepage)
  121. .css('background-color', '#dfd');
  122. cachedHomepages.setValue(packageName, homepage);
  123. }
  124. else {
  125. console.warn(url + ': No homepage found!');
  126. console.dir(data);
  127. $a.css('background-color', '#fdd');
  128. }
  129. },
  130. onerror: function(response) {
  131. console.warn(url + ': ' + response.status + ' ' + response.statusText);
  132. $a.css('background-color', '#fdd');
  133. }
  134. });
  135. }
  136.  
  137.  
  138. // --------------------------------------------------------------------------
  139. var dependencyKeys = [
  140. 'dependencies',
  141. 'devDependencies',
  142. 'peerDependencies',
  143. 'bundleDependencies',
  144. 'optionalDependencies'
  145. ];
  146.  
  147.  
  148. // --------------------------------------------------------------------------
  149.  
  150. var cachedHomepages = new Cache('github-linkify-urls');
  151. // console.info(cachedHomepages);
  152.  
  153. var
  154. $cont = $('.file .js-file-line-container'),
  155. $strings = $cont.find('.pl-s:first-of-type'),
  156. packageJson = JSON.parse($cont.text());
  157.  
  158. dependencyKeys.forEach(function(k) {
  159. var dependencies = packageJson[k] || {};
  160.  
  161. Object.keys(dependencies).forEach(function(packageName) {
  162. var homepage,
  163. ns = '"' + packageName + '"',
  164. $e = $strings.filter(function() {
  165. return this.textContent.trim() === ns;
  166. }),
  167. $a;
  168.  
  169. if ($e.length === 0) {
  170. console.warn('No matching string found for package "' + packageName + '"!');
  171. return;
  172. }
  173.  
  174. if (cachedHomepages.hasValue(packageName)) {
  175. homepage = cachedHomepages.getValue(packageName);
  176. // console.info('Found "' + homepage + '" for package "' + packageName + '" in cache');
  177.  
  178. $a = getPackageLink(packageName, homepage, '#dfd');
  179. }
  180. else {
  181. homepage = 'http://www.npmjs.com/package/' + packageName;
  182. // console.info('No homepage found for package "' + packageName + '"');
  183.  
  184. $a = getPackageLink(packageName, homepage);
  185. getPackageData(packageName, $a);
  186. }
  187.  
  188. $e
  189. .empty()
  190. .append('<span class="pl-pds">"</span>')
  191. .append($a)
  192. .append('<span class="pl-pds">"</span>');
  193. });
  194. });
  195.  
  196.  
  197. // --------------------------------------------------------------------------
  198.  
  199. GM_registerMenuCommand('Edit cached packages', function() {
  200. cachedHomepages.edit();
  201. }, 'p');
  202.  
  203. })(jQuery);