Interesting Wikipedia userscript

Does evil things to wikipedia articles

当前为 2024-01-28 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Interesting Wikipedia userscript
  3. // @namespace roxwize
  4. // @match *://*.wikipedia.org/*
  5. // @grant none
  6. // @version 1.3.1
  7. // @author roxwize
  8. // @description Does evil things to wikipedia articles
  9. // @license GPL-3.0-or-later
  10. // @homepageURL https://greasyfork.org/en/scripts/479665-interesting-wikipedia-userscript
  11. // ==/UserScript==
  12.  
  13. const images = [
  14. "https://cdn.discordapp.com/attachments/862154953295396884/1173367948249927720/anim9.gif",
  15. "https://media.tenor.com/MBkt9DXPaUYAAAAd/ddostumka%C3%A7.gif",
  16. "https://media.discordapp.net/attachments/836622752735690792/892543216514117662/ezgif.com-gif-maker.gif",
  17. "https://media.discordapp.net/attachments/203413905865834496/625861266988335115/flanders_fucking_dies.gif",
  18. "https://media.discordapp.net/attachments/1114953713153486968/1166939127942500523/vivaldi10807_1698290357.gif",
  19. "https://media.discordapp.net/attachments/816133227508662292/1172693664171040829/anim2.gif",
  20. "https://media.discordapp.net/attachments/972366344983031838/1028865879343120454/Ut3Yx38fp4.gif",
  21. "https://media.discordapp.net/attachments/600630338795995136/1144468663467003924/Untitled-2.gif",
  22. "https://media.tenor.com/C8aEDgYC1y4AAAAd/aphex-twin-come-to-daddy.gif",
  23. "https://cdn.discordapp.com/attachments/1099111307380277331/1125686366668341298/download_8.gif",
  24. "https://media.discordapp.net/attachments/846920921599836180/983072664023363655/FILE0319.gif",
  25. "https://media.tenor.com/4i00_7OrisUAAAAC/sandoz-canu-sandoz.gif",
  26. "https://media.tenor.com/hrNDlz8yD3UAAAAC/harley-quinn-margot-robbie.gif",
  27. "https://cdn.discordapp.com/attachments/800044401501798403/942883938978914354/caption-17-1.gif",
  28. "https://media.tenor.com/s1w-Sc5ahpEAAAAd/paz-pazzin.gif",
  29. "https://media.discordapp.net/attachments/907403580011601931/908189601888354384/image0-2.gif",
  30. "https://media.discordapp.net/attachments/862154953295396884/1168344353014562816/anim8.gif",
  31. "https://cdn.discordapp.com/attachments/862154953295396884/1173407665305690172/1D1cW2Ntai.gif",
  32. "https://media.tenor.com/dWS427mpAZAAAAAd/secu-rity-meme.gif",
  33. "https://media.tenor.com/XUFDsSt48GYAAAAd/eminem.gif",
  34. "https://media.tenor.com/QgphpoWrjaAAAAAd/retro-retro-dev.gif",
  35. "https://media.tenor.com/uSo4lQu9dVgAAAAC/homer-smile.gif",
  36. "https://media.tenor.com/QMpyBmPBlhoAAAAC/wtf-roblox.gif",
  37. "https://media.tenor.com/47hdAGX-uAwAAAAC/charjabug-weegee.gif",
  38. "https://cdn.discordapp.com/attachments/862154953295396884/1176264387883974716/IMG_7766.gif",
  39. "https://cdn.discordapp.com/attachments/862154953295396884/1176264385795207300/5D5A47EA-FD2A-4F96-AAE0-EC24DFF85E9E.gif",
  40. "https://cdn.discordapp.com/attachments/862154953295396884/1176264384977326221/253mof.gif",
  41. "https://media.discordapp.net/attachments/847904283142651964/910315898575917076/allo_balling.gif",
  42. "https://media.tenor.com/HcQ44DFmPccAAAAC/video-gaming.gif",
  43. "https://media.tenor.com/79djON9nNhMAAAAC/0001.gif",
  44. "https://media.tenor.com/U2ilbVQ-DAwAAAAC/jameis-winston-crab.gif",
  45. "https://media.discordapp.net/attachments/810597667091644427/1023288366059499620/ezgif.com-gif-maker.gif",
  46. "https://media.discordapp.net/attachments/862154953295396884/1188233304370065509/GwvzAonc89.gif",
  47. "https://media.discordapp.net/attachments/831015313365270528/1146956684707762197/sad.gif",
  48. "https://media.discordapp.net/attachments/862154953295396884/1186850455419101244/farmer.gif",
  49. "https://media.discordapp.net/attachments/862154953295396884/1177824053713703013/CiEIEGrarE.gif",
  50. "https://media.discordapp.net/attachments/862154953295396884/1183912305885466767/KADLBkzqrL.gif",
  51. "https://media.discordapp.net/attachments/1054852621191610499/1055176904153497631/1671563280861164.gif",
  52. "https://cdn.discordapp.com/attachments/862154953295396884/1200958970924384266/markiplier-dancing.gif",
  53. "https://cdn.discordapp.com/attachments/862154953295396884/1200958971352195245/mechanic.gif",
  54. "https://cdn.discordapp.com/attachments/862154953295396884/1200958970173604052/gotohell.gif",
  55. "https://cdn.discordapp.com/attachments/862154953295396884/1200958971788406834/not_cooking_shit.gif",
  56. "https://cdn.discordapp.com/attachments/862154953295396884/1200958968655261818/kitty_kitty_cat_cat.gif",
  57. "https://media.discordapp.net/attachments/1082130348143562823/1156916220663189564/62CF58C8-B646-4E87-A197-46F168459DB7.gif",
  58. "https://c.tenor.com/jZlLTydic2UAAAAd/tenor.gif",
  59. "https://media.discordapp.net/attachments/1167563705299501126/1200199638486110338/90rSldDEdY.gif",
  60. "https://media.discordapp.net/attachments/936813623538499595/955285532152311878/speed.gif",
  61. "https://c.tenor.com/KE0dcwJ1VS4AAAAC/tenor.gif"
  62. ];
  63. const imageWhitelist = new Array(images.length).fill(-1).map((_, i) => i);
  64. const style = `
  65. #god{position:fixed;bottom:1em;left:1em;background:rgba(50,40,80,0.8);padding:1em;color:white;}
  66. #gantzgraf{position:fixed;bottom:1em;right:1em;background:rgba(50,40,80,0.8);padding:1em;color:white;text-align:right;}
  67. #gantzgraf .option{display:flex;align-items:center;gap:1em;}
  68. #gantzgraf .option label{flex-grow:1;text-align:right;}
  69. #giflist-root{position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(245,248,242,0.85);padding:1rem;overflow-y:auto;box-sizing:border-box;}
  70. #giflist-root-header{height:10%;border-bottom:1px solid rgba(0,0,0,0.2);overflow-x:hidden;margin-bottom:1rem;}
  71. #giflist-root-header h1{font-size:300%;border-bottom:0;margin:0;font-weight:bold;}
  72. #giflist-root-list{display:grid;grid-template-columns:1fr 1fr 1fr 1fr 1fr 1fr;grid-auto-rows:minmax(120px,1fr);gap:2%;}
  73. #giflist-root-list div{display:flex;align-items:center;justify-content:center;background-color:rgba(255,255,255,0.7);border:1px solid rgba(0,0,0,0.25);border-radius:10px;padding:6px;}
  74. #giflist-root-list div:hover{background-color:rgba(180,180,180,0.7);cursor:pointer;}
  75. #giflist-root-list div img{width:80%;max-height:80%;}
  76. #giflist-root-list div:hover img{filter:grayscale(1);}
  77. span.small{display:block;font-size:smaller;}
  78. span.sub{display:block;color:rgba(0,0,0,0.7);font-style:italic;}
  79. .iwusbox a{color:white;font-weight:bold;text-decoration:underline;}
  80. `;
  81. let words = [];
  82.  
  83. const config = {
  84. styleModifications: {
  85. label: "Modify page style",
  86. current: false
  87. },
  88. linkModifications: {
  89. label: "Modify links",
  90. current: true
  91. },
  92. figCaptions: {
  93. label: "Modify image captions",
  94. current: false
  95. },
  96. textualModifications: {
  97. label: "Screw up text nodes",
  98. current: true
  99. }
  100. };
  101.  
  102. function modify(e, f) {
  103. const n = e.childNodes;
  104. for (let d of n) {
  105. if (d.nodeType === Node.TEXT_NODE) f(d);
  106. else modify(d, f);
  107. }
  108. }
  109.  
  110. const chance = () => Math.random() * 100;
  111. const rand = (a) => a[Math.floor(Math.random() * a.length)];
  112. const screwup = (str) => {
  113. const s = str.split("");
  114. let o = "";
  115. let i = 0;
  116. for (let l of s) {
  117. if (chance() > 60) continue;
  118. if (chance() < 20 && s[i+1]) o += s[i+1];
  119. if (chance() > 80 && s[i-1]) o += s[i-1];
  120. if (chance() < 80) o += l;
  121. if (chance() > 90) o += l;
  122. i++;
  123. }
  124. return o;
  125. }
  126.  
  127. (function() {
  128. // Add userscript styles
  129. const stylesheet = document.createElement("style");
  130. stylesheet.innerHTML = style;
  131. document.head.appendChild(stylesheet);
  132. // Root element.
  133. const rootEl = document.createElement("div");
  134. rootEl.id = "god";
  135. rootEl.classList.add("iwusbox");
  136. rootEl.innerHTML = `<span class="small">iwus v${GM.info.script.version} | <a href="https://greasyfork.org/en/scripts/479665-interesting-wikipedia-userscript" data-immune="true">greasyfork</a></span><input type="text" id="bregex" placeholder="regex" /><br/><input type="text" id="breplacement" placeholder="replacement" /><br/><button id="bok" style="cursor:pointer;">ok</button>`;
  137. document.body.appendChild(rootEl);
  138. document.getElementById("bok").addEventListener("click", () => {
  139. words = [];
  140. const regexp = new RegExp(document.getElementById("bregex").value, "g");
  141. const replce = document.getElementById("breplacement").value;
  142. document.querySelectorAll(`p, ${config.figCaptions.current ? "figcaption," : ""} th, td, li, h1, h2, h3, h4, h5, h6`).forEach((e) => {
  143. modify(e, (node) => {
  144. node.textContent = node.textContent.replaceAll(regexp, replce); words.push(node.textContent);
  145. // == TEXTUAL MODIFICATIONS == //
  146. if (config.textualModifications.current) {
  147. if (chance() > 90) {
  148. node.textContent = node.textContent.replaceAll(/[aeiou]/g, "");
  149. } else if (chance() > 90) {
  150. node.textContent = screwup(node.textContent);
  151. }
  152. }
  153. });
  154. // == STYLE MODIFICATIONS == //
  155. if (config.styleModifications.current) {
  156. e.style.color = `hsl(${Math.round(Math.random()*360)} 50% 50%)`;
  157. if (chance() > 75) e.style.backgroundColor = `hsl(${Math.round(Math.random()*360)} 50% 50%)`;
  158. e.style.textDecoration = chance() > 70 ? "underline" : "normal";
  159. e.style.fontStyle = chance() > 70 ? "italic" : "normal";
  160. if (chance() > 30) {
  161. e.style.transform = `translate(${Math.random()*25}px, ${Math.random()*50}px)`;
  162. } else {
  163. e.style.transform = `rotate(${Math.random()*5-2.5}deg)`;
  164. if (chance() > 45) {
  165. e.style.transform += ` scale(${Math.random()*2+0.5})`;
  166. }
  167. }
  168. e.style.fontSize = `${9 + Math.floor(Math.random()*10)}pt`;
  169. }
  170. });
  171. document.querySelectorAll("img").forEach((e) => {
  172. e.src = images[rand(imageWhitelist)];
  173. });
  174. // == LINK MODIFICATIONS == //
  175. if (config.linkModifications.current) {
  176. document.querySelectorAll("a").forEach((e) => {
  177. if (e.dataset.immune === "true") return;
  178. e.setAttribute("href", "https://en.wikipedia.org/wiki/Special:Random");
  179. modify(e, (node) => {
  180. e.dataset.original = node.textContent;
  181.  
  182. node.textContent = rand(words);
  183. let _t;
  184. e.addEventListener("mouseover", () => {
  185. _t = document.createElement("div");
  186. _t.innerHTML = `<a href="https://en.wikipedia.org/wiki/${e.dataset.original.replaceAll(/ /g,'_')}">${e.dataset.original}</a>`;
  187. _t.style = "display:inline;font-size:smaller;background-color:rgba(0,0,0,0.3);padding:0.25rem;margin:0.25rem;";
  188. e.appendChild(_t);
  189. });
  190. e.addEventListener("mouseout", () => {
  191. if (_t) _t.remove();
  192. });
  193. });
  194. });
  195. }
  196. });
  197. // Config options
  198. const configEl = document.createElement("div");
  199. configEl.id = "gantzgraf";
  200. configEl.classList.add("iwusbox");
  201. for (let [k, v] of Object.entries(config)) {
  202. const e = document.createElement("div");
  203. e.classList.add("option");
  204. e.innerHTML = `<label for="bo-${k}">${v.label}</label>`;
  205. let o;
  206. if (typeof v.current === "number" && v.vals != undefined) {
  207. o = document.createElement("div");
  208. o.style = "display:block;"
  209. v.vals.forEach((el, i) => {
  210. const vO = document.createElement("input");
  211. vO.type = "radio";
  212. vO.name = `bo-${k}`;
  213. vO.id = `ro-${k}-${i}`;
  214. vO.value = i.toString();
  215. o.appendChild(vO);
  216. const vL = document.createElement("label");
  217. vL.setAttribute("for", vO.id);
  218. vL.innerHTML = el;
  219. vL.style.display = "block";
  220. o.appendChild(vL);
  221. });
  222. } else {
  223. o = document.createElement("input");
  224. o.type = "checkbox";
  225. o.checked = config[k].current;
  226. o.addEventListener("input", () => {
  227. config[k].current = o.checked;
  228. });
  229. }
  230. o.name = `bo-${k}`;
  231. o.id = o.name;
  232. e.appendChild(o);
  233. configEl.appendChild(e);
  234. }
  235. // Giflist opener
  236. const openGifListLink = document.createElement("a");
  237. openGifListLink.innerHTML = "open the gif list";
  238. openGifListLink.href = "javascript:void(0);"
  239. openGifListLink.onclick = renderGifList;
  240. openGifListLink.dataset.immune = true;
  241. configEl.appendChild(openGifListLink);
  242. document.body.appendChild(configEl);
  243. })();
  244.  
  245. // Maybe run automatically on page load
  246. function renderGifList() {
  247. // Root div
  248. const rootDiv = document.createElement("div");
  249. rootDiv.id = "giflist-root";
  250. rootDiv.innerHTML = `
  251. <div id="giflist-root-header">
  252. <h1>Giflist</h1><span class="sub">Click on a gif to remove it | <a href="javascript:document.getElementById('giflist-root').remove()" data-immune="true">close</a></span>
  253. </div>
  254. `;
  255. const rootList = document.createElement("div");
  256. rootList.id = "giflist-root-list";
  257. // Individual gif elements
  258. let i = 0;
  259. for (let gif of images) {
  260. const gifDiv = document.createElement("div");
  261. gifDiv.id = `iwusdiv-${i}`;
  262. gifDiv.dataset.index = i;
  263. gifDiv.innerHTML = `<img src="${gif}" alt="no.${i}">`;
  264. gifDiv.addEventListener("click", () => {
  265. if (imageWhitelist.length === 1) {
  266. alert("No");
  267. return;
  268. }
  269. imageWhitelist.splice(imageWhitelist.indexOf(parseInt(gifDiv.dataset.index)), 1);
  270. gifDiv.remove();
  271. });
  272. rootList.appendChild(gifDiv);
  273. i++;
  274. }
  275. rootDiv.appendChild(rootList);
  276. document.body.appendChild(rootDiv);
  277. }