User:Erutuon/scripts/moduleDocumentation.js

/* jshint boss: true, eqeqeq: true, esversion: 6, undef: true, unused: true, varstmt: true */ /* globals $, apiWrapper, mw, OO */

//

(function subpageLinkIIFE { "use strict";

const subpageLinkSelector = ".mw-prefixindex-list a";

if (!document.querySelector(subpageLinkSelector)) return;

mw.loader.using([	"mediawiki.storage", "mediawiki.Title", "mediawiki.util" ]).done( => {	const baseText = mw.config.get("wgPageName").match(/^(?:[^\/]+|\/)/)[0].replace(/_/g, " ");	if (!(baseText === "Module:accel" || baseText === "Module:number list")) {		console.info("Wrong page");		return;	}	const baseTitle = mw.Title.newFromText(baseText);	const baseTitleRegExp = new RegExp("^" + mw.util.escapeRegExp(baseTitle.getMainText + "/") + "?");	function getSubpage(unprefixedPageName) {		return unprefixedPageName.replace(baseTitleRegExp, "");	}	function removeChildren(elem) {		let child;		while (child = elem.firstChild)			elem.removeChild(child);	}	function appendLangNode(elem, languageCodeToName, langCode) {		const langCodeNode = document.createElement("code");		langCodeNode.textContent = langCode;		for (const child of [ document.createTextNode(languageCodeToName[langCode] + " ("),			langCodeNode,			document.createTextNode(")") ])			elem.appendChild(child);	}	// Must match the following (minus the namespace):	// Module:number list/data/en	// Module:accel/en	function getLangCode(subpageName) {		const match = subpageName.match(/^(?:data\/)?([a-z]{2,3}(?:-[a-z]{2,3}){0,2})$/);		return match && match[1];	}	function processPrefixIndex(languageCodeToName) {		Array.prototype.forEach.call($(subpageLinkSelector), subpageLink => { const text = subpageLink.textContent; const subpage = getSubpage(text); subpageLink.textContent = subpage; const langCode = getLangCode(subpage); if (!languageCodeToName[langCode]) { if (langCode) console.info("invalid language code: ", langCode); else console.info("no language code in ", subpage); subpageLink.parentNode.remove; // Remove list items containing non-language modules. return; }			removeChildren(subpageLink); appendLangNode(subpageLink, languageCodeToName, langCode); });	}	/*	 * Create an object that loads JSON data with a template on demand and	 * saves it in localStorage.	 * It provides a doWithData option that takes a callback that requires	 * the data, and returns a new function that when called, calls the callback,	 * supplying the data to it as the first parameter.	 */	function LanguageData(storageKey, template) {		if (!(typeof storageKey === "string" && typeof template === "string"))			throw new TypeError("Expected string");		this.storageKey = storageKey;		this.template = template;	}	LanguageData.prototype = {		get storage {			return mw.storage.get(this.storageKey);		},		set storage(val) {			if (val === null || val === undefined)				mw.storage.remove(this.storageKey);			else if (typeof val === "object")				mw.storage.set(this.storageKey, val);			else				throw new TypeError("Expected object, null, or undefined");		},		get data {			return window[this.storageKey]; },		set data(val) { window[this.storageKey] = val; },	};	LanguageData.prototype.loadJSON = function loadJSON(JSONData) { try { if (JSONData) { const data = JSON.parse(JSONData);

if (typeof data !== "object") throw new TypeError("Object expected");

this.data = data; return true; }		} catch (error) { console.error(error); }	};	LanguageData.prototype.doWithData = function doWithData(callback, thisValue) { return => { if (this.data || this.loadJSON(this.storage)) { callback.call(thisValue, this.data); return; }			$.getScript("//en.wiktionary.org/w/index.php?title=User:Erutuon/scripts/apiWrapper.js&action=raw") .done( => {				apiWrapper.expandTemplates( this.template, (JSONData) => { this.storage = JSONData; if (this.loadJSON(JSONData)) callback.call(thisValue, this.data); else console.error("Fail"); });			});		};	};	const codeToCanonical = new LanguageData(		"WiktionaryCodeToName",		""	); $(codeToCanonical.doWithData(processPrefixIndex)); mw.loader.using("oojs-ui").done(function {		const $box = $("#create-new input[type=text]");		const popupContent = $(" ");		const popup = new OO.ui.PopupWidget({ $content: popupContent, padded: true, position: 'above', });		$box.before(popup.$element);		popup.toggle(false); // hidden initially		function langCatLink(langName) {			const pageName = "Category:" + (langName.indexOf("Language") === -1 ? langName + " language" : langName);			return $("").attr("href", mw.util.getUrl(pageName)).html(langName);		}		$box.on("input", codeToCanonical.doWithData(function (codeToName) {			if (this.val === "" || codeToName[this.val]) {				this.css({ "background-color": "", "color": "", "border-color": "", });				if (this.val !== "") {					popupContent.html("language code for ");					popupContent.append(langCatLink(codeToName[this.val]));					popup.toggle(true);				} else					popup.toggle(false);			} else {				popup.toggle(false);				this.css({ "background-color": "pink", "color": "red", "border-color": "red", });			}		}, $box));		$box.trigger("input");		// const enterKey = 0x0D;		const $form = $box.closest("form");		codeToCanonical.doWithData(function (codeToName) { $form.submit(function keydownKeyup(event) {				if (!(codeToName[$box.val])) {					popupContent.html($box.val + " isn't a valid language code!");					popup.toggle(true);					return false;				}			}); }, $box);	}); });

});

//