Skip to content

Instantly share code, notes, and snippets.

@Dobby233Liu
Last active January 22, 2025 10:18
Show Gist options
  • Save Dobby233Liu/e852d272eef8411c2337edfba9f6da27 to your computer and use it in GitHub Desktop.
Save Dobby233Liu/e852d272eef8411c2337edfba9f6da27 to your computer and use it in GitHub Desktop.
OwOiki: OwOifies most English-language Wikimedia Foundation wikis
// ==UserScript==
// @name OwOiki
// @version 0.2.8a
// @icon data:image/png;base64,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
// @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/[email protected]/dist/owoify-js.umd.production.min.js
// @require https://unpkg.com/[email protected]/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*/
"use strict";
/* global $ */
const ME = "[OwOiki]"
const DEBUG = false // will make noise in console
const _owoify = window["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? */
}
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-title[original-title]," // FIXME
bannedElems += ".mw-mmv-download-select-menu *, .mw-mmv-download-image-size, .mw-mmv-download-image-size-name," // FIXME: ????
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;
}
#siteSub, .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 = true
}
})
}
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: true, ...opts }, function(el) {
if (DEBUG) {
console.warn(ME, `caught you${readableType ? `, ${readableType}` : ""}!! >w< the conversion will take place shortly`, el)
}
el = $(el)
owoifyElementAndChildrenAuto(el)
if (xtra) { xtra(el) }
})
}
injectStyles()
owoifyElements().catch(e => console.error(ME, e))
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")
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(".mw-mmv-main *", "Media Viewer") // buggy
//catchOnArrive(".mw-mmv-dialog *", "Media Viewer dialog (I think the text is loaded on demand)")
//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(".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("p[data-i18n]", "anything that has data-i18n, notably ULS components")
catchOnArrive(".vector-search-box-input", "Vector 2011 search boxes")
catchOnArrive(".ve-init-target", "VisualEditor")
catchOnArrive(".ca-ve-edit > a", { fireOnAttributesModification: true }, "wiki.gg VisualEditor activator")
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