├── .gitignore ├── .prettierrc.json ├── LICENSE ├── README.md ├── annegate-krank-knarrenbauer.crx ├── content.js ├── manifest.json ├── options.html ├── options.js ├── package.json └── people.js /.gitignore: -------------------------------------------------------------------------------- 1 | # os stuff 2 | 3 | # npm stuff 4 | node_modules/ 5 | npm-debug.log 6 | package-lock.json 7 | 8 | # browser files 9 | web-ext-artifacts/ -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Viktor Seč 4 | Copyright (c) 2019 voodoocode 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pannengerät Krank-Knarrenbauer 2 | 3 | Browser extension, which replaces _Ammenschreck Krebs-Katzenjammer_ by silly names. 4 | Finds the combination of first name and last, or only last name. 5 | 6 | It is also possible to enable some other replacements for other persons in the extensions settings page. 7 | 8 | ## 🛠 Installation 9 | 10 | ### Firefox (>= 51) 11 | 12 | - Get the extension from the [Firefox Add-ons page](https://addons.mozilla.org/de-DE/firefox/addon/pannengerat-krank-knarrenbauer/) 13 | 14 | or 15 | 16 | - download the repo 17 | - open `about:debugging` 18 | - click "Load Temporary Add-on" 19 | - select any file in your extension's directory, e.g. `manifest.json` 20 | 21 | ### Chrome / Opera / Edge (>= 76) 22 | 23 | - download the repo 24 | - open `chrome://extensions/` (or `opera://extensions/` or `edge://extensions/`) 25 | - toggle "Developer mode" switch on 26 | - click button "Load unpacked" 27 | - choose the folder of the repo 28 | 29 | ## 🕰 Version history 30 | 31 | ### ✨ v0.4: Options page to toggle replacements and disabling other names 32 | 33 | By default this restores the original behavoiur of the extension, only replacing AKK. 34 | 35 | It disables the other replacements introduced in the previous version. 36 | You are now free to choose which replacements are enabled via the extensions settings page (Extras > Add-ons > Extensions > Choose the extenstion > switch to second tab). 37 | 38 | ### v0.3: Replacement of other people 39 | 40 | Other relevant people are being found and replaced with silly names. 41 | 42 | I added some logic/randomness wheter a combined name of first-, middle- and lastname is used _or_ a full nickname. 43 | 44 | ## ℹ️ Notice 45 | 46 | Use browser extensions at your own risk. 47 | 48 | Always reassure that the extension didn't edit any input fields or textareas in the browser, like Github or other sites where frontend editing is possible. 49 | 50 | I'm not responsible for possible wrong submitted data or reduced rendering performance. 51 | 52 | ## 🔀 Contribution 53 | 54 | Feel free to open pull requests with new names or persons. 55 | 56 | When adding new persons follow this format of the object: 57 | 58 | ```javascript 59 | { 60 | regexName: /(?:Vorname )?Nachname/gi, // looking for optional firstname, lastname not optional 61 | regexAbbrev: /VN/gi, 62 | substitutionsFirst: ["Vorname1"], 63 | substitutionsMiddle: ["Zwischenname1"], 64 | substitutionsLast: ["Nachname1"], // for hyphen "-" concatenated, names add those in front of the lastname 65 | substitutionsComplete: ["Spitzname1"], 66 | } 67 | ``` 68 | 69 | Please don't submit stuff, that is out of the borders of satire. 70 | 71 | ## 🔨 Development 72 | 73 | - first do: `npm install` 74 | - for development in Firefox run `npm run start:firefox` 75 | - the extension will reload if any source file changes 76 | - Before submitting code: 77 | please use Prettier by using `npx prettier --write .` 78 | 79 | ## 👍 Credits 80 | 81 | - Inspiration and original substitutions come from this [reddit.com/r/de thread](https://old.reddit.com/r/de/comments/cea32a/kleine_ansammlung_von_namensbausteinen_und/) 82 | 83 | - Forked from https://github.com/viktorsec/bumpercar-candysnatch 84 | - Or write an issue with suggestions and I'll add them later 85 | 86 | - Thanks to all the contributors, be it PRs, suggestions on reddit or whatever 87 | -------------------------------------------------------------------------------- /annegate-krank-knarrenbauer.crx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voodoocode/pannengeraet-krank-knarrenbauer/e94de7d60f6bd9fdf41798acc2b128957563a116/annegate-krank-knarrenbauer.crx -------------------------------------------------------------------------------- /content.js: -------------------------------------------------------------------------------- 1 | const getRandomEntry = (entries) => 2 | entries[Math.floor(Math.random() * entries.length)]; 3 | 4 | const pageHtml = document.getElementsByTagName("html")[0].innerHTML; 5 | 6 | let getting = chrome.storage.sync.get("settings", (res)=> { 7 | doReplacements(res) 8 | }); 9 | 10 | function doReplacements(storage) { 11 | let settings_persons; 12 | 13 | if (storage.settings) { 14 | settings_persons = JSON.parse(storage.settings); 15 | } else { 16 | settings_persons = { 17 | "person-0": "on", 18 | }; 19 | 20 | var json = JSON.stringify(settings_persons); 21 | chrome.storage.sync.set({ 22 | settings: json, 23 | }); 24 | } 25 | 26 | for (const person of people) { 27 | if ([person.id] in settings_persons) { 28 | if ( 29 | (person.regexName !== null && pageHtml.match(person.regexName)) || 30 | (person.regexAbbrev !== null && pageHtml.match(person.regexAbbrev)) 31 | ) { 32 | const elements = document.getElementsByTagName("*"); 33 | 34 | for (const element of elements) { 35 | const tagName = element.tagName.toLowerCase(); 36 | if (tagName === "textarea") continue; 37 | if (tagName === "input") continue; 38 | if (element.hasAttribute("contentEditable")) continue; 39 | 40 | for (const node of element.childNodes) { 41 | if (node.nodeType === 3) { 42 | const replacementComplete = 43 | getRandomEntry(person.substitutionsComplete) + " "; 44 | 45 | //default is complete names 46 | let usedReplacement = replacementComplete; 47 | 48 | //if first and last names exist, by chance a combined name may used 49 | if ( 50 | person.substitutionsFirst.length && 51 | person.substitutionsLast.length 52 | ) { 53 | const replacementCombiName = 54 | getRandomEntry(person.substitutionsFirst) + 55 | " " + 56 | getRandomEntry(person.substitutionsMiddle) + //middle is optional 57 | "" + 58 | getRandomEntry(person.substitutionsLast) + 59 | " "; 60 | 61 | usedReplacement = 62 | Math.random() > 0.5 63 | ? replacementCombiName 64 | : replacementComplete; 65 | } 66 | 67 | const text = node.nodeValue; 68 | const replacedText = text 69 | .replace(person.regexName, usedReplacement) 70 | .replace(person.regexAbbrev, usedReplacement); 71 | 72 | if (replacedText !== text) { 73 | element.replaceChild( 74 | document.createTextNode(replacedText), 75 | node 76 | ); 77 | } 78 | } 79 | } 80 | } 81 | } 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "name": "Pannengerät Trumpf Knarrenbauer", 4 | "description": "Replaces Annegret Kramp-Karrenbauer with silly names", 5 | "version": "0.4.2", 6 | "content_scripts": [ 7 | { 8 | "matches": ["*://*/*"], 9 | "js": ["people.js", "content.js"], 10 | "run_at": "document_end" 11 | } 12 | ], 13 | "options_ui": { 14 | "page": "options.html" 15 | }, 16 | "permissions": ["storage"], 17 | "browser_specific_settings": { 18 | "gecko": { 19 | "id": "{c8bae626-a662-43bc-966b-c432ab4f74c7}" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 | Please select which replacements should be enabled: 15 |
16 | 17 |
18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /options.js: -------------------------------------------------------------------------------- 1 | function saveOptions(e) { 2 | e.preventDefault(); 3 | 4 | var formData = new FormData(document.querySelector("form")); 5 | var object = {}; 6 | formData.forEach(function (value, key) { 7 | object[key] = value; 8 | }); 9 | var json = JSON.stringify(object); 10 | 11 | chrome.storage.sync.set({ 12 | settings: json, 13 | }); 14 | } 15 | 16 | function restoreOptions() { 17 | function setCurrentChoice(result) { 18 | let persons; 19 | 20 | if (result.settings) { 21 | persons = JSON.parse(result.settings); 22 | } else { 23 | //default: start with 0 enabled 24 | persons = { 25 | "person-0": "on", 26 | }; 27 | 28 | var json = JSON.stringify(persons); 29 | chrome.storage.sync.set({ 30 | settings: json, 31 | }); 32 | } 33 | 34 | document.querySelectorAll(".checkbox").checked = false; 35 | 36 | for (const key in persons) { 37 | document.querySelector(`[name="${key}"]`).checked = true; 38 | } 39 | } 40 | 41 | let getting = chrome.storage.sync.get("settings", (res)=> { 42 | setCurrentChoice(res); 43 | }); 44 | } 45 | 46 | function loadPeople() { 47 | for ([index, person] of people.entries()) { 48 | { 49 | var input = document.createElement("input"); 50 | input.type = "checkbox"; 51 | input.className = "checkbox"; 52 | input.id = `check-${index}`; 53 | input.name = `person-${index}`; 54 | 55 | var label = document.createElement("label"); 56 | label.for = `check-${index}`; 57 | label.innerText = person.regexName + ""; 58 | 59 | var div = document.createElement("div"); 60 | div.appendChild(input); 61 | div.appendChild(label); 62 | 63 | document.querySelector("#settings").appendChild(div); 64 | } 65 | } 66 | 67 | restoreOptions(); 68 | 69 | document.querySelector("form").addEventListener("submit", saveOptions); 70 | } 71 | 72 | document.addEventListener("DOMContentLoaded", loadPeople); 73 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "annegate-krank-knarrenbauer", 3 | "description": "Browser extension, which replaces *Ammenschreck Krebs-Katzenjammer* and other politicians by silly names.", 4 | "version": "0.4.2", 5 | "main": "content.js", 6 | "scripts": { 7 | "start:firefox": "web-ext run --source-dir ./", 8 | "build": "web-ext build --overwrite-dest" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/voodoocode/pannengeraet-krank-knarrenbauer.git" 13 | }, 14 | "author": "voodoocode", 15 | "license": "MIT", 16 | "bugs": { 17 | "url": "https://github.com/voodoocode/pannengeraet-krank-knarrenbauer/issues" 18 | }, 19 | "homepage": "https://github.com/voodoocode/pannengeraet-krank-knarrenbauer#readme", 20 | "dependencies": {}, 21 | "devDependencies": { 22 | "prettier": "2.2.1", 23 | "web-ext": "6.1.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /people.js: -------------------------------------------------------------------------------- 1 | const people = [ 2 | { 3 | id: "person-0", 4 | regexName: /(?:Annegret )?Kramp[ -]Karrenbauer/gi, 5 | regexAbbrev: /\bAKK\b(?![ -]47)/gi, 6 | substitutionsFirst: [ 7 | "Aalgerät", 8 | "Abendbrot", 9 | "Abfluggate", 10 | "Abgeweht", 11 | "Abhörgerät", 12 | "Affenzeh", 13 | "Aggressiv", 14 | "Akazienfleck", 15 | "Aknecreme", 16 | "Algensee", 17 | "Allesgeht", 18 | "Alleskleb", 19 | "Allesweg", 20 | "Alter Met", 21 | "Altgewebt", 22 | "Ammenschreck", 23 | "Ammoniak", 24 | "Ampelgrät", 25 | "Ampferbeet", 26 | "Ananasbeet", 27 | "Angedreht", 28 | "Angedreht", 29 | "Angelgrät", 30 | "Angerät", 31 | "Angriffskrieg", 32 | "Ankerbett", 33 | "Annegate", 34 | "Annegret", 35 | "Annektiert", 36 | "Annregret", 37 | "Apfelmet", 38 | "Apfeltee", 39 | "Arbeitsamt", 40 | "Armeegebet", 41 | "Armgedreht", 42 | "Arschgeweih", 43 | "Assizeh", 44 | "Astverdreht", 45 | "Atemgerät", 46 | "Aufgedreht", 47 | "Ausgelebt", 48 | "Ballergret", 49 | "Bannegret", 50 | "Pannengerät", 51 | "Pansensalat", 52 | "Panzergret", 53 | "Stoßgebet", 54 | "Un-Fair Trade", 55 | "Undefined", 56 | "Windgedreht", 57 | "Windverweht", 58 | ], 59 | substitutionsMiddle: [ 60 | "Band", 61 | "Ganz", 62 | "Hanf", 63 | "Harz", 64 | "Kampf", 65 | "Kann", 66 | "Kant", 67 | "Katz", 68 | "Kein", 69 | "Kennt", 70 | "Klamm", 71 | "Klang", 72 | "Klein", 73 | "Klotz", 74 | "Klump", 75 | "Kommt", 76 | "Kotz", 77 | "Krabbe", 78 | "Kramp", 79 | "Krampf", 80 | "Kran", 81 | "Krank", 82 | "Kranz", 83 | "Krebs", 84 | "Krupp", 85 | "Land", 86 | "Lanz", 87 | "Mampf", 88 | "Pfand", 89 | "Pflanz", 90 | "Punk", 91 | "Rang", 92 | "Sand", 93 | "Schrank", 94 | "Tand", 95 | "Tank", 96 | "Trump", 97 | "Trumpf", 98 | "Wand", 99 | ], 100 | substitutionsLast: [ 101 | //combined lastnames now need a dash upfront 102 | "-Akkuschrauber", 103 | "-Flaschenknauser", 104 | "-Gartenlaube", 105 | "-Gassenhauer", 106 | "-Harkenklauber", 107 | "-Haubentaucher", 108 | "-Kackebauer", 109 | "-Kackenkarrer", 110 | "-Kalterschauer", 111 | "-Kamelraucher", 112 | "-Kamillenbrauer", 113 | "-Kampfhubschrauber", 114 | "-Kapillarenkalker", 115 | "-Karatehauer", 116 | "-Kardinalvertrauer", 117 | "-Karottenbauer", 118 | "-Karpfenkauer", 119 | "-Karrenbauer", 120 | "-Karrenklauer", 121 | "-Kastratenkrauler", 122 | "-Katerflauer", 123 | "-Katzenjammer", 124 | "-Katzenkrauler", 125 | "-Katzenmiauer", 126 | "-Keilerhauer", 127 | "-Klammerkauer", 128 | "-Klausverhauer", 129 | "-Klimperpower", 130 | "-Kliniktrauer", 131 | "-Kloakenrauer", 132 | "-Klosteinmauer", 133 | "-Knarrenbauer", 134 | "-Knotentauer", 135 | "-Koksanbauer", 136 | "-Kolabrauer", 137 | "-Kolibriklabauter", 138 | "-Konradadenauer", 139 | "-Koreamauer", 140 | "-Krakenkrauler", 141 | "-Kranbauer", 142 | "-Kreisbegatter", 143 | "-Krillverdauer", 144 | "-Krimkalauer", 145 | "-Kroatenlauer", 146 | "-Nasenklauer", 147 | "-Nervenklauer", 148 | "-Neunmalschlauer", 149 | "-Pfaffenhauer", 150 | "-Pfarrerklauer", 151 | "-Schinkenklauber", 152 | "-Schnakenfauna", 153 | "-Wackelbauchtier", 154 | "-Wannentaucher", 155 | "-Winterpflaume", 156 | ], 157 | substitutionsComplete: [ 158 | "AKK-47", 159 | "Büchsengretl", 160 | "CDUzi", 161 | "Granaten-Gretel", 162 | "Knarren-Greta", 163 | ], 164 | }, 165 | { 166 | id: "person-1", 167 | regexName: /(?:Olaf )?Scholz/gi, 168 | regexAbbrev: null, 169 | substitutionsFirst: ["Olaf"], 170 | substitutionsMiddle: [" "], 171 | substitutionsLast: ["Schulz"], 172 | substitutionsComplete: ["Giro Olaf", "Wumms-Olaf"], 173 | }, 174 | { 175 | id: "person-2", 176 | regexName: /(?:Andreas |Andi |Andy )?[S]{1}cheuer/gi, 177 | regexAbbrev: null, 178 | substitutionsFirst: ["Andi"], 179 | substitutionsMiddle: [" "], 180 | substitutionsLast: ["Bescheuert", "B. Scheuert"], 181 | substitutionsComplete: ["Roller-Andi"], 182 | }, 183 | { 184 | id: "person-3", 185 | regexName: /(?:Julia )?Klöckner/gi, 186 | regexAbbrev: null, 187 | substitutionsFirst: ["Julia"], 188 | substitutionsMiddle: [" "], 189 | substitutionsLast: [" von Nestlé"], 190 | substitutionsComplete: ["Die Weinkönigin"], 191 | }, 192 | { 193 | id: "person-4", 194 | regexName: /(?:Armin )?Laschet/gi, 195 | regexAbbrev: null, 196 | substitutionsFirst: ["Achim"], 197 | substitutionsMiddle: [" "], 198 | substitutionsLast: ["Laschet", "Lachet"], 199 | substitutionsComplete: ["Würfel-Armin"], 200 | }, 201 | { 202 | id: "person-5", 203 | regexName: /(?:Annalena )?Baerbock/gi, 204 | regexAbbrev: null, 205 | substitutionsFirst: ["Annalena"], 206 | substitutionsMiddle: [" "], 207 | substitutionsLast: ["Bärbaum"], 208 | substitutionsComplete: ["Die Annalena"], 209 | }, 210 | { 211 | id: "person-6", 212 | regexName: /(?:Angela )?Merkel/gi, 213 | regexAbbrev: null, 214 | substitutionsFirst: ["Angola"], 215 | substitutionsMiddle: [" "], 216 | substitutionsLast: ["Merkel"], 217 | substitutionsComplete: ["Mutti"], 218 | }, 219 | { 220 | regexName: /(?:Björn )?Höcke/gi, 221 | regexAbbrev: null, 222 | substitutionsFirst: ["Bernd"], 223 | substitutionsMiddle: [" "], 224 | substitutionsLast: ["Höcke"], 225 | substitutionsComplete: ["AfD-Onkel"], 226 | }, 227 | ]; 228 | --------------------------------------------------------------------------------