Reddit Robin Filter

Filters comments. Works on usernames and messages.

От 05.04.2016. Виж последната версия.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name         Reddit Robin Filter
// @namespace    http://kmcgurty.com
// @version      2.3
// @description  Filters comments. Works on usernames and messages.
// @author       Kmc - [email protected]
// @match        https://www.reddit.com/robin
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_deleteValue
// @grant        GM_addStyle
// ==/UserScript==

//GM_deleteValue("filter_list");

//will click the grow button and type /count every 15 seconds (to prevent abandoning)
setInterval(function() {
    if($(".text-counter-input")[0].value == ""){
        $(".robin-chat--vote-increase").click();
        $(".text-counter-input")[0].value = "/count";
        $("input[type=submit]").click();
    }
}, 15000);

//setup the default filter
var defaultFilter = ["voted to grow", "voted to stay", "voted to abandon"];
if (GM_getValue("filter_list") === undefined || typeof GM_getValue("filter_list") !== "object") GM_setValue("filter_list", defaultFilter);

//filtery things
function doFilter(div) {
    var filter = GM_getValue("filter_list");

    for (var i = 0; i < filter.length; i++) {
        var messageDiv = $(div).find(".robin-message--message");
        var usernameDiv = messageDiv.parent().find(".robin--username");

        //messageDiv[0] is occasionally undefined?
        if (messageDiv[0] != undefined) {
            var message = messageDiv[0].innerHTML.toLowerCase();
            
            var currentFilter = filter[i].toLowerCase();
            var matches = message.includes(currentFilter);

            var isAscii = $("#remove-ascii")[0].checked && isAsciiArt(message);

            var silentDelete = $("#silent-delete")[0].checked;

            if (matches || isAscii) {
                deleteMessage(messageDiv, silentDelete);
            }
        }

        if(usernameDiv[0] != undefined){
            var username = usernameDiv[0].innerHTML.toLowerCase();
            var matches = username.includes(currentFilter);

            var silentDelete = $("#silent-delete")[0].checked;

            if (matches) {
                deleteMessage(messageDiv, silentDelete);
            }
        }
    }
}

