GreasyFork Bullshit Filter

Hides scripts for popular browser games and social networks as well as scripts that use "foreign" characters in descriptions. Applies to posts in Forum too.

当前为 2018-09-14 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name GreasyFork Bullshit Filter
  3. // @namespace darkred
  4. // @version 2018.9.14
  5. // @description Hides scripts for popular browser games and social networks as well as scripts that use "foreign" characters in descriptions. Applies to posts in Forum too.
  6. // @author kuehlschrank, darkred
  7. // @license MIT
  8. // @icon https://raw.githubusercontent.com/darkred/Userscripts/master/GreasyFork_Bullshit_Filter/large.png
  9. // @include /^https:\/\/(greasy|sleazy)fork\.org\/(.*\/)?(scripts|forum|users).*$/
  10. // @exclude /^https:\/\/(greasy|sleazy)fork\.org\/(.*\/)((scripts\/\d+)|forum\/(discussion\/|profile|messages)).*$/
  11. // @grant none
  12. // This is an edited version of this script (http://userscripts-mirror.org/scripts/show/97145) by kuehlschrank.
  13. // Thanks a lot to kuehlschrank for making another great script.
  14. // ==/UserScript==
  15.  
  16.  
  17. if (window.location.href.indexOf('forum') === -1) {
  18. (function() {
  19. var filters = {
  20. 'Non-ASCII': /[^\x00-\x7F\s]+/iu,
  21. 'Games': /AntiGame|Agar|agar\.io|alis\.io|angel\.io|ExtencionRipXChetoMalo|AposBot|DFxLite|ZTx-Lite|AposFeedingBot|AposLoader|Blah Blah|Orc Clan Script|Astro\s*Empires|^\s*Attack|^\s*Battle|BiteFight|Blood\s*Wars|Bots|Bots4|Brawler|\bBvS\b|Business\s*Tycoon|Castle\s*Age|City\s*Ville|chopcoin\.io|Comunio|Conquer\s*Club|CosmoPulse|cursors\.io|Dark\s*Orbit|Dead\s*Frontier|Diep\.io|\bDOA\b|doblons\.io|DotD|Dossergame|Dragons\s*of\s*Atlantis|driftin\.io|Dugout|\bDS[a-z]+\n|elites\.io|Empire\s*Board|eRep(ublik)?|Epic.*War|ExoPlanet|Falcon Tools|Feuerwache|Farming|FarmVille|Fightinfo|Frontier\s*Ville|Ghost\s*Trapper|Gladiatus|Goalline|Gondal|gota\.io|Grepolis|Hobopolis|\bhwm(\b|_)|Ikariam|\bIT2\b|Jellyneo|Kapi\s*Hospital|Kings\s*Age|Kingdoms?\s*of|knastv(ö|oe)gel|Knight\s*Fight|\b(Power)?KoC(Atta?ck)?\b|\bKOL\b|Kongregate|Last\s*Emperor|Legends?\s*of|Light\s*Rising|lite\.ext\.io|Lockerz|\bLoU\b|Mafia\s*(Wars|Mofo)|Menelgame|Mob\s*Wars|Mouse\s*Hunt|Molehill\s*Empire|NeoQuest|MyFreeFarm|narwhale\.io|Neopets|Nemexia|\bOGame\b|Ogar(io)?|Pardus|Pennergame|Pigskin\s*Empire|PlayerScripts|pokeradar\.io|Popmundo|Po?we?r\s*(Bot|Tools)|PsicoTSI|Ravenwood|Schulterglatze|slither\.io|slitherplus\.io|slitheriogameplay|SpaceWars|splix\.io|\bSW_[a-z]+\n|\bSnP\b|The\s*Crims|The\s*West|torto\.io|Travian|Treasure\s*Isl(and|e)|Tribal\s*Wars|TW.?PRO|Vampire\s*Wars|vertix\.io|War\s*of\s*Ninja|West\s*Wars|wings\.io|\bWoD\b|World\s*of\s*Dungeons|wtf\s*battles|Wurzelimperium/iu,
  22. 'Social Networks': /Face\s*book|Google(\+| Plus)|\bHabbo|Kaskus|\bLepra|Leprosorium|MySpace|meinVZ|odnoklassniki|Одноклассники|Orkut|sch(ue|ü)ler(VZ|\.cc)?|studiVZ|Unfriend|Valenth|VK|vkontakte|ВКонтакте|Qzone|Twitter|TweetDeck/iu,
  23. 'Clutter': /^\s*(.{1,3})\1+\n|^\s*(.+?)\n+\2\n*$|^\s*.{1,5}\n|do\s*n('|o)?t (install|download)|nicht installieren|(just)?(\s*a)?\s*test|^\s*.{0,4}test.{0,4}\n|\ntest(ing)?\s*|^\s*(\{@|Smolka|Hacks)|\[\d{4,5}\]|free\s*download|theme|(night|dark) ?(mode)?/iu
  24. };
  25. if (typeof GM_getValue === 'undefined' || (typeof GM_getValue.toString === 'function' && GM_getValue.toString().indexOf('not supported') > -1)) {
  26. GM_getValue = my_GM_getValue;
  27. GM_setValue = my_GM_setValue;
  28. }
  29. insertStyle();
  30. insertStatus();
  31. filterScripts();
  32. insertSwitches();
  33.  
  34. // Note: you may uncomment line 35 (and comment out line 36), in order the filtered scripts to be highlighted khaki -instead of hiding them- so that you can check which scripts have been filtered
  35. function insertStyle() {
  36. var style = document.createElement('style');
  37. // style.textContent = 'li.filtered { background-color:khaki; !important;} .filter-status { margin-left: 6px; } .filter-switches { display:none; } *:hover > .filter-switches { display:block !important; } .filter-on, .filter-off {display:block !important; width: 97px;}} .filter-switches a { text-decoration:none !important; color:inherit; cursor:pointer; } .filter-switches a { margin-left: 8px; padding: 0 4px; } a.filter-on { background-color:#ffcccc; color:#333333; text-decoration:line-through !important } a.filter-off { background-color:#ccffcc; color:#333333 } ';
  38. style.textContent = 'li.filtered { display:none !important; } .filter-status { margin-left: 6px; } .filter-switches { display:none; } *:hover > .filter-switches { display:block !important; } .filter-on, .filter-off {display:block !important; width: 97px;}} .filter-switches a { text-decoration:none !important; color:inherit; cursor:pointer; } .filter-switches a { margin-left: 8px; padding: 0 4px; } a.filter-on { background-color:#ffcccc; color:#333333; text-decoration:line-through !important } a.filter-off { background-color:#ccffcc; color:#333333 } ';
  39. style.type = 'text/css';
  40. document.querySelector('head').appendChild(style);
  41. }
  42.  
  43. function insertStatus() {
  44. var p = document.querySelector('#script-list-option-groups');
  45. if (p) {
  46. var status = document.createElement('span');
  47. status.className = 'filter-status';
  48. p.appendChild(status);
  49. }
  50. }
  51.  
  52. function filterScripts() {
  53. var activeFilters = [];
  54. for (var filter in filters) {
  55. if (filters.hasOwnProperty(filter) && GM_getValue(filter, 'on') === 'on') {
  56. activeFilters.push(filters[filter]);
  57. }
  58. }
  59. var nodes = document.querySelectorAll('article > h2'),
  60. numActiveFilters = activeFilters.length,
  61. numFiltered = 0;
  62. for (var i = 0, numNodes = nodes.length, td = null; i < numNodes && (td = nodes[i]); i++) {
  63. td.parentNode.parentNode.classList.remove('filtered');
  64. for (var j = 0; j < numActiveFilters; j++) {
  65. if (td.innerText.match(activeFilters[j])) {
  66. td.parentNode.parentNode.classList.add('filtered');
  67. numFiltered++;
  68. break;
  69. }
  70. }
  71. }
  72. document.querySelector('.filter-status').textContent = document.querySelectorAll('article > h2').length - numFiltered + ' scripts (' + numFiltered + ' filtered)';
  73. }
  74.  
  75. function insertSwitches() {
  76. var span = document.createElement('span');
  77. span.className = 'filter-switches';
  78. for (var filter in filters) {
  79. if (filters.hasOwnProperty(filter)) {
  80. span.appendChild(createSwitch(filter, GM_getValue(filter, 'on') === 'on'));
  81. }
  82. }
  83. document.querySelector('.filter-status').parentNode.appendChild(span);
  84. }
  85.  
  86. function createSwitch(label, isOn) {
  87. var a = document.createElement('a');
  88. a.className = isOn ? 'filter-on' : 'filter-off';
  89. a.textContent = label;
  90. a.addEventListener('click', function(e) {
  91. if (this.className === 'filter-on') {
  92. this.className = 'filter-off';
  93. GM_setValue(this.textContent, 'off');
  94. } else {
  95. this.className = 'filter-on';
  96. GM_setValue(this.textContent, 'on');
  97. }
  98. filterScripts();
  99. e.preventDefault();
  100. }, false);
  101. return a;
  102. }
  103.  
  104. function my_GM_setValue(name, value) {
  105. localStorage.setItem(name, value);
  106. }
  107.  
  108. function my_GM_getValue(name, defaultValue) {
  109. var value;
  110. if (!(value = localStorage.getItem(name))) {
  111. return defaultValue;
  112. }
  113. return value;
  114. }
  115. })();
  116.  
  117. } else {
  118.  
  119. (function() {
  120. var filters = {
  121. 'Non-ASCII': /[^\x00-\x7F\s]+/iu,
  122. 'Games': /AntiGame|Agar|agar\.io|alis\.io|angel\.io|ExtencionRipXChetoMalo|AposBot|DFxLite|ZTx-Lite|AposFeedingBot|AposLoader|Blah Blah|Orc Clan Script|Astro\s*Empires|^\s*Attack|^\s*Battle|BiteFight|Blood\s*Wars|Bots|Bots4|Brawler|\bBvS\b|Business\s*Tycoon|Castle\s*Age|City\s*Ville|chopcoin\.io|Comunio|Conquer\s*Club|CosmoPulse|cursors\.io|Dark\s*Orbit|Dead\s*Frontier|Diep\.io|\bDOA\b|doblons\.io|DotD|Dossergame|Dragons\s*of\s*Atlantis|driftin\.io|Dugout|\bDS[a-z]+\n|elites\.io|Empire\s*Board|eRep(ublik)?|Epic.*War|ExoPlanet|Falcon Tools|Feuerwache|Farming|FarmVille|Fightinfo|Frontier\s*Ville|Ghost\s*Trapper|Gladiatus|Goalline|Gondal|gota\.io|Grepolis|Hobopolis|\bhwm(\b|_)|Ikariam|\bIT2\b|Jellyneo|Kapi\s*Hospital|Kings\s*Age|Kingdoms?\s*of|knastv(ö|oe)gel|Knight\s*Fight|\b(Power)?KoC(Atta?ck)?\b|\bKOL\b|Kongregate|Last\s*Emperor|Legends?\s*of|Light\s*Rising|lite\.ext\.io|Lockerz|\bLoU\b|Mafia\s*(Wars|Mofo)|Menelgame|Mob\s*Wars|Mouse\s*Hunt|Molehill\s*Empire|NeoQuest|MyFreeFarm|narwhale\.io|Neopets|Nemexia|\bOGame\b|Ogar(io)?|Pardus|Pennergame|Pigskin\s*Empire|PlayerScripts|pokeradar\.io|Popmundo|Po?we?r\s*(Bot|Tools)|PsicoTSI|Ravenwood|Schulterglatze|slither\.io|slitherplus\.io|slitheriogameplay|SpaceWars|splix\.io|\bSW_[a-z]+\n|\bSnP\b|The\s*Crims|The\s*West|torto\.io|Travian|Treasure\s*Isl(and|e)|Tribal\s*Wars|TW.?PRO|Vampire\s*Wars|vertix\.io|War\s*of\s*Ninja|West\s*Wars|wings\.io|\bWoD\b|World\s*of\s*Dungeons|wtf\s*battles|Wurzelimperium/iu,
  123. 'Social Networks': /Face\s*book|Google(\+| Plus)|\bHabbo|Kaskus|\bLepra|Leprosorium|MySpace|meinVZ|odnoklassniki|Одноклассники|Orkut|sch(ue|ü)ler(VZ|\.cc)?|studiVZ|Unfriend|Valenth|VK|vkontakte|ВКонтакте|Qzone|Twitter|TweetDeck/iu,
  124. 'Clutter': /^\s*(.{1,3})\1+\n|^\s*(.+?)\n+\2\n*$|^\s*.{1,5}\n|do\s*n('|o)?t (install|download)|nicht installieren|(just)?(\s*a)?\s*test|^\s*.{0,4}test.{0,4}\n|\ntest(ing)?\s*|^\s*(\{@|Smolka|Hacks)|\[\d{4,5}\]|free\s*download/iu
  125. };
  126. if (typeof GM_getValue === 'undefined' || (typeof GM_getValue.toString === 'function' && GM_getValue.toString().indexOf('not supported') > -1)) {
  127. GM_getValue = my_GM_getValue;
  128. GM_setValue = my_GM_setValue;
  129. }
  130. insertStyle();
  131. insertStatus();
  132. filterScripts();
  133. insertSwitches();
  134.  
  135. // Note: you may uncomment line 35 (and comment out line 36), in order the filtered scripts to be highlighted khaki -instead of hiding them- so that you can check which scripts have been filtered
  136. function insertStyle() {
  137. var style = document.createElement('style');
  138. // style.textContent = '.ItemDiscussion.filtered { background-color:khaki !important;} .filter-status { margin-left: 6px; } .filter-switches { display:none; } *:hover > .filter-switches { display:block !important; } .filter-on, .filter-off {display:block !important; width: 97px;}} .filter-switches a { text-decoration:none !important; color:inherit; cursor:pointer; } .filter-switches a { margin-left: 8px; padding: 0 4px; } a.filter-on { background-color:#ffcccc; color:#333333; text-decoration:line-through !important } a.filter-off { background-color:#ccffcc; color:#333333 } ';
  139. style.textContent = '.ItemDiscussion.filtered { display:none !important; } .filter-status { margin-left: 6px; } .filter-switches { display:none; } *:hover > .filter-switches { display:block !important; } .filter-on, .filter-off {display:block !important; width: 97px;}} .filter-switches a { text-decoration:none !important; color:inherit; cursor:pointer; } .filter-switches a { margin-left: 8px; padding: 0 4px; } a.filter-on { background-color:#ffcccc; color:#333333; text-decoration:line-through !important } a.filter-off { background-color:#ccffcc; color:#333333 } .filter-on, .filter-off { color: black !important;} ';
  140. style.type = 'text/css';
  141. document.querySelector('head').appendChild(style);
  142. }
  143.  
  144. function insertStatus() {
  145. var p = document.querySelector('#Head');
  146. if (p) {
  147. var status = document.createElement('span');
  148. status.className = 'filter-status';
  149. p.appendChild(status);
  150. }
  151. }
  152.  
  153. function filterScripts() {
  154. var activeFilters = [];
  155. for (var filter in filters) {
  156. if (filters.hasOwnProperty(filter) && GM_getValue(filter, 'on') === 'on') {
  157. activeFilters.push(filters[filter]);
  158. }
  159. }
  160. var nodes = document.querySelectorAll('.ItemDiscussion'),
  161. numActiveFilters = activeFilters.length,
  162. numFiltered = 0;
  163. for (var i = 0, numNodes = nodes.length, td = null; i < numNodes && (td = nodes[i]); i++) {
  164. td.classList.remove('filtered');
  165. for (var j = 0; j < numActiveFilters; j++) {
  166. var temp = td.children[1].firstElementChild.innerText;
  167. if(temp.match(activeFilters[j])) {
  168. td.classList.add('filtered');
  169. numFiltered++;
  170. break;
  171. }
  172. }
  173. }
  174. document.querySelector('.filter-status').innerText = (document.querySelectorAll('.ItemDiscussion').length - numFiltered) + ' discussions (' + numFiltered + ' filtered)';
  175. }
  176.  
  177. function insertSwitches() {
  178. var span = document.createElement('span');
  179. span.className = 'filter-switches';
  180. for (var filter in filters) {
  181. if (filters.hasOwnProperty(filter)) {
  182. span.appendChild(createSwitch(filter, GM_getValue(filter, 'on') === 'on'));
  183. }
  184. }
  185. document.querySelector('.filter-status').parentNode.appendChild(span);
  186. }
  187.  
  188. function createSwitch(label, isOn) {
  189. var a = document.createElement('a');
  190. a.className = isOn ? 'filter-on' : 'filter-off';
  191. a.textContent = label;
  192. a.addEventListener('click', function(e) {
  193. if (this.className === 'filter-on') {
  194. this.className = 'filter-off';
  195. GM_setValue(this.textContent, 'off');
  196. } else {
  197. this.className = 'filter-on';
  198. GM_setValue(this.textContent, 'on');
  199. }
  200. filterScripts();
  201. e.preventDefault();
  202. }, false);
  203. return a;
  204. }
  205.  
  206. function my_GM_setValue(name, value) {
  207. localStorage.setItem(name, value);
  208. }
  209.  
  210. function my_GM_getValue(name, defaultValue) {
  211. var value;
  212. if (!(value = localStorage.getItem(name))) {
  213. return defaultValue;
  214. }
  215. return value;
  216. }
  217. })();
  218.  
  219.  
  220.  
  221.  
  222. }