您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Highlight mentions, make link clickable, use channels & automatically remove spam
当前为
// ==UserScript== // @name Robin Enhancement Script // @namespace https://www.reddit.com/ // @version 1.9.1 // @description Highlight mentions, make link clickable, use channels & automatically remove spam // @author mr_bag // @match https://www.reddit.com/robin* // @grant none // ==/UserScript== (function() { // Grab users username + play nice with RES var robin_user = $("#header-bottom-right .user a").first().text(); var ignored_users = {}; // for spam counter - very important i know :P var blocked_spam_el = null; var blocked_spam = 0; /** * Check if a message is "spam" */ var is_spam = function(line){ return ( // Hide auto vote messages (/^voted to (grow|stay|abandon)/.test(line)) || // random unicode? (/[\u0080-\uFFFF]/.test(line)) || // hide any auto voter messages (/\[.*autovoter.*\]/.test(line)) || // Common bots (/^(\[binbot\]|\[robin-grow\])/.test(line)) || // repeating chars in line (more than 5). e.g. aaaaaaa !!!!!!!! (/(.)\1{5,}/.test(line)) || // Some common messages (/(voting will end in approximately|\[i spam the most used phrase\]|\[message from creator\]|\[.*bot.*\])/.test(line)) || // no spaces = spam if its longer than 25 chars (dont filter links) (line.indexOf(" ") === -1 && line.length > 25 && line.indexOf("http") === -1) || // repeating same word /(\b\S+\b)\s+\b\1\b/i.test(line) ); }; /** * Check if a message is from an ignored user * */ var is_ignored = function($usr, $ele){ // no user name, go looking for when said it if($usr.length === 0){ while($usr.length === 0){ $ele = $ele.prev(); $usr = $ele.find(".robin--username"); } } // are they ignored? return (ignored_users[$usr.text()]); }; /** * Make links clickable * */ var auto_link = function($msg){ var text = $msg.html(); // read as html so stuff stays escaped // normal links text = text.replace(/\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim, '<a target="blank" href="$&">$&</a>'); // reddit subreddit links text = text.replace(/ \/r\/(\w+)/gim, ' <a target="blank" href="https://reddit.com/r/$1">/r/$1</a>'); // update text $msg.html(text); }; /** * Mute a user */ var _mute_user = function(usr){ // Add to ignore list ignored_users[usr] = true; _render_muted_list(); }; /** * un-mute a user */ var _unmute_user = function(usr){ // Add to ignore list delete ignored_users[usr]; _render_muted_list(); }; // Render list of ignored users var _render_muted_list = function(){ var html = "<strong>Ignored users</strong><br>"; for(var u in ignored_users){ html += "<div data-usr='"+ u + "'>" + u + " - [unmute]</div>"; } $("#muted_users").html(html); }; // Scroll chat back to bottom var _scroll_to_bottom = function(){ $("#robinChatWindow").scrollTop($("#robinChatMessageList").height()); }; var update_spam_count = function(){ blocked_spam++; blocked_spam_el.innerHTML = blocked_spam; } /** * Parse a link and apply changes */ var parse_line = function($ele){ var $msg = $ele.find(".robin-message--message"); var $usr = $ele.find(".robin--username"); var line = $msg.text().toLowerCase(); // If user is ignored or message looks like "Spam". hide it if (is_ignored($usr, $ele) || is_spam(line)) { $ele.addClass("spam-hidden"); update_spam_count(); } // Highlight mentions if(line.indexOf(robin_user) !== -1){ $ele.css("font-weight", "bold"); } // Make links clickable if(line.indexOf("http") !== -1){ auto_link($msg); } // Add mute button to users if(!$ele.hasClass("robin--user-class--system") && $usr.text() != robin_user){ $("<span style='font-size:.8em;cursor:pointer'> [mute] </span>").insertBefore($usr).click(function(){ _mute_user($usr.text()); }); } // Add filter support if(line.indexOf("%") === 0){ $ele.addClass("filter-percent in-channel");} if(line.indexOf("$") === 0){ $ele.addClass("filter-dollar in-channel");} if(line.indexOf("#") === 0){ $ele.addClass("filter-hash in-channel"); } if(line.indexOf("~") === 0){ $ele.addClass("filter-tilde in-channel"); } if(line.indexOf("^") === 0){ $ele.addClass("filter-hat in-channel"); } if(line.indexOf("+") === 0){ $ele.addClass("filter-plus in-channel"); } if(line.indexOf("&") === 0){ $ele.addClass("filter-and in-channel"); } if(line.indexOf("*") === 0){ $ele.addClass("filter-star in-channel"); } }; // Detect changes, are parse the new message $("#robinChatWindow").on('DOMNodeInserted', function(e) { if ($(e.target).is('div.robin-message')) { // Apply changes to line parse_line($(e.target)); } }); // When everything is ready $(document).ready(function(){ // Set default spam filter type $("#robinChatWindow").addClass("hide-spam"); // Add checkbox to toggle "hide" behaviors $("#robinDesktopNotifier").append("<label><input type='checkbox' checked='checked'>Hide spam completely (<span id='spamcount'>0</span> removed)</label>").click(function(){ if($(this).find("input").is(':checked')){ $("#robinChatWindow").removeClass("mute-spam").addClass("hide-spam"); }else{ $("#robinChatWindow").removeClass("hide-spam").addClass("mute-spam"); } // correct scroll after spam filter change _scroll_to_bottom(); }); blocked_spam_el = $("#spamcount")[0]; // Add Muted list & hook up unmute logic $('<div id="muted_users" class="robin-chat--sidebar-widget robin-chat--notification-widget"><strong>Ignored users</strong></div>').insertAfter($("#robinDesktopNotifier")); $('#muted_users').click(function(e){ var user = $(e.target).data("usr"); if(user) _unmute_user(user); }); // Hook up toggles for filters $('<div id="filter_mode">Filter: <span data-filter="none" style="font-weight:bold;">Everything</span> | <span data-filter="%">% Only</span> | <span data-filter="$">$ Only</span> | <span data-filter="#"># Only</span> | <span data-filter="~">~ Only</span> | <span data-filter="^">^ Only</span> | <span data-filter="&">& Only</span> | <span data-filter="+">+ Only</span> | <span data-filter="*">* Only</span> | <span data-filter="channels">All channels</span> | <span data-filter="hide">Without channels</span></div>').insertAfter("#robinSendMessage").click(function(e){ var filter = $(e.target).data("filter"); // filter was toggled? if(!filter) return; var robin_window = $("#robinChatWindow"); // Toggle selected "tab" $(e.target).parent().find("span").css("font-weight", "normal"); $(e.target).css("font-weight", "bold"); // remove filters robin_window.removeAttr("data-filter").removeClass("filter_on").removeClass("filter_all_channels").removeClass("filter_only_channels"); if(filter === 'none'){ // Show all }else if(filter === 'hide'){ // Hide any channel conversations robin_window.addClass("filter_all_channels"); }else if(filter === 'channels'){ // Hide any channel conversations robin_window.addClass("filter_only_channels"); }else{ // apply a filter robin_window.addClass("filter_on").attr("data-filter", filter); } // correct scroll after filter change _scroll_to_bottom(); }); // Auto append % when in filtered mode $("#robinSendMessage").submit(function(){ if($("#robinChatWindow").hasClass("filter_on")){ if($(".text-counter-input").val().indexOf("/") !== 0){ // /commands should work as normal $(".text-counter-input").val($("#robinChatWindow").attr("data-filter") + " " + $(".text-counter-input").val()); } } }); }); // filter for channel document.styleSheets[0].insertRule("#robinChatWindow.filter_on div.robin-message { display:none; }", 0); document.styleSheets[0].insertRule("#robinChatWindow.filter_on[data-filter='$'] div.robin-message.filter-dollar,#robinChatWindow.filter_on[data-filter='*'] div.robin-message.filter-star,#robinChatWindow.filter_on[data-filter='&'] div.robin-message.filter-and, #robinChatWindow.filter_on[data-filter='%'] div.robin-message.filter-percent,#robinChatWindow.filter_on[data-filter='#'] div.robin-message.filter-hash,#robinChatWindow.filter_on[data-filter='~'] div.robin-message.filter-tilde,#robinChatWindow.filter_on[data-filter='^'] div.robin-message.filter-hat,#robinChatWindow.filter_on[data-filter='+'] div.robin-message.filter-plus,#robinChatWindow.filter_on div.robin-message.robin--user-class--system { display:block; }", 0); // filter, hide all channels document.styleSheets[0].insertRule("#robinChatWindow.filter_all_channels div.robin-message.in-channel{ display:none; }", 0); // filter show all channels document.styleSheets[0].insertRule("#robinChatWindow.filter_only_channels div.robin-message {display:none; }", 0); document.styleSheets[0].insertRule("#robinChatWindow.filter_only_channels div.robin-message.in-channel { display:block; }", 0); document.styleSheets[0].insertRule("#filter_mode span { cursor: pointer;}", 0); // Add initial styles for "spam" messages document.styleSheets[0].insertRule("#robinChat #robinChatWindow.hide-spam div.robin-message.spam-hidden { display:none; }", 0); document.styleSheets[0].insertRule("#robinChat #robinChatWindow.mute-spam div.robin-message.spam-hidden { opacity:0.3; font-size:1.2em; }", 0); // muted user box document.styleSheets[0].insertRule("#muted_users { font-size:1.2em; }", 0); document.styleSheets[0].insertRule("#muted_users div { padding: 2px 0; }", 0); document.styleSheets[0].insertRule("#muted_users strong { font-weight:bold; }", 0); // FIX RES nightmode (ish) document.styleSheets[0].insertRule(".res-nightmode #robinChatWindow div.robin-message { color: #ccc; }", 0); })();