NGA Filter

troll must die

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

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