// ==UserScript==
// @name Wikipedia skins
// @description Restore the old Wikipedia look or choose between other available skins: Vector 2022, Vector legacy 2010, MinervaNeue, MonoBook, Timeless, Modern, Cologne Blue
// @version 1.2.0
// @author Pabli
// @homepageURL https://greasyfork.org/scripts/523252-wikipedia-skins
// @supportURL https://greasyfork.org/scripts/523252-wikipedia-skins/feedback
// @namespace https://github.com/pabli24
// @license MIT
// @match *://*.wikipedia.org/*
// @match *://*.wiktionary.org/*
// @match *://*.wikiquote.org/*
// @match *://*.wikinews.org/*
// @match *://*.wikidata.org/*
// @match *://*.wikivoyage.org/*
// @match *://*.wikiversity.org/*
// @match *://*.wikifunctions.org/*
// @match *://*.wikisource.org/*
// @match *://*.wikibooks.org/*
// @match *://*.wikimedia.org/*
// @match *://*.mediawiki.org/*
// @run-at document-start
// @icon https://www.google.com/s2/favicons?sz=64&domain=wikipedia.org
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand
// ==/UserScript==
(async () => {
'use strict';
const url = new URL(window.location.href);
const domains = ['wikipedia.org', 'wiktionary.org', 'wikiquote.org', 'wikinews.org', 'wikidata.org', 'wikivoyage.org', 'wikiversity.org', 'wikifunctions.org', 'wikisource.org', 'wikibooks.org', 'wikimedia.org', 'mediawiki.org'];
// https://en.wikipedia.org/wiki/Wikipedia:Skin
const skin = await GM_getValue('skin', 'vector');
const skins = {
'vector-2022': 'Vector 2022 (default on desktop from 2022)',
vector: 'Vector legacy 2010 (default on desktop from 2010 to 2021)',
minerva: 'MinervaNeue (mobile)',
monobook: 'MonoBook (default from 2004 to 2009)',
timeless: 'Timeless',
modern: 'Modern (created in 2008 and deprecated in 2021)',
cologneblue: 'Cologne Blue (created in 2002 and deprecated in 2019)'
};
const options = {
nostalgia: {
value: await GM_getValue('nostalgia', true),
label: 'Nostalgia on the nostalgia.wikipedia.org (original skin from 2001)',
},
cleanUrl: {
value: await GM_getValue('cleanUrl', true),
label: 'Clean URL (remove ?useskin=skinname from the URL)',
},
};
Object.entries(skins).forEach(([key, label]) => {
GM_registerMenuCommand(
`${skin === key ? '◉' : '○'} ${label}`,
async () => {
await GM_setValue('skin', key);
const url = new URL(window.location.href);
url.searchParams.append('useskin', key);
window.location.href = url;
}
);
});
Object.entries(options).forEach(([key, config]) => {
GM_registerMenuCommand(
`${config.value ? '☑' : '☐'} ${config.label}`,
async () => {
options[key].value = !options[key].value;
await GM_setValue(key, options[key].value);
deleteUseskinParam()
window.location.reload();
}
);
});
if (options.nostalgia.value && window.location.hostname === 'nostalgia.wikipedia.org') return;
function deleteUseskinParam() {
const url = new URL(window.location.href);
if (url.searchParams.has('useskin')) {
url.searchParams.delete('useskin');
window.history.replaceState({}, '', url);
}
}
if (!url.searchParams.has('useskin') && url.pathname !== '/') {
url.searchParams.append('useskin', skin);
window.location.href = url;
} else if (options.cleanUrl.value) {
deleteUseskinParam();
setTimeout(deleteUseskinParam, 1000);
setTimeout(deleteUseskinParam, 3000);
}
function linkUseskin(e) {
let link = e.target.closest('a[href]:not([href^="#"])');
if (!link || link.dataset.useskin) return;
if (!link.getAttribute('href').startsWith('/') &&
!domains.some(domain => link.hostname.endsWith(`.${domain}`) || link.hostname === domain)) return;
const url = new URL(link.href);
url.searchParams.append('useskin', skin);
link.href = url.toString();
link.dataset.useskin = true;
}
document.addEventListener('mouseover', linkUseskin);
document.addEventListener('focusin', linkUseskin);
})();