NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Stump Script // @description Make the web great again! // @author camconn // @version 1.0.10 // // @copyright 2016, Cameron Conn (https://www.camconn.cc/) // @license GPL-3.0 // @homepageURL https://github.com/camconn/stumpscript/ // @supportURL https://github.com/camconn/stumpscript/issues/ // @updateURL https://openuserjs.org/meta/camconn/Stump_Script.meta.js // // @include http* // @include https* // @include file* // // @namespace https://www.camconn.cc/ // @grant none // @run-at document-end // ==/UserScript== /* * Stump Script - Make the Web Great Again! * Copyright (C) 2016 Cameron Conn * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ "use strict"; /* * This is where the magic happens. * * For some Regexes (for example the two #makedonalddrumpfagain matches * in the first section below) there are two nearly-duplicate entries. * These are duplicated because twitter doesn't play nice with hashtags, * and doesn't include the hashtag in the *actual* text content, and * just shows it with some CSS trickery. */ var MATCHES = [ // Things cucks say (well, thats everything in this array, you get the idea) [/\bTrumpkin/gi, "Nimble Navigator"], [/\bDrumpf/gi, "The God-Emperor"], [/\bTrumpeteer/gi, "centipede"], [/\bTrumpies?/gi, "centipede"], [/\b(Donald )?Trump (Supporter|Fan)/gi, "Nimble Navigator"], [/\b\#makedonalddrumpfagain/gi, "#IAmACuck"], [/\bmakedonalddrumpfagain/gi, "IAmACuck"], [/\b\#NeverTrump/gi, "#IHateAmerica"], [/\bNeverTrump/gi, "IHateAmerica"], [/\b\#Dump(Trump|Drumpf?)/gi, "ImAChump"], [/\bDump(Trump|Drumpf?)/gi, "ImAChump"], // El Rato [/\bLyin.? Ted Cruz/gi, "The Lyin' Rat"], [/\bTed Cruz/gi, "El Rato"], [/\bcruz (supporter|fan)s?/gi, "Cruzcucks"], [/\b#TedCruz/gi, "#ElRato"], [/\bTedCruz/gi, "ElRato"], [/\b\#cruz2016/gi, "#ElRato2016"], [/\bcruz2016/gi, "ElRato2016"], [/\b\#choosecruz/gi, "#ZodiacKiller"], [/\bchoosecruz/gi, "ZodiacKiller"], [/\b\#cruzcrew/gi, "#RatAttack"], [/\bcruzcrew/gi, "RatAttack"], // Low Energy [/\b(Jeb|John Ellis) Bush/gi, "The Foolish Guac Merchant"], [/\bJeb\!?/gi, "Yeb!"], // Golly Gee Guy [/\bOhio Gov(ernor|\.?) (John )?Kasich/gi, "Golly Gee Guy"], [/\bJohn Kasich/gi, "Literally Who"], [/\bKasich/gi, "Cucksich"], // Rubot [/\bMarco Rubio/gi, "the Choke Artist"], [/\b(Candidate|Senator) (Marco )?Rubio/gi, "the Foolish Foam Boi"], [/\bRubio/gi, "Rubot"], // Bernouts [/\bBernie ([\'\"]?Bernard[\'\"]? )?Sanders/gi, "Bolshevik Bernie"], [/\bBernie[\- ]?Bros/gi, "Berniebots"], [/\bBernie[\- ]?Bro/gi, "Berniebot"], // Yes, its a duplicate but it matches the plural form! [/\bFeel(ing)? The Bern/gi, "Help Im Berning"], [/\bFree College/gi, "Free Coll Edge"], [/\b\#FeelTheBern/gi, "#HelpImBerning"], [/\bFeelTheBern/gi, "HelpImBerning"], [/\b\#Bernie2016/gi, "#BernVictim"], [/\bBernie2016/gi, "BernVictim"], [/\b\#Birdie2016/gi, "#Bernout"], [/\bBirdie2016/gi, "Bernout"], // $hillary [/\bHRC/gi, "$hillary"], [/\bHillary (D\.? |Diane )?(R\.? |Rodham )?Clinton/gi, "Shillary"], [/\bHillary (Clinton(\'s)? )?(Super)?PAC/gi, "Shillary's PAC"], [/\bSecretary (Hillary )?Clinton/gi, "Secretary Shillary"], [/\b\#Hillary(Clinton)?/gi, "#Shillary"], [/\bHillary(Clinton?)/gi, "Shillary"], // British Cuck [/\bJohn Oliver/gi, "Current Year Man"], [/\bBecause It'?s [0-2][0-9]{3}\b/gi, "Because Current Year"], [/\bIt'?s [1-2][0-9]{3}\b/gi, "It's Current Year"], // Establishment [/\bGOP( Establishment|e)/gi, "cuckservatives"], [/r\/conservative/gi, "r/cuckservative"], // [new RegExp(/\bground[- ]game/gi, "corruption"], // Conflicts too much with muh sports [/\bGlenn (Lee )?Beck/gi, "Glenn Cuck"], [/\bGlennBeck/gi, "GlennCuck"], [/TheBlaze/gi, "TheCuck"], // Terrorism/Islam [/\b(ISIS|ISL\b|ISIL\b|Daesh|(Islamic State of Iraq and the Levant))/gi, "Islamic State of Idiotic Savages"], [/\bSyrian (migrant|refugee|immigrant)/gi, "Syrian totally-not-terrorist"], [/\bReligion of Peace/gi, "Religion of Pieces"], [/\b(Kaaba|Kabah)/gi, "stupid rock"], [/\bmosque/gi, "terrorist recruiting center"], // Bad Guys [/\b(George )?Soros/gi, "the Sith Lord"], [/\bTrump protesters/gi, "some losers"], [/\b(Mark )?Zuckerberg/gi, "Mark Cuckerberg"], [/\bundocumented (citizen|worker)/gi, "snake"]]; // CASES constants - these represent what the source text's casing is. var UNKNOWN = 0; // UnKnOwN (or any other variation) var UPPER = 1; // UPPERCASE var LOWER = 2; // lowercase var TITLE = 3; // TitleCase /** * Get the Title Case for a string. * * Modified from http://stackoverflow.com/a/196991 * * @param {text} The string to convert to Title Case. * @return The string in Title Case. */ function titleCase(text) { return text.replace(/([^\W_]+[^\s-]*) */g, function (s) { return s.charAt(0).toUpperCase() + s.substr(1).toLowerCase(); }); } /** * Determine the type of capitalization a string uses. Returns one of the * case constants available. * * @param {text} The string to detect the casing of. * @return What type of casing the text uses (see CASES constants for information). */ function caseType(text) { var possibleUppercase = true; var possibleLowercase = true; var possibleTitlecase = true; var prevChar = null; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = text[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var c = _step.value; if (/[A-Za-z]/.test(c)) { var isUpper = c === c.toUpperCase(); if (isUpper) possibleLowercase = false;else possibleUppercase = false; if (prevChar === null || /[\s\-_\+\.]/.test(prevChar)) { if (!isUpper) possibleTitlecase = false; } else if (isUpper) { possibleTitlecase = false; } } prevChar = c; } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } if (possibleTitlecase) return TITLE; if (possibleLowercase) return LOWER; if (possibleUppercase) return UPPER; return UNKNOWN; } /** * Helper method for string replacement according to capitalization type. * * @param {original} The original text to be replaced. * @param {replacement} The replacement text. * @return The replacement text in the appropriate casing. */ function replaceAppropriateCase(original, replacement) { var sourceCase = caseType(original); switch (sourceCase) { case UPPER: return replacement.toUpperCase(); case LOWER: return replacement.toLowerCase(); case TITLE: return titleCase(replacement); case UNKNOWN: return replacement; } } /** * Perform a "walk" through all of the children of this node and apply the * necessary text substitution. * * Adapted from Mozilla Developer Network: * https://developer.mozilla.org/en-US/docs/Web/API/Node#Browse_all_child_nodes * * @param {oParent} The Node to walk through. */ function walk(oParent) { for (var node = oParent.firstChild; node; node = node.nextSibling) { walk(node); }if (oParent.nodeType === Node.TEXT_NODE) { var initialText = oParent.textContent + ""; if (initialText.length > 0) { var newText = transformText(initialText); if (initialText !== newText) { oParent.textContent = newText; } } } } /** * Replaces the text in text with more *appropriate* text. * @param {text} The text to transform. * @return The transformed text. */ function transformText(text) { // console.log("before: " + text) var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { var _loop = function _loop() { var pair = _step2.value; text = text.replace(pair[0], function (r) { return replaceAppropriateCase(r, pair[1]); }); }; for (var _iterator2 = MATCHES[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { _loop(); } // console.log("after: " + text) } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } return text; } // Cache any nodes we modify so we don't accidentially mess with nodes twice var nodeCache = []; /** * Callback for modern MutationObserver API. This is used as implementing the * newer DOM4 standards. */ function mutationHandler(mutations) { mutations.forEach(function (m) { // Don't modify a node twice in a row var index = nodeCache.indexOf(m); if (index !== -1) { nodeCache.splice(index, 1); return; } walk(m.target); m.addedNodes.forEach(function (n) { nodeCache.push(n);walk(n); }); // Store this node in temporary cache nodeCache.push(m.target); }); } if (MutationObserver) { var observer = new MutationObserver(mutationHandler); observer.observe(window.document.body, { childList: true, attributes: true }); } else { // shim code in case DOM4 APIs aren't supported window.document.body.addEventListener("DOMNodeInserted", function (ev) { walk(ev.target); }, false); } var oldTitle = window.document.title + ""; window.document.title = transformText(oldTitle); walk(window.document.body);