function parseURLs(messageDiv){
    var messageDiv = $(messageDiv).find(".robin-message--message")[0];

    var text = messageDiv.innerHTML;
    var parsedText = text.replace(/(\r\n|\r|\n)/g, '<br/>').replace(/((?:(http|https|Http|Https|rtsp|Rtsp):\/\/(?:(?:[a-zA-Z0-9\$\-\_\.\+\!\*\'\(\)\,\;\?\&\=]|(?:\%[a-fA-F0-9]{2})){1,64}(?:\:(?:[a-zA-Z0-9\$\-\_\.\+\!\*\'\(\)\,\;\?\&\=]|(?:\%[a-fA-F0-9]{2})){1,25})?\@)?)?((?:(?:[a-zA-Z0-9][a-zA-Z0-9\-]{0,64}\.)+(?:(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])|(?:biz|b[abdefghijmnorstvwyz])|(?:cat|com|coop|c[acdfghiklmnoruvxyz])|d[ejkmoz]|(?:edu|e[cegrstu])|f[ijkmor]|(?:gov|g[abdefghilmnpqrstuwy])|h[kmnrtu]|(?:info|int|i[delmnoqrst])|(?:jobs|j[emop])|k[eghimnrwyz]|l[abcikrstuvy]|(?:mil|mobi|museum|m[acdghklmnopqrstuvwxyz])|(?:name|net|n[acefgilopruz])|(?:org|om)|(?:pro|p[aefghklmnrstwy])|qa|r[eouw]|s[abcdeghijklmnortuvyz]|(?:tel|travel|t[cdfghjklmnoprtvwz])|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw]))|(?:(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[0-9])))(?:\:\d{1,5})?)(\/(?:(?:[a-zA-Z0-9\;\/\?\:\@\&\=\#\~\-\.\+\!\*\'\(\)\,\_])|(?:\%[a-fA-F0-9]{2}))*)?(?:\b|$)/gi, "<a class='link' href='http://$3$4' target='_blank'>$3$4</a>");

    messageDiv.innerHTML = parsedText;
}

function deleteMessage(messageDiv, silent){
    if(silent){
        messageDiv.parent().remove();
    } else {
        messageDiv.replaceWith(`
            <span class='deleted'>
                <a href="#" data-deleted="` + messageDiv[0].innerHTML + `">&#x3c;deleted&#x3e;</a>
            </span>
        `);
    }
}


function removeMaxMessages(){
    var maxMessages = parseInt($("#max-messages")[0].value);
    var numberOfMessages = $("#robinChatMessageList").children().length;

    if(numberOfMessages > maxMessages){
        var messages = $("#robinChatMessageList").children();
        
        for(var i = numberOfMessages; i > maxMessages; i--){
            if(messages[0] != undefined){
                messages[0].remove();
            }
        }
    }
}


//checks for a new message, and then calls doFilter();
createObserver();
function createObserver() {
    var target = $('#robinChatMessageList')[0];

    var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            var messageDiv = mutation.addedNodes[0];
            
            if(messageDiv != undefined){
                doFilter(messageDiv);
                parseURLs(messageDiv);
            }

            removeMaxMessages();
        });
    });

    // configuration of the observer:
    var config = { childList: true };

    // pass in the target node, as well as the observer options
    observer.observe(target, config);
}

//ty to fam
//http://stackoverflow.com/questions/8746882/jquery-contains-selector-uppercase-and-lower-case-issue
//makes :contains case-insensitive
jQuery.expr[':'].Contains = function(a, i, m) { return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0; };

//also thanks to this guy
//http://stackoverflow.com/questions/147824/how-to-find-whether-a-particular-string-has-unicode-characters-esp-double-byte
function isAsciiArt(s) { // "art"
    return /[^\u0000-\u00ff]/.test(s);
}

createEventListeners();
function createEventListeners(){
    $(document.body).on("click", ".filter-img#filter-remove", function(event){
        var filterList = GM_getValue("filter_list");
        var word = event.currentTarget.getAttribute("data-word");
        var index = filterList.indexOf(word);

        filterList.splice(index, 1);
        
        GM_setValue("filter_list", filterList);

        event.currentTarget.parentElement.outerHTML = "";
    });

    $(document.body).on("click", ".filter-img#filter-create", function(){
        var newWord = window.prompt("Enter a new filter to add");
        if(newWord != null){
            appendWordToList(newWord);

            var newFilterList = GM_getValue("filter_list");
            newFilterList.push(newWord);
            GM_setValue("filter_list", newFilterList);
        }
    });
    
    $(document.body).on("click", ".deleted a", function(event){
        event.preventDefault();
        var element = event.toElement;

        element.outerHTML = $(element).attr("data-deleted");
    });
}

//everything below is html/css stuff

createHTML();
function createHTML(){
    var html = `
    <div>
        <div>Create word or username filters below by clicking the green +. Message /u/kmcgurty1 for help.</div>
        <input id="remove-ascii" type="checkbox" checked>&nbsp;Remove ascii art<br>
        <input id="silent-delete" type="checkbox" checked>&nbsp;Silently delete<br>
        <input id="max-messages" type="number" value="150" style="width: 3em">&nbsp;Max messages to keep
        <div class="filter-list">
            <div class="item-wrapper">
                <div class="filter-img" id="filter-create"></div>
            </div>
        </div>
    </div>
    `;

    $("div[role=main]").after(html);

    var filterList = GM_getValue("filter_list");

    for (var i = 0; i < filterList.length; i++) {
        appendWordToList(filterList[i]);
    }

    createButton = ``;
}

function appendWordToList(word){
    var html = `
        <div class="item-wrapper">
            <div class="filter-word">` + word + `</div>
            <div class="filter-img" id="filter-remove" data-word="` + word + `" ></div>
        </div>
    `;

    $(html).insertBefore(".item-wrapper:last");
}

var css = `
.deleted a{
    color: rgba(0,0,0, .4);
}

div input{
    display: inline-block;    
    vertical-align: bottom; 
}

.filter-word{
    color: black;
    height: 25px;
    padding-right: 10px;
}

.filter-img{
    cursor:  pointer;
    width: 15px;
    height: 15px;
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
    
}

.filter-img#filter-create{
    height: 25px;
    width: 25px;
    background-image: url(https://i.imgur.com/nw1I62o.png);
}

.filter-img#filter-remove{
    background-image: url(https://i.imgur.com/3bYSOxq.png);
}

.item-wrapper{
    display: inline-block;
    background-color: rgb(235, 235, 235);
    border: 4px solid rgba(20, 20, 20, .7);
    border-radius: 5px;
    padding: 2px;
    margin: 4px;
}

.item-wrapper div{
    vertical-align: middle;
    display: table-cell;
}

.filter-list{
    font: normal small verdana,arial,helvetica,sans-serif;
    line-height: 1em;
    margin: 5px;
}

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
    /* display: none; <- Crashes Chrome on hover */
    -webkit-appearance: none;
    margin: 0; /* <-- Apparently some margin are still there even though it's hidden */
}

a.link{
    color: blue;
}

a.link:link {
    color: #0000EE;
}

a:hover{
    text-decoration: underline;
}
`;

GM_addStyle(css);