مستخدم:Mr.Ibrahembot/fix html/مستخدم:Majed/wikiTranslTools.js

من ويكيبيديا، الموسوعة الحرة

ملاحظة: بعد الحفظ، قد يلزمك إفراغ الكاش لرؤية التغييرات.

/* Wiki Translation Tools v. 2.0 - March 20 2015
 * home page: //en.wikipedia.org/wiki/User:V111P/js/Wiki_Translation_Tools
 * CC0 Public Domain Dedication:
 * http://creativecommons.org/publicdomain/zero/1.0/
 * If you use large parts of this code, please let me know.
 * You should also let others know where the code originates:
 * //en.wikipedia.org/wiki/User:V111P/js/wikiTranslTools.js
 * Thanks!
 */
window.wikiTranslTools = (function ()
{
	"use strict";
	var THIS_ARTICLE = mw.config.get('wgPageName').replace(/_/g, ' ');
	var nl = '\n';
 
	// Target-wiki links will be added only to these namespaces:
	// Namespases: main=0, user=2, wikipedia/wp=4, template=10, help=12, category=14, portal=100
	var NamespacesWithInterwikis = [0, 2, 4, 10, 12, 14, 100];
 
 
	/*******
	 * Target-Wiki Config
	 ******/
	var targetWiki = {
		lang: '',
		server: '',
		translatedPageTemplate: '{{translated page|%sourceWiki%|%pageTitle%|version=%revisionId%}}'
	};
 
	var skin = { // values must be CSS/jQuery selectors
		interwikiDiv: '#p-lang',
		catLinks: '#mw-normal-catlinks' // the <div> with the non-hidden categories
		//  Leave empty to use the built-in wgCategories array (which includes hidden cats)
	};
 
	/*******
	 * Local-Wiki Config
	 ******/
	var thisWiki = {
		lang: mw.config.get('wgContentLanguage'),
 
		catNS: mw.config.get('wgFormattedNamespaces')[14] // The local name of the Category namespace
	};
 
	/******
	 * Other customizable options
	 ******/
	var options = {
		helpUrl: '//en.wikipedia.org/wiki/User:V111P/js/Wiki_Translation_Tools',
 
		defaultWiki: 'en', // used if targetWiki.lang is not set
 
		// number of rows for the output textarea
		taRows: 10,
 
		// this has no effect in Monobook and other skins
		taCols: 80,
 
		// if the article has that many categories or less, they will be auto-expanded
		//   when the Category Browser is shown for the first time on the page.
		maxCatsToAutoExpand: 5,
 
		// A function called with the wiki code just before displaying it in the text area
		// Must return the wiki code to be displayed
		hook: void(0)
	};
 
 
	/*******
	 * The Messages
	 ******/
	var msgs = {
		error: 'error',
		okButtonLabel: 'OK',
		translatedPageOption: 'Translated page',
		commonsOption: 'Commons',
		interwikis: 'Interwikis',
		categories: 'Categories',
		showPanelLink: 'Cat/Tr/Comm',
		showPanelTitle: 'Categories, {{Translated page}}, {{Commons}} ',
		alreadyListed: 'already listed',
		linksToLang: 'Links to %targetWiki%',
		enterTargetWiki: 'Please, enter the language code of the other Wikipedia:',
		targetWiki: 'target wiki: %targetWiki%'
	};
 
 
	/*******
	 * Private Variables
	 ******/
	var allCats; // used for the Category Browser
 
 
	// a shortcut for document.createTextNode()
	function textNode(str)
	{
		return document.createTextNode(str);
	}
 
 
	/*************************
	 ***  INTERWIKIS
	 ***
	 ***/
 
 
	// reads the interwikis from the element with the specified in SKIN.INTERWIKI_DIV id
	function getInterwikiCode()
	{
		var interwikis = getInterwikis();
		var links = interwikis.links;
		var langs = interwikis.langs;
 
		/* adding this page's wikilink to the array */
		links[thisWiki.lang] = THIS_ARTICLE;
		langs.push(thisWiki.lang);
		langs.sort();
 
		var interwikisStr = '';
		for (var i = 0; i < langs.length; i++)
			interwikisStr += '[[' + langs[i] + ':' + links[langs[i]] + ']]' + nl;
 
		return interwikisStr;
	}
 
 
	function getInterwikis()
	{
		var links = [], langs = [];
		$(skin.interwikiDiv + ' a').each(function (){
			var result = $(this).attr('href').match(/\/\/([^\.]+)\.[^\/]+\/wiki\/(.+)/);
			if (!result || result[1] == 'www')
				return;
			var lang = result[1];
			var title = decodeURI(result[2]).replace(/_/g, ' ');
			if (lang != targetWiki.lang) {
				links[lang] = title;
				langs.push(lang);
			}
		});
		return {langs: langs, links: links};
	}
 
 
	/*************************
	 ***  COMMONS templates
	 ***
	 ***/
 
 
	function getCommonsTemplates() {
		var commonsStr = '', template;
		var $commonsLinks = $('a[href*="//commons.wikimedia.org/wiki/"]');
		var commonsLinksArr = [];
		$commonsLinks.each(function (i, el) {
			var href = $(this).attr('href');
			if (href.match(/wiki\/(file|image|media):/i) || href.match(/Special:UploadWizard/))
				return;
			href = href.replace(/_/g, ' ').replace(/\?.*$/, '');
			var title = decodeURIComponent(href.replace(/.+?\/wiki\//, ''));
			var page = title.replace(/^Category:/, '');
			if (title != href) {
				if (title.match(/^Atlas of/))
					template = '* {{wikiatlas|' + title.replace(/^Atlas of./, '') + '}}';
				else
					template = '{{commons' + (page != title ? 'cat' : '')
						+ '|' + page + '}}';
				if ($.inArray(template, commonsLinksArr) == -1)
					commonsLinksArr.push(template);
			}
		});
		if (commonsStr = commonsLinksArr.join('\n'))
			commonsStr += '\n\n';
 
		return commonsStr;
	}
 
 
	/*************************
	 ***  OPTIONS PANEL
	 ***
	 ***/
 
 
	/* PUBLIC */
	// called when the user clicks on the "Cat/Tr/FA/Comm" portlet link
	function showPanel()
	{
		$('#wikiTranslToolsCodeBox').remove();
 
		if (!$('#wikiTranslToolsPanel').show()[0])
			createThePanel();
	}
 
 
	function createThePanel()
	{
		if (!targetWiki.lang)
			setTargetWiki(prompt(msgs.enterTargetWiki, options.defaultWiki));
 
		var $wikiTranslToolsPanel = $('</div>', {
			css: {
				color: '#000',
				backgroundColor: '#f4f4f4',
				fontSize: 'small',
				position: 'relative',
				margin: '1em auto'
			},
			id: 'wikiTranslToolsPanel'
		}).append(
			$('</a>', {
				text: msgs.targetWiki.replace(/%targetWiki%/, (targetWiki.lang || options.defaultWiki)),
				href: '#',
				'class': 'wtt_targetWikiLangLink',
				css: {
					marginRight: '1em',
					position: 'absolute',
					bottom: '2px',
					right: '2px'
				},
				click: function (e) {
					e.preventDefault();
					setTargetWiki(prompt(msgs.enterTargetWiki, (targetWiki.lang || options.defaultWiki)));
				}
			}),
			$('</div>', {
				css: {position: 'absolute', right: '2px', top: '2px'}
			}).append(
				$('</a>', {
					text: '[?]',
					target: '_blank',
					href: options.helpUrl
				}),
				$('</a>', {
					text: '[X]',
					href: '#',
					click: function (e) {
						e.preventDefault();
						$wikiTranslToolsPanel.hide();
					}
				})
			)
		);
 
		var optionCheckboxes = [
			{val: 'translatedPage', checked: true, label: msgs.translatedPageOption},
			{val: 'commons', checked: true, label: msgs.commonsOption},
			{val: 'interwikis', checked: false, label: msgs.interwikis}
		];
 
		if (targetWiki.translatedPageTemplate == 'none') {
			optionCheckboxes[0].checked = null;
			optionCheckboxes[0].disabled = 'disabled';
		}
 
		var $form = $('</form>', {
			id: 'wikiTranslToolsForm',
			submit: function (e) {
				e.preventDefault();
				formOk(this);
			}
		})
		.append('</input type="submit" value="' + msgs.okButtonLabel + '">');
 
		$.each(optionCheckboxes, function (i, val) {
			$form.append($('</label style="margin-left:0.5em;">').append($('</input type="checkbox">').attr({
				name: 'options',
				value: val.val,
				checked: (val.checked ? 'checked' : null),
				disabled: (val.disabled ? 'disabled' : null)
			}), textNode(val.label)))
		});
 
		$form.append('<div style="margin-top:1em;"><b>' + msgs.categories + '</b><div>',
			createTheCategoryBrowser(),
			'</input type="submit" value="' + msgs.okButtonLabel + '" style="margin-top:1em;">'
		);
		display($wikiTranslToolsPanel.append($form));
	} // createThePanel()
 
 
	function formOk(frm)
	{
		var checkedOptions = {};
		var optionCheckboxes = $('input:checkbox[name=options]:checked', frm);
 
		$.each(optionCheckboxes, function (i, val) {
			checkedOptions[val.value] = true;
		});
 
		var catsStr = getCheckedCats(frm);
		$('#wikiTranslToolsPanel').hide();
 
		displayCode(
			(checkedOptions.commons ? getCommonsTemplates() : '')
			+ (checkedOptions.translatedPage ? targetWiki.translatedPageTemplate + nl + nl : '')
			+ (catsStr ? catsStr + nl + nl : '')
			+ (checkedOptions.interwikis ? getInterwikiCode() : '')
		);
	}
 
 
	/*************************
	 ***  CATEGORIES
	 ***
	 ***/
 
 
	function createTheCategoryBrowser() {
		var catArr = [];
 
		// if possible, fill catArr with the non-hidden cats only,
		//  otherwise use wgCategories
		if (skin.catLinks)
			catArr = $(skin.catLinks + ' a').map(function(i) {
				if (i == 0) return null; // skip the 'Categories:' link
				return $(this).text();
			}).toArray();
		else
			catArr = mw.config.get('wgCategories');
 
		if (catArr.length == 0)
			return $([]);
 
		allCats = {};
 
		// create the main UL and sub li's with the category names
		var $top_ul = $('</ul>', {'class': 'wtt_catBrowser'});
 
		var $top_li;
		for (var i = 0; i < catArr.length; i++)
		{
			var expandLink = createExpandCatLink();
 
			$top_li = $('</li>').append(expandLink, textNode(' '), '<span>' + catArr[i] + '</span>');
			allCats[catArr[i]] = {
				name: catArr[i],
				liElement: $top_li // the innermost <li> within which the category's name is shown
			};
 
			$top_ul.append($top_li);
 
			if (catArr.length <= options.maxCatsToAutoExpand)
				expandLink.click();
		}
 
		return $top_ul[0];
	} // createTheCategoryBrowser
 
 
	function createExpandCatLink()
	{
		return $('</a>', {
			text: '[+]',
			href: '#',
			click: function() {
				expandCat(this);
				return false;
			},
			css: {textDecoration: 'none'}
		});
	}
 
 
	// Called when the user clicks on a [+] expand link in the Category Browser
	function expandCat(startCatExpandLinkEl)
	{
		var startCatLink = $(startCatExpandLinkEl);
		var catSpan = $('span', startCatLink.parent()); // it contains the name of the cat to be expanded
 
		startCatLink.off('click').text('...'); // replace "[+]" with "..."
		startCatLink.attr('class', 'waitingExpandLink');
		var cat = allCats[$(catSpan[0]).text()];
		var catNsAndNameEscaped = encodeURIComponent(thisWiki.catNS + ':' + cat.name);
		$.ajax({
			url: '/w/api.php?action=query&prop=langlinks|categories&titles='
				+ catNsAndNameEscaped
				+ '&lllang=' + (targetWiki.lang || options.defaultWiki)
				+ '&cllimit=200&redirects&format=json',
			dataType: 'json',
			success: catInfoReceived(cat),
			error: function (XMLHttpRequest) {
				showCatParents(cat);
			}
		});
	}
 
 
	// creates and returns a function to be called when the requested Category page information is received
	function catInfoReceived(cat)
	{
		return function(data) {
			function parentCats(data) {
				var pages = data && data.query && data.query.pages;
				if (!pages)
					return;
 
				var pg;
				for (var p in pages) {
					if (pages.hasOwnProperty(p))
						pg = pages[p];
				}
 
				var catObjs = pg && pg.categories;
				if (!catObjs)
					return;
 
				var cats = [];
				for (var i = 0; i < catObjs.length; i++) {
					cats.push(catObjs[i].title.replace(/^[^:]+:/, ''));
				}
				return cats;
			}
 
			showCatParents(cat, parentCats(data), getTargetwikiFromJson(data));
		};
	} // catInfoReceived
 
 
	// called by expandCat() to add the parent categories
	//  of the specified category to the displayed list.
	function showCatParents(cat, parents, targetWikiCat)
	{
		var top_li = cat.liElement;
		var server = mw.config.get('wgServer');
 
		$('.waitingExpandLink', top_li).remove();
 
		if (targetWikiCat) {
			var targetWikiLink = $('</a>', {
				text: targetWikiCat,
				href: targetWiki.server + '/wiki/' + targetWikiCat,
				target: '_blank'
			});
 
			top_li.append(textNode(' – '),
				'</input type="checkbox" name="targetWikiCats" value="' + targetWikiCat + '">',
				textNode(' ' + (targetWiki.lang || options.defaultWiki) + ':'),
				targetWikiLink);
		}
		else if (parents && parents.length > 0) {
			var new_ul = $('</ul>');
 
			var new_li;
			var alreadyListed;
			for (var i = 0; i < parents.length; i++) {
				new_li = $('</li>');
 
				alreadyListed = false;
 
				if (allCats[parents[i]])
					alreadyListed = $('<em>(' + msgs.alreadyListed + ')</em>');
				else {
					new_li.append(createExpandCatLink(), textNode(' '));
					allCats[parents[i]] = {
						name: parents[i],
						liElement: new_li // the innermost <li> within which the category's name is shown
					};
				}
 
				new_li.append('<span>' + parents[i] + '</span>');
				if (alreadyListed)
					new_li.append(textNode(' '), alreadyListed);
				new_ul.append(new_li);
			}
 
			top_li.append(new_ul);
		} // if (parents.length > 0)
		else { // if no target-wiki cat and no parent cats found, create a link to the cat,
			//  so the user can check manually
			var catSpan = $('span', top_li).empty();
			catSpan.append($('</a>', {
				href: server + '/wiki/'
					+ thisWiki.catNS + ':' + cat.name,
				target: '_blank',
				text: cat.name
			}))
			.append(textNode(' '),
				// no parents arr is passed if the cat doesn't exist (404 or other error received)
				$('<em>(' + msgs.error + ')</em>')
			);
		}
	} // showCatParents
 
 
	function getCheckedCats(frm)
	{
		var targetWikiCats = $('input:checkbox[name=targetWikiCats]:checked', frm).map(function(){
			return this.value;
		}).toArray();
 
		if (targetWikiCats.length == 0)
			return '';
		else
			return '[[' + targetWikiCats.join(']]' + nl + '[[') + ']]';
	}
 
 
	/*************************
	 ***  TRANSLATE LINKS
	 ***
	 ***/
 
 
	/* PUBLIC */
	// called when the user clicks on the "Links to (language code)" portlet link
	function translateLinks()
	{
		var namespaceIds = mw.config.get('wgNamespaceIds');
		var hWLs = $('.wtt_targetWikiLink');
		if (hWLs.length > 0) {
			hWLs.toggle(); // previously shown for the current language
			return;
		}
 
		if (!targetWiki.lang) {
			setTargetWiki(prompt(msgs.enterTargetWiki, options.defaultWiki));
			if (!targetWiki.lang)
				return;
		}
 
		$($('#mw-content-text')[0] || $('body')).find('a')
		.not('#wikiTranslToolsPanel a').not(skin.catLinks + ' a').not('a.external')
		.filter('[href^="/wiki/"]').after(function () {
			var article = this.href.match(/wiki\/([^#?]+)/);
 
			if (!article)
				return null;
			article = article[1];
 
			// Check if the namespace is in the array of approved namespaces: NamespacesWithInterwikis
			var ns = article.match(/[^:]+(?=:)/);
			if (ns) {
				var nsNum = namespaceIds[ns[0].toLowerCase()];
				if (nsNum && ($.inArray(nsNum, NamespacesWithInterwikis) == -1))
					return null;
			}
 
			var span = $('</sup>', {
				text: ' [[',
				'class': 'wtt_targetWikiLink reference'
			}).append($('</a>', {
				text: targetWiki.lang + ':?',
				href: '#',
				data: {articleName: article},
				click: function () {
					findTargetWikiLink($(this));
					return false;
				}
			})).append(textNode(']]'));
 
			return span;
		});
	}
 
 
	// This function is called when the user clicks on one of the [[lang:?]] links
	function findTargetWikiLink($clickedLink)
	{
		var articleName = $clickedLink.data('articleName');
		$.ajax({
			url: '/w/api.php?action=query&prop=langlinks&titles=' + articleName
				+ '&lllang=' + targetWiki.lang + '&redirects&format=json',
			dataType: 'json',
			success: function (data) {
				interwikiReceived(data, $clickedLink);
			}
		});
	}
 
 
	function interwikiReceived(data, $clickedLink)
	{
		var targetWikiPage = getTargetwikiFromJson(data);
		if (!targetWikiPage) {
			$clickedLink.replaceWith($('</span>', {
				text: targetWiki.lang,
				css: {textDecoration: 'line-through'}
			}));
			return;
		}
 
		var newLink = $('</a>', {
			href: targetWiki.server + '/wiki/' + targetWikiPage.replace(/ /, '_'),
			target: '_blank',
			text: targetWiki.lang + ':'
		});
 
		var input = $('<input type="text" style="vertical-align: bottom; direction: ltr;">').attr({
			value: targetWikiPage,
			size: Math.floor(targetWikiPage.length * 4/3),
			readonly: 'readonly'
		});
 
		var redirects = data && data.query && data.query.redirects;
		if (redirects)
			for (var i = 0; i < redirects.length; i++) {
				$clickedLink.before($('<span title="' + redirects[i].to + '">&gt;</span>'));
			}
		$clickedLink.after(input);
		$clickedLink.replaceWith(newLink);
		input.select();
	}
 
 
	/*************************
	 ***  Other Functions
	 ***
	 ***/
 
 
	function getTargetwikiFromJson(data) {
		//{"query":{"pages":{"5152":{"pageid":5152,"ns":0,"title":"2007","langlinks":[{"lang":"bg","*":"2007"}]}}}}
		var pages = data && data.query && data.query.pages;
		if (!pages)
			return;
 
		var pg;
		for (var p in pages) {
			if (pages.hasOwnProperty(p))
				pg = pages[p];
		}
 
		return pg && pg.langlinks && pg.langlinks[0] && pg.langlinks[0]['*'];
	}
 
 
	function display($el) {
		// any normal skin || Cologne Blue skin:
		$('#contentSub').prepend($el)[0] || $('#mw-content-text').prepend($el);
		//	mw.util.$content.prepend($el) doesn't work in IE 7 (layout bug)
		$('html, body').scrollTop(0);
	}
 
 
	function displayCode(str)
	{
		str = $.trim(str);
		if ($.isFunction(options.hook))
			str = options.hook(str);
 
		var $ta = $('</textarea>', {
			css: {direction: 'ltr'},
			cols: options.taCols,
			rows: options.taRows
		});
 
		var $codeBoxDiv = $('</div>', {
			id: 'wikiTranslToolsCodeBox',
			css: {width: '80%', margin: '1em auto', position: 'relative'}
		}).append($ta,
			$('</div>')
			.css({position: 'absolute', top: 0, right: '-4em', fontSize: 'small'})
			.append(
				$('</a>', {
					href: '#',
					text: '[<]',
					click: function (e) {
						e.preventDefault();
						$codeBoxDiv.remove();
						showPanel();
					}
				}),
				$('</a>', {
					href: options.helpUrl,
					target: '_blank',
					text: '[?]'
				}),
				$('</a>', {
					href: '#',
					text: '[X]',
					click: function (e) {
						e.preventDefault();
						$codeBoxDiv.remove();
					}
				})
			)
		);
 
		display($codeBoxDiv);
		$ta.focus().val(str).select().scrollTop(0);
	}
 
 
	function addPortletLinks()
	{
		var ns = mw.config.get('wgCanonicalNamespace');
		var linksToLang = msgs.linksToLang.replace(/%targetWiki%/, (targetWiki.lang || '?'));
 
		if (ns != 'Special' && ns != 'MediaWiki') {
			if (!$('#wtt_showPanelLink')[0])
				mw.util.addPortletLink('p-tb', 'javascript:wikiTranslTools.showPanel(); void(0);',
					msgs.showPanelLink,
					'wtt_showPanelLink',
					msgs.showPanelTitle
				);
		}
		if (!$('#wtt_translateLinksLink')[0])
			mw.util.addPortletLink('p-tb', 'javascript:wikiTranslTools.translateLinks(); void(0);',
				linksToLang,
				'wtt_translateLinksLink',
				linksToLang
			);
	}
 
 
	/* PUBLIC */
	// call after updating window.wikiTranslToolsConfig
	function init(noPortletLinks)
	{
		$('#wtt_showPanelLink').remove();
		$('#wtt_translateLinksLink').remove();
		$('#wikiTranslToolsPanel').remove();
		$('.wtt_targetWikiLink').remove();
 
		var wttC = window.wikiTranslToolsConfig;
		if (wttC) {
			if (!wttC.targetWiki) wttC.targetWiki = wttC.homeWiki; //' To be removed soon...
			$.extend(targetWiki, wttC.targetWiki);
			$.extend(true, thisWiki, wttC.thisWiki);
			$.extend(skin, wttC.skin);
			$.extend(msgs, wttC.msgs);
			$.extend(options, wttC.options);
			if (wttC.msgs && !wttC.msgs.linksToLang && wttC.msgs.linksTo) //' To be removed soon...
				msgs.linksToLang = msgs.linksTo + ' %targetWiki%';
			if (targetWiki.translatedPageTemplate == 'Превод от') //' To be removed soon...
				targetWiki.translatedPageTemplate = '{{Превод от|%sourceWiki%|%pageTitle%|%revisionId%}}';
		}
 
		if (!checkIfValidWiki(options.defaultWiki))
			options.defaultWiki = 'en';
		if (!checkIfValidWiki(targetWiki.lang))
			targetWiki.lang = '';
		else
			setTargetWiki(targetWiki.lang);
 
		targetWiki.server = mw.config.get('wgServer')
			.replace(thisWiki.lang, (targetWiki.lang || options.defaultWiki));
 
		targetWiki.translatedPageTemplate = targetWiki.translatedPageTemplate
		.replace(/%sourceWiki%/g, thisWiki.lang)
		.replace(/%pageTitle%/g, THIS_ARTICLE)
		.replace(/%revisionId%/g, mw.config.get('wgRevisionId'));
 
		if (!noPortletLinks && mw.config.get('wgAction') == 'view')
			$(addPortletLinks);
	}
 
 
	function checkIfValidWiki(wikiCode)
	{
		return (wikiCode && !/[^A-Za-z0-9-]/.test(wikiCode));
	}
 
 
	function setTargetWiki(newTargetWiki)
	{
		newTargetWiki = $.trim(newTargetWiki);
		if (!checkIfValidWiki(newTargetWiki) || newTargetWiki == targetWiki.lang)
			return;
 
		targetWiki.lang = newTargetWiki;
		targetWiki.server = mw.config.get('wgServer').replace(thisWiki.lang, newTargetWiki);
		$('.wtt_targetWikiLink').remove();
 
		var newLinksToLangPortletText = msgs.linksToLang.replace(/%targetWiki%/, targetWiki.lang);
		$('#wtt_translateLinksLink a').attr('title', newLinksToLangPortletText).text(newLinksToLangPortletText);
		var $panel = $('#wikiTranslToolsPanel');
		if ($panel[0]) {
			$panel.find('.wtt_targetWikiLangLink').text(msgs.targetWiki.replace(/%targetWiki%/, targetWiki.lang));
			$panel.find('.wtt_catBrowser').replaceWith(createTheCategoryBrowser());
		}
	}
 
 
	init();
 
 
	/* All public member functions */
	return {
		init:              init,
		showPanel:         showPanel,
		translateLinks:    translateLinks
	};
}());