Reddit Robin Filter

Filters comments. Works on usernames and messages.

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

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Reddit Robin Filter
// @namespace    http://kmcgurty.com
// @version      2.2.1
// @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 && usernameDiv[0] != undefined) {
            var message = messageDiv[0].innerHTML.toLowerCase();
            var username = usernameDiv[0].innerHTML.toLowerCase();
            var currentFilter = filter[i].toLowerCase();
            var matches = message.includes(currentFilter) || username.includes(currentFilter);

            if (matches || isAscii) {
                messageDiv.replaceWith(`
                    <span class='deleted'>
                        <a href="#" data-deleted="` + messageDiv[0].innerHTML + `">&#x3c;deleted&#x3e;</a>
                    </span>
                `);
            }
        }
    }

    var messageDiv = $(div).find(".robin-message--message");

    if(filter.length != 0 && messageDiv[0] != undefined){
        var message = messageDiv[0].innerHTML.toLowerCase();
        var isAscii = $("#remove-ascii")[0].checked && isAsciiArt(message);

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

//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];
            doFilter(messageDiv);
        });
    });

    // 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");
        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>Remove ascii art
        <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);
}

#remove-ascii{
    display: inline-block;    
    vertical-align: bottom; 
}

.deleted:hover{
    text-decoration: underline;
}

.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;
}
`;

GM_addStyle(css);