User:Tacsipacsi/AjaxTranslation.js

Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
/**
 * Ajax Translations
 *
 * Translates layout templates (licenses templates)
 * See talk page for documentation.
 *
 * Maintainers: [[User:ערן]], [[User:Ilmari Karonen]], [[User:DieBuche]]
 * Last update: 2019-07-05
 */
// Avoid post-save expansion: <nowiki>
/*global mw:false, $:false*/
/*jslint browser: true */
/*jshint curly:false */
(function () {
	"use strict";

	if (mw.libs.AjaxTranslations) {
		return;
	}
	
	var langLinkRgx;

	var AjaxTranslations = {
		/**
		 * Add click handler to all language links in a given chunk of document,
		 * or in the whole document.
		 *
		 * @param {jQuery|null} $content A jQuery object to add handlers to descendants of,
		 *  or null if in the whole document
		 */
		updateLangLinks: function ($content) {
			if (typeof window.disableAjaxTranslation !== 'undefined') {
				return;
			}
			// Initialized here because it uses mw.RegExp, which is not available initially
			langLinkRgx = new RegExp(
				'^(' +
				mw.RegExp.escape(mw.config.get('wgServer')).replace(/(https?\:)?\/\//, '(https?\\:)?//') +
				'|)' +
				mw.RegExp.escape(mw.config.get('wgArticlePath')).replace('\\$1', '(Template:.*/[a-z]{2,3}(-[a-z]+)?)') +
				'$'
			);
			$('div.layouttemplate a, table.layouttemplate a', $content).each(function () {
				// If not translation link, skip it
				if (langLinkRgx.exec($(this).attr('href'))) {
					$(this).click(function (e) {
						e.preventDefault();
						AjaxTranslations.loadAjaxTranslation(e);
					});
				}
				AjaxTranslations.state = 'Ok, ready';
			});
		},

		/**
		 * Click handler.
		 *
		 * @param {jQuery.Event} e
		 */
		loadAjaxTranslation: function (e) {
			var templateName,
				templateParts,
				aT = this,
				templateArgs = '',
				linkElement = e.target,
				templateLink = linkElement.href;

			if (!templateLink) {
				return;
			}

			templateLink = templateLink.replace(/[\s_]+/g, '_');
			templateName = langLinkRgx.exec(templateLink);
			if (templateName) {
				templateName = templateName[3];
			}
			templateParts = /^Template:(.*)\/([a-z]{2,3}(-[a-z]+)?)$/.exec(templateName);

			if (!templateParts || !templateParts.length) {
				return;
			}

			this.lastLayoutTemplate = $(linkElement).parents('.layouttemplate');

			// try to find encoded template args, if supplied (EXPERIMENTAL)
			this.lastLayoutTemplate.find('.layouttemplateargs').each(function () {
				var args = this.title.split(/\s+/);
				args.shift();
				$.each(args, function (key, val) {
					if (!/\S/.test(val)) {
						return true;
					}
					templateArgs += '|' + decodeURIComponent(val.replace(/\+/g, ' ')).replace(/\|/g, '{{!}}');
				});
			});

			// {{urlencode:}} turns parser extension tags into garbage; we can't undo it, so we just give up if that's happened
			if (/\x7FUNIQ/.test(templateArgs)) {
				templateArgs = '';
			}

			$.ajax({
				url: mw.util.wikiScript('api'),
				type: 'POST',
				data: {
					format : 'json',
					action : 'parse',
					prop : 'text',
					text : '{{' + templateName + templateArgs + '}}',
					title : mw.config.get('wgPageName'),
					uselang : templateParts[2]
				},
				dataType: 'json',
				success: function (result) {
					if (result && result.parse && result.parse.text['*']) {
						aT.lastLayoutTemplate.replaceWith(result.parse.text['*']);
						$('.translatedTag').hide();
						aT.updateLangLinks();
					}
				}
			});

			e.preventDefault();
		}
	};

	AjaxTranslations.state = 'Waiting for DOM-ready';

	mw.loader.using(['mediawiki.util', 'mediawiki.RegExp'], function () {
		mw.hook('wikipage.content').add(AjaxTranslations.updateLangLinks);
	});

	mw.libs.AjaxTranslations = AjaxTranslations;

}());
//</nowiki>