Word & Text Replace

replaces text with other text.

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

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Word & Text Replace
// @namespace    http://tampermonkey.net/
// @version      1.3.1
// @description  replaces text with other text.
// @author       listfilterErick
// @grant        none

// @match        *://*/*

// @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*/

/*
    Update Log 1.3.1
    - new options: 
    -- logMatches, logChangedText
    -- dontMarkDivs, checkHyperlinkElements
    - cleanup: changed variable names, cleaned up function code.

    * Text nodes are trimmed before checking but changed text is not trimmed unless specified in the regex.
*/

(function () {

    let replaceRules = [];
    
    /*
        regex reference
        \b: word boundry
        \W: any non-alpha character
    */
    if (1) {
        replaceRules.push(
            // basic examples:
            //[/(.\W?)*/i, 'words'], //replace all text instances with "words".
            //[/\w/gi, 'a'], //replace all characters with an "a" character.
            //[/match/gi, 'a'], //matches "match" in "ABmarchCD" and "red match".
            //[/\bmatch\b/gi, 'a'], //does not match "ABmatchesCD" but does match "this match is red".
            //[/scripts/gi, 'dictionaries'],
            //[/script/gi, 'dictionary'],
            //[/(web)?site/gi, 'webzone'],
        );
        // separated just for an example of an option of grouping/sorting.
        replaceRules.push(
            //[/user/gi, 'individual'],
            //[/\buse\b/gi, 'utilize'],
        );
    }
    /*
        #### note on moving rules to a seperate userscript ####
        https://wiki.greasespot.net/UnsafeWindow
        unsafeWindow.replaceRules = replaceRules; //set rules(page scope) to rules(script scope)
        replaceRules = unsafeWindow.replaceRules; //set rules(script scope) to rules(page scope)
    */

    const showReplaceButton = 0; // set to 1 to show a button to manually run this script.
    const buttonTransparency = .2; // set to a value between 0 and 1, 1 is no transparency, .5 is 50% transparency.
    const dynamicChecking = 1; // set to 1 to run the script automatically when new image elements are detected.

    const showLogMessages = 0; // set to 1 to log script messages, overrides the following log options.
    const logMatches = 1; // set to 1 to log matches to the console.
    const logChangedText = 0; // set to 1 to log changed text to the console.
    const logRuntimes = 1; // set to 1 to log function runtimes to the console.

    const dontMarkDivs = 1; // set to 1 to not mark divs as checked, solves some site issues.
    // setting to 1 would make dynamic checks recheck checked divs.

    function consolelog(text, showOption) {
        if (showLogMessages && showOption) {
            console.log(text);
        }
    }

    let titleChecked = 0;
    let nodeCounter = 1;
    let aCounter = 1;

    // ==== replaceText() =========================================================================|
    function replaceText() {

        if (logRuntimes) {
            var startTime = performance.now();
        }

        let numTerms = replaceRules.length;
        let ruleMatched = 0;

        // ==== title element =====================================================================|
        let titleText = jQuery("title").text();
        if (titleText && !titleChecked) {
            for (let index = 0; index < numTerms; index++) {
                if (replaceRules[index][0].test(titleText)) {
                    consolelog("(title match): "+ titleText +" | "+ replaceRules[index][0], logMatches);
                    titleText = titleText.replace(replaceRules[index][0], replaceRules[index][1]);
                    jQuery("title").text(titleText);
                }
            }
            titleChecked = 1;
        }

        // ==== text elements =====================================================================|
        let textWalker = document.createTreeWalker(
            document.body,
            NodeFilter.SHOW_TEXT,
            {
                acceptNode: function (node) {
                    if (node.nodeValue.trim() &&
                        !/CODE|SCRIPT|STYLE/.test(node.parentNode.nodeName) && // exclude scripts and style elements
                        !/wr-checked/.test(node.parentNode.classList)) { // exclude checked elements
                        return NodeFilter.FILTER_ACCEPT;
                    }
                    return NodeFilter.FILTER_SKIP;
                }
            },
            false
        );
        let textNode = textWalker.nextNode();
        while (textNode) {
            let currentText = textNode.nodeValue;
            let parentNode = textNode.parentNode;
            if (!dontMarkDivs || parentNode.nodeName != "DIV") { //supposedly adding a class to a div broke a site somehow.
                parentNode.classList.add("wr-checked");
            }
            for (let index = 0; index < numTerms; index++) {
                if (replaceRules[index][0].test(currentText.trim())) {// ## checks the trimmed text.
                    ruleMatched = 1;
                    consolelog(nodeCounter +" (text match): "+ currentText +" | "+ replaceRules[index][0], logMatches);
                    currentText = currentText.replace(replaceRules[index][0], replaceRules[index][1]);
                }
            }
            if (ruleMatched) {
                ruleMatched = 0;
                textNode.nodeValue = currentText;
                consolelog(nodeCounter +" (text): "+ currentText.trim(), logChangedText);
                nodeCounter++;
            }
            textNode = textWalker.nextNode();
        }

        if (logRuntimes) {
            const endTime = performance.now();
            const runTime = ((endTime - startTime) / 1000).toFixed(2);
            if (runTime > 1) {
                consolelog('(WR) finished after ' + runTime + ' seconds.', 1);
            }else {
                consolelog('(WR) finished in less than 1 second.', 1);
            }
        }

    } //end function replaceText()

    replaceText();
    if (dynamicChecking) {
        jQuery(document).ready(waitForKeyElements("img", replaceText));
        //jQuery(window).on("load", function() { //after all initial images are loaded.
            //waitForKeyElements("img", replaceText);
        //});
    }

    if (showReplaceButton) {
        if (!jQuery("#wt-buttons").length) {
            consolelog("(WR) created #wt-buttons.");
            jQuery("body").prepend("<div id='wt-buttons'><div id='wr-reset'>WR</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: 50px;
        display: block;
        opacity: `+ buttonTransparency + `;
        position: fixed;
        top: 0px;
        right: 0px;
        z-index: 999;
    }
    #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='wr-reset'>WR</div>");
        }
        jQuery("#wr-reset").click(replaceText);

        const wordReplaceCss =
            `<style type="text/css">
    #wr-reset {
        background: #ffb51b;
    }
</style>`;

        jQuery(document.body).append(wordReplaceCss);
    } // end if (showReplaceButton)
})();