MediaWiki:Gadget-categoryTreeLanguageNames.js

From Linguifex
Jump to navigation Jump to search

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
"use strict";

// {{documentation}}
// <nowiki>
/* global mw */

(function categoryTreeLanguageNamesGadget() {
	const ALLOWED_NAMESPACES = [
		0,      // Main
		14,     // Category
		100,    // Appendix
		118     // Reconstruction
	];

	const CATEGORY_PREFIX = mw.config.get("wgFormattedNamespaces")[14] + ":";

	function getLanguageCodeToCanonicalName() {
		const CACHE_DURATION = 24 * 60 * 60; // 24 hours
		const KEY = "enwiktLanguageCodeToCanonicalNameJson";

		let timeNow = new Date().getTime() * 1e-3;
		try {
			let cachedData = JSON.parse(localStorage.getItem(KEY));
			if (timeNow - cachedData.timestamp < CACHE_DURATION)
				return Promise.resolve(cachedData.data);
		} catch (e) { }

		const actionAPI = new mw.Api({ ajax: { headers: { "Api-User-Agent": "Gadget developed by [[User:Surjection]]" } } });
		return actionAPI.get({
			"action": "parse",
			"page": "Module:languages/code to canonical name.json",
			"prop": "wikitext",
			"formatversion": "2",
			"format": "json"
		})
		.then(response => {
			let languageData = JSON.parse(response.parse.wikitext);
			localStorage.setItem(KEY, JSON.stringify({
				timestamp: timeNow,
				data: languageData
			}));
			return languageData;
		});
	}

	function addCategoryTreeLanguageName(codeToCanonicalName, catElement, doNotTagLanguageCode) {
		// not a category link/name
		if (!catElement.href.includes(CATEGORY_PREFIX))
			return;

		// do not duplicate
		if (catElement.querySelector(".wikt-category-tree-language-name"))
			return;

		let firstTextNode = Array.from(catElement.childNodes).find(node => node.nodeType === Node.TEXT_NODE);
		if (!firstTextNode)
			return;

		let categoryName = firstTextNode.textContent;
		let parseCategoryTreeName = categoryName.match(/^([a-z-]+):(.+)/);
		if (!parseCategoryTreeName)
			return;

		let languageCode = parseCategoryTreeName[1];
		let subcategoryName = parseCategoryTreeName[2];
		let canonicalName = codeToCanonicalName[languageCode];
		if (!canonicalName)
			return;

		if (catElement.title === categoryName || catElement.title === CATEGORY_PREFIX + categoryName)
			catElement.title += ` [${canonicalName}: ${subcategoryName}]`;

		if (languageCode !== doNotTagLanguageCode) {
			let langElement = document.createElement("span");
			langElement.className = "wikt-category-tree-language-name";
			langElement.textContent = ` [${canonicalName}]`;
			catElement.append(langElement);
		}
	}

	mw.hook("wikipage.content").add(() => {
		if (mw.config.get("wgAction") === "view" &&
				ALLOWED_NAMESPACES.includes(mw.config.get("wgNamespaceNumber"))) {

			mw.util.addCSS(`
				.wikt-category-tree-language-name {
					font-size: 85%;
				}
			`);

			let thisLanguageCode = null;
			if (mw.config.get("wgNamespaceNumber") === 14) {
				let categoryName = mw.config.get("wgTitle");
				let parseCategoryTreeName = categoryName.match(/^([a-z-]+):(.+)/);
				if (parseCategoryTreeName)
					thisLanguageCode = parseCategoryTreeName[1];
			}

			getLanguageCodeToCanonicalName().then(codeToCanonicalName => {
				for (let catElement of document.querySelectorAll("#catlinks ul > li a"))
					addCategoryTreeLanguageName(codeToCanonicalName, catElement, thisLanguageCode);

				if (mw.config.get("wgNamespaceNumber") === 14) {
					for (let catElement of document.querySelectorAll("#mw-subcategories a"))
						addCategoryTreeLanguageName(codeToCanonicalName, catElement, thisLanguageCode);
				}
			});
		}
	});
})();

// </nowiki>