Skip to content

Instantly share code, notes, and snippets.

@jaawerth
Last active April 26, 2024 10:44
Show Gist options
  • Save jaawerth/318194541b41dba32cb3599b17706a8d to your computer and use it in GitHub Desktop.
Save jaawerth/318194541b41dba32cb3599b17706a8d to your computer and use it in GitHub Desktop.

Revisions

  1. jaawerth revised this gist Feb 9, 2022. 4 changed files with 13908 additions and 77 deletions.
    13 changes: 10 additions & 3 deletions desc.md
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,8 @@
    # Non-Funkadelic Tokers userscript
    # Non-Funkadelic Toasters userscript

    Because sometimes I don't want to see the word "Necromancy's Fiscal Tecumseh's."

    ![nft-replacer](https://user-images.githubusercontent.com/5314507/152530349-8b0a73a6-3391-4b03-a664-7486070c0005.png)
    ![Nonintervention Feline Targets-replacer](https://user-images.githubusercontent.com/5314507/152530349-8b0a73a6-3391-4b03-a664-7486070c0005.png)

    ## Not properly documenting this, but if you wanna use it...

    @@ -19,4 +19,11 @@ I may or may not eventually get around to properly packaging this as a shareable
    }
    ```

    You should then get a new a button in the extension menu to toggle it on and off to get randomizing.
    You should then get a new a button in the extension menu to toggle it on and off to get randomizing. You can also just paste in the data below, but...

    ## NOTE ABOUT REPLACEMENT WORDS

    The replacement words below were pulled from a system/dictd wordlist. I did my best to filter out anything derogatory using a filter list, but I *may* have missed a few - it's a huge wordlist! If any others turn up, naturally I'll remove them, but fair warning it hasn't been audited all that carefully.

    Also, **I definitely left a bunch of profanity in there** because it's funnier that way, so, you know, keep that in mind.

    114 changes: 114 additions & 0 deletions no-fun-tuesdays.user.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,114 @@
    // ==UserScript==
    // @name no-fun-tuesdays
    // @namespace Violentmonkey Scripts
    // @match *://*/*
    // @grant GM.getValue
    // @grant GM.setValue
    // @grant GM.deleteValue
    // @grant GM.registerMenuCommand
    // @run-at document-idle
    // @version 1.0
    // @author jaawerth
    // @description 2/4/2022, 5:58:12 AM
    // ==/UserScript==

    'use strict';

    const randomEntry = (items =[]) => items[Math.floor(Math.random() * items.length)];
    const keys = {enabled: 'lol_enabled', lolwords: 'dictwords'};
    const isEnabled = async () => GM.getValue(keys.enabled, true);

    function textNodeIterator(tgt = document.body) {
    const nIter = document.createNodeIterator(tgt, NodeFilter.SHOW_TEXT, {
    acceptNode: (node) => node.nodeValue.trim().length >= 3,
    });
    nIter[Symbol.iterator] = nIter[Symbol.iterator] || (() => ({
    next() {
    const currentNode = nIter.nextNode();
    return {
    done: !currentNode,
    value: currentNode,
    };
    },
    [Symbol.iterator]() {
    return this;
    },
    }));
    return nIter;
    }

    let replacer = '';
    async function genReplacer() {
    const {N, F, T} = await GM.getValue(keys.lolwords, {N: ['No'], F: ['Fun'], T:['Tuesdays']}) || {};
    replacer = [N, F, T].map(randomEntry).join(' ');
    return replacer;
    }

    async function replaceText(newWord = replacer, tgt = document.body) {
    if (!newWord) {
    newWord = await genReplacer();
    }
    const start = Date.now();
    for (const node of textNodeIterator(tgt)) {
    const value = node.nodeValue;
    const replaced = value.replace(/\bNFT('s|s|)?\b/gi, () => newWord);
    if (replaced !== value) node.nodeValue = replaced;
    }
    const end = Date.now();
    const delta = end - start;
    if (delta > 100) {
    console.debug(`[timing] Replaced in ${delta}ms`);
    }
    }

    let observer;
    const raf = (cb, ...args) => new Promise((resolve) => requestAnimationFrame(() => resolve(cb(...args))));
    async function observerCB(mutList, _observer) {
    if (!(await isEnabled())) return;
    const now = Date.now();
    Function.prototype(`raf replace ${now}`)
    return Array.from(mutList)
    .flatMap(mut => Array.from(mut.addedNodes))
    .reduce(async (prev, node) => {
    await prev;
    return raf(n => replaceText(replacer, n), node)
    }, Promise.resolve())
    .catch((e) => {console.error(e); console.timeEnd('raf replace');});
    }

    function observe(root = document.body) {
    observer = observer || new MutationObserver(observerCB);
    observer.observe(root, {subtree: true, childList: true, attributes: false});
    }
    const unobserve = () => observer && observer.disconnect();

    async function lolwords(newReplacer) {
    if (!(await isEnabled())) return;
    try {
    if (newReplacer || !replacer) await genReplacer();
    const msg = `En Eff Tee -> ${replacer}`;
    console.time(msg);
    await replaceText();
    console.timeEnd(msg);
    observe();
    } catch(e) {
    console.error('bork', e);
    }
    }

    const state = {
    async enable(newReplacer) {
    await GM.setValue(keys.enabled, true);
    await lolwords(newReplacer);
    },
    async disable() {
    await GM.setValue(keys.enabled, false);
    unobserve();
    },
    toggle: async (newReplacer = true) => await isEnabled() ?
    await state.disable() : await state.enable(newReplacer),
    }

    GM.registerMenuCommand('lolwords', state.toggle);

    lolwords().catch(e => console.error(e));
    74 changes: 0 additions & 74 deletions non-funkadelic-tokers.user.js
    Original file line number Diff line number Diff line change
    @@ -1,74 +0,0 @@
    // ==UserScript==
    // @name Non-Funkadelic Tokers
    // @namespace Violentmonkey Scripts
    // @match *://*/*
    // @grant GM_getValue
    // @grant GM_setValue
    // @grant GM_deleteValue
    // @grant GM_registerMenuCommand
    // @version 1.0
    // @author -
    // @description 2/4/2022, 5:58:12 AM
    // ==/UserScript==

    const randomEntry = (items =[]) => items[Math.floor(Math.random() * items.length)];
    const keys = {enabled: 'lol_enabled', lolwords: 'lolwords'};

    const isEnabled = () => GM_getValue(keys.enabled, false);

    const toggle = (enable = null) => {
    const prev = isEnabled(), set = typeof enable === 'boolean' ? enable : !prev;
    GM_setValue(keys.enabled, set);
    if (!prev && set) lolwords();
    };

    function lazyWalkText(skipEmptyString = true) {
    const walker = document.createTreeWalker(
    document.body, NodeFilter.SHOW_TEXT, null, false,
    );
    return {
    next() {
    do {
    var skippingEmpty = false;
    const done = !walker.nextNode();
    if (done) {
    return { done, value: undefined };
    } else if (!skipEmptyString || walker.currentNode.nodeValue.trim()) {
    return { done: false, value: walker.currentNode };
    } else {
    skippingEmpty = true;
    }
    } while(skippingEmpty);
    },
    [Symbol.iterator]() {
    return this;
    },
    }
    }

    function replaceText(newWord) {
    for (const node of lazyWalkText()) {
    const value = node.nodeValue;
    const replaced = value.replace(/\bNFT('s|s|)?\b/gi, () => newWord);
    if (replaced !== value) node.nodeValue = replaced;
    }
    }

    function lolwords() {
    if (!isEnabled()) return;
    try {
    console.time('lolwords');
    const {N, F, T} = GM_getValue(keys.lolwords, {N: [], F: [], T:[]}) || {};
    const newWords = [N, F, T].map(randomEntry).join(' ');
    console.log('EN EFF TEE', newWords);
    replaceText(newWords);
    console.timeEnd('lolwords');
    } catch(e) {
    console.error(e);
    }
    }


    GM_registerMenuCommand('lolwords', toggle);

    lolwords();
    13,784 changes: 13,784 additions & 0 deletions z_dictwords.json
    13,784 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
  2. jaawerth revised this gist Feb 4, 2022. 1 changed file with 1 addition and 2 deletions.
    3 changes: 1 addition & 2 deletions non-funkadelic-tokers.user.js
    Original file line number Diff line number Diff line change
    @@ -60,11 +60,10 @@ function lolwords() {
    console.time('lolwords');
    const {N, F, T} = GM_getValue(keys.lolwords, {N: [], F: [], T:[]}) || {};
    const newWords = [N, F, T].map(randomEntry).join(' ');
    console.log('NEW', newWords);
    console.log('EN EFF TEE', newWords);
    replaceText(newWords);
    console.timeEnd('lolwords');
    } catch(e) {
    console.error('bork')
    console.error(e);
    }
    }
  3. jaawerth revised this gist Feb 4, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion desc.md
    Original file line number Diff line number Diff line change
    @@ -9,7 +9,7 @@ Because sometimes I don't want to see the word "Necromancy's Fiscal Tecumseh's."
    I may or may not eventually get around to properly packaging this as a shareable userscript or extension, complete with preloaded replacement words and such, so to use it:

    1. Load up a userscript extension that's compatible with the greasemonkey API (violentmonkey is an open source one I've been using, or there's tampermonkey, greasemonkey itself, etc), and paste the code into a newly created script.
    2. GO to the "values" tab to add a new field to the data store with the key `lolwords`, and fill in your replacements with JSON in the form:
    2. Go to the "values" tab to add a new field to the data store with the key `lolwords`, and fill in your replacements with JSON in the form:

    ```json
    {
  4. jaawerth created this gist Feb 4, 2022.
    22 changes: 22 additions & 0 deletions desc.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,22 @@
    # Non-Funkadelic Tokers userscript

    Because sometimes I don't want to see the word "Necromancy's Fiscal Tecumseh's."

    ![nft-replacer](https://user-images.githubusercontent.com/5314507/152530349-8b0a73a6-3391-4b03-a664-7486070c0005.png)

    ## Not properly documenting this, but if you wanna use it...

    I may or may not eventually get around to properly packaging this as a shareable userscript or extension, complete with preloaded replacement words and such, so to use it:

    1. Load up a userscript extension that's compatible with the greasemonkey API (violentmonkey is an open source one I've been using, or there's tampermonkey, greasemonkey itself, etc), and paste the code into a newly created script.
    2. GO to the "values" tab to add a new field to the data store with the key `lolwords`, and fill in your replacements with JSON in the form:

    ```json
    {
    "N": ["possible", "replacement..."],
    "F": ["possible", "replacement..."],
    "T": ["possible", "replacement..."]
    }
    ```

    You should then get a new a button in the extension menu to toggle it on and off to get randomizing.
    75 changes: 75 additions & 0 deletions non-funkadelic-tokers.user.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,75 @@
    // ==UserScript==
    // @name Non-Funkadelic Tokers
    // @namespace Violentmonkey Scripts
    // @match *://*/*
    // @grant GM_getValue
    // @grant GM_setValue
    // @grant GM_deleteValue
    // @grant GM_registerMenuCommand
    // @version 1.0
    // @author -
    // @description 2/4/2022, 5:58:12 AM
    // ==/UserScript==

    const randomEntry = (items =[]) => items[Math.floor(Math.random() * items.length)];
    const keys = {enabled: 'lol_enabled', lolwords: 'lolwords'};

    const isEnabled = () => GM_getValue(keys.enabled, false);

    const toggle = (enable = null) => {
    const prev = isEnabled(), set = typeof enable === 'boolean' ? enable : !prev;
    GM_setValue(keys.enabled, set);
    if (!prev && set) lolwords();
    };

    function lazyWalkText(skipEmptyString = true) {
    const walker = document.createTreeWalker(
    document.body, NodeFilter.SHOW_TEXT, null, false,
    );
    return {
    next() {
    do {
    var skippingEmpty = false;
    const done = !walker.nextNode();
    if (done) {
    return { done, value: undefined };
    } else if (!skipEmptyString || walker.currentNode.nodeValue.trim()) {
    return { done: false, value: walker.currentNode };
    } else {
    skippingEmpty = true;
    }
    } while(skippingEmpty);
    },
    [Symbol.iterator]() {
    return this;
    },
    }
    }

    function replaceText(newWord) {
    for (const node of lazyWalkText()) {
    const value = node.nodeValue;
    const replaced = value.replace(/\bNFT('s|s|)?\b/gi, () => newWord);
    if (replaced !== value) node.nodeValue = replaced;
    }
    }

    function lolwords() {
    if (!isEnabled()) return;
    try {
    console.time('lolwords');
    const {N, F, T} = GM_getValue(keys.lolwords, {N: [], F: [], T:[]}) || {};
    const newWords = [N, F, T].map(randomEntry).join(' ');
    console.log('NEW', newWords);
    replaceText(newWords);
    console.timeEnd('lolwords');
    } catch(e) {
    console.error('bork')
    console.error(e);
    }
    }


    GM_registerMenuCommand('lolwords', toggle);

    lolwords();