Text Filter

For the following sites, this will allow you to auto-filter selected text.

Pada tanggal 13 September 2020. Lihat %(latest_version_link).

// ==UserScript==
// @name         Text Filter
// @namespace    mailto:[email protected]
// @version      1
// @description  For the following sites, this will allow you to auto-filter selected text.
// @author       You
// @match        https://www.fanfiction.net/s/*
// @match        https://forums.sufficientvelocity.com/threads/*
// @match        https://forums.spacebattles.com/threads/*
// @match        https://forum.questionablequesting.com/threads/*
// @match        https://www.tthfanfic.org/Story*
// @match        https://www.tthfanfic.org/wholestory*
// @grant        GM_registerMenuCommand
// ==/UserScript==

class Page {
    constructor(){
        console.clear();
        GM_registerMenuCommand("XFilter Selected", ()=>this.deleteSelected(), 'x');
        this.storyChildElements = window.location.pathname.split('/')[1]=="wholestory.php";
        this.location = window.location.host.split('.')[1];
        this.storyClassName = {
            fanfiction:"storytext xcontrast_txt nocopy",
            questionablequesting:"messageText SelectQuoteContainer ugc baseHtml",
            tthfanfic:"paragraphs",
            spacebattles:"bbWrapper",
            sufficientvelocity:"bbWrapper"
        }
        this.storyNodes = this.getStoryContainer();
    }
    tagFilter(target){
        return target.filter((b,i)=>{
            if(b.tagName=="BR"||b.textContent==""||b.textContent.trim().length==0)return false;
            return true;
        });
    }
    getStoryContainer(){
        var cont=document.getElementsByClassName(this.storyClassName[this.location]);
        var nodes = [];
        var subElements = [];
        for(let i=0,len=cont.length;i<len;i++){
            if(this.storyChildElements){
                subElements = [...cont[i].childNodes];
                subElements.pop();
                for(let j=0,lenj=subElements.length;j<lenj;j++){
                    nodes=[...nodes,...this.tagFilter([...subElements[j].childNodes])];
                }
            } else {
                nodes=[...nodes,...this.tagFilter([...cont[i].childNodes])];
            }
            //if(this.storyChildElements) subElements=subElements[i].childNodes;
        }
        return nodes;
    }
    deleteSelected(){
        this.deleteTargets(this.getSelectionText());
    }
    deleteTargets(target){
        if(target){
            for(let i=0, len=this.storyNodes.length;i<len;i++){
                if(this.checkText(this.storyNodes[i],target)){
                    this.deleteTarget(this.storyNodes[i]);
                }
            }
        }
    }
    deleteTarget(target){
        while(true){
            let nextSib=target.nextSibling;
            if(nextSib.tagName=="HR"||nextSib.tagName=="BR"||nextSib.textContent==""||nextSib.textContent.trim().length==0){
                this.deleteElement(target.nextSibling);
            }else{
                break;
            }
        }
        this.deleteElement(target);
    }
    deleteElement(target){
        target.parentNode.removeChild(target);
    }
    checkText(text, target){
        return ~text.textContent.toLowerCase().indexOf(target) ;
    }
    getSelectionText() {
        var text = "";
        if (window.getSelection) {
            text = window.getSelection().toString();
        } else if (document.selection && document.selection.type != "Control") {
            text = document.selection.createRange().text;
        }
        return text.toLowerCase().trim();
    }
}

var page = new Page();