MediaWiki:Gadget-TargetedTranslations.js

Note – after saving, you may have to bypass your browser’s cache to see the changes.

  • Mozilla / Firefox / Safari: hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Command-R on a Macintosh);
  • Konqueror and Chrome: click Reload or press F5;
  • Opera: clear the cache in Tools → Preferences;
  • Internet Explorer: hold Ctrl while clicking Refresh, or press Ctrl-F5.

See also: Special:Gadgets.


/* This is a modified version of [[User:Atelaes/TargetedTranslations.js]] by Yair rand
 *
 * Todo: jQuerise, code cleaning.
 *
 * dependencies: mediawiki.storage, mediawiki.cookie, ext.gadget.StorageUtils
 */

/* jshint unused:true */
/* globals $, mw, StorageWrapper */

'use strict';

function clarifyTransTable() {
	var storageWrapper = new StorageWrapper();
	function setStartVars() {
		targetedTranslationsSavedData = storageWrapper.get('TargetedTranslations') || '|';
		targetLanguages = targetedTranslationsSavedData.split('|')[0].split(';');
		targetSubLanguages = targetedTranslationsSavedData.split('|')[1].split(';');
		targetLanguagesParents = {};
		while (targetSubLanguages[0]) {
			(targetLanguagesParents[c = targetSubLanguages[0].split('/')[1]] = targetLanguagesParents[c] || []).push(targetSubLanguages.shift().split('/')[0]);
		}
	}

	setStartVars();

	var targetLanguages, targetSubLanguages, targetLanguagesParents, c, targetedTranslationsSavedData,
		targetTrans, targetTransEmpty,
		tables = $('.translations').toArray(),
		lis, li, dls, dds,
		NavHead, temp;

	// For lis, check if language is targeted
	function isRight(node) {
		for (var l = 0, ll = targetLanguages.length, t = node.innerText || node.textContent; l < ll; l++) {
			if (t.indexOf(targetLanguages[l] + ':') === 0) {
				return true;
			}
		}
	}
	// For dds, check if sub-language is targeted
	function isRight2(node) {
		temp = targetLanguagesParents[(node.innerText || node.textContent).split(':')[0]];
		if (temp) {
			node = node.parentNode.parentNode;
			node = (node.innerText || node.textContent).split(':')[0];
			for (var l = 0; l < temp.length; l++) {
				if (temp[l] == node) {
					return true;
				}
			}
		}
	}

	for (var i = 0, tableslength = tables.length; i < tableslength; i++) {
		if (tables[i].className == 'translations') {
			addTargetedTranslationsButton(tables[i]);
			if (targetedTranslationsSavedData != '|') {
				if (!targetTransEmpty) {
					targetTrans = document.createElement('span');
					targetTransEmpty = true;
				}
				lis = tables[i].getElementsByTagName('li');
				for (var j = 0, lislength = lis.length; j < lislength; j++) {
					dls = (li = lis[j]).getElementsByTagName('dl');
					//If we have subelements in the li....
					if (dls.length == 1) {
						if (isRight(li) && li.childNodes[1].nodeName != 'DL') {
							temp = document.createElement('span');
							for (var k = 0; k < li.childNodes.length; k++) {
								if (li.childNodes[k].nodeName != 'DL') {
									temp.appendChild(li.childNodes[k].cloneNode(true));
								}
							}
							if (!targetTransEmpty) {
								targetTrans.appendChild(document.createTextNode('; '));
							}
							targetTransEmpty = false;
							targetTrans.appendChild(temp);
						}
						dds = dls[0].getElementsByTagName('dd');
						for (var k = 0; k < dds.length; k++) {
							if (isRight2(dds[k])) {
								temp = document.createElement('span');
								temp.innerHTML = (dds[k].parentNode.parentNode.innerText || dds[k].parentNode.parentNode.textContent).split(':')[0] + ': ' + dds[k].innerHTML;
								if (!targetTransEmpty) {
									targetTrans.appendChild(document.createTextNode('; '));
								}
								targetTransEmpty = false;
								targetTrans.appendChild(temp);
							}
						}
					} else if (isRight(li)) {
						temp = document.createElement('span');
						temp.innerHTML = li.innerHTML;
						if (!targetTransEmpty) {
							targetTrans.appendChild(document.createTextNode('; '));
						}
						targetTransEmpty = false;
						targetTrans.appendChild(temp);
					}
				}
				if (!targetTransEmpty) {
					NavHead = $(tables[i].parentNode.parentNode).find('.NavHead')[0];
					NavHead.appendChild(document.createTextNode(' - '));
					NavHead.appendChild(targetTrans);
				}
			}
		}
	}


	function addTargetedTranslationsButton(node) {
		var $button = $("<a>Select preferred languages</a>").css("font-size", "85%").on("click", function() {
			addtargetlangfavoriteicons($button.parent().next().find('tr')[0].getElementsByTagName('li'));
			for (var i = 0; i++ < 4;) {
				$button.parent().next().find('ul')[i % 2].style[i < 3 ? 'listStyleImage' : 'listStyleType'] = 'none';
			}
			$button.replaceWith($("<a>Save preferences</a>").css("font-size", "85%").attr("href", "javascript:location.reload(true)"));
		});

		$(node).before($('<div>').append($button));
	}

	function addtargetlangfavoriteicons(q) {
		function w(x, xx) {
			x.insertBefore($('<a>').addClass('translationtargetstar').on("click", function() {
				selecttargetlangfavorite(x.firstChild, xx);
			})[0], x.firstChild);
			if ((xx && isRight2(x)) || ((!xx) && isRight(x))) {
				x.firstChild.className += 'checked';
			}
		}
		for (var i = 0; i < q.length; i++) {
			w(q[i]);
			for (var ii = 0, xx = q[i].getElementsByTagName('dd'); ii < xx.length; ii++) {
				w(xx[ii], true);
			}
		}
	}

	function selecttargetlangfavorite(qq, xx) {
		if ((xx && isRight2(qq.parentNode)) || ((!xx) && isRight(qq.parentNode))) {
			temp = targetedTranslationsSavedData;
			qq.className = 'translationtargetstar';
			if (!xx) { // rm li pref
				temp = (';' + temp.split('|')[0].replace(/;/g, ';;') + ';').replace(';' + (qq.parentNode.innerText || qq.parentNode.textContent).split(':')[0] + ';', '').replace(/;(?=;)|;$|^;/g, '') + '|' + temp.split('|')[1];
			} else { // rm dd pref
				temp = temp.split('|')[0] + '|' + temp.split('|')[1].replace((qq.parentNode.parentNode.parentNode.innerText || qq.parentNode.parentNode.parentNode.textContent).split(':')[0] + '/' + (qq.parentNode.innerText || qq.parentNode.textContent).split(':')[0], '').replace(/;(?=;)|;$|^;/, '');
			}
		} else {
			temp = targetedTranslationsSavedData;
			if (!xx) { // add li pref
				temp = temp.replace(/\|/, (temp.charAt(0) == '|' ? '' : ';') + (qq.parentNode.innerText || qq.parentNode.textContent).split(':')[0] + '|');
			} else { // add dd pref
				temp += (temp.split('|')[1] === '' ? '' : ';') + (qq.parentNode.parentNode.parentNode.innerText || qq.parentNode.parentNode.parentNode.textContent).split(':')[0] + '/' + (qq.parentNode.innerText || qq.parentNode.textContent).split(':')[0];
			}
			qq.className = 'translationtargetstarchecked';
		}
		
		storageWrapper.set("TargetedTranslations", temp);
		setStartVars();
	}
}

if (new StorageWrapper().storageAvailable && mw.config.get('wgNamespaceNumber') === 0)
	$(clarifyTransTable);