Filter, Highlight & Delete

Highlights, Lowlights, or Deletes page elements based on their text.

当前为 2019-09-03 提交的版本,查看 最新版本

// ==UserScript==
// @name         Filter, Highlight & Delete
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Highlights, Lowlights, or Deletes page elements based on their text.
// @author       listfilterErick
// @grant        none

// @match        *://news.google.com/*
// @match        *://www.youtube.com/*
// @match        *://www.reddit.com/r/*

// @require      http://code.jquery.com/jquery-1.12.4.min.js
// @require      https://greasyfork.org/scripts/5392-waitforkeyelements/code/WaitForKeyElements.js?version=115012

// @licence      CC-BY-NC-SA-4.0; https://creativecommons.org/licenses/by-nc-sa/4.0/
// @licence      GPL-3.0-or-later; http://www.gnu.org/licenses/gpl-3.0.txt
// ==/UserScript==
/*jshint esversion: 6 */

/* Last update: 09-02-2019 */

/*
    Google News: Only works for the front page of google news. Need a more robust selector for other special sections.
    Reddit: Only works for compact view.
*/

/*
    Search for these markers for locations where you need to add new selectors for new sites.
    markA (select the text block)
    markB (select the block you want to apply css to)
    markC (css of each class)
*/

(function () {
    'use strict';

    let lfShowFilterButton = 0; // set to 1 to show a button to manually run this script.
    let lfButtonTransparency = .33; // set to a value between 0 and 1, 1 is no transparency, .5 is 50% transparency.
    let lfDynamicChecking = 1; // set to 1 to run the script automatically when new block elements are detected.
    let lfShowConsoleMsg = 0; // set to 1 to show console messages about how the filter checked each block.
    let lfPrintRuntime = 0; // set to 1 to display runtime.

    function consolelog(text) {
        if (lfShowConsoleMsg) {
            console.log(text);
        }
    }
    consolelog("list filter script start.");

    if (lfPrintRuntime) {
        var lfStartTime = performance.now();
    }

    // ==== filter lists ====

    //strong highlight
    var highlight1 = [
        /apple/i,
    ];
    //weak highlight
    var highlight2 = [
        /gamestop/i,
    ];
    //weak lowlight
    var lowlight1 = [
        /goodbye/i,
    ];
    //strong lowlight
    var lowlight2 = [
        /\btv\b/i,
    ];
    //delete block
    var delete1 = [
        /throne|dany|\bgot\b/i,
    ];

    let domainName = window.location.hostname; //href might be less limiting
    let hrefString = window.location.href;

    // ==== function definitions ====

    // checks string against given list of regular expressions.
    function checkReg(string, regList) {
        for (let i = 0; i < regList.length; i++) {
            if (regList[i].test(string)) {
                return true;
            }
        }
        return false;
    }

    let elementCounter = 0;

    // check attributes of a block to choose what class to add to it.
    function checkBlock(index, element) {

        let titleText;

        // markA start
        if (/news\.google\.com/gi.test(domainName)) {
            titleText = jQuery(this).find("div>article>h3").eq(0).text().trim();
        } else if (/www\.youtube\.com/gi.test(domainName)) {
            titleText = jQuery(this).find("span#video-title").text().trim();
        } else if (/www\.reddit\.com/gi.test(domainName)) {
            titleText = jQuery(this).find("span>a>h2").text().trim();
        }
        // markA end

        // class list identifies what was checked in past iterations
        let classList = "";
        if (jQuery(this).attr("class")) {
            classList = jQuery(this).attr("class");
            //consolelog(classList);
        }

        if (titleText && (!classList || !/\blf-/.test(classList))) {
            //if ( titleText ) {
            elementCounter++;
            var matchCode = "n1";

            // delete and lowlight lists are checked before highlight lists
            if (checkReg(titleText, delete1)) {
                matchCode = "d1";
                jQuery(this).remove();
            } else if (checkReg(titleText, lowlight2)) {
                matchCode = "l2";
                jQuery(this).addClass("lf-lowlight2");
            } else if (checkReg(titleText, lowlight1)) {
                matchCode = "l1";
                jQuery(this).addClass("lf-lowlight1");
            } else if (checkReg(titleText, highlight1)) {
                matchCode = "h1";
                jQuery(this).addClass("lf-highlight1");
            } else if (checkReg(titleText, highlight2)) {
                matchCode = "h2";
                jQuery(this).addClass("lf-highlight2");
            } else {
                jQuery(this).addClass("lf-checked");
            }

            // prints to console the outcome of what the block matched.
            //if (1) {
            if (lfShowConsoleMsg && /d|l/gi.test(matchCode)) {
                var printMsg = elementCounter;
                printMsg += " " + matchCode;
                printMsg += ": " + titleText;
                consolelog(printMsg);
            }
            //console.log(elementCounter +" "+ matchCode +": "+ titleText +"("+ vidLength +")");
        }

    } // end function checkBlock()

    // ==== adds reset button for highlight/lowlight and runs initial execution. ====

    // markB start
    let blockSelector = "article";
    if (/news\.google\.com/gi.test(domainName)) {
        blockSelector = "main>c-wiz>div>div";
        checkBlocks();
    } else if (/www\.youtube\.com/gi.test(domainName)) {
        blockSelector = "ytd-compact-video-renderer";
        checkBlocks();
    } else if (/www\.reddit\.com/gi.test(domainName)) {
        blockSelector = ".scrollerItem>div>div:nth-child(2)";
        checkBlocks();
    }
    // markB end

    function checkBlocks() {
        jQuery(blockSelector).each(checkBlock);
        consolelog("end checkBlocks().");
    }

    jQuery("#lf-reset").click(function () {
        consolelog("highlight/lowlight reset began.");
        elementCounter = 0;
        checkBlocks();
        consolelog("highlight/lowlight reset finished.");
    });

    if (lfDynamicChecking) {
        waitForKeyElements(blockSelector, checkBlocks);
    } else {
        checkBlocks();
    }

    if (lfShowFilterButton) {
        if (!jQuery("#wt-buttons").length) {
            consolelog("created #wt-buttons.");
            jQuery("body").prepend('<div id="wt-buttons"><div id="lf-reset">H/L</div><div id="wt-close">&times;</div></div>');
            jQuery("#wt-close").click(function () { jQuery("#wt-buttons").remove(); });

            const webToolsCss =
                `<style type="text/css">
    #wt-buttons {
        width: 40px;
        display: block !important;
        position: fixed;
        top: 0px;
        right: 0px;
        z-index: 9000;
        opacity: `+ lfButtonTransparency + `;
    }
    #wt-buttons:hover {
        opacity: 1;
    }
    #wt-buttons div {
        display: block !important;
        padding: 5px;
        border-radius: 5px;
        margin-top: 2px;
        font-size: initial !important;
        font-weight: bold;
        color: white;
        cursor: pointer;
    }
    #wt-close {
        background: #777777;
        text-align: center;
    }
</style>`;
            jQuery(document.body).append(webToolsCss);
        } else {
            jQuery("#wt-buttons").prepend('<div id="lf-reset">H/L</div>');
        }
        const listFilterCss =
            `<style>
    #lf-reset {
        background: #177e14;
    }
</style>`;
        jQuery(document.body).append(listFilterCss);
    }

    // markC start
    const googleFilterCss =
        `<style>
    main>c-wiz>div>div.lf-highlight1 {
        background: #baffc9;/*green*/
    }
    main>c-wiz>div>div.lf-highlight2 {
        background: #ffffba;/*yellow*/
    }
    main>c-wiz>div>div.lf-lowlight1 {
        background: #ffdfba;/*orange*/
        opacity: .3;
    }
    main>c-wiz>div>div.lf-lowlight2 {
        background: #ffccca;/*red*/
        opacity: .5;
    }
    </style>`;
    const youtubeFilterCss =
        `<style>
    ytd-compact-video-renderer.lf-highlight1 {
        background: #baffc9;/*green*/
    }
    ytd-compact-video-renderer.lf-highlight2 {
        background: #ffffba;/*yellow*/
    }
    ytd-compact-video-renderer.lf-lowlight1 {
        background: #ffdfba;/*orange*/
        opacity: .3;
    }
    ytd-compact-video-renderer.lf-lowlight2 {
        background: #ffccca;/*red*/
        opacity: .5;
    }
    </style>`;
    const redditFilterCss =
        `<style>
    .scrollerItem>div>div:nth-child(2).lf-highlight1 {
        background: #baffc9;/*green*/
    }
    .scrollerItem>div>div:nth-child(2).lf-highlight2 {
        background: #ffffba;/*yellow*/
    }
    .scrollerItem>div>div:nth-child(2).lf-lowlight1 {
        background: #ffdfba;/*orange*/
        opacity: .3;
    }
    .scrollerItem>div>div:nth-child(2).lf-lowlight2 {
        background: #ffccca;/*red*/
        opacity: .5;
    }
    </style>`;

    if (/news\.google\.com/gi.test(domainName)) {
        jQuery(document.body).append(googleFilterCss);
    } else if (/www\.youtube\.com/gi.test(domainName)) {
        jQuery(document.body).append(youtubeFilterCss);
    } else if (/www\.reddit\.com/gi.test(domainName)) {
        jQuery(document.body).append(redditFilterCss);
    }
    // markC end

    if (lfPrintRuntime) {
        let lfEndTime = performance.now();
        console.log('(LF) finished after ' + ((lfEndTime - lfStartTime) / 1000).toFixed(2) + ' seconds.');
    }

    consolelog("list filter script finished.");
})();