Jump to content

User:Macaw*/Vector 2022 Skin Switcher.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/**
 * SkinSwitcher.js
 * Fork of [[user:ClaudineChionh/Scripts/SkinSwitcher.js]]
 * @author Macaw*
 * @version 0.2.4
 * @license Apache-2.0
 * @external "jQuery"
 * @external "mediawiki.util"
 */
mw.loader.using("mediawiki.util", function () {
	"use strict";

	var SkinSwitcher = {
		lang: {
			script: "Skin Switcher",
			viewIn: "View this page in $1 skin"
		},
		skins: {
			"minerva": "Minerva Neue",      
			"vector-2022": "Vector 2022",    
			"vector": "Vector 2010",         
			"timeless": "Timeless",
			"monobook": "MonoBook",
			"apioutput": "ApiOutput"
		},

		/**
		 * Create a link element for a given skin.
		 * @param {string} selectedSkin - Key for the skin.
		 * @param {string} itemText - Display name.
		 * @returns {string} HTML for a list item.
		 */
		constructElement: function (selectedSkin, itemText) {
			var href = window.location.href.replace(/#.*/, "");
			var param = (window.location.search) ? "&" : "?";

			return mw.html.element("li", {
				"id": "skinSwitcher-li-" + selectedSkin,
				"class": "skinSwitcher-li"
			}, new mw.html.Raw(
				mw.html.element("a", {
					"href": href + param + jQuery.param({ useskin: selectedSkin }),
					"title": this.lang.viewIn.replace("$1", itemText),
					"id": "skinSwitcher-a-" + selectedSkin,
					"class": "skinSwitcher-a"
				}, itemText)
			));
		},

		/**
		 * Assemble all link elements.
		 * @returns {Array} Array of list item HTML strings.
		 */
		assembleElements: function () {
			var elementsArray = [];
			Object.keys(this.skins).forEach(function (property) {
				elementsArray.push( this.constructElement(property, this.skins[property]) );
			}, this);
			return elementsArray;
		},

		/**
		 * Finds a container to place the skin switcher.
		 * Priority:
		 *   1. "#p-cactions .vector-menu" — Tools tab dropdown.
		 *   2. "#p-cactions" — The entire actions container.
		 *   3. ".mw-panel" — For legacy skins, the sidebar panel.
		 *   4. Top of the body (fallback).
		 * @returns {jQuery} The jQuery object for the chosen container.
		 */
		findPlacementContainer: function () {
			var $container = jQuery("#p-cactions .vector-menu");
			if (!$container.length) {
				$container = jQuery("#p-cactions");
			}
			if (!$container.length) {
				// For older or different skins.
				$container = jQuery(".mw-panel");
			}
			if (!$container.length) {
				// Last resort: insert at the very top of the body.
				$container = jQuery("body");
			}
			return $container;
		},

		/**
		 * Inserts or creates the skin switcher container (an unordered list)
		 * into the chosen placement container.
		 * @returns {jQuery} The jQuery object for the skin switcher container.
		 */
		insertSkinSwitcherContainer: function () {
			var $placement = this.findPlacementContainer();

			// Check if #skinSwitcher already exists; if not, create one.
			if (jQuery("#skinSwitcher").length === 0) {
				$placement.append("<ul id='skinSwitcher' class='skinSwitcher-menu'></ul>");
			}
			return jQuery("#skinSwitcher");
		},

		/**
		 * Places the skin switcher links into the chosen container.
		 * @param {Array} assembledElements - Array of LI HTML strings.
		 */
		determinePlacement: function (assembledElements) {
			var appendLocation = this.insertSkinSwitcherContainer();
			assembledElements.forEach(function (element) {
				jQuery(element).appendTo(appendLocation);
			});
		},

		/**
		 * Initializes the skin switcher.
		 */
		init: function () {
			if (window.isSkinSwitcherLoaded || jQuery("#skinSwitcher").length) {
				return;
			}
			window.isSkinSwitcherLoaded = true;
			this.currentSkin = mw.config.get("skin");

			// Remove the current skin from the options.
			if (this.skins.hasOwnProperty(this.currentSkin)) {
				delete this.skins[this.currentSkin];
				this.determinePlacement( this.assembleElements() );
			}
		}
	};

	// Initialize when the document is ready.
	jQuery(document).ready(function () {
		SkinSwitcher.init();
	});
});