Filter, Highlight & Delete

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

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

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Filter, Highlight & Delete
// @namespace    http://tampermonkey.net/
// @version      1.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 lfShowLogMsgs = 0; // set to 1 to show console messages, required to enable the following message rules.
    let lfLogMatches = 1; // set to 1 to log to console what was matched.
    let lfLogRuntime = 1; // set to 1 to log to console how long this takes to run.

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

    if (lfShowLogMsgs && lfLogRuntime) {
        var lfStartTime = performance.now();
    }

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

    if (1) {
        //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;
    let hrefString = window.location.href; //href lets you be more specific

    // ==== 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 searchText;

        // ==== markA start =======================================================================|
        if (/news\.google\.com/gi.test(domainName)) {
            searchText = jQuery(this).find("div>article>h3").eq(0).text().trim();
        } else if (/www\.youtube\.com/gi.test(domainName)) {
            searchText = jQuery(this).find("span#video-title").text().trim();
        } else if (/www\.reddit\.com/gi.test(domainName)) {
            searchText = 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 (searchText && (!classList || !/\blf-/.test(classList))) {
            //if ( searchText ) {
            elementCounter++;
            var matchCode = "n1";

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

            //if (1) {
            if (lfShowLogMsgs && lfLogMatches && /d|l/.test(matchCode)) {
                let printMsg = elementCounter;
                printMsg += " "+ matchCode;
                printMsg += ": "+ searchText;
                consolelog(printMsg);
            }
            //console.log(elementCounter +" "+ matchCode +": "+ searchText +"("+ vidLength +")");
        }

    } // end function checkBlock()

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

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

    // ==== optional button code ==================================================================|
    if (lfShowFilterButton) {
        if (!jQuery("#wt-buttons").length) {
            consolelog("(LF) 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 ===========================================================================|
    // May want to define custom rules per site.
    if (/news\.google\.com/gi.test(domainName)) {
        var blockElement = "main>c-wiz>div>div";
    } else if (/www\.youtube\.com/gi.test(domainName)) {
        var blockElement = "ytd-compact-video-renderer";
    } else if (/www\.reddit\.com/gi.test(domainName)) {
        var blockElement = ".scrollerItem>div>div:nth-child(2)";
    }
    // ==== markC end =============================================================================|
    var filterCss = 
`<style>
    `+ blockElement +`.lf-highlight1 {
        background: #baffc9;/*green*/
    }
    `+ blockElement +`.lf-highlight2 {
        background: #ffffba;/*yellow*/
    }
    `+ blockElement +`.lf-lowlight1 {
        background: #ffdfba;/*orange*/
        opacity: .3;
    }
    `+ blockElement +`.lf-lowlight2 {
        background: #ffccca;/*red*/
        opacity: .5;
    }
</style>`;
    jQuery(document.body).append(filterCss);

    if (lfShowLogMsgs && lfLogRuntime) {
        let lfEndTime = performance.now();
        consolelog('(LF) finished after ' + ((lfEndTime - lfStartTime) / 1000).toFixed(2) + ' seconds.');
    }

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