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