Last active
June 18, 2026 13:32
-
-
Save Dobby233Liu/e852d272eef8411c2337edfba9f6da27 to your computer and use it in GitHub Desktop.
OwOiki: OwOifies most English-language Wikimedia Foundation wikis
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 OwOiki | |
| // @version 0.2.11 | |
| // @icon data:image/gif;base64,R0lGODdhQABAAPQeAP///xwcHPr6+uvr65GRkeHh4fDw8G1tbcbGxjo6OlRUVEZGRjExMSQkJICAgGNjY/f397GxsSgoKO/v76WlpXl5eS0tLbu7u8rKytra2s/Pz9XV1YmJiZmZmQICAr+/vywAAAAAQABAAAAF/yAgjmRpnmiqrmzrvnAsz3Rt33iu7/EQEQRKgScqUICRQe2yaCQSTodBZ3AwnNfFZUZoKCKZAuIQOExwE/IBUchEFA0CBEYpD0l1s81ApsxHBX0vGwwKdyUdAQ42DgEdJwVwGy5kCCmVNBgNeicIEgctGpsCKYQPpDIHFpOXDRosHAEYK42zMZqLKrgrBgkKf6WKMrW8CglTwXLFxzC9v7CyKl2W0K+DjqHYKVaHutoudR8tBQy5JwbGZyzk5i3c4wvP5wmnLc7Ay8gsD8zznPsL9BWr10KVOhMTElRAxaJCv3UKGdJ6WCLhQhfv4LWbeLBiRIwMlGh8YRBFL4LQRP9C3KiCn8AS6UCq5GXhIot720JSsjBTxQAG/3yWkxbtZkx78V6i2PCtU9MUP22649kinFBQLDwpczGtYIOeJvh1Q9H12lao9CSesOrzqAucKiI8nScPhVYZZU26JRqhpQRWMEzhKyH3EdIFGew2YAlyC6SkLz5sApsB8owB8RJXxASjywHNRZpQyyQBMYkMZM6+7ZIgSAQrFhyb+DAaAAJxTstF+AFFdWBVEoKvaSUyqtoRGoALt2VDzIU7BsACKCyCbUVkzsfuyDsC514RmnwTQS7MxLS7JoiNR/EdADkFkhAWOr6+eoC+6T14YEy9PqS5tgVQFCIBgObfaeWVkIGGgAaOUEGBB57QHhllqJVQXRGOkEht0ykSC37kGZYhglL9dIyJMz2o3YhiaXiffVu9R1+GF2gj4wjxdSjbiCT8VE8staH3wFc8njDkADeScKSPRa4lC5CzKYJek6eVNoqRWKzYJAH67UjCBfqJRyU5Os3zF5V2cVjCbWi26eabcMYp55xvhgAAOw== | |
| // @author Liu "Dobby233Liu" Wenyuan | |
| // @namespace https://dobby233liu.github.io | |
| // @description OwOifies most English-language Wikimedia Foundation wikis | |
| // @match *://www.wikipedia.org/* | |
| // @match *://en.wikipedia.org/* | |
| // @match *://en.m.wikipedia.org/* | |
| // @match *://simple.wikipedia.org/* | |
| // @match *://simple.m.wikipedia.org/* | |
| // @match *://test.wikipedia.org/* | |
| // @match *://test2.wikipedia.org/* | |
| // @match *://test.m.wikipedia.org/* | |
| // @match *://test2.m.wikipedia.org/* | |
| // @match *://www.wiktionary.org/* | |
| // @match *://en.wiktionary.org/* | |
| // @match *://en.m.wiktionary.org/* | |
| // @match *://simple.wiktionary.org/* | |
| // @match *://simple.m.wiktionary.org/* | |
| // @match *://*.mediawiki.org/* | |
| // @match *://meta.wikimedia.org/* | |
| // @match *://wikitech.wikimedia.org/* | |
| // @match *://*.wikidata.org/* | |
| // @match *://commons.wikimedia.org/* | |
| // @match *://test-commons.wikimedia.org/* | |
| // @match *://species.wikimedia.org/* | |
| // @match *://en.wikibooks.org/* | |
| // @match *://wikisource.org/* | |
| // @match *://en.wikisource.org/* | |
| // @match *://en.wikiquote.org/* | |
| // @match *://en.wikinews.org/* | |
| // @match *://en.wikiversity.org/* | |
| // @match *://beta.wikiversity.org/* | |
| // @match *://en.wikivoyage.org/* | |
| // @match *://incubator.wikimedia.org/* | |
| // @match *://outreach.wikimedia.org/* | |
| // @match *://wikimania.wikimedia.org/* | |
| // @match *://www.wikifunctions.org/* | |
| // @match *://foundation.wikimedia.org/* | |
| // @match *://*.beta.wmflabs.org/* | |
| // @run-at document-end | |
| // @grant GM_addElement | |
| // @grant GM_addStyle | |
| // @require https://code.jquery.com/jquery-3.7.1.slim.min.js | |
| // @require https://unpkg.com/arrive@2.5.2/minified/arrive.min.js | |
| // @connect https://fonts.googleapis.com | |
| // @connect https://fonts.gstatic.com | |
| // @updateURL https://gist.githubusercontent.com/Dobby233Liu/e852d272eef8411c2337edfba9f6da27/raw/owo.user.js | |
| // @downloadURL https://gist.githubusercontent.com/Dobby233Liu/e852d272eef8411c2337edfba9f6da27/raw/owo.user.js | |
| // @supportURL https://gist.github.com/Dobby233Liu/e852d272eef8411c2337edfba9f6da27#comments | |
| // ==/UserScript== | |
| /*// @grant unsafeWindow*/ | |
| // the following blob is owoify-js.umd.development.js built from: | |
| // https://github.com/Dobby233Liu/owoify-js/tree/2.0.0%2Bowoiki-patch5 | |
| (function (global, factory) { | |
| typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
| typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
| (global = global || self, factory(global['@dobby233liu/owoify-js'] = {})); | |
| }(this, (function (exports) { 'use strict'; | |
| function _unsupportedIterableToArray(o, minLen) { | |
| if (!o) return; | |
| if (typeof o === "string") return _arrayLikeToArray(o, minLen); | |
| var n = Object.prototype.toString.call(o).slice(8, -1); | |
| if (n === "Object" && o.constructor) n = o.constructor.name; | |
| if (n === "Map" || n === "Set") return Array.from(o); | |
| if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); | |
| } | |
| function _arrayLikeToArray(arr, len) { | |
| if (len == null || len > arr.length) len = arr.length; | |
| for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; | |
| return arr2; | |
| } | |
| function _createForOfIteratorHelperLoose(o, allowArrayLike) { | |
| var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; | |
| if (it) return (it = it.call(o)).next.bind(it); | |
| if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { | |
| if (it) o = it; | |
| var i = 0; | |
| return function () { | |
| if (i >= o.length) return { | |
| done: true | |
| }; | |
| return { | |
| done: false, | |
| value: o[i++] | |
| }; | |
| }; | |
| } | |
| throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); | |
| } | |
| function searchValueContainsReplacedWords(searchValue, replaceValue, replacedWords) { | |
| return Array.from(replacedWords).some(function (word) { | |
| return word.replace(searchValue, replaceValue) !== word; | |
| }); | |
| } | |
| var Word = /*#__PURE__*/function () { | |
| function Word(word) { | |
| this.word = word.trim(); | |
| this.replacedWords = new Set(); | |
| } | |
| var _proto = Word.prototype; | |
| _proto.replace = function replace(searchValue, replaceValue, replaceReplacedWords) { | |
| if (replaceReplacedWords === void 0) { | |
| replaceReplacedWords = false; | |
| } | |
| if (!replaceReplacedWords && searchValueContainsReplacedWords(searchValue, replaceValue, this.replacedWords)) return this; | |
| var replacingWord = this.word.replace(searchValue, replaceValue).trim(); | |
| var matchArray = this.word.match(searchValue); | |
| var replacedWords = matchArray !== null ? Array.from(matchArray).map(function (x) { | |
| return x.replace(x, replaceValue); | |
| }) : []; | |
| if (replacingWord !== this.word) { | |
| for (var _iterator = _createForOfIteratorHelperLoose(replacedWords), _step; !(_step = _iterator()).done;) { | |
| var word = _step.value; | |
| this.replacedWords.add(word); | |
| } | |
| this.word = replacingWord; | |
| } | |
| return this; | |
| }; | |
| _proto.toString = function toString() { | |
| return this.word; | |
| }; | |
| return Word; | |
| }(); | |
| /** | |
| * Interleaves 2 arrays | |
| * @internal | |
| * @param a first array | |
| * @param b second arry | |
| * @returns array with interleaved elements | |
| */ | |
| function interleaveArrays(a, b) { | |
| var arr = []; | |
| var observed = a; | |
| var other = b; | |
| var temp = null; | |
| while (observed.length > 0) { | |
| arr.push(observed.shift()); | |
| temp = observed; | |
| observed = other; | |
| other = temp; | |
| } | |
| if (other.length > 0) arr.push.apply(arr, other); | |
| return arr; | |
| } | |
| var faces = ['(・`ω´・)', ';;w;;', 'owo', 'UwU', '>w<', '^w^', '(* ^ ω ^)', '(⌒ω⌒)', 'ヽ(*・ω・)ノ', '(o´∀`o)', '(o・ω・o)', '\(^▽^)/']; | |
| var Map_O_To_OwO = function Map_O_To_OwO(input) { | |
| return input.replace(/o/g, function () { | |
| return Math.round(Math.random()) ? 'owo' : 'o'; | |
| }); | |
| }; | |
| var Map_Ew_To_UwU = function Map_Ew_To_UwU(input) { | |
| return input.replace(/ew/g, 'uwu'); | |
| }; | |
| var Map_Hey_To_Hay = function Map_Hey_To_Hay(input) { | |
| return input.replace(/([Hh])ey/g, '$1ay'); | |
| }; | |
| var Map_Dead_To_Ded = function Map_Dead_To_Ded(input) { | |
| return input.replace(/Dead/g, 'Ded').replace(/dead/g, 'ded'); | |
| }; | |
| var Map_N_Vowel_T_To_Nd = function Map_N_Vowel_T_To_Nd(input) { | |
| return input.replace(/n[aeiou]*t/g, 'nd'); | |
| }; | |
| var Map_Read_To_Wead = function Map_Read_To_Wead(input) { | |
| return input.replace(/Read/g, 'Wead').replace(/read/g, 'wead'); | |
| }; | |
| var Map_Brackets_To_StarTrails = function Map_Brackets_To_StarTrails(input) { | |
| return input.replace(/[({<]/g, '。・:*:・゚★,。・:*:・゚☆').replace(/[)}>]/g, '☆゚・:*:・。,★゚・:*:・。'); | |
| }; | |
| var Map_PeriodCommaExclamationSemicolon_To_Kaomojis = function Map_PeriodCommaExclamationSemicolon_To_Kaomojis(input) { | |
| return input.replace(/[.,](?![0-9])/g, function () { | |
| return ' ' + faces[Math.floor(Math.random() * faces.length)]; | |
| }).replace(/[!;]+/g, function () { | |
| return ' ' + faces[Math.floor(Math.random() * faces.length)]; | |
| }); | |
| }; | |
| var Map_That_To_Dat = function Map_That_To_Dat(input) { | |
| return input.replace(/that/g, 'dat').replace(/That/g, 'Dat'); | |
| }; | |
| var Map_Th_To_F = function Map_Th_To_F(input) { | |
| return input.replace(/[Tt]h(?![Ee])/g, 'f').replace(/TH(?!E)/g, 'F'); | |
| }; | |
| var Map_Le_To_Wal = function Map_Le_To_Wal(input) { | |
| return input.replace(/le$/g, 'wal'); | |
| }; | |
| var Map_Ve_To_We = function Map_Ve_To_We(input) { | |
| return input.replace(/ve/g, 'we').replace(/Ve/g, 'We'); | |
| }; | |
| var Map_Ry_To_Wwy = function Map_Ry_To_Wwy(input) { | |
| return input.replace(/ry/g, 'wwy'); | |
| }; | |
| var Map_ROrL_To_W = function Map_ROrL_To_W(input) { | |
| return input.replace(/(?:r|l)/g, 'w').replace(/(?:R|L)/g, 'W'); | |
| }; | |
| var Map_Ll_To_Ww = function Map_Ll_To_Ww(input) { | |
| return input.replace(/ll/g, 'ww'); | |
| }; | |
| var Map_VowelOrRExceptO_L_To_Wl = function Map_VowelOrRExceptO_L_To_Wl(input) { | |
| return input.replace(/[aeiur]l$/g, 'wl').replace(/[AEIUR]([lL])$/g, 'W$1'); | |
| }; | |
| var Map_Old_To_Owld = function Map_Old_To_Owld(input) { | |
| return input.replace(/([Oo])ld/g, '$1wld').replace(/OLD/g, 'OWLD'); | |
| }; | |
| var Map_Ol_To_Owl = function Map_Ol_To_Owl(input) { | |
| return input.replace(/([Oo])l/g, '$1wl').replace(/OL/g, 'OWL'); | |
| }; | |
| var Map_LOrR_O_To_Wo = function Map_LOrR_O_To_Wo(input) { | |
| return input.replace(/[lr]o/g, 'wo').replace(/[LR]([oO])/g, 'W$1'); | |
| }; | |
| var Map_SpecificConsonants_O_To_Letter_And_Wo = function Map_SpecificConsonants_O_To_Letter_And_Wo(input) { | |
| return input.replace(/([bcdfghjkmnpqstxyz])o/g, '$1wo').replace(/([BCDFGHJKMNPQSTXYZ])([oO])/g, function (_, m1, m2) { | |
| return m1 + (m2.toUpperCase() === m2 ? 'W' : 'w') + m2; | |
| }); | |
| }; | |
| var Map_VOrW_Le_To_Wal = function Map_VOrW_Le_To_Wal(input) { | |
| return input.replace(/[vw]le/g, 'wal'); | |
| }; | |
| var Map_Fi_To_Fwi = function Map_Fi_To_Fwi(input) { | |
| return input.replace(/([Ff])i/g, '$1wi').replace(/FI/g, 'FWI'); | |
| }; | |
| var Map_Ver_To_Wer = function Map_Ver_To_Wer(input) { | |
| return input.replace(/([Vv])er/g, 'wer'); | |
| }; | |
| var Map_Poi_To_Pwoi = function Map_Poi_To_Pwoi(input) { | |
| return input.replace(/([Pp])oi/g, '$1woi'); | |
| }; | |
| var Map_SpecificConsonants_Le_To_Letter_And_Wal = function Map_SpecificConsonants_Le_To_Letter_And_Wal(input) { | |
| return input.replace(/([DdFfGgHhJjPpQqRrSsTtXxYyZz])le$/g, '$1wal'); | |
| }; | |
| var Map_Consonant_R_To_Consonant_W = function Map_Consonant_R_To_Consonant_W(input) { | |
| return input.replace(/([BbCcDdFfGgKkPpQqSsTtWwXxZz])r/g, '$1w'); | |
| }; | |
| var Map_Ly_To_Wy = function Map_Ly_To_Wy(input) { | |
| return input.replace(/ly/g, 'wy').replace(/Ly/g, 'Wy'); | |
| }; | |
| var Map_Ple_To_Pwe = function Map_Ple_To_Pwe(input) { | |
| return input.replace(/([Pp])le/g, '$1we'); | |
| }; | |
| var Map_Nr_To_Nw = function Map_Nr_To_Nw(input) { | |
| return input.replace(/([Nn])r/g, '$1w').replace(/NR/g, 'NW'); | |
| }; | |
| var Map_Mem_To_Mwem = function Map_Mem_To_Mwem(input) { | |
| return input.replace(/([Mm])em/g, '$1wem'); | |
| }; | |
| var Unmap_Nywo_To_Nyo = function Unmap_Nywo_To_Nyo(input) { | |
| return input.replace(/([Nn])ywo/g, '$1yo', true); | |
| }; | |
| var Map_Fuc_To_Fwuc = function Map_Fuc_To_Fwuc(input) { | |
| return input.replace(/([Ff])uc/g, '$1wuc'); | |
| }; | |
| var Map_Mom_To_Mwom = function Map_Mom_To_Mwom(input) { | |
| return input.replace(/([Mm])om/g, '$1wom'); | |
| }; | |
| var Map_Me_To_Mwe = function Map_Me_To_Mwe(input) { | |
| return input.replace(/^Me$/g, 'Mwe').replace(/^me$/g, 'mwe'); | |
| }; | |
| var Map_NVowel_To_Ny = function Map_NVowel_To_Ny(input) { | |
| return input.replace(/n([aeiou])/g, 'ny$1').replace(/N([aeiou])/g, 'Ny$1').replace(/N([AEIOU])/g, 'NY$1'); | |
| }; | |
| var Map_Ove_To_Uv = function Map_Ove_To_Uv(input) { | |
| return input.replace(/ove/g, 'uv').replace(/OVE/g, 'UV'); | |
| }; | |
| var Map_Haha_To_HehexD = function Map_Haha_To_HehexD(input) { | |
| return input.replace(/\b(ha|hah|heh|hehe)+\b/g, 'hehe xD'); | |
| }; | |
| var Map_The_To_Teh = function Map_The_To_Teh(input) { | |
| return input.replace(/\b([Tt])he\b/g, '$1eh'); | |
| }; | |
| var Map_You_To_U = function Map_You_To_U(input) { | |
| return input.replace(/\bYou\b/g, 'U').replace(/\byou\b/g, 'u'); | |
| }; | |
| var Map_Time_To_Tim = function Map_Time_To_Tim(input) { | |
| return input.replace(/\b([Tt])ime\b/g, '$1im'); | |
| }; | |
| var Map_Over_To_Owor = function Map_Over_To_Owor(input) { | |
| return input.replace(/([Oo])ver/g, '$1wor'); | |
| }; | |
| var Map_Worse_To_Wose = function Map_Worse_To_Wose(input) { | |
| return input.replace(/([Ww])orse/g, '$1ose'); | |
| }; | |
| var Map_Great_To_Gwate = function Map_Great_To_Gwate(input) { | |
| return input.replace(/([Gg])reat/g, '$1wate'); | |
| }; | |
| var Map_Aviat_To_Awiat = function Map_Aviat_To_Awiat(input) { | |
| return input.replace(/([Aa])viat/g, '$1wiat'); | |
| }; | |
| var Map_Dedicat_To_Deditat = function Map_Dedicat_To_Deditat(input) { | |
| return input.replace(/([Dd])edicat/g, '$1editat'); | |
| }; | |
| var Map_Remember_To_Rember = function Map_Remember_To_Rember(input) { | |
| return input.replace(/([Rr])emember/g, '$1ember'); | |
| }; | |
| var Map_When_To_Wen = function Map_When_To_Wen(input) { | |
| return input.replace(/([Ww])hen/g, '$1en'); | |
| }; | |
| var Map_Frightened_To_Frigten = function Map_Frightened_To_Frigten(input) { | |
| return input.replace(/([Ff])righten(ed)*/g, '$1rigten'); | |
| }; | |
| var Map_Meme_To_Mem = function Map_Meme_To_Mem(input) { | |
| return input.replace(/Meme/g, 'mem').replace(/Mem/g, 'Mem'); | |
| }; | |
| var Map_Feel_To_Fell = function Map_Feel_To_Fell(input) { | |
| return input.replace(/^([Ff])eel$/g, '$1ell'); | |
| }; | |
| var specificWordMappingArray = [Map_Fuc_To_Fwuc, Map_Mom_To_Mwom, Map_Time_To_Tim, Map_Me_To_Mwe, Map_Over_To_Owor, Map_Ove_To_Uv, Map_Haha_To_HehexD, Map_The_To_Teh, Map_You_To_U, Map_Read_To_Wead, Map_Worse_To_Wose, Map_Great_To_Gwate, Map_Aviat_To_Awiat, Map_Dedicat_To_Deditat, Map_Remember_To_Rember, Map_When_To_Wen, Map_Frightened_To_Frigten, Map_Meme_To_Mem, Map_Feel_To_Fell]; | |
| var uvuMappingArray = [Map_O_To_OwO, Map_Ew_To_UwU, Map_Hey_To_Hay, Map_Dead_To_Ded, Map_N_Vowel_T_To_Nd]; | |
| var uwuMappingArray = [Map_Brackets_To_StarTrails, Map_PeriodCommaExclamationSemicolon_To_Kaomojis, Map_That_To_Dat, Map_Th_To_F, Map_Le_To_Wal, Map_Ve_To_We, Map_Ry_To_Wwy, Map_ROrL_To_W]; | |
| var owoMappingArray = [Map_NVowel_To_Ny, Map_Ll_To_Ww, Map_VowelOrRExceptO_L_To_Wl, Map_Old_To_Owld, Map_Ol_To_Owl, Map_LOrR_O_To_Wo, Map_SpecificConsonants_O_To_Letter_And_Wo, Map_VOrW_Le_To_Wal, Map_Fi_To_Fwi, Map_Ver_To_Wer, Map_Poi_To_Pwoi, Map_SpecificConsonants_Le_To_Letter_And_Wal, Map_Consonant_R_To_Consonant_W, Map_Ly_To_Wy, Map_Ple_To_Pwe, Map_Nr_To_Nw, Map_Mem_To_Mwem, Unmap_Nywo_To_Nyo]; | |
| /** | |
| * owoify everything | |
| * @param v word to owoify | |
| * @param level level of owo-ness. (owo -> uwu -> uvu) | |
| */ | |
| function owoify(v, level) { | |
| if (level === void 0) { | |
| level = 'owo'; | |
| } | |
| var whitespace = v.split(/[^\s]+/g); | |
| var words = v.split(/\s+/g).map(function (x) { | |
| return new Word(x); | |
| }); | |
| words = words.map(function (x) { | |
| specificWordMappingArray.reduce(function (word, f) { | |
| return f(word); | |
| }, x); | |
| switch (level) { | |
| case 'uvu': | |
| uvuMappingArray.reduce(function (word, f) { | |
| return f(word); | |
| }, x); | |
| case 'uwu': | |
| uwuMappingArray.reduce(function (word, f) { | |
| return f(word); | |
| }, x); | |
| case 'owo': | |
| owoMappingArray.reduce(function (word, f) { | |
| return f(word); | |
| }, x); | |
| } | |
| return x; | |
| }); | |
| return interleaveArrays(whitespace, words).join(''); | |
| } | |
| function uwuify(v) { | |
| return owoify(v, 'uwu'); | |
| } | |
| function uvuify(v) { | |
| return owoify(v, 'uvu'); | |
| } | |
| exports.default = owoify; | |
| exports.uvuify = uvuify; | |
| exports.uwuify = uwuify; | |
| Object.defineProperty(exports, '__esModule', { value: true }); | |
| }))); | |
| "use strict"; | |
| /* global $ */ | |
| const ME = "[OwOiki]" | |
| const DEBUG = false // will make noise in console | |
| const _owoify = window["@dobby233liu/owoify-js"].default | |
| const siteNameMap = { | |
| "Wikipedia": "Wikipewdiaw", | |
| "Wiktionary": "Wiktionyary", | |
| "Wiktionyawwy": "Wiktionyary", | |
| "Wiktiowonyawwy": "Wiktionyary", | |
| "Wikiquote": "Wikiquowote", | |
| "Wikinews": "Wikinyews", | |
| "Wikinyuwus": "Wikinyews", | |
| "Wikivoyage": "Wikivowoyage", | |
| "Wikisource": "Wikiswowuce", | |
| "Wikibooks": "Wikibowoks", | |
| "Wikimedia Commons": "Wikimedia Cwommwons", | |
| "Wikimedia Cwowommwons": "Wikimedia Cwommwons", | |
| } | |
| function mapSiteNames(x) { | |
| for (let [k, v] of Object.entries(siteNameMap)) { | |
| x = x.replaceAll(k, v) | |
| } | |
| return x | |
| } | |
| function owoify(...args) { | |
| return mapSiteNames(_owoify(...args)) | |
| } | |
| function donateSpaces(x, y, dbg = false) { | |
| dbg = dbg && DEBUG | |
| const a = y.match(/^(\s*)/), b = y.match(/(\s*)$/); | |
| const c = x.match(/^(\s*)/), d = x.match(/(\s*)$/); | |
| const fore = (c[1].length < a[1].length ? a[1] : c[1]), end = (d[1].length < b[1].length ? b[1] : d[1]) | |
| if (dbg) { | |
| console.log(ME, "dono spaces", x, y) | |
| console.log(ME, a, b, c, d) | |
| console.log(ME, "fore", fore.length) | |
| console.log(ME, "end", end.length) | |
| } | |
| return fore + x.trim() + end | |
| } | |
| function owoifyPreserveSpaces(x, style) { | |
| return donateSpaces(owoify(x, style), x) | |
| } | |
| if (DEBUG && unsafeWindow) { | |
| unsafeWindow.owoiki_dbg_owoify = owoify | |
| unsafeWindow.owoiki_dbg_owoifyPreserveSpaces = owoifyPreserveSpaces | |
| } | |
| function owoifyTextnodes(array, style, afs=false, dbg=false) { | |
| dbg = dbg && DEBUG | |
| function addForeSpace(x) { | |
| return (x.match(/^[,./;'[\]=+_\-`~!@#$%^&*]+$/) ? " " : "") + x | |
| } | |
| let text = [ | |
| ...array.map((_, x) => x.data ? (afs ? addForeSpace(x.data) : x.data) : "") | |
| ].join("\u0000") | |
| if (dbg) console.log(ME, "otn", array, text) | |
| text = owoify(text.trim() /* mitigation for #footer-info-lastmod */, style) | |
| let res = text.split("\u0000") | |
| if (dbg) console.log(ME, "end", text, res) | |
| array.each(function(i, node) { | |
| let newContent = donateSpaces(res[i], (afs ? addForeSpace(node.data) : node.data), dbg) | |
| if (node.data == "Wiktionary,") newContent += " " | |
| node.data = newContent /*+ (newContent.trim() != "" ? ` [${style}]` : "")*/ | |
| }) | |
| } | |
| function owoifyAttr(i, j, style) { | |
| if (i.attr(j)) { | |
| i.attr(j, owoifyPreserveSpaces(i.attr(j), style)) | |
| } | |
| } | |
| const bodyHasClass = x => document.body.classList.contains(x) | |
| let isMWSite = bodyHasClass("mediawiki") | |
| let isWiktionary = location.host.endsWith(".wiktionary.org") | |
| let isMailingList = location.host == "lists.wikimedia.org" | |
| function shouldntFabricateTitle() { | |
| let ns = $(".mw-page-title-namespace") | |
| return isWiktionary && (ns.length <= 0 || ns[0].textContent == "Citations") | |
| } | |
| function selfNChild(x, suff=true) { | |
| if (Array.isArray(x)) { return x.map(y => selfNChild(y, suff)).join(suff ? " " : ", ") } | |
| return `${x}, ${x} *${suff ? "," : ""}` | |
| } | |
| const selfNChildI = x => selfNChild(x, false) | |
| // https://en.wiktionary.org/wiki/Module:scripts/data | |
| // small subset otherwise performance impact | |
| const wiktionaryScriptClassesBasic = [ | |
| "Latn", "Latnx", "Latf", "Latg", "pjt-Latn", | |
| "Arab", "Cyrl", | |
| "IPA" | |
| ] | |
| // FIXME: are we banning children wiki names or language names | |
| let bannedElems = "script, style," | |
| bannedElems += `${selfNChildI("pre:not(blockquote.templatequote > pre)")}, ${selfNChildI("code")}, ${selfNChildI("tt")}, ${selfNChildI("math")}, ` | |
| // obvious case: https://en.wikipedia.org/wiki/Treasure_of_the_Rudras | |
| bannedElems += selfNChild("[lang]:not([lang=\"en\"]):not([lang=\"en-x-rtl\"]):not(.wbmi-entityview-emptyCaption, html)") | |
| bannedElems += selfNChildI("html[lang]:not([lang=\"en\"]):not([lang=\"en-x-rtl\"]) head") // TODO: hreflang | |
| if (isMWSite) { | |
| bannedElems += "," | |
| bannedElems += `#pt-userpage *, #pt-userpage-2 *, .mw-input-wpusername, ${selfNChildI(".mw-userlink")},` | |
| bannedElems += ".wikipedia-languages-langs *, .skin-love .i18n a:not([title=\"Help:i18n\"]), .mainpage-languages *, .interlanguage-link *, .mw-AnonymousI18N-picker, .mw-pt-languages-list *," | |
| bannedElems += "#main_page_mp-mp tbody > tr:nth-child(4) > td .extiw," // what the fuck | |
| bannedElems += ".wikibase-title-id," | |
| bannedElems += ".lemma-widget_lemma-value, .lemma-widget_lemma-language," | |
| if (shouldntFabricateTitle()) { | |
| bannedElems += "title, .mw-page-title-main," /* FIXME: deal with title again? */ | |
| } | |
| bannedElems += `#searchform ${selfNChild(".cdx-search-result-title")}` | |
| if (isWiktionary) { | |
| bannedElems += wiktionaryScriptClassesBasic.map(x => selfNChild(`.${x}`)).join(" ") | |
| } | |
| /*if (isWiktionary) { | |
| if ($(".mw-page-title-namespace").length <= 0) { | |
| bannedElems += "h2 > .mw-headline, .toclevel-1 *," | |
| } | |
| }*/ // language | |
| // why the fuck does this not have a script class | |
| // this won't have a effect on the word in Octwober 13, 2023 WOTD's *description* too | |
| bannedElems += selfNChild("#WOTD-rss-title") | |
| bannedElems += selfNChild([".e-quotation", ".h-usage-example"]) // NTS: wiktionary | |
| bannedElems += ".diff-context *, .diff-deletedline *, .diff-addedline *, .wikEdDiffFragment *," | |
| bannedElems += ".mw-mmv-filename," | |
| bannedElems += ".mw-mmv-download-select-menu *, .mw-mmv-download-image-size, .mw-mmv-download-image-size-name," // FIXME: ???? | |
| bannedElems += ".mw-mmv-download-dialog .cdx-dialog__body .cdx-text-input," | |
| bannedElems += ".mw-ext-score *," // avoid destroying lilypod code alt text | |
| bannedElems += ".wikiEditor-ui-toolbar .page-characters span[role=\"option\"]," | |
| bannedElems += `${selfNChildI("#mw-search-DYM-suggestion")}, ` | |
| bannedElems += `${selfNChildI(".texhtml")}, ${selfNChildI(".mwe-math-element")}, ${selfNChildI(".mwe-math-fallback-image-inline")}` | |
| } else if (isMailingList) { | |
| bannedElems += ", .list-address" | |
| } else { | |
| bannedElems += ", .central-featured-lang *, .langlist *, #jsLangLabel, #searchLanguage *" | |
| } | |
| bannedElems += `, ${selfNChildI(".notranslate")}, ${selfNChildI('[translate="no"]')}` | |
| let uvuElems = "#UQ0_5 *, .phabricator-standard-page-footer, .phabricator-standard-page-footer *" // phab only | |
| if (isMWSite) { | |
| uvuElems = "#mp-topbanner *, .wd-mp-overlay *, .mf-tagline-title," | |
| uvuElems += "#main_page_mp-mp tbody > tr:nth-child(1) *," // again, what the fuck | |
| uvuElems += "#mf-main > :nth-child(2) *," // nvm this one is worse | |
| uvuElems += ".page-Wikiversity_Main_Page .mw-parser-output > div:nth-child(1) > div > div > div:nth-child(1) *," // even worse | |
| uvuElems += ".main-banner .main-welcome *," // thanks Wikispecies | |
| uvuElems += ".uls-menu" | |
| } | |
| let uwuElems = "" // "title" | |
| if (isMWSite) { | |
| // uwuElems += "," | |
| // uwuElems += `${selfNChildI("#firstHeading")}, .wikibase-title-label,` | |
| uwuElems += "#siteSub," | |
| uwuElems += "#footer-info *," | |
| uwuElems += ".mw-portlet *, .portal *, .pBody *, #p-personal *, .vector-page-tools *, #footer-places *" | |
| uwuElems += ".navbar *," | |
| uwuElems += "#simpleSearch *" | |
| } | |
| if (DEBUG) { | |
| console.log(ME, "rules - banned:", bannedElems) | |
| console.log(ME, "uvu:", uvuElems) | |
| console.log(ME, "uwu:", uwuElems) | |
| } | |
| async function injectStyles() { | |
| /* TODO: consider adding configuration support */ | |
| const sansSerif = "Comic Neue", | |
| serifHeading = /*Indie Flower,Fuzzy Bubbles,Chilanka*/"Chilanka", | |
| serifQuote = /*Handlee,Klee One,Edu NSW ACT Foundation*/"Klee One"; | |
| await addGoogleFonts([serifHeading, sansSerif, serifQuote]) | |
| GM_addStyle(` | |
| ${location.hostname.endsWith(".beta.wmflabs.org") ? "" : ` | |
| ${wiktionaryScriptClassesBasic.map(x => selfNChildI(`.${x}`)).join(", ")}, #WOTD-rss-title, .owoiki-wkt-word { | |
| font-family: sans-serif; | |
| font-size: 0.95rem; | |
| } | |
| :root { | |
| --OwOiki-serif-heading-font: '${serifHeading}','Linux Libertine','Georgia','Times','Source Serif Pro',serif; | |
| } | |
| .mw-body h1, .mw-body-content h1, | |
| .mw-body-content h2, .mw-parser-output h2, | |
| .skin-love #mw-content-text h1, .skin-love #mw-content-text h2, | |
| h2 > .mw-headline[data-mw-thread-id] { | |
| font-family: var(--OwOiki-serif-heading-font); | |
| } | |
| /* https://meta.wikimedia.org/wiki/WMDE_Technical_Wishes/styles.css */ | |
| .rootpage-WMDE_Technical_Wishes .mw-parser-output h2 { | |
| font-family: var(--OwOiki-serif-heading-font); | |
| font-weight: normal; | |
| } | |
| .rootpage-WMDE_Technical_Wishes .mw-parser-output h2.h2-black { | |
| font-weight: bold; | |
| } | |
| ${shouldntFabricateTitle() ? ` | |
| .mw-page-title-main, | |
| .mw-first-heading > span:only-child { | |
| font-family: 'Linux Libertine','Georgia','Times',serif; | |
| } | |
| /* hax mucho */ | |
| .mw-body h1 { | |
| line-height: 1.2; | |
| } | |
| ` : ""} | |
| .wikibase-title-id { font-family: sans-serif; } | |
| .skin-fandomdesktop .mw-headline { | |
| font-family: '${serifHeading}',var(--theme-page-headings-font),rubik,helvetica,arial,sans-serif; | |
| } | |
| #siteSub, .mw-editsection, .mw-indicators, .mw-body-content, .skin-love #mw-content-text, .skin-love #mw-content-text div, .skin-love #mw-content-text li, | |
| /* !important minus !important */ | |
| .diff-editfont-sans-serif .diff-context, .diff-editfont-sans-serif .diff-addedline, .diff-editfont-sans-serif .diff-deletedline, | |
| .ext-discussiontools-init-section-bar, .ext-discussiontools-init-section-subscribeButton, | |
| .mw-mmv-main, .cnotice-message, #cnotice-translation-link, select, input[type="button"], | |
| #mw-toc-heading, | |
| .page-Wikifunctions_Main_Page .mw-parser-output .mainpage_header h1, | |
| body.skin-fandomdesktop, | |
| .oo-ui-window-body, | |
| .mw-kartographer-attribution, .leaflet-right.leaflet-bottom .leaflet-control.leaflet-control-attribution, | |
| .mw-headline .reference, | |
| .oo-ui-toolGroup-tools, .ve-init-target, | |
| .mwe-popups-extract | |
| { | |
| font-family: '${sansSerif}',sans-serif; | |
| } | |
| body:not(.skin-vector-2022) #siteSub, body:not(.skin-vector-2022) .mw-body-content, | |
| .mw-mmv-main, .mwe-popups-extract, | |
| .ve-init-target | |
| { | |
| font-size: 1.12em; | |
| } | |
| .skin-love #mw-content-text { font-size: 1em; } | |
| .diff-editfont-sans-serif .diff-addedline, .diff-editfont-sans-serif .diff-deletedline, .diff-editfont-sans-serif .diff-context { | |
| font-size: 0.95rem; | |
| } | |
| .mw-parser-output #mapbanner-container, .mw-parser-output .jcarousel-wrapper { font-size: 0.875rem; } | |
| .skin-fandomdesktop .toc { font-size: 0.875rem; } | |
| .mw-parser-output .inline-quote-talk, .mw-parser-output .example { font-family: '${serifQuote}',Georgia,"DejaVu Serif",serif !important; font-weight: 600; } | |
| `} | |
| ${location.hostname.match("test2?\.(?:m\.)?wikipedia\.org") || location.hostname == "test-commons.wikimedia.org" ? ` | |
| .skin-vector #p-logo:before { | |
| content: "${owoify("TESTSITE", "uvu")}"; | |
| } | |
| .skin-vector-2022 .mw-logo:before { | |
| content: "${owoify("TESTSITE", "uvu")}"; | |
| } | |
| ` : ""} | |
| ${location.hostname.endsWith(".beta.wmflabs.org") ? ` | |
| .skin-theme-clientpref-day .mw-logo::before { | |
| content: "${owoify("Beta-Cluster", "uvu")}"; | |
| } | |
| ` : ""} | |
| footer#wikigg-footer { justify-content: space-evenly; } | |
| footer#wikigg-footer > div { margin: 0 !important; width: fit-content !important; } | |
| `) | |
| } | |
| async function addGoogleFonts(families) { | |
| let url = new URL("https://fonts.googleapis.com/css2") | |
| for (let i of families) { | |
| if (i && i != "") { | |
| url.searchParams.append("family", i) | |
| } | |
| } | |
| url.searchParams.set("display", "swap") | |
| GM_addElement(document.body, "link", { | |
| rel: "stylesheet", | |
| href: url.href | |
| }) | |
| } | |
| function textIsLink(text, link){ | |
| if (link == text || decodeURIComponent(link) == text) return true | |
| let linkObj | |
| try { linkObj = new URL(link, location.href) } catch(e) { return false } | |
| if (linkObj.href == text) return true | |
| let protocolShort = linkObj.protocol.substring(0, linkObj.protocol.lastIndexOf(":")) | |
| let strippedLink, stripStep1 = function stripStep1(removeTrailingSlashes){ | |
| strippedLink = linkObj.href | |
| if (removeTrailingSlashes) strippedLink = strippedLink.replace(/(\/)(?=\?|$)/, "") | |
| strippedLink = strippedLink.substring(protocolShort.length) | |
| if (strippedLink == text) return true | |
| if (strippedLink.startsWith(":")) { | |
| strippedLink = strippedLink.substring((":").length) | |
| if (strippedLink == text) return true | |
| } | |
| strippedLink = strippedLink.substring(("//").length) | |
| if (strippedLink == text) return true | |
| } | |
| let r = stripStep1(); if (typeof r == "boolean") return r; | |
| if (linkObj.search != "") { | |
| linkObj.search = "" | |
| let r = stripStep1(); if (typeof r == "boolean") return r; | |
| } | |
| if (linkObj.pathname.endsWith("/")) { | |
| let r = stripStep1(true); if (typeof r == "boolean") return r; | |
| } | |
| if (linkObj.pathname == "/" && (linkObj.host == text || linkObj.hostname == text)) { | |
| return true | |
| } | |
| return false | |
| } | |
| let cacheIsInCategoryIndex = $(".mw-page-title-namespace")[0] && $(".mw-page-title-namespace")[0].textContent == "Category" | |
| let categoryPage = ".mw-category-group > ul > li > a" | |
| async function owoifyElements(selector = "*") { | |
| $(selector).each((_, i) => { | |
| i = $(i) | |
| let cateLinkQualify1 = isWiktionary && cacheIsInCategoryIndex && i.is(categoryPage) | |
| if (i.is(bannedElems) || cateLinkQualify1) { | |
| let failed = true | |
| if (i.is("title")) { | |
| let newTitle = i.text() | |
| let newTitleSpl = newTitle.split(" - ") | |
| if (newTitleSpl.length >= 2) { | |
| newTitleSpl[newTitleSpl.length - 1] = owoify(newTitleSpl[newTitleSpl.length - 1], "uvu") | |
| newTitle = newTitleSpl.join(" - ") | |
| } | |
| newTitle = mapSiteNames(newTitle) | |
| i.text(newTitle) | |
| } | |
| if (cateLinkQualify1) { | |
| if (!i.text().includes(":")) { | |
| i.addClass("owoiki-wkt-word") | |
| } else if (!i.text().includes("Citations:")) { | |
| failed = false | |
| } | |
| } | |
| if (failed) { | |
| return | |
| } | |
| } | |
| // https://commons.wikimedia.org/wiki/File:ISS055-E-84821_-_View_of_Earth.jpg#P7482, https://en.wikipedia.org/wiki/LilyPond | |
| if (i.is("a") && textIsLink(i.text().trim(), i.attr("href"))) { | |
| return | |
| } | |
| let fuckupStyle = (uvuElems && i.is(uvuElems)) ? "uvu" : ((uwuElems && i.is(uwuElems)) ? "uwu" : "owo") | |
| let doNotObfValue = i.is("input, textarea") | |
| if (!doNotObfValue) { | |
| owoifyTextnodes( | |
| i.contents() | |
| .filter(function(){ return this.nodeType === Node.TEXT_NODE }) | |
| , fuckupStyle, i.is("#mp-topbanner *")) | |
| } | |
| owoifyAttr(i, "title", fuckupStyle) | |
| owoifyAttr(i, "alt", fuckupStyle) | |
| owoifyAttr(i, "placeholder", fuckupStyle) | |
| owoifyAttr(i, "label", fuckupStyle) | |
| owoifyAttr(i, "aria-label", fuckupStyle) | |
| if (!doNotObfValue) { | |
| owoifyAttr(i, "value", fuckupStyle) | |
| } | |
| if (DEBUG) { | |
| i[0].dataset.owoifyTouched = i[0].dataset.owoifyTouched ? parseInt(i[0].dataset.owoifyTouched) + 1 : 1 | |
| i[0].dataset.owoifyTouchedTime = +new Date() | |
| } | |
| }) | |
| } | |
| async function owoifyElementAndChildrenAuto(el) { | |
| try { | |
| await owoifyElements([el, ...el.find("*")]) | |
| } catch(e) { | |
| console.error(ME, e) | |
| throw e | |
| } | |
| } | |
| function catchOnArrive(selector, readableType, opts={}, xtra) { | |
| if (DEBUG && !readableType) { | |
| console.warn(ME, `\`${selector}\`'s catchOnArrive entry should have a readable type explaination to assist debugging`) | |
| } | |
| $("body").arrive(selector, { existing: false, /*TODO*/ ...opts }, function(el) { | |
| if (DEBUG) { | |
| console.warn(ME, `caught you${readableType ? `, ${readableType}` : ""}!! (t=${el.dataset.owoifyTouched ?? 0}) >w< the conversion will take place shortly`, el) | |
| } | |
| el = $(el) | |
| owoifyElementAndChildrenAuto(el) | |
| if (xtra) { xtra(el) } | |
| }) | |
| } | |
| injectStyles() | |
| owoifyElements().catch(e => console.error(ME, e)) | |
| catchOnArrive("title", "Page title", { existing: false, fireOnAttributesModification: true }) | |
| if (isMWSite) { | |
| catchOnArrive(".mwe-popups", "page preview") | |
| catchOnArrive(".mw-notification-area", "OOUI notification") | |
| //catchOnArrive(".oo-ui-messageDialog-text", "OOUI message dialog") // FIXME | |
| catchOnArrive(".oo-ui-tabOptionWidget", "OOUI tab label") | |
| // caused very horrible WNR in Special:Preferences#mw-prefsection-echo, esstintially obselete by now | |
| //catchOnArrive(".oo-ui-fieldLayout", "OOUI input field") | |
| catchOnArrive(".mw-htmlform-field-HTMLSelectField", "OOUI simple <select>") | |
| catchOnArrive(".mw-htmlform-field-HTMLTitlesMultiselectField", "OOUI page multi-select field") | |
| catchOnArrive(".mw-htmlform-field-HTMLUsersMultiselectField", "OOUI user multi-select field") | |
| catchOnArrive(".oo-ui-labelElement-label", "OOUI label") | |
| catchOnArrive(".mw-ui-button", "mediawiki.ui button (ULS)") | |
| catchOnArrive(".mw-htmlform-matrix", "OOUI matrix form") | |
| // FIXME: this breaks frb | |
| catchOnArrive("#centralNotice *", "central notice") // wlm_2023_us doesn't use .cnotice | |
| catchOnArrive("#p-visibility", "Wiktionary visibility toggle") | |
| catchOnArrive("#p-feedback", "feedback link (Wiktionary etc.)") | |
| catchOnArrive(".cdx-button, .cdx-text-input, .cdx-tabs, .cdx-dialog__header, .cdx-dialog__body, .cdx-menu-item", "CDX components", { existing: false }) | |
| // catchOnArrive(".mw-mmv-main *", "Media Viewer") // buggy | |
| catchOnArrive(".mw-mmv-dialog .mw-mmv-dialog-warning", "Media Viewer dialog warning") | |
| catchOnArrive(".mw-mmv-post-image *", "Media Viewer image info", { fireOnAttributesModification: true }) | |
| //catchOnArrive(".mw-echo-ui-overlay", "Echo notifications popup") CHECK AGAIN | |
| catchOnArrive(".oo-ui-popupWidget-popup", "OOUI popup") | |
| catchOnArrive(".mw-echo-ui-notificationItemWidget", "Echo notifications item") | |
| catchOnArrive("#p-page"/*, #ca-purge"*/, "Page portlet (from an enwiki gadget)") | |
| catchOnArrive(".mw-kartographer-attribution, .leaflet-control-attribution, .leaflet-control-attribution *", "Kartographer map credits") | |
| catchOnArrive(".mw-kartographer-buttonfoot", "Kartographer map button") | |
| // pain | |
| catchOnArrive(".mw-collapsible-toggle", "collapsible content toggle", { fireOnAttributesModification: true }, function(el) { | |
| el.on("click", function() { | |
| owoifyElementAndChildrenAuto(el) | |
| }) | |
| }) | |
| catchOnArrive(".wbmi-entityview-emptyCaption", "unfilled file caption") | |
| catchOnArrive(".wbmi-link-notice", "WBMI structured data link-back notice") | |
| catchOnArrive(".wbmi-statements-widget", "WBMI structured data statement widget") | |
| catchOnArrive(".wbmi-add-property", "WBMI structured data add statement button") | |
| catchOnArrive(".wbmi-entity-header", "WBMI structured data entity data") | |
| catchOnArrive(".wbmi-entity-title", "WBMI structured data entity label") | |
| catchOnArrive(".wbmi-entity-label", "WBMI structured data entity label") | |
| catchOnArrive(".wbmi-snak", "WBMI structured data snak") | |
| catchOnArrive("#t-print > a", "\"printable version\" link (may get overwritten)", { fireOnAttributesModification: true }) | |
| // FIXME | |
| catchOnArrive(".uls-menu, .uls-menu *", "ULS menus", { fireOnAttributesModification: true }) | |
| // likely covered by the above | |
| /*catchOnArrive(".languagesettings-menu, #languagesettings-settings-panel", "ULS settings dialog") | |
| catchOnArrive(".uls-display-settings", "ULS settings, display pane") | |
| catchOnArrive(".uls-input-settings", "ULS settings, input pane") | |
| catchOnArrive(".interlanguage-uls-menu", "ULS language menu") | |
| catchOnArrive(".uls-language-list", "ULS language list") | |
| catchOnArrive(".uls-lcd-region-title", "ULS language list region title") | |
| catchOnArrive("#uls-settings-block", "ULS settings block") | |
| catchOnArrive(".cx-uls-relevant-languages-banner, .cx-uls-relevant-languages-banner > .cx-uls-relevant-languages-banner__text", "ULS relevant languages banner") | |
| catchOnArrive(".uls-filterinput", "ULS language searchbar") | |
| catchOnArrive(".cx-uls-entrypoint", "ULS subpage")*/ | |
| //catchOnArrive("*[data-i18n]", "anything that has data-i18n, notably ULS components", { fireOnAttributesModification: true }) | |
| catchOnArrive(".mw-parser-output", "Lazyloaded articles/wikitext system messages", { existing: false }) | |
| catchOnArrive(".vector-search-box-input", "Vector 2011 search boxes") | |
| catchOnArrive(".ve-init-target", "VisualEditor") | |
| catchOnArrive(".ca-ve-edit > a", "wiki.gg VisualEditor activator", { fireOnAttributesModification: true }) | |
| catchOnArrive(".oo-ui-popupToolGroup-handle, .oo-ui-toolGroup-tools", "OOUI/VE tool dropdown") | |
| catchOnArrive(".msupload-dropzone", "MsUpload drop zone") | |
| catchOnArrive(".wikiEditor-ui-toolbar .tool > a, .wikiEditor-ui-toolbar > .tabs > .tab", "WikiEditor v?? toolbar tabs & tools") | |
| catchOnArrive(".wikiEditor-ui-toolbar .booklet div[role=\"option\"]", "WikiEditor special character page labels") | |
| catchOnArrive(".suggestions .suggestions-special > .special-label", "Search suggestions Special:Search link") | |
| catchOnArrive(".vector-appearance .mw-portlet", "Vector 2022 client skin selection menu") | |
| // TODO: what if a wikitionary page is in wikidata and the wdi shows up? | |
| catchOnArrive(".mw-content-subtitle, .WDI-box", "Page subtitle") | |
| // FIXME | |
| catchOnArrive(".survey-content", "QuickSurveys content") | |
| } else if (isMailingList) { | |
| catchOnArrive(".list-group-item, .maker", "list group item") | |
| catchOnArrive(".email", "email") | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment