NGA Filter

troll must die

当前为 2019-09-01 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name NGA Filter
  3. // @namespace https://greasyfork.org/users/263018
  4. // @version 0.4
  5. // @author snyssss
  6. // @description troll must die
  7. // @match *bbs.nga.cn/thread.php?fid=*
  8. // @match *bbs.nga.cn/read.php?tid=*
  9. // @match *ngabbs.com/thread.php?fid=*
  10. // @match *ngabbs.com/read.php?tid=*
  11. // @grant GM_registerMenuCommand
  12. // @grant GM_unregisterMenuCommand
  13. // @noframes
  14. // ==/UserScript==
  15.  
  16. (function () {
  17. 'use strict';
  18.  
  19. const dataKey = 'troll_data';
  20. const modeKey = 'troll_mode';
  21.  
  22. const keyword = [
  23. '魔兽', '拼多多'
  24. ];
  25.  
  26. let filterMode = ~~localStorage.getItem(modeKey);
  27.  
  28. let trollMap = (function () {
  29. try {
  30. return JSON.parse(localStorage.getItem(dataKey)) || {};
  31. } catch (e) {
  32. localStorage.setItem(dataKey, '{}');
  33. }
  34. return {};
  35. })();
  36.  
  37. const isTroll = function (uid) {
  38. uid = ~~uid;
  39. if (uid) {
  40. return trollMap[uid];
  41. }
  42. return false;
  43. };
  44.  
  45. const isMatch = function (text) {
  46. for (var i in keyword) {
  47. if (text.search(keyword[i]) >= 0) {
  48. return true;
  49. }
  50. }
  51. return false;
  52. };
  53.  
  54. const toggleTroll = function (uid) {
  55. uid = ~~uid;
  56. if (uid) {
  57. if (trollMap[uid]) {
  58. delete trollMap[uid];
  59. } else {
  60. trollMap[uid] = true;
  61. }
  62. localStorage.setItem(dataKey, JSON.stringify(trollMap));
  63. }
  64. };
  65.  
  66. const getUID = function (e) {
  67. let ele = e.getElementsByClassName('author')[0];
  68. if (ele) {
  69. return ele.search.match(/uid=(\S*)/)[1];
  70. }
  71. };
  72.  
  73. const getLink = function (e) {
  74. let ele = e.getElementsByClassName('topic')[0];
  75. ele.hide = function () {
  76. if (filterMode) {
  77. e.remove();
  78. }else{
  79. ele.style.textDecoration = 'line-through';
  80. }
  81. }
  82. return ele;
  83. };
  84.  
  85. const getToggleButton = function (e) {
  86. let ele = e.getElementsByClassName('author')[0].nextElementSibling;
  87. if (ele.nextElementSibling) {
  88. ele = ele.nextElementSibling;
  89. }
  90. let uid = ~~ele.text;
  91. if (uid) {
  92. if (isTroll(uid)) {
  93. ele.style.background = '#CB4042';
  94. } else {
  95. ele.style.background = '#AAA';
  96. }
  97. return ele;
  98. }
  99. else {
  100. ele.onclick = null;
  101. }
  102. };
  103.  
  104. const getAvatar = function (e) {
  105. let ele = e.getElementsByClassName('avatar')[0] || { style: { display: '' } };
  106. ele.show = function () {
  107. ele.style.display = '';
  108. }
  109. ele.hide = function () {
  110. ele.style.display = 'none';
  111. }
  112. return ele;
  113. };
  114.  
  115. const getContent = function (e) {
  116. let uid = getUID(e);
  117. let name = '$troll_' + uid;
  118. let ele = e.getElementsByClassName('postcontent')[0] || { innerHTML: '' };
  119. ele.content = ele.content || ele.innerHTML;
  120. ele.show = function () {
  121. if (filterMode) {
  122. e.style.display = '';
  123. } else {
  124. ele.innerHTML = ele.content;
  125. }
  126. }
  127. ele.hide = function () {
  128. if (filterMode) {
  129. e.style.display = 'none';
  130. } else {
  131. ele.innerHTML =
  132. '<div class="lessernuke" style="background: #81C7D4; border-color: #66BAB7;">' +
  133. '<span class="crimson">Troll must die.</span> ' +
  134. '<a href="javascript:void(0)" onclick="var x = document.getElementsByName(&quot;' + name + '&quot;);for(var i=0;i<x.length;i++){x[i].style.display=&quot;&quot;}">点击查看</a>' +
  135. '<div style="display:none" name="' + name + '">' + ele.content + '</div>' +
  136. '</div>';
  137. }
  138. }
  139. return ele;
  140. };
  141.  
  142. const observerElements = [
  143. (function () {
  144. let container = document.getElementById('topicrows');
  145. let func = function (e) {
  146. if (e.tagName == 'SCRIPT') return;
  147. let uid = getUID(e);
  148. let link = getLink(e);
  149. if (isTroll(uid) ||
  150. isMatch(link.innerHTML)) {
  151. link.hide();
  152. }
  153. }
  154. return [
  155. container,
  156. func
  157. ]
  158. })(),
  159. (function () {
  160. let container = document.getElementById('m_posts_c');
  161. let func = function (e) {
  162. if (e.tagName == 'SCRIPT') return;
  163. let uid = getUID(e);
  164. let toggle = getToggleButton(e);
  165. if (toggle) {
  166. toggle.onclick = function () {
  167. toggleTroll(uid);
  168. container.refilter();
  169. };
  170. } else {
  171. return;
  172. }
  173. let avatar = getAvatar(e);
  174. let content = getContent(e);
  175. if (isTroll(uid)) {
  176. avatar.hide();
  177. content.hide();
  178. }
  179. else {
  180. avatar.show();
  181. content.show();
  182. }
  183. }
  184. return [
  185. container,
  186. func
  187. ]
  188. })()
  189. ];
  190.  
  191. [].slice.call(observerElements).forEach(function (e) {
  192. if (!e[0]) return;
  193.  
  194. e[0].refilter = function () {
  195. [].slice.call(e[0].children).forEach(function (c) {
  196. e[1](c);
  197. });
  198. }
  199.  
  200. e[0].refilter();
  201.  
  202. let observer = new MutationObserver(function (mutations) {
  203. mutations.forEach(function (mutation) {
  204. if (mutation.addedNodes.length) {
  205. e[1](mutation.addedNodes[0]);
  206. }
  207. });
  208. });
  209.  
  210. observer.observe(e[0], {
  211. childList: true
  212. });
  213. });
  214.  
  215. if (filterMode) {
  216. GM_registerMenuCommand('过滤模式:删除', () => {
  217. localStorage.setItem(modeKey, 0);
  218. location.reload();
  219. });
  220. } else {
  221. GM_registerMenuCommand('过滤模式:标记', () => {
  222. localStorage.setItem(modeKey, 1);
  223. location.reload();
  224. });
  225. }
  226. })();