FA Content Filter

Filters user-defined content while browsing Furaffinity.

当前为 2017-03-11 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name FA Content Filter
  3. // @namespace fa-filter
  4. // @description Filters user-defined content while browsing Furaffinity.
  5. // @include *://www.furaffinity.net/*
  6. // @require http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js
  7. // @version 1.5.4
  8. // @grant GM_getValue
  9. // @grant GM_setValue
  10. // @grant GM_deleteValue
  11. // @grant GM_openInTab
  12. // ==/UserScript==
  13.  
  14. // === WARNING ===
  15. // THE TAG FUNCTIONS ARE COMMENTED OUT IN ORDER TO PREVENT ACCIDENTAL DDoS DETECTION ON FURAFFINITY.
  16. this.$ = this.jQuery = jQuery.noConflict(true);
  17.  
  18. // === INITIALIZE USER ARRAY ===
  19. var userArray = JSON.parse(GM_getValue('userList', '{}'));
  20. //var tagArray = JSON.parse(GM_getvalue('tagList', '{}'));
  21.  
  22. // === GENERAL TEMPORARY VARIABLES ===
  23. var filterEnabled = {['subs']:true, ['shouts']:true, ['coms']:true, ['notifications']:true};
  24.  
  25. // === FILTER ===
  26. var parseSettings = function() {
  27. if (!(userArray instanceof Array)) {
  28. $.each(userArray, function(username, data) {
  29. if (data['subs'] === 1) { hideSubmissions(username); }
  30. if (data['shouts'] === 1) { hideShouts(username); }
  31. if (data['coms'] === 1) { hideComments(username); }
  32. if (data['notifications'] === 1) { hideNotifications(username); }
  33. });
  34. }
  35. };
  36.  
  37. //var parseTagSettings = function() {
  38. // $('.t-image a[href^="/view"]').each(function() {
  39. // var url = $(this).attr('href');
  40. // console.log(url);
  41. // $.post(url, function(data) {
  42. // console.log($('#keywords', data).text());
  43. // });
  44. // });
  45. //}
  46.  
  47.  
  48. // === SAVE ===
  49. function writeSettings() {
  50. GM_setValue('userList', JSON.stringify(userArray));
  51. }
  52.  
  53. // === FUNCTIONS ===
  54. // Hide user submissions
  55. function hideSubmissions(username) {
  56. if ($('figure').length) {
  57. // Beta
  58. var submissionBeta = $('figure.u-' + escapeUsername(username));
  59. var submissionInboxBeta = $('a[href="/user/' + username + '"]').closest('figure');
  60.  
  61. stylizeHidden(submissionBeta);
  62. stylizeHidden(submissionInboxBeta);
  63.  
  64. submissionBeta.addClass('hidden-sub').hide();
  65. submissionInboxBeta.find('input').prop('checked', true);
  66. submissionInboxBeta.addClass('hidden-sub').hide();
  67.  
  68. if (!filterEnabled['subs']) {
  69. submissionBeta.show();
  70. submissionInboxBeta.show();
  71. }
  72. } else {
  73. // Classic
  74. // Browse/Submissions
  75. var submission1 = $('b[id^="sid_"] a[href="/user/' + username + '/"]').closest('b');
  76. stylizeHidden(submission1);
  77. // Mark Submissions as Checked
  78. submission1.children('small').children('input').prop('checked', true);
  79. submission1.addClass('hidden-sub').hide();
  80.  
  81. // Favorites/Front Page
  82. var submission2 = $('b[id^="sid_"] img[src$="#' + username + '"]').closest('b');
  83. stylizeHidden(submission2);
  84. submission2.addClass('hidden-sub').hide();
  85.  
  86. // Correspond to UI
  87. if (!filterEnabled['subs']) {
  88. submission1.show();
  89. submission2.show();
  90. }
  91. }
  92. }
  93.  
  94. function showSubmissions(username) {
  95. // Browse/Submissions
  96. var submission1 = $('b[id^="sid_"] a[href="/user/' + username + '/"]').closest('b');
  97. var submissionBeta = $('figure.u-' + escapeUsername(username));
  98. var submissionInboxBeta = $('a[href^="/user/' + username + '"]').closest('figure');
  99. undoStylize(submission1);
  100. undoStylize(submissionBeta);
  101. undoStylize(submissionInboxBeta);
  102. // Mark Submissions as Checked
  103. submission1.children('small').children('input').prop('checked', false);
  104. submission1.removeClass('hidden-sub').show();
  105. submissionBeta.removeClass('hidden-sub').show();
  106. submissionInboxBeta.removeClass('hidden-sub').show();
  107. submissionInboxBeta.find('input').prop('checked', false);
  108.  
  109. // Favorites/Front Page
  110. var submission2 = $('b[id^="sid_"] img[src$="#' + username + '"]').closest('b');
  111. undoStylize(submission2);
  112. submission2.removeClass('hidden-sub').show();
  113. }
  114.  
  115. // Hide user shouts
  116. function hideShouts(username) {
  117. // Classic
  118. var shout = $('table[id^="shout-"] td.alt1 img[alt="' + username + '"]').closest('table[id^="shout-"]');
  119. shout.addClass('hidden-shout').hide();
  120. stylizeHidden(shout.find('table'));
  121. shout.next('br').addClass('hidden-shout-br').hide();
  122.  
  123. // Beta
  124. var shoutBeta = $('.comment_container .shout-avatar img[alt="' + username +'"]').closest('.comment_container');
  125. shoutBeta.addClass('hidden-shout').hide();
  126. stylizeHidden(shoutBeta.find('.header'));
  127. stylizeHidden(shoutBeta.find('.body'));
  128.  
  129. // We want to only highlight and check
  130. var shoutManageBeta = $('table[id^="shout-"] .comments-flex-item-icon img[alt="' + username +'"]').closest('table[id^="shout-"]');
  131. shoutManageBeta.addClass('hidden-shout');
  132. stylizeHidden(shoutManageBeta.find('.comments-userline-flex'));
  133. stylizeHidden(shoutManageBeta.find('.comment_text'));
  134. shoutManageBeta.find('input[type="checkbox"]').prop('checked', true);
  135. }
  136.  
  137. // Hide user comments and threads
  138. function hideComments(username) {
  139. // Classic
  140. var comments = $('.container-comment td.icon img[alt="' + username + '"]').closest('.container-comment');
  141.  
  142. $(comments).each(function() {
  143. // Hide comment and get width
  144. if (!($(this).hasClass('hidden-comment'))) {
  145. var width = Number($(this).addClass('hidden-comment').hide().attr('width').slice(0,-1));
  146. var current = $(this).next('.container-comment');
  147.  
  148. // Iterate through comments until there's a width that is greater than or equal
  149. while (true) {
  150. if (current.length) {
  151. if (Number(current.attr('width').slice(0,-1)) < width) {
  152. current.addClass('hidden-comment').hide();
  153. current = current.next('.container-comment');
  154. } else {
  155. break;
  156. }
  157. } else {
  158. break;
  159. }
  160. }
  161. }
  162. });
  163.  
  164. // Beta
  165. var commentsBeta = $('.comment_container .avatar img[alt="' + username + '"]').closest('.comment_container');
  166. stylizeHidden(commentsBeta.find('.header'));
  167. stylizeHidden(commentsBeta.find('.body'));
  168.  
  169. $(commentsBeta).each(function() {
  170. // Get width, then hide comment
  171. if (!($(this).hasClass('hidden-comment'))) {
  172. var width = $(this).width();
  173. var current = $(this).next('.comment_container');
  174.  
  175. $(this).addClass('hidden-comment').hide();
  176.  
  177. // Iterate through the comments until there's a width that is greater than or equal
  178. while (true) {
  179. if (current.length) {
  180. if (current.width() < width) {
  181. current.addClass('hidden-comment').hide();
  182. current = current.next('.comment_container');
  183. } else {
  184. break;
  185. }
  186. } else {
  187. break;
  188. }
  189. }
  190. }
  191. });
  192. }
  193.  
  194. // Hide user notifications
  195. function hideNotifications(username) {
  196. var notification = $('.message-stream a[href="/user/' + username + '/"]').closest('li');
  197. notification.addClass('hidden-notification').hide();
  198. stylizeHidden(notification);
  199. notification.children('input').prop('checked', true);
  200.  
  201. // Classic only
  202. notification.children('table').children('tbody').children('tr').children('td').children('.checkbox').children('input').prop('checked', true);
  203. }
  204.  
  205. function stylizeHidden(item) {
  206. $(item).css('background-color', '#FFBBBB');
  207. $(item).css('color', '#FF0000');
  208. $('a:link', item).css('color', '#FF0000');
  209. $('a:visited', item).css('color', '#FF0000');
  210. }
  211.  
  212. function undoStylize(item) {
  213. $(item).css('background-color', '');
  214. $(item).css('color', '');
  215. $('a:link', item).css('color', '');
  216. $('a:visited', item).css('color', '');
  217. }
  218.  
  219. // === UI ===
  220. // == Filter Toggle ==
  221. // Submissions
  222. function filtersSubs() {
  223. // Remove all pre-existing UI for soft-refresh
  224. $('[id="faf-toggle-subs"]').remove();
  225. $('.faf-remove-user-external').parent().remove();
  226. $('.faf-add-user-external').parent().remove();
  227.  
  228. if ($('.hidden-sub').length > 0) {
  229. // Classic
  230. if (!$('li.lileft').length) {
  231. $display = '<input style="float:right;" id="faf-toggle-subs" class="button" type="button" value="Toggle Filtered Submissions (' + $('.hidden-sub').length + ')"></input>';
  232. $('form').first().append($display);
  233. // Beta
  234. } else {
  235. $display = '<li class="lileft"><a class="top-heading" id="faf-toggle-subs" href="#!"><div class="sprite-nuke menu-space-saver hideonmobile"></div>Toggle Filtered Submissions (' + $('.hidden-sub').length + ')</a></li>';
  236. $('.lileft').last().after($display);
  237. }
  238. } else {
  239. filterEnabled['subs'] = true;
  240. }
  241.  
  242. if ($('figure').length) {
  243. // Beta
  244. $('figure').each(function() {
  245. var username = $(this).attr('class').match('u-([^\\s]+)')[1];
  246. if (username) {
  247. if (username in userArray && userArray[username]['subs'] === 1) {
  248. $(this).find('figcaption').append('<p><a style="color: #FF5555!important;" class="faf-remove-user-external" id="faf-' + username + '" href="#!" title="Remove ' + username + ' from filter">[Unfilter]</a></p>');
  249. } else {
  250. $(this).find('figcaption').append('<p><a style="color: #FF5555!important;" class="faf-add-user-external" id="faf-' + username + '" href="#!" title="Add ' + username + ' to filter">[Filter]</a></p>');
  251. }
  252. }
  253. });
  254. } else {
  255. $('b[id^="sid_"]').each(function() {
  256. var username = $(this).find('small a').attr('href');
  257. username = username.match('/user/(.*)/');
  258. if (username) {
  259. if (username[1] in userArray && userArray[username[1]]['subs'] === 1) {
  260. $(this).find('small').append('<span>&nbsp;<a style="color: #FF5555!important;" class="faf-remove-user-external" id="faf-' + username[1] + '" href="#!" title="Remove ' + username[1] + ' from filter">[Unfilter]</a></span>');
  261. } else {
  262. $(this).find('small').append('<span>&nbsp;<a style="color: #FF5555!important;" class="faf-add-user-external" id="faf-' + username[1] + '" href="#!" title="Add ' + username[1] + ' to filter">[Filter]</a></span>');
  263. }
  264. }
  265. });
  266. }
  267. }
  268.  
  269. // Followed Submissions
  270. function filtersSubsFollow() {
  271. if ($('.hidden-sub').length > 0) {
  272. // Beta
  273. if ($('.button-nav-item').length) {
  274. $display = '<div class="button-nav-item"><button class="button mobile-button" id="faf-toggle-subs" type="button">Toggle Filtered Submissions (' + $('.hidden-sub').length + ')</button></div>';
  275. $('.actions').css('max-width', '700px');
  276. } else {
  277. $display = '<input id="faf-toggle-subs" class="button" type="button" value="Toggle Filtered Submissions (' + $('.hidden-sub').length + ')"></input>';
  278. }
  279. $('.actions').append($display);
  280. }
  281. }
  282.  
  283. // Shouts
  284. function filtersShouts() {
  285. if ($('.hidden-shout').length > 0) {
  286. $display = '<center><input id="faf-toggle-shouts" class="button" type="button" value="Toggle Filtered Shouts (' + $('.hidden-shout').length + ')"></input></center>';
  287. // Classic
  288. $('table[id^="shout-"]').first().prevAll('table.maintable:first').append($display);
  289. // Beta
  290. $($display).insertAfter('#shoutboxentry');
  291. }
  292. }
  293.  
  294. // Shouts (Controls, Beta Only)
  295. function filtersShoutsControl() {
  296. if ($('.hidden-shout').length > 0) {
  297. $display = '<button id="faf-toggle-shouts" class="button mobile-button" type="button" value="Toggle Filtered Shouts (' + $('.hidden-shout').length + ')">Toggle Filtered Shouts (' + $('.hidden-shout').length + ')</button>';
  298. $('.section-divider').last().append($display);
  299. $('.hidden-shout input').prop('checked', true);
  300. }
  301. }
  302.  
  303. // Comments
  304. function filtersComments() {
  305. if ($('.hidden-comment').length > 0) {
  306. $display = '<input style="float:right;" id="faf-toggle-comments" class="button" type="button" value="Toggle Filtered Comments (' + $('.hidden-comment').length + ')"></input>';
  307. if (!$('.flex-submission-container').length) {
  308. // Classic
  309. $('table.container-comment').first().parent().parent().prev().children().append($display);
  310. } else {
  311. // Beta
  312. $($display).insertAfter('.flex-submission-container');
  313. }
  314. }
  315. }
  316.  
  317. // Notifications
  318. function filtersNotifications() {
  319. if ($('.hidden-notification').length > 0) {
  320. $display = '<input id="faf-toggle-notifications" class="button" type="button" value="Toggle Filtered Notifications (' + $('.hidden-notification').length + ')"></input>';
  321. $('.global-controls').append($display);
  322. $('.global_controls').append($display);
  323.  
  324. // = Notification Count =
  325. // Classic
  326. if ($('fieldset[id^="messages-watches"] .hidden-notification').length > 0)
  327. $('fieldset[id^="messages-watches"] h3').append(' (' + $('fieldset[id^="messages-watches"] .hidden-notification').length + ' filtered)');
  328. if ($('fieldset[id^="messages-comments-submission"] .hidden-notification').length > 0)
  329. $('fieldset[id^="messages-comments-submission"] h3').append(' (' + $('fieldset[id^="messages-comments-submission"] .hidden-notification').length + ' filtered)');
  330. if ($('fieldset[id^="messages-shouts"] .hidden-notification').length > 0)
  331. $('fieldset[id^="messages-shouts"] h3').append(' (' + $('fieldset[id^="messages-shouts"] .hidden-notification').length + ' filtered)');
  332. if ($('fieldset[id^="messages-favorites"] .hidden-notification').length > 0)
  333. $('fieldset[id^="messages-favorites"] h3').append(' (' + $('fieldset[id^="messages-favorites"] .hidden-notification').length + ' filtered)');
  334.  
  335. // Beta
  336. if ($('div[id^="messages-watches"] .hidden-notification').length > 0)
  337. $('div[id^="messages-watches"] h2').append(' (' + $('div[id^="messages-watches"] .hidden-notification').length + ' filtered)');
  338. if ($('div[id^="messages-comments-submission"] .hidden-notification').length > 0)
  339. $('div[id^="messages-comments-submission"] h2').append(' (' + $('div[id^="messages-comments-submission"] .hidden-notification').length + ' filtered)');
  340. if ($('div[id^="messages-shouts"] .hidden-notification').length > 0)
  341. $('div[id^="messages-shouts"] h2').append(' (' + $('div[id^="messages-shouts"] .hidden-notification').length + ' filtered)');
  342. if ($('div[id^="messages-favorites"] .hidden-notification').length > 0)
  343. $('div[id^="messages-favorites"] h2').append(' (' + $('div[id^="messages-favorites"] .hidden-notification').length + ' filtered)');
  344. if ($('div[id^="messages-journals"] .hidden-notification').length > 0)
  345. $('div[id^="messages-journals"] h2').append(' (' + $('div[id^="messages-journals"] .hidden-notification').length + ' filtered)');
  346. }
  347. }
  348.  
  349. // == Buttons ==
  350. // Show/Hide Submissions
  351. $(document.body).on('click', '#faf-toggle-subs', function() {
  352. $('.hidden-sub').toggle();
  353. filterEnabled['subs'] = !filterEnabled['subs'];
  354. });
  355.  
  356. // Show/Hide Shouts
  357. $(document.body).on('click', '#faf-toggle-shouts', function() {
  358. $('.hidden-shout').toggle();
  359. $('.hidden-shout-br').toggle();
  360. filterEnabled['shouts'] = !filterEnabled['shouts'];
  361. });
  362.  
  363. // Show/Hide Comments
  364. $(document.body).on('click', '#faf-toggle-comments', function() {
  365. $('.hidden-comment').toggle();
  366. filterEnabled['coms'] = !filterEnabled['coms'];
  367. });
  368.  
  369. // Show/Hide Notifications
  370. $(document.body).on('click', '#faf-toggle-notifications', function() {
  371. $('.hidden-notification').toggle();
  372. filterEnabled['notifications'] = !filterEnabled['notifications'];
  373. });
  374.  
  375. // == External Filters ==
  376. // Add submission filter outside of settings
  377. $(document.body).on('click', '.faf-add-user-external', function() {
  378. var addUser = $(this).attr('id').match('faf-(.*)')[1];
  379.  
  380. // Add to array
  381. if (!(addUser in userArray)) {
  382. userArray[addUser] = {'subs':1, 'shouts':0, 'coms':0, 'notifications':0};
  383. } else {
  384. userArray[addUser]['subs'] = 1;
  385. }
  386.  
  387. // Hide, replace link, and save
  388. hideSubmissions(addUser);
  389. filtersSubs();
  390. writeSettings();
  391. });
  392.  
  393. // Remove submission filter outside of settings
  394. $(document.body).on('click', '.faf-remove-user-external', function() {
  395. var removeUser = $(this).attr('id').match('faf-(.*)')[1];
  396.  
  397. // Remove from array
  398. if (removeUser in userArray) {
  399. userArray[removeUser]['subs'] = 0;
  400. }
  401.  
  402. // Show, replace link, and save
  403. showSubmissions(removeUser);
  404. filtersSubs();
  405. writeSettings();
  406. });
  407.  
  408. // == User Settings ==
  409. function displaySettings() {
  410. // Navbar link
  411. $('<li class="noblock"><a target="_blank" href="/controls/site-settings#fa-filter">FA Filter</a></li>').insertAfter($('li.sfw-toggle'));
  412.  
  413. if (window.location.pathname.lastIndexOf('/controls/site-settings', 0) === 0) {
  414. // Brute forced, but there are no tables in the beta layout site-settings page. This is one of the major differences.
  415. if (!$('table').length) {
  416. // Beta HTML Code
  417. var settingsDisplay = '<section>' +
  418. '<div class="section-body">' +
  419. '<h2 id="fa-filter">FA Filter</h2>' +
  420. '<h4>Add a User</h4>' +
  421. '<div class="control-panel-option">' +
  422. '<div class="control-panel-item-1">' +
  423. '<p>Tired of seeing somebody\'s contributions on the site? Add them to your filter list!<br/><strong>Note:</strong> Enter in the username of the person you want to filter, which is the username that would appear after "furaffinity.net/user/".' +
  424. '</div>' +
  425. '<div class="control-panel-item-2">' +
  426. '<input class="textbox" type="text" id="faf-add-username" maxlength="50"></input>&nbsp;<input id="faf-add" class="button" type="button" value="Add" />' +
  427. '</div>' +
  428. '</div>' +
  429. '<h4>Validate Filters</h4>' +
  430. '<div class="control-panel-option">' +
  431. '<div class="control-panel-item-1">' +
  432. '<p>This double-checks to make sure that your filtered usernames are correct and, optionally, removes users that don\'t have any enabled filters.<br/><strong>Note:</strong> This automatically saves the list.</p>' +
  433. '</div>' +
  434. '<div class="control-panel-item-2">' +
  435. '<select name="faf-validate-options" id="select-faf-validate-options" class="styled">' +
  436. '<option value="v" selected="selected">Vaildate Filters Only</option>' +
  437. '<option value="vr">Validate and Remove Unused Filters</option>' +
  438. '</select><input id="faf-validate" class="button" type="button" value="Apply" /><br/>' +
  439. '<span class="faf-validate-status" style="font-weight: bold; color: #009900; display: none;">Validated! 0 user(s) have been modified or removed.</span>' +
  440. '</div>' +
  441. '</div>' +
  442. '<div class="maintable rounded">' +
  443. '<table class="sessions-list faf-list faf-list-beta" width="100%" cellspacing="0" cellpadding="0" border="0" style="padding:0 15px 10px 15px">' +
  444. '<tbody>' +
  445. '<tr>' +
  446. '<td class="p10t p5r p5b"><h3>Username</h3></td>' +
  447. '<td class="p10t p5r p5b" width="200px"><h3>Submissions</h3></td>' +
  448. '<td class="p10t p5r p5b" width="200px"><h3>Shouts</h3></td>' +
  449. '<td class="p10t p5r p5b" width="200px"><h3>Comments</h3></td>' +
  450. '<td class="p10t p5r p5b" width="200px"><h3>Notifications</h3></td>' +
  451. '</tr>' +
  452. '</tbody>' +
  453. '</table>' +
  454. '</div>' +
  455. '</div>' +
  456. '<div class="section-footer alignright">' +
  457. '<span class="faf-update-status" style="font-weight: bold; color: #006600; display: none;">Update successful!</span>&nbsp;&nbsp;<input class="button mobile-button" id="faf-update" type="button" value="Apply Filters (FA Filter)">' +
  458. '</div>' +
  459. '</section>';
  460. $(settingsDisplay).insertBefore($('section').last());
  461. } else {
  462. // Classic HTML Code
  463. var settingsDisplay = '<table id="fa-filter" cellpadding="0" cellspacing="1" border="0" class="section maintable"><tbody>' +
  464. '<tr><td height="22" class="cat links">&nbsp;<strong>FA Filter</strong></td></tr>' +
  465. '<tr><td class="alt1 addpad ucp-site-settings" align="center">' +
  466. '<table cellspacing="1" cellpadding="0" border="0"><tbody>' +
  467. '<tr>' +
  468. '<th><strong>Add a User</strong></th>' +
  469. '<td><input type="text" id="faf-add-username" maxlength="50"></input>&nbsp;<input id="faf-add" class="button" type="button" value="Add User"></td>' +
  470. '<td class="option-description">' +
  471. '<h3>Hide a user\'s contributions to the site.</h3>' +
  472. '<p>Tired of seeing somebody\'s contributions on the site? Add them to your filter list!<br>Note: Enter in the username of the person you want to filter, which is the username that would appear after "furaffinity.net/user/".</p>' +
  473. '</td>' +
  474. '</tr>' +
  475. '<tr>' +
  476. '<th><strong>Validate Filters</strong></th>' +
  477. '<td>' +
  478. '<select name="faf-validate-options" id="select-faf-validate-options" class="styled">' +
  479. '<option value="v" selected="selected">Vaildate Filters Only</option>' +
  480. '<option value="vr">Validate and Remove Unused Filters</option>' +
  481. '</select>&nbsp;<input id="faf-validate" class="button" type="button" value="Apply" /><br/>' +
  482. '<span class="faf-validate-status" style="font-weight: bold; color: #009900; display: none;">Validated! 0 user(s) have been modified or removed.</span>' +
  483. '</td>' +
  484. '<td class="option-description">' +
  485. '<h3>Clean up everything and revalidate filtered usernames.</h3>' +
  486. '<p>This double-checks to make sure that your filtered usernames are correct and, optionally, removes users that don\'t have any enabled filters.<br/><strong>Note:</strong> This automatically saves the list.</p>' +
  487. '</td>' +
  488. '</tr>' +
  489. '<tr>' +
  490. '<th class="noborder" style="vertical-align: text-top;"><strong style="position: relative; top: 25px;">Modify Filters</strong></th>' +
  491. '<td class="noborder">' +
  492. '<table cellspacing="0" cellpadding="0" border="0" class="faf-list faf-list-classic">' +
  493. '<tr><th><strong>Username</strong></th><th><strong>Submissions</strong></th><th><strong>Shouts</strong></th><th><strong>Comments</strong></th><th><strong>Notifications</strong></th></tr>' +
  494. '</table>' +
  495. '<br><br><input class="button" id="faf-update" type="button" value="Apply Filters (FA Filter)"> <span class="faf-update-status" style="font-weight: bold; color: #006600; display: none;">Update successful!</span>' +
  496. '</td>' +
  497. '<td class="option-description noborder">' +
  498. '<h3>Choose what items you don\'t want to see.</h3>' +
  499. '<p>If you still want to see some of the things that a user contributes, you can control that here.</p>' +
  500. '</td>' +
  501. '</tr>' +
  502. '</tbody></table>' +
  503. '</td></tr>' +
  504. '</tbody></table>';
  505. $('form').append(settingsDisplay);
  506. }
  507.  
  508. // Populate list
  509. $.each(userArray, function(username, data) {
  510. addFilterUser(username, data);
  511. });
  512. }
  513. }
  514.  
  515. // Display user in the filter table
  516. function addFilterUser(username, data) {
  517. // Classic
  518. if ($('table.faf-list-classic').length) {
  519.  
  520. var row = '<tr class="checked" id="filter-' + username + '"><td class="noborder"><a class="fa-filter-remove fonthighlight" id="faf-rm-' + username + '" href="#!">[x]</a> ' + username + '</td>';
  521. if (data['subs'] === 1) { row += '<td class="noborder"><input id="faf-check-subs-' + username + '" type="checkbox" checked="checked"></td>'; } else { row += '<td class="noborder"><input id="faf-check-subs-' + username + '" type="checkbox"></td>'; }
  522. if (data['shouts'] === 1) { row += '<td class="noborder"><input id="faf-check-shouts-' + username + '" type="checkbox" checked="checked"></td>'; } else { row += '<td class="noborder"><input id="faf-check-shouts-' + username + '" type="checkbox"></td>'; }
  523. if (data['coms'] === 1) { row += '<td class="noborder"><input id="faf-check-coms-' + username + '" type="checkbox" checked="checked"></td>'; } else { row += '<td class="noborder"><input id="faf-check-coms-' + username + '" type="checkbox"></td>'; }
  524. if (data['notifications'] === 1) { row += '<td class="noborder"><input id="faf-check-notifications-' + username + '" type="checkbox" checked="checked"></td>'; } else { row += '<td class="noborder"><input id="faf-check-notifications-' + username + '" type="checkbox"></td>'; }
  525.  
  526. row += '</tr>';
  527.  
  528. $('table.faf-list tr:last').after(row);
  529. // Beta
  530. } else {
  531. var rowBeta = '<tr id="filter-' + username + '"><td class="p5r" valign="middle" width="auto"><a class="fa-filter-remove" id="faf-rm-' + username + '" href="#!">[x]</a> ' + username + '</td>';
  532. if (data['subs'] === 1) { rowBeta += '<td class="p5r" valign="middle" width="auto"><input id="faf-check-subs-' + username + '" type="checkbox" checked="checked"></td>'; } else { rowBeta += '<td class="p5r" valign="middle" width="auto"><input id="faf-check-subs-' + username + '" type="checkbox"></td>'; }
  533. if (data['shouts'] === 1) { rowBeta += '<td class="p5r" valign="middle" width="auto"><input id="faf-check-shouts-' + username + '" type="checkbox" checked="checked"></td>'; } else { rowBeta += '<td class="p5r" valign="middle" width="auto"><input id="faf-check-shouts-' + username + '" type="checkbox"></td>'; }
  534. if (data['coms'] === 1) { rowBeta += '<td class="p5r" valign="middle" width="auto"><input id="faf-check-coms-' + username + '" type="checkbox" checked="checked"></td>'; } else { rowBeta += '<td class="p5r" valign="middle" width="auto"><input id="faf-check-coms-' + username + '" type="checkbox"></td>'; }
  535. if (data['notifications'] === 1) { rowBeta += '<td class="p5r" valign="middle" width="auto"><input id="faf-check-notifications-' + username + '" type="checkbox" checked="checked"></td>'; } else { rowBeta += '<td class="p5r" valign="middle" width="auto"><input id="faf-check-notifications-' + username + '" type="checkbox"></td>'; }
  536.  
  537. rowBeta += '</tr>';
  538.  
  539. $('table.faf-list tr:last').after(rowBeta);
  540. }
  541. }
  542.  
  543. // Add
  544. $(document.body).on('click', '#faf-add', function() {
  545. var username = $.trim($('#faf-add-username').val());
  546. $('#faf-add-username').val('');
  547. if (username !== '') {
  548. username = username.toLowerCase();
  549. username = username.replace(/[_]/g, '');
  550. if (!(username in userArray)) {
  551. userArray[username] = {'subs':1, 'shouts':1, 'coms':1, 'notifications':1};
  552. addFilterUser(username, userArray[username]);
  553. }
  554. }
  555. });
  556.  
  557. // Remove
  558. $(document.body).on('click', 'a.fa-filter-remove', function(event) {
  559. var username = event.target.id.substr(7);
  560. delete userArray[username];
  561.  
  562. userEsc = escapeUsername(username);
  563.  
  564. $('table.faf-list tr#filter-' + userEsc).remove();
  565. });
  566.  
  567. // Update
  568. $(document.body).on('click', '#faf-update', function() {
  569. $('.faf-list tr[id^="filter-"]').each(function() {
  570. var username = this.id.substr(7);
  571. var vals = {'subs':0, 'shouts':0, 'coms':0, 'notifications':0};
  572.  
  573. userEsc = escapeUsername(username);
  574.  
  575. // Check checkboxes
  576. if ($('#faf-check-subs-' + userEsc).is(':checked')) { vals['subs'] = 1; }
  577. if ($('#faf-check-shouts-' + userEsc).is(':checked')) { vals['shouts'] = 1; }
  578. if ($('#faf-check-coms-' + userEsc).is(':checked')) { vals['coms'] = 1; }
  579. if ($('#faf-check-notifications-' + userEsc).is(':checked')) { vals['notifications'] = 1; }
  580.  
  581. userArray[username] = vals;
  582. });
  583.  
  584. // Save
  585. writeSettings();
  586.  
  587. // Display message
  588. $('.faf-update-status').fadeIn('slow');
  589. setTimeout(function() {
  590. $('.faf-update-status').fadeOut('slow');
  591. }, 5000);
  592. });
  593.  
  594. // Validate
  595. $(document.body).on('click', '#faf-validate', function() {
  596. var modCount = 0;
  597. // Validate
  598. $.each(userArray, function(username, data) {
  599. var tempUsername = username;
  600. tempUsername = tempUsername.trim();
  601. if (tempUsername !== '') {
  602. tempUsername = tempUsername.toLowerCase();
  603. tempUsername = tempUsername.replace(/[_ ]/g, '');
  604. if (tempUsername !== username) {
  605. userArray[tempUsername] = data;
  606. delete userArray[username];
  607. $('tr[id="filter-' + username + '"]').remove();
  608. modCount++;
  609. }
  610. }
  611. });
  612.  
  613. // Remove empty
  614. if ($('#select-faf-validate-options').val() === 'vr') {
  615. $.each(userArray, function(username, data) {
  616. var isEmpty = true;
  617. $.each(data, function(entity, value) {
  618. if (value === 1) {
  619. isEmpty = false;
  620. }
  621. });
  622. if (isEmpty) {
  623. delete userArray[username];
  624. $('tr[id="filter-' + username + '"]').remove();
  625. modCount++;
  626. }
  627. });
  628. }
  629.  
  630. // Save
  631. writeSettings();
  632.  
  633. // Display message
  634. $('.faf-validate-status').text('Validated! ' + modCount + ' user(s) have been modified or removed.');
  635. $('.faf-validate-status').fadeIn('slow');
  636. setTimeout(function() {
  637. $('.faf-validate-status').fadeOut('slow');
  638. }, 5000);
  639. });
  640.  
  641. // === UTILITIES ===
  642. function escapeUsername(username) {
  643. // Replace periods/colons/tildes with escaped versions. Who the fuck allows periods AND tildes in usernames, seriously?
  644. userEsc = username.replace(/\./g, '\\.');
  645. userEsc = userEsc.replace(/:/g, '\\:');
  646. userEsc = userEsc.replace(/~/g, '\\~');
  647. return userEsc;
  648. }
  649.  
  650. function updateCSS() {
  651. var newCSS = '<style type="text/css">' +
  652. 'section.gallery figure { padding-bottom: 62px; }' +
  653. '</style>';
  654. $('head').append(newCSS);
  655. }
  656.  
  657. displaySettings();
  658. updateCSS();
  659.  
  660. setTimeout(parseSettings, 50);
  661. //setTimeout(parseTagSettings, 100);
  662.  
  663. // Submissions
  664. if (window.location.pathname.lastIndexOf('/browse', 0) === 0) setTimeout(filtersSubs, 100);
  665. else if (window.location.pathname.lastIndexOf('/favorites', 0) === 0) setTimeout(filtersSubs, 100);
  666. else if (window.location.pathname.lastIndexOf('/msg/submissions', 0) === 0) setTimeout(filtersSubsFollow, 100);
  667. // Shouts
  668. else if (window.location.pathname.lastIndexOf('/user', 0) === 0) setTimeout(filtersShouts, 100);
  669. else if (window.location.pathname.lastIndexOf('/controls/shouts', 0) === 0) setTimeout(filtersShoutsControl, 100);
  670. // Comments
  671. else if (window.location.pathname.lastIndexOf('/view', 0) === 0) setTimeout(filtersComments, 100);
  672. // Notifications
  673. else if (window.location.pathname.lastIndexOf('/msg/others', 0) === 0) setTimeout(filtersNotifications, 100);
  674. else setTimeout(filtersSubs, 100);