Last active
June 10, 2026 23:52
-
-
Save Gkjsdll/aa104d222d9f38d087473aa37e4f9cd4 to your computer and use it in GitHub Desktop.
Persists the beta appearance settings on Wikipedia across sessions
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 Persist Wikipedia Appearance | |
| // @namespace http://gkjsdll.com/ | |
| // @version 0.0.1 | |
| // @description Persist Wikipedia Appearance settings between sessions | |
| // @author Zack (Gkjsdll) Winchell | |
| // @match https://*.wikipedia.org/* | |
| // @icon https://icons.duckduckgo.com/ip2/wikipedia.org.ico | |
| // @grant GM_setValue | |
| // @grant GM_getValue | |
| // ==/UserScript== | |
| (async function() { | |
| 'use strict'; | |
| const [textRadioInputs, widthRadioInputs, colorRadioInputs] = await Promise.all([ | |
| getInputsInId('skin-client-prefs-vector-feature-custom-font-size'), | |
| getInputsInId('skin-client-prefs-vector-feature-limited-width'), | |
| getInputsInId('skin-client-prefs-skin-theme'), | |
| ]); | |
| const savedTextValue = GM_getValue('textValue', null); | |
| const savedWidthValue = GM_getValue('widthValue', null); | |
| const savedColorValue = GM_getValue('colorValue', null); | |
| if (savedTextValue !== null) { | |
| selectRadioOption(textRadioInputs, savedTextValue); | |
| } | |
| if (savedWidthValue !== null) { | |
| selectRadioOption(widthRadioInputs, savedWidthValue); | |
| } | |
| if (savedColorValue !== null) { | |
| selectRadioOption(colorRadioInputs, savedColorValue); | |
| } | |
| listenForRadioUpdates(textRadioInputs, 'text'); | |
| listenForRadioUpdates(widthRadioInputs, 'width'); | |
| listenForRadioUpdates(colorRadioInputs, 'color'); | |
| async function getInputsInId(id) { | |
| await waitForElementToBeInPage(`#${id} input`); | |
| return Array.from(document.getElementById(id).querySelectorAll('input')); | |
| } | |
| function listenForRadioUpdates(inputs, label) { | |
| for (const input of inputs) { | |
| input.addEventListener('change', (event) => { | |
| GM_setValue(label, event.target.value); | |
| }); | |
| } | |
| } | |
| function selectRadioOption(inputs, value) { | |
| const matchingInput = inputs.find((input) => input.value === value); | |
| if (matchingInput === null) { | |
| return; | |
| } | |
| matchingInput.click(); | |
| } | |
| function waitForElementToBeInPage(selector) { | |
| if (document.querySelector(selector)) { | |
| return Promise.resolve(document.querySelector(selector)); | |
| } | |
| return new Promise((resolve) => { | |
| const observer = new MutationObserver((mutations) => { | |
| for (const mutation of mutations) { | |
| if (mutation.addedNodes === undefined) { | |
| return; | |
| } | |
| for (const addedNode of mutation.addedNodes) { | |
| const matchingNode = addedNode.querySelector(selector); | |
| if (matchingNode) { | |
| observer.disconnect(); | |
| resolve(document.querySelector(selector)); | |
| } | |
| } | |
| } | |
| }); | |
| observer.observe(document.documentElement, { | |
| childList: true, | |
| subtree: true | |
| }); | |
| }); | |
| } | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment