简体   繁体   中英

How do I replace text on website only if the userscript sees a trigger word?

I want my userscript to replace word "A", on a page, with word "B", unless word "C" is present.
If "C" is present, then I want to replace "A" with "D" instead.

For example,

  1. Normally, it would replace Cat with Feline .
  2. But, if the userscript sees the word Kitten on the webpage, it would instead change Cat to Meow .
  3. Obviously, it should do the same with multiple other word sets, if I want it to.

I found this old userscript written by Joe Simmons ; see the relevant code, below. Although it works extremely well, How do I add the conditional functionality?

(function () { 'use strict';
    var words = {
        // Syntax: 'Search word' : 'Replace word',
        'your a':       'you\'re a',
        'imo':          'in my opinion',
        'im\\*o':       'matching an asterisk, not a wildcard',
        '/\\bD\\b/g':   '[D]',

        ///////////////////////////////////////////////////////
        '': ''
    };

    var regexs = [],
        replacements = [],
        tagsWhitelist = ['PRE', 'BLOCKQUOTE', 'CODE', 'INPUT', 'BUTTON', 'TEXTAREA'],
        rIsRegexp = /^\/(.+)\/([gim]+)?$/,
        word, text, texts, i, userRegexp;

    // prepareRegex by JoeSimmons
    // used to take a string and ready it for use in new RegExp()
    function prepareRegex (string) {
        return string.replace (/([\[\]\^\&\$\.\(\)\?\/\\\+\{\}\|])/g, '\\$1');
    }

    // function to decide whether a parent tag will have its text replaced or not
    function isTagOk (tag) {
        return tagsWhitelist.indexOf (tag) === -1;
    }

    delete words['']; // so the user can add each entry ending with a comma,
    // I put an extra empty key/value pair in the object.
    // so we need to remove it before continuing

    // convert the 'words' JSON object to an Array
    for (word in words) {
        if (typeof word === 'string' && words.hasOwnProperty (word) ) {
            userRegexp = word.match (rIsRegexp);

            // add the search/needle/query
            if (userRegexp) {
                regexs.push (
                    new RegExp (userRegexp[1], 'g')
                );
            }
            else {
                regexs.push (
                    new RegExp (prepareRegex (word)
                        .replace (/\\?\*/g, function (fullMatch) {
                            return fullMatch === '\\*' ? '*' : '[^ ]*';
                        } ),
                        'g'
                    )
                );
            }

            // add the replacement
            replacements.push(words[word]);
        }
    }

    // do the replacement
    texts = document.evaluate ('//body//text()[ normalize-space(.) != "" ]', document, null, 6, null);
    for (i = 0; text = texts.snapshotItem (i); i += 1) {
        if (isTagOk (text.parentNode.tagName) ) {
            regexs.forEach (function (value, index) {
                text.data = text.data.replace (value, replacements[index]);
            } );
        }
    }
} () );

You could abuse the execution order by creating a kitten filter that would trigger before the cat filter.

var words = {
///////////////////////////////////////////////////////
    // Syntax: 'Search word' : 'Replace word',
    '/(kitten.*)?Cat(.*kitten)?/gi' : 'Meow',
    'Cat'                           : 'Feline',
///////////////////////////////////////////////////////
};

It's certainly less annoying than implementing a callback.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM