Jump to content

User:Doc James/punctuation2.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
$.when(mw.loader.using('mediawiki.util'), $.ready).then(function ()
{
	// Temporary copy from https://ru.wikipedia.org/wiki/Участник:Ignatus/shiftrefs.js
	// Authors: https://ru.wikipedia.org/wiki/Участник:Ignatus/shiftrefs.js?action=history

	/*************************************************************/
	/*****      Сдвигает все ссылки на знаки препинания      *****/
	/*************************************************************/
	function lebedevrefs()
	{
		var diglasttext;
		var getsimpletext;
		diglasttext = function (n)
		{
			return n.lastChild ? diglasttext(n.lastChild) : n
		};
		getsimpletext = function (n)
		{
			return n.innerHTML.replace(/<(?:"(?:\\\\|\\"|\\[^"]|[^\\"])*"|'(?:\\\\|\\'|\\[^']|[^\\'])*'|[^"'>])+>/ig, ''); //'
		}; //innerText работает не везде
		var zone = document.getElementById('wikiPreview') || document.getElementById('bodyContent') ||
			document.getElementById('mw_contentholder') || document.getElementById('article');

		var alles = Array();
		{
			var j = zone.getElementsByTagName('*');
			for (var i = 0; i < j.length; i++)
			{
				alles[i] = j[i]
			};
		};
		var getdots = /^([\s\S]*?)([.,…،؛]*)$/;
		var i = 0;
		var f = function ()
		{
			if (i < alles.length)
			{
				var ch = alles[i].childNodes;
				// Ищем последовательности элементов класса reference
				// а также рассматриваем ноды до и после них
				for (var j = 0; j < ch.length; j++)
				{
					var l = 0;
					while (j + l < ch.length // &&
						&&
						(ch[j + l].nodeType == 1) // && // элемент
						&&
						/(^|\s)reference(\s|$)/i.test(ch[j + l].className)
					)
					{
						l++
					};
					if (l)
					{ //есть группа
						var grp = document.createElement('span');
						for (var k = 0; k < l; k++)
						{
							grp.appendChild(ch[j]);
							//alles[i].removeChild(ch[j]);//автоматом
						};
						if (j < ch.length)
						{
							alles[i].insertBefore(grp, ch[j])
						}
						else
						{
							alles[i].appendChild(grp)
						};
						grp.style.whiteSpace = 'nowrap';
						var ppw = 0.;
						if (j)
						{
							if (ch[j - 1].nodeType == 3)
							{ // текст
								var a = /^([\S\s]*\s)?(\S*?)([،؛.,…]*)?$/.exec(ch[j - 1].nodeValue);
								ch[j - 1].nodeValue = a[1] || '';
								var b = document.createElement('span');
								var t = document.createTextNode(a[3] || a[2]);
								b.appendChild(t);
								grp.insertBefore(b, grp.firstChild);
								if (a[3])
								{
									if (mw.config.get('wgPageContentLanguage') == 'ar')
									{
										b.style.marginLeft = '-' + b.offsetWidth + 'px';
									}
									else
									{
										b.style.marginRight = '-' + b.offsetWidth + 'px';

									}
									t.nodeValue = a[2] + t.nodeValue;
								};
								ppw = b.offsetWidth;
							}
							else
							{ // если предыдущий узел - элемент
								var lt = diglasttext(ch[j - 1]);
								var a = getdots.exec(lt.nodeValue);
								if (a[2])
								{ //финишные точки выделяем
									lt.nodeValue = a[1];
									var b = document.createElement('span');
									b.appendChild(document.createTextNode(a[2]));
									lt.parentNode.appendChild(b);
									ppw = b.offsetWidth;
									if (mw.config.get('wgPageContentLanguage') == 'ar')
									{
										b.style.marginLeft = '-' + ppw + 'px';
									}
									else
									{
										b.style.marginRight = '-' + ppw + 'px';

									}
								};
								if (/nowrap|pre$/.test(ch[j - 1].style.whiteSpace) || !/\s/.test(getsimpletext(ch[j - 1])))
								{
									//если его можно втащить в неразрывный текст, делаем это
									grp.insertBefore(ch[j - 1], grp.firstChild);
									ppw += grp.firstChild.offsetWidth;
								}
							}; //else  
						}; //if ( j )
						if (grp.nextSibling)
						{ //Смотрим дальше, если текст, отрезаем начальную точку
							if (grp.nextSibling.nodeType == 3)
							{
								var a = /^([.،؛,…]*)([\s\S]*?)$/.exec(grp.nextSibling.nodeValue);
								if (a[1])
								{
									grp.nextSibling.nodeValue = a[2];
									var b = document.createElement('span');
									b.appendChild(document.createTextNode(a[1]));
									grpw = grp.offsetWidth;
									grp.appendChild(b);
									if (mw.config.get('wgPageContentLanguage') == 'ar')
									{
										b.previousSibling.style.marginLeft = (ppw - grpw) + 'px';
									}
									else
									{
										b.previousSibling.style.marginRight = (ppw - grpw) + 'px';

									}
									b.previousSibling.style.position = 'relative';
									if (mw.config.get('wgPageContentLanguage') == 'ar')
									{
										b.previousSibling.style.right = '2px';
									}
									else
									{
										b.previousSibling.style.left = '2px';

									}
									b.previousSibling.style.borderBottom = 'red 2px dotted';
									if (mw.config.get('wgPageContentLanguage') == 'ar')
									{
										b.style.marginLeft = (grpw - ppw - b.offsetWidth) + 'px';
									}
									else
									{
										b.style.marginRight = (grpw - ppw - b.offsetWidth) + 'px';

									}
								} //if(a[1])
							} //if( grp.nextSibling.nodeType==3 )
						} //if(grp.nextSibling)
					} //if(l)
				}; //for(ch)
				i++;
				window.setTimeout(f, 0); //обрабатываем действия пользователя, затем идём дальше
			}
			else
			{ //(i>=alles.length)
				f = null; //помогаем мусорнице
			}; //if(i<alles.length)
		}; //f
		if (alles.length)
		{
			f()
		}; //запускаем выполнение
	};
	if (mw.config.get('wgNamespaceNumber') >= 0 && mw.config.get('wgUserName')) $(lebedevrefs);
	log('loaded shiftrefs');

});


//زر صندوق التحرير

//importScript( 'User:Erutuon/scripts/footnoteCleanup.js' ); // Backlink: [[User:Erutuon/scripts/footnoteCleanup.js]] // Moves refs and citation needed tags after punctuation.

var customizeToolbar = function ()
{
	$('#wpTextbox1').wikiEditor('addToToolbar',
	{
		'section': 'advanced',
		'group': 'format',
		'tools':
		{
			'section':
			{
				label: 'تصويب مكان علامات المراجع',
				type: 'button',
				icon: '//upload.wikimedia.org/wikipedia/commons/e/e0/نقطة_مرجع_محرر_الويكي.png',
				action:
				{
					type: 'callback',
					execute: function (context)
					{
						cleanUpFootnotes();
					}
				}
			}
		}
	});
};

/* Check if view is in edit mode and that the required modules are available. Then, customize the toolbar … */
if (['edit', 'submit'].indexOf(mw.config.get('wgAction')) !== -1)
{
	mw.loader.using('user.options').then(function ()
	{
		// This can be the string "0" if the user disabled the preference ([[phab:T54542#555387]])
		if (mw.user.options.get('usebetatoolbar') == 1)
		{
			$.when(
				mw.loader.using('ext.wikiEditor'), $.ready
			).then(customizeToolbar);
		}
	});
}

// Add the customizations to LiquidThreads' edit toolbar, if available
mw.hook('ext.lqt.textareaCreated').add(customizeToolbar);


function cleanUpFootnotes()
{
	var textbox = $("#wpTextbox1");
	if (!textbox)
		return;
	const oldContents = textbox.val();
	var contents = oldContents;
	var escaped = [];
	var i = 0;
	var replacements = [];
	var count = 0;
	var escape = function (text, regexString)
	{
		var regex = new RegExp(regexString, "g");
		text = text.replace(
			regex,
			function (match)
			{
				escaped[i] = match;
				var replacement = "%%" + i + "%%";
				i += 1;
				return replacement;
			}
		);
		return text;
	};
	var puncRegex = /((?:%%\d+%%)+)([\؛\،\.\,\;\:\"]{1,3})/g;
	var reorder = function (match, capture1, capture2)
	{
		count += 1;
		var replacement = capture2 + capture1;
		replacements.push(replacement);
		return replacement;
	};
	var fixPunctuationPlacement = function (text)
	{
		while (puncRegex.test(text))
			text = text.replace(
				/((?:%%\d+%%)+)([\؛\،\.\,\;\:\"]{1,3})/g,
				reorder
			);
		return text;
	};
	/* Escape various things:
	ref tags */
	contents = escape(
		contents,
		"<ref[^>]*>[^<]+<\\/ref>"
	);
	contents = escape(
		contents,
		"<ref[^\\/]+\\/>"
	);
	// citation needed
	contents = escape(
		contents,
		"\\{\\{(?:[Cc]itation needed|[Cc]n|[Ff]act|[Cc]b|[Cc]tn|[Rr]ef\\?)\\|[^\}]+\\}\\}"
	);
	contents = fixPunctuationPlacement(contents);
	// footnote templates
	/* Handles up to one level of nested templates.
	Any more, and there may be problems. */
	contents = escape(
		contents,
		"\\{\\{(?:sfn|efn|rfn)\\|(?:[^\\}]*?(?:\\{\\{[^\\}]+\\}\\})?)+\\}\\}"
	);
	if (i > 0)
	{
		mw.notify(i + " refs found.");
	}
	contents = fixPunctuationPlacement(contents);
	if (count > 0)
	{
		mw.notify(count + " correction" + ((count > 1 && "s") || "") + " made: " + replacements.join());
	}
	/* Unescape the various things escaped above.
	This has to be done twice, since escaping was done twice. */
	contents = contents.replace(
		/%%(\d+)%%/g,
		function (wholematch, number)
		{
			number = Number(number);
			return escaped[number];
		}
	);
	contents = contents.replace(
		/%%(\d+)%%/g,
		function (wholematch, number)
		{
			number = Number(number);
			return escaped[number];
		}
	);
	var isUnchanged = (oldContents === contents);
	if (isUnchanged)
	{
		mw.notify("No misplaced footnotes or tagging templates were found.");
	}
	textbox.val(contents);
	$("#wpSummary").val(function (index, summary)
	{
		var addition = "[[:ar:mediawiki:gadget-shiftrefs|تصويب مكان علامة المرجع]]";
		const afterSectionName = summary.match(/^(?:\/\*[^\*]+\*\/)?\s*(.+)/);
		if (afterSectionName && afterSectionName[1].length > 1)
		{
			addition = "; " + addition;
		}
		if (!isUnchanged && (!afterSectionName || !afterSectionName[1].includes(addition)))
			return summary + addition;
		else
			return summary;
	});
};