Robin Enhancement Script

Highlight mentions, auto link links & automatically remove spam

目前為 2016-04-03 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Robin Enhancement Script
  3. // @namespace https://www.reddit.com/
  4. // @version 1.5
  5. // @description Highlight mentions, auto link links & automatically remove spam
  6. // @author mr_bag
  7. // @match https://www.reddit.com/robin/
  8. // @grant none
  9. // ==/UserScript==
  10. (function() {
  11.  
  12. // Grab users username + play nice with RES
  13. var robin_user = $("#header-bottom-right .user a").first().text();
  14. var ignored_users = {};
  15.  
  16. /**
  17. * Check if a message is "spam"
  18. */
  19. var is_spam = function(line){
  20. return (
  21. // Hide auto vote messages
  22. (/^voted to (grow|stay|abandon)/.test(line)) ||
  23. // random unicode?
  24. (/[\u0080-\uFFFF]/.test(line)) ||
  25. // hide any auto voter messages
  26. (/\[.*autovoter.*\]/.test(line)) ||
  27. // Common bots
  28. (/^(\[binbot\]|\[robin-grow\])/.test(line)) ||
  29. // repeating chars in line (more than 5). e.g. aaaaaaa !!!!!!!!
  30. (/(.)\1{5,}/.test(line)) ||
  31. // Some common messages
  32. (/(voting will end in approximately|\[i spam the most used phrase\]|\[message from creator\])/.test(line)) ||
  33. // no spaces = spam if its longer than 25 chars (dont filter links)
  34. (line.indexOf(" ") === -1 && line.length > 25 && line.indexOf("http") === -1) ||
  35. // repeating same word
  36. /(\b\S+\b)\s+\b\1\b/i.test(line)
  37. );
  38. };
  39.  
  40. /**
  41. * Check if a message is from an ignored user
  42. *
  43. */
  44. var is_ignored = function($usr, $ele){
  45. // no user name, go looking for when said it
  46. if($usr.length === 0){
  47. while($usr.length === 0){
  48. $ele = $ele.prev();
  49. $usr = $ele.find(".robin--username");
  50. }
  51. }
  52. // are they ignored?
  53. return (ignored_users[$usr.text()]);
  54. };
  55.  
  56. /**
  57. * Make links clickable
  58. *
  59. */
  60. var auto_link = function($msg){
  61. var text = $msg.html(); // read as html so stuff stays escaped
  62. // normal links
  63. text = text.replace(/\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim, '<a target="blank" href="$&">$&</a>');
  64. // reddit subreddit links
  65. text = text.replace(/ \/r\/(\w+)/gim, ' <a target="blank" href="https://reddit.com/r/$1">/r/$1</a>');
  66. // update text
  67. $msg.html(text);
  68. };
  69.  
  70. /**
  71. * Mute a user
  72. */
  73. var _mute_user = function(usr){
  74. // Add to ignore list
  75. ignored_users[usr] = true;
  76. _render_muted_list();
  77. };
  78.  
  79. /**
  80. * un-mute a user
  81. */
  82. var _unmute_user = function(usr){
  83. // Add to ignore list
  84. delete ignored_users[usr];
  85. _render_muted_list();
  86. };
  87.  
  88. // Render list of ignored users
  89. var _render_muted_list = function(){
  90. var html = "<strong>Ignored users</strong><br>";
  91. for(var u in ignored_users){
  92. html += "<div data-usr='"+ u + "'>" + u + " - [unmute]</div>";
  93. }
  94. $("#muted_users").html(html);
  95. };
  96.  
  97. // Scroll chat back to bottom
  98. var _scroll_to_bottom = function(){
  99. $("#robinChatWindow").scrollTop($("#robinChatMessageList").height());
  100. }
  101.  
  102. /**
  103. * Parse a link and apply changes
  104. */
  105. var parse_line = function($ele){
  106. var $msg = $ele.find(".robin-message--message");
  107. var $usr = $ele.find(".robin--username");
  108.  
  109. var line = $msg.text().toLowerCase();
  110.  
  111. // If user is ignored or message looks like "Spam". hide it
  112. if (is_ignored($usr, $ele) || is_spam(line)) {
  113. $ele.addClass("spam-hidden");
  114. }
  115.  
  116. // Highlight mentions
  117. if(line.indexOf(robin_user) !== -1){
  118. $ele.css("font-weight", "bold");
  119. }
  120.  
  121. // Make links clickable
  122. if(line.indexOf("http") !== -1){
  123. auto_link($msg);
  124. }
  125.  
  126. // Add mute button to users
  127. if(!$ele.hasClass("robin--user-class--system") && $usr.text() != robin_user){
  128. $("<span style='font-size:.8em;cursor:pointer'> [mute] </span>").insertBefore($usr).click(function(){
  129. _mute_user($usr.text());
  130. });
  131. }
  132.  
  133. // Add filter support
  134. if(line.indexOf("%") === 0){
  135. $ele.addClass("filter-percent");
  136. }
  137.  
  138. };
  139.  
  140. // Detect changes, are parse the new message
  141. $("#robinChatWindow").on('DOMNodeInserted', function(e) {
  142. if ($(e.target).is('div.robin-message')) {
  143. // Apply changes to line
  144. parse_line($(e.target));
  145. }
  146. });
  147.  
  148. // When everything is ready
  149. $(document).ready(function(){
  150. // Set default spam filter type
  151. $("#robinChatWindow").addClass("hide-spam");
  152.  
  153. // Add checkbox to toggle "hide" behaviors
  154. $("#robinDesktopNotifier").append("<label><input type='checkbox' checked='checked'>Hide spam completely</label>").click(function(){
  155. if($(this).find("input").is(':checked')){
  156. $("#robinChatWindow").removeClass("mute-spam").addClass("hide-spam");
  157. }else{
  158. $("#robinChatWindow").removeClass("hide-spam").addClass("mute-spam");
  159. }
  160. // correct scroll after spam filter change
  161. _scroll_to_bottom();
  162. });
  163.  
  164. // Add Muted list & hook up unmute logic
  165. $('<div id="muted_users" class="robin-chat--sidebar-widget robin-chat--notification-widget"><strong>Ignored users</strong></div>').insertAfter($("#robinDesktopNotifier"));
  166. $('#muted_users').click(function(e){
  167. var user = $(e.target).data("usr");
  168. if(user) _unmute_user(user);
  169. });
  170.  
  171. // Hook up toggles for filters
  172. $('<div id="filter_mode">Filter: <span data-filter="">Show all</span> | <span data-filter="%">% Only</span></div>').insertAfter("#robinSendMessage").click(function(e){
  173. var filter = $(e.target).data("filter");
  174. if(filter === ''){
  175. $("#robinChatWindow").removeClass("filter_on");
  176. }else if(filter === '%'){
  177. $("#robinChatWindow").addClass("filter_on");
  178. }
  179. // correct scroll after filter change
  180. _scroll_to_bottom();
  181. });
  182. // Auto append % when in filtered mode
  183. $("#robinSendMessage").submit(function(){
  184. if($("#robinChatWindow").hasClass("filter_on")){
  185. $(".text-counter-input").val("% " + $(".text-counter-input").val());
  186. }
  187. });
  188. });
  189.  
  190. // Add initial styles for "spam" messages
  191. document.styleSheets[0].insertRule("#robinChatWindow.hide-spam div.robin-message.spam-hidden { display:none; }", 0);
  192. document.styleSheets[0].insertRule("#robinChatWindow.mute-spam div.robin-message.spam-hidden { opacity:0.3; font-size:1.2em; }", 0);
  193.  
  194. // filter styles
  195. document.styleSheets[0].insertRule("#robinChatWindow.filter_on div.robin-message { display:none; }", 0);
  196. document.styleSheets[0].insertRule("#robinChatWindow.filter_on div.robin-message.filter-percent, #robinChatWindow.filter_on div.robin-message.robin--user-class--system { display:block; }", 0);
  197. document.styleSheets[0].insertRule("#filter_mode span { cursor: pointer;}", 0);
  198.  
  199. // muted user box
  200. document.styleSheets[0].insertRule("#muted_users { font-size:1.2em; }", 0);
  201. document.styleSheets[0].insertRule("#muted_users div { padding: 2px 0; }", 0);
  202. document.styleSheets[0].insertRule("#muted_users strong { font-weight:bold; }", 0);
  203.  
  204. // FIX RES nightmode (ish)
  205. document.styleSheets[0].insertRule(".res-nightmode #robinChatWindow div.robin-message { color: #ccc; }", 0);
  206. })();