Greasy Fork - Change Default Script Sort

Change default script sort on GreasyFork

当前为 2016-09-04 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Greasy Fork - Change Default Script Sort
  3. // @namespace https://greasyfork.org/users/649
  4. // @version 1.1.2
  5. // @description Change default script sort on GreasyFork
  6. // @author Adrien Pyke
  7. // @match *://greasyfork.org/*/users/*
  8. // @match *://greasyfork.org/*/scripts*
  9. // @grant GM_getValue
  10. // @grant GM_setValue
  11. // @grant GM_registerMenuCommand
  12. // @run-at document-start
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17.  
  18. var Util = {
  19. getQueryParameter: function(name, url) {
  20. if (!url) url = window.location.href;
  21. name = name.replace(/[\[\]]/g, "\\$&");
  22. var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
  23. results = regex.exec(url);
  24. if (!results) return null;
  25. if (!results[2]) return '';
  26. return decodeURIComponent(results[2].replace(/\+/g, " "));
  27. },
  28.  
  29. setQueryParameter: function(key, value, url) {
  30. if (!url) url = window.location.href;
  31. var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"),
  32. hash;
  33.  
  34. if (re.test(url)) {
  35. if (typeof value !== 'undefined' && value !== null)
  36. return url.replace(re, '$1' + key + "=" + value + '$2$3');
  37. else {
  38. hash = url.split('#');
  39. url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, '');
  40. if (typeof hash[1] !== 'undefined' && hash[1] !== null)
  41. url += '#' + hash[1];
  42. return url;
  43. }
  44. }
  45. else {
  46. if (typeof value !== 'undefined' && value !== null) {
  47. var separator = url.indexOf('?') !== -1 ? '&' : '?';
  48. hash = url.split('#');
  49. url = hash[0] + separator + key + '=' + value;
  50. if (typeof hash[1] !== 'undefined' && hash[1] !== null)
  51. url += '#' + hash[1];
  52. return url;
  53. }
  54. else
  55. return url;
  56. }
  57. }
  58. };
  59.  
  60. var Config = {
  61. load: function() {
  62. var defaults = {
  63. all: 'daily-installs',
  64. search: 'relevance',
  65. user: 'daily-installs'
  66. };
  67.  
  68. var cfg = GM_getValue('cfg');
  69. if (!cfg) return defaults;
  70.  
  71. cfg = JSON.parse(cfg);
  72. for (var property in defaults) {
  73. if (defaults.hasOwnProperty(property)) {
  74. if (!cfg[property]) {
  75. cfg[property] = defaults[property];
  76. }
  77. }
  78. }
  79.  
  80. return cfg;
  81. },
  82.  
  83. save: function (cfg) {
  84. GM_setValue('cfg', JSON.stringify(cfg));
  85. },
  86.  
  87. setup: function() {
  88. var createContainer = function() {
  89. var div = document.createElement('div');
  90. div.style.backgroundColor = 'white';
  91. div.style.padding = '5px';
  92. div.style.border = '1px solid black';
  93. div.style.position = 'fixed';
  94. div.style.top = '0';
  95. div.style.right = '0';
  96. div.style.zIndex = 99999;
  97. return div;
  98. };
  99.  
  100. var createSelect = function(label, options, value) {
  101. var select = document.createElement('select');
  102. select.style.margin = '2px';
  103. var optgroup = document.createElement('optgroup');
  104. if (label) {
  105. optgroup.setAttribute('label', label);
  106. }
  107. select.appendChild(optgroup);
  108. options.forEach(function(opt) {
  109. var option = document.createElement('option');
  110. option.setAttribute('value', opt.value);
  111. option.textContent = opt.text;
  112. optgroup.appendChild(option);
  113. });
  114. select.value = value;
  115. return select;
  116. };
  117.  
  118. var createButton = function(text, onclick) {
  119. var button = document.createElement('button');
  120. button.style.margin = '2px';
  121. button.textContent = text;
  122. button.onclick = onclick;
  123. return button;
  124. };
  125.  
  126. var createLabel = function(label) {
  127. var lbl = document.createElement('span');
  128. lbl.textContent = label;
  129. return lbl;
  130. };
  131.  
  132. var createLineBreak = function() {
  133. return document.createElement('br');
  134. };
  135.  
  136. var init = function(cfg) {
  137. var div = createContainer();
  138.  
  139. var all = createSelect('All Scripts Sort', [
  140. { value: 'daily-installs', text: 'Daily installs' },
  141. { value: 'total_installs', text: 'Total installs' },
  142. { value: 'ratings', text: 'Ratings' },
  143. { value: 'created', text: 'Created date' },
  144. { value: 'updated', text: 'Updated date' },
  145. { value: 'name', text: 'Name' }
  146. ], cfg.all);
  147. div.appendChild(createLabel('All Scripts Sort: '));
  148. div.appendChild(all);
  149. div.appendChild(createLineBreak());
  150.  
  151. var search = createSelect('Search Sort', [
  152. { value: 'relevance', text: 'Relevance' },
  153. { value: 'daily_installs', text: 'Daily installs' },
  154. { value: 'total_installs', text: 'Total installs' },
  155. { value: 'ratings', text: 'Ratings' },
  156. { value: 'created', text: 'Created date' },
  157. { value: 'updated', text: 'Updated date' },
  158. { value: 'name', text: 'Name' }
  159. ], cfg.search);
  160. div.appendChild(createLabel('Search Sort: '));
  161. div.appendChild(search);
  162. div.appendChild(createLineBreak());
  163.  
  164. var user = createSelect('User Profile Sort', [
  165. { value: 'daily-installs', text: 'Daily installs' },
  166. { value: 'total_installs', text: 'Total installs' },
  167. { value: 'ratings', text: 'Ratings' },
  168. { value: 'created', text: 'Created date' },
  169. { value: 'updated', text: 'Updated date' },
  170. { value: 'name', text: 'Name' }
  171. ], cfg.user);
  172. div.appendChild(createLabel('User Profile Sort: '));
  173. div.appendChild(user);
  174. div.appendChild(createLineBreak());
  175.  
  176. div.appendChild(createButton('Save', function(e) {
  177. var settings = {
  178. all: all.value,
  179. search: search.value,
  180. user: user.value
  181. };
  182. Config.save(settings);
  183. div.remove();
  184. }));
  185.  
  186. div.appendChild(createButton('Cancel', function(e) {
  187. div.remove();
  188. }));
  189.  
  190. document.body.appendChild(div);
  191. };
  192. init(Config.load());
  193. }
  194. };
  195.  
  196. GM_registerMenuCommand('GreasyFork Sort Settings', Config.setup);
  197.  
  198. var onScripts = location.href.match(/^https?:\/\/greasyfork\.org\/[^\/]+\/scripts\/?(?:\?.*)?$/i);
  199. var onSearch = location.href.match(/^https?:\/\/greasyfork\.org\/[^\/]+\/scripts\/search?(?:\?.*)?$/i);
  200. var onProfile = location.href.match(/^https?:\/\/greasyfork\.org\/[^\/]+\/users\/[^\/]+?(?:\?.*)?$/i);
  201.  
  202. document.addEventListener('DOMContentLoaded', function(e) {
  203. var defaultSort = document.querySelector('#script-list-sort > ul > li:nth-child(1) > a');
  204. if (defaultSort) {
  205. if (onSearch) {
  206. defaultSort.href = Util.setQueryParameter('sort', 'relevance', defaultSort.href);
  207. } else {
  208. defaultSort.href = Util.setQueryParameter('sort', 'daily-installs', defaultSort.href);
  209. }
  210. }
  211. });
  212.  
  213. var sort = Util.getQueryParameter('sort');
  214. if (!sort) {
  215. var cfg = Config.load();
  216. var cfgSort;
  217. if (onScripts) {
  218. cfgSort = cfg.all;
  219. } else if (onSearch) {
  220. cfgSort = cfg.search;
  221. } else if (onProfile) {
  222. cfgSort = cfg.user;
  223. }
  224. if (cfgSort) {
  225. window.location.replace(Util.setQueryParameter('sort', cfgSort));
  226. }
  227. }
  228. })();