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);
})();