Created
January 3, 2026 11:37
-
-
Save neuhaus/f4d8f91639ba7dbf3119ada0d6a44550 to your computer and use it in GitHub Desktop.
User script for Violentmonkey / Tampermonkey / Greasemonkey to replace text
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript==( | |
| // @name Drumpf III | |
| // @match *://*/* | |
| // @grant none | |
| // @run-at document-end | |
| // @version 2.0 | |
| // @description Makes you feel better by replacing 'Trump' with 'Drumpf' (asynchronously for no slowdown). | |
| // ==/UserScript== | |
| (() => { | |
| const CHUNK_SIZE = 50; | |
| const queue = []; | |
| let processing = false; | |
| const RE = /\bTrump\b/g; | |
| function replaceInNode(textNode) { | |
| // Skip editable fields (contentEditable without a value is also covered) | |
| if (textNode.parentNode && textNode.parentNode.isContentEditable) return; | |
| if (textNode.parentNode && textNode.parentNode.matches?.('textarea, input')) return; | |
| const txt = textNode.nodeValue; | |
| if (txt && RE.test(txt)) { | |
| textNode.nodeValue = txt.replace(RE, 'Drumpf'); | |
| } | |
| } | |
| function processChunk() { | |
| if (queue.length === 0) { | |
| processing = false; | |
| return; | |
| } | |
| let i = 0; | |
| while (i < CHUNK_SIZE && queue.length) { | |
| const node = queue.shift(); | |
| if (node && node.parentNode) replaceInNode(node); | |
| i++; | |
| } | |
| setTimeout(processChunk, 0); // yield to UI thread | |
| } | |
| function enqueue(node) { | |
| queue.push(node); | |
| if (!processing) { | |
| processing = true; | |
| processChunk(); | |
| } | |
| } | |
| // Walk a subtree and enqueue all Text nodes | |
| function walkAndEnqueue(root) { | |
| // Do not descend into editable containers | |
| if (root.nodeType === Node.ELEMENT_NODE && root.isContentEditable) return; | |
| if (root.matches?.('textarea, input')) return; | |
| const walker = document.createTreeWalker( | |
| root, | |
| NodeFilter.SHOW_TEXT, | |
| null, | |
| false | |
| ); | |
| let n; | |
| while ((n = walker.nextNode())) enqueue(n); | |
| } | |
| const observer = new MutationObserver(mutations => { | |
| for (const m of mutations) { | |
| // 4a) New nodes added somewhere in the tree | |
| if (m.type === 'childList') { | |
| for (const added of m.addedNodes) { | |
| // If the added node itself is a Text node → enqueue directly | |
| if (added.nodeType === Node.TEXT_NODE) { | |
| enqueue(added); | |
| } else { | |
| // Normal DOM walk for the rest of the subtree | |
| walkAndEnqueue(added); | |
| } | |
| } | |
| } | |
| } | |
| }); | |
| walkAndEnqueue(document.body); | |
| observer.observe(document.body, { | |
| childList: true, | |
| subtree: true | |
| }); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment