Greasy Fork tweaks

opens pages of scripts from lists in a new tab and makes the user interface more compact, informative and interactive

目前為 2020-05-30 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Greasy Fork tweaks
  3. // @namespace almaceleste
  4. // @version 0.4.2
  5. // @description opens pages of scripts from lists in a new tab and makes the user interface more compact, informative and interactive
  6. // @description:ru открывает страницы скриптов из списков в новой вкладке и делает пользовательский интерфейс более компактным, информативным и интерактивным
  7. // @author (ɔ) almaceleste (https://almaceleste.github.io)
  8. // @license AGPL-3.0-or-later; http://www.gnu.org/licenses/agpl.txt
  9. // @icon https://greasyfork.org/assets/blacklogo16-bc64b9f7afdc9be4cbfa58bdd5fc2e5c098ad4bca3ad513a27b15602083fd5bc.png
  10. // @icon64 https://greasyfork.org/assets/blacklogo96-e0c2c76180916332b7516ad47e1e206b42d131d36ff4afe98da3b1ba61fd5d6c.png
  11.  
  12. // @homepageURL https://greasyfork.org/en/users/174037-almaceleste
  13. // @homepageURL https://openuserjs.org/users/almaceleste
  14. // @homepageURL https://github.com/almaceleste/userscripts
  15. // @supportURL https://github.com/almaceleste/userscripts/issues
  16.  
  17. // @require https://code.jquery.com/jquery-3.3.1.js
  18. // @require https://code.jquery.com/ui/1.12.1/jquery-ui.js
  19. // @require https://openuserjs.org/src/libs/sizzle/GM_config.js
  20. // @grant GM_getValue
  21. // @grant GM_setValue
  22. // @grant GM_registerMenuCommand
  23. // @grant GM_openInTab
  24. // @grant GM_getResourceText
  25.  
  26. // @resource css https://github.com/almaceleste/userscripts/raw/master/css/default.css
  27.  
  28. // @match https://greasyfork.org/*/users/*
  29. // @match https://greasyfork.org/*/scripts*
  30. // ==/UserScript==
  31.  
  32. // ==OpenUserJS==
  33. // @author almaceleste
  34. // ==/OpenUserJS==
  35.  
  36. const listitem = '.script-list li';
  37. const separator = '.name-description-separator';
  38. const scriptversion = 'data-script-version';
  39. const scriptrating = 'dd.script-list-ratings';
  40. const scriptstats = '.inline-script-stats';
  41. const dailyinstalls = '.script-list-daily-installs';
  42. const totalinstalls = '.script-list-total-installs';
  43. const createddate = '.script-list-created-date';
  44. const updateddate = '.script-list-updated-date';
  45.  
  46. const userprofile = {};
  47. userprofile.path = '#user-profile';
  48. userprofile.header = 'body > div.width-constraint > section:first-child > h2';
  49.  
  50. const sections = {};
  51. sections.controlpanel = '#control-panel';
  52. sections.discussions = '#user-discussions-on-scripts-written';
  53. sections.scriptsets = 'section:has(h3:contains("Script Sets"))';
  54.  
  55. const configId = 'greasyforktweaksCfg';
  56. const iconUrl = GM_info.script.icon64;
  57. const pattern = {};
  58. pattern[`#${configId}`] = /#configId/g;
  59. pattern[`${iconUrl}`] = /iconUrl/g;
  60.  
  61. let css = GM_getResourceText('css');
  62. Object.keys(pattern).forEach((key) => {
  63. css = css.replace(pattern[key], key);
  64. });
  65. const windowcss = css;
  66. const iframecss = `
  67. height: 455px;
  68. width: 435px;
  69. border: 1px solid;
  70. border-radius: 3px;
  71. position: fixed;
  72. z-index: 9999;
  73. `;
  74.  
  75. GM_registerMenuCommand(`${GM_info.script.name} Settings`, () => {
  76. GM_config.open();
  77. GM_config.frame.style = iframecss;
  78. });
  79.  
  80. GM_config.init({
  81. id: `${configId}`,
  82. title: `${GM_info.script.name} ${GM_info.script.version}`,
  83. fields: {
  84. version: {
  85. section: ['', 'Script list options (own and other pages)'],
  86. label: 'add script version number in the list of scripts',
  87. labelPos: 'right',
  88. type: 'checkbox',
  89. default: true,
  90. },
  91. ratingscore: {
  92. label: 'display script rating score',
  93. labelPos: 'right',
  94. type: 'checkbox',
  95. default: true,
  96. },
  97. compact: {
  98. label: 'compact script information',
  99. labelPos: 'right',
  100. type: 'checkbox',
  101. default: true,
  102. },
  103. userprofile: {
  104. section: ['', 'User page options (own page and other users`)'],
  105. label: 'collapse user profile info on user page',
  106. labelPos: 'right',
  107. type: 'checkbox',
  108. default: true,
  109. },
  110. controlpanel: {
  111. label: 'collapse control panel on user page',
  112. labelPos: 'right',
  113. type: 'checkbox',
  114. default: true,
  115. },
  116. discussions: {
  117. label: 'collapse discussions on user page',
  118. labelPos: 'right',
  119. type: 'checkbox',
  120. default: true,
  121. },
  122. scriptsets: {
  123. label: 'collapse script sets on user page',
  124. labelPos: 'right',
  125. type: 'checkbox',
  126. default: true,
  127. },
  128. newtab: {
  129. section: ['', 'Other options'],
  130. label: 'open script page in new tab',
  131. labelPos: 'right',
  132. type: 'checkbox',
  133. default: true,
  134. },
  135. background: {
  136. label: 'open new tab in background',
  137. labelPos: 'right',
  138. type: 'checkbox',
  139. default: false,
  140. },
  141. insert: {
  142. label: 'insert new tab next to the current instead of the right end',
  143. labelPos: 'right',
  144. type: 'checkbox',
  145. default: true,
  146. },
  147. setParent: {
  148. label: 'return to the current tab after new tab closed',
  149. labelPos: 'right',
  150. type: 'checkbox',
  151. default: true,
  152. },
  153. support: {
  154. section: ['', 'Support'],
  155. label: 'almaceleste.github.io',
  156. title: 'more info on almaceleste.github.io',
  157. type: 'button',
  158. click: () => {
  159. GM_openInTab('https://almaceleste.github.io', {
  160. active: true,
  161. insert: true,
  162. setParent: true
  163. });
  164. }
  165. },
  166. },
  167. css: windowcss,
  168. events: {
  169. save: function() {
  170. GM_config.close();
  171. }
  172. },
  173. });
  174.  
  175. function arrow(element){
  176. const arrow = $(`
  177. <svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
  178. <style>
  179. .collapsed {
  180. transform: rotate(0deg);
  181. }
  182. .expanded {
  183. transform: rotate(180deg);
  184. }
  185. </style>
  186. <text x='0' y='18'>▼</text>
  187. </svg>
  188. `).css({
  189. fill: 'whitesmoke',
  190. height: '20px',
  191. width: '30px',
  192. });
  193. $(element).append(arrow);
  194. }
  195.  
  196. function collapse(element, header){
  197. $(element).css({
  198. cursor: 'pointer',
  199. });
  200. arrow($(element).find(header));
  201. $(element).accordion({
  202. collapsible: true,
  203. active: false,
  204. beforeActivate: () => {
  205. rotate($(element).find('svg'));
  206. }
  207. });
  208. }
  209.  
  210. function rotate(element){
  211. if ($(element).hasClass('expanded')) {
  212. $(element).animate({
  213. transform: 'rotate(0deg)',
  214. });
  215. }
  216. else {
  217. $(element).animate({
  218. transform: 'rotate(180deg)',
  219. });
  220. }
  221. $(element).toggleClass('expanded');
  222. }
  223.  
  224. function compact(first, second){
  225. $('dt' + first).each(function(){
  226. $(this).css('display','none');
  227. $(this).siblings('dt' + second).find('span').append(' (' + $(this).find('span').text() + ')');
  228. });
  229. $('dd' + first).each(function(){
  230. $(this).css('display','none');
  231. $(this).siblings('dd' + second).find('span').append(' (' + $(this).find('span').text() + ')');
  232. });
  233. }
  234.  
  235. function newtaber(e){
  236. const options = {active: !GM_config.get('background'), insert: GM_config.get('insert'), setParent: GM_config.get('setParent')};
  237. e.preventDefault();
  238. e.stopPropagation();
  239. GM_openInTab(e.target.href, options);
  240. }
  241.  
  242. (function() {
  243. 'use strict';
  244.  
  245. const version = GM_config.get('version');
  246. const newtab = GM_config.get('newtab');
  247.  
  248. if (GM_config.get('userprofile')){
  249. $(userprofile.path).slideUp();
  250. arrow($(userprofile.header));
  251. $(userprofile.header).css({
  252. cursor: 'pointer',
  253. })
  254. .click(function(){
  255. $(userprofile.path).slideToggle();
  256. rotate($(this).find('svg'));
  257. });
  258. }
  259. Object.keys(sections).forEach((section) => {
  260. if (GM_config.get(section)) {
  261. collapse(sections[section], 'header h3');
  262. }
  263. });
  264. $(listitem).each(function(){
  265. if (version){
  266. $(this).find(separator).before(` ${$(this).attr(scriptversion)}`);
  267. }
  268. if (newtab){
  269. $(this).find(separator).prev('a').click(newtaber);
  270. }
  271. });
  272. if (GM_config.get('ratingscore')) {
  273. $(scriptrating).each(function(){
  274. $(this).children('span').after(` - ${$(this).attr('data-rating-score')}`);
  275. });
  276. }
  277. if (GM_config.get('compact')){
  278. $(scriptstats).children().css('width','auto');
  279. compact(totalinstalls, dailyinstalls);
  280. compact(updateddate, createddate);
  281. }
  282. })();