پرش به محتوا

کاربر:Ahmad252/scripts/editProtectedHelper.js

از ویکی‌پدیا، دانشنامهٔ آزاد

نسخه‌ای که می‌بینید نسخه‌ای قدیمی از صفحه است که توسط Ahmad252 (بحث | مشارکت‌ها) در تاریخ ‏۳ سپتامبر ۲۰۱۹، ساعت ۱۵:۳۰ ویرایش شده است. این نسخه ممکن است تفاوت‌های عمده‌ای با نسخهٔ فعلی داشته باشد.

نکته: برای دیدن تغییرات، ممکن است نیاز باشد که حافظهٔ نهانی مرورگر خود را پس از انتشار پاک‌سازی کنید. گوگل کروم، فایرفاکس، مایکروسافت اج و سافاری: کلید Shift را نگه دارید و روی دکمهٔ Reload در نوار ابزار مرورگر کلیک کنید. برای آگاهی از جزئیات و نحوهٔ پاک‌سازی حافظهٔ نهانی سایر مرورگرها، صفحهٔ ویکی‌پدیا:میانگیر مرورگرتان را خالی کنید را ببینید.
// Credits to [[:en:User:Jackmcbarn]], from [[:en:User:Jackmcbarn/editProtectedHelper.js]]
// <nowiki>
var browserHasDataCorruptionBug = $('<div style="color:#ffd"></div>')[0].outerHTML != '<div style="color:#ffd"></div>';
if(browserHasDataCorruptionBug && ('undefined' === typeof ephAllowDataCorruptionBug || !ephAllowDataCorruptionBug)) {
	$(document).ready(function() {
		$('.editrequest .mbox-text').append('<small>The editProtectedHelper script is currently disabled because your browser has a bug which will cause corruption of pages that it edits with Parsoid. See <a href="https://www.mediawiki.org/wiki/User:Catrope/IE_bugs#style_attributes_are_aggressively_normalized.2C_causing_data_loss">here</a> for details. To override this, add "ephAllowDataCorruptionBug = true;" immediately above the line where you load this script. You are responsible for any damage to pages that this causes.</small>');
	});
// only enable this on the latest revision of the page
} else if(mw.config.get('wgRevisionId') == mw.config.get('wgCurRevisionId')) {
	$(document).ready(function() {
		mw.loader.using( ['mediawiki.api'], function() {
			'use strict';
			var templateResponses = [
				[ '', '(پاسخ بدون الگو)' ],
				[ 'شد', 'انجام شد' ],
				[ 'نیمه شد', 'تا حدودی انجام شد:' ],
				[ 'نشد', 'انجام نشد:' ],
				[ 'حالا نه', 'فعلاً انجام نشد:' ],
				[ 'اجماع', 'انجام نشد: لطفاً پیش از استفاده از الگوی {{ویرایش حفاظت‌شده}}، برای این تغییر اجماع بگیرید.'] , // TODO make dynamic
				[ 'معتبر', 'انجام نشد: لطفاً برای تغییری که می‌خواهید انجامش دهید، منابع معتبری که از آن پشتیبانی کنند ارائه دهید.' ],
				[ 'جزئیات', 'انجام نشد: مشخص نیست که چه تغییری مدنظر شماست. لطفاً تغییر را به‌صورت «فلان را به بهمان تغییر بدهید» مطرح کرده و، در صورت نیاز، منابع معتبری برای آن فراهم کنید.' ],
				[ 'نادرست', 'انجام نشد: اینجا صفحهٔ بحث بحث روی بهبود الگو {{وح}} است. لطفاً درخواست خود را در بحث مقالهٔ مربوط مطرح کنید.'], // TODO make dynamic
				[ 'تمرین', 'انجام نشد: لطفاً ابتدا درخواستتان را در صفحهٔ تمرین الگو قرار دهید؛ برای اطلاعات بیشتر ویکی‌پدیا:تمرین و نمونه‌های آزمایشی الگو را ببینید.' ],
				[ 'حب', 'انجام نشد: اینجا صفحهٔ بحث بحث روی بهبود الگو {{وح}} است. اگر ممکن است، لطفاً درخواستتان را در صفحهٔ بحث مقالهٔ مربوط مطرح کنید. اگر قادر به ویرایش صفحهٔ بحث مقاله نیستید، می‌توانید درخواست را در ویکی‌پدیا:درخواست محافظت صفحه بنویسید.' ],
				[ 'قبلاً', 'پیشتر انجام شده' ],
				[ 'دارای دسترسی', 'انجام نشد: با توجه به سطح حفاظت صفحه، شما می‌توانید صفحه را ویرایش کنید. اگر همچنان نمی‌توانید چنین کنید، لطفاً درخواست را با ذکر جزئیات بیشتر باز کنید.'],
				[ 'منقضی', 'انجام نشد: سطح حفاظت صفحه از زمان قرارگیری این الگو تغییر کرده‌است و شما می‌توانید صفحه را ویرایش کنید. اگر همچنان نمی‌توانید چنین کنید، لطفاً درخواست را با ذکر جزئیات بیشتر باز کنید.'],
				[ 'توضیحات', 'انجام نشد: {{ویرایش حفاظت‌شده}} معمولاً برای ویرایش توضیحات، رده‌ها یا پیوندهای زبانی الگو که در زیرصفحهٔ توضیحات ثبت شده‌اند موردنیاز نیست. برای ویرایش زیرصفحهٔ توضیحات، روی گزینهٔ «ویرایش» در کنار عبارت «توضیحات الگو» در جعبهٔ آبی کلیک کنید.' ],
				[ 'نمک', 'انجام نشد: درخواست ایجاد دوباره صفحه‌های حذف‌شده و محافظت‌شده در برابر ایجاد باید در ویکی‌پدیا:بررسی حذف مطرح شوند.' ],
				[ 'افزایش', 'انجام نشد: درخواست‌های افزایش سطح حفاظت صفحه باید در ویکی‌پدیا:درخواست محافظت صفحه مطرح شوند.' ],
				[ 'کاهش', 'انجام نشد: درخواست کاهش سطح حفاظت صفحه باید با مدیر محافظت‌کننده یا در صورت عدم پاسخگویی یا رد شدن درخواست توسط او، در ویکی‌پدیا:درخواست محافظت صفحه مطرح شوند.' ],
				[ 'دبد', 'انجام نشد: این صفحه برای درخواست دسترسی‌های بیشتر نیست. می‌توانید این درخواست را با مشخص کردن تغییری که مدنظرتان است باز کنید تا یک کاربر دارای دسترسی انجامش دهد.'], // TODO make dynamic
				[ 'انتقال', 'انجام نشد: درخواست‌های انتقال صفحه باید در ویکی‌پدیا:درخواست انتقال مطرح شوند.' ],
				[ 'پرسش', 'پرسش:' ],
				[ 'یاد', 'یادداشت:' ],
				[ 'نیمه‌وگ', 'خنثی‌شده: بخشی از این درخواست خنثی شده‌است.' ],
				[ 'وگ', 'خنثی‌شده: این درخواست خنثی شده‌است.' ]
			];
			var selector = $('.editrequest .mbox-text');

			// Global variable. In onParsoidDomReceived, this is set
			// to the ETag header so that we can pass it back later 
			// in convertModifiedDom.
			var gEtag;

			// Global variable. In onParsoidDomReceived, this is
			// set to the string we get back from the Parsoid API.
			// Used in convertModifiedDom.
			var parsoidDom;

			var selectedLevel = { semi: [' selected="selected"', '', '', '', ''], extended: ['', ' selected="selected"', '', '', ''], template: ['', '', ' selected="selected"', '', ''], full: ['', '', '', ' selected="selected"', ''], interface: ['', '', '', '', ' selected="selected"'] };
			var templateLevel = { semi: 'نیمه‌', extended: 'پایدار', template: 'الگو', full: '', interface: 'رابط‌' };
			var responseLevel = { semi: '{' + '{جا:ونح|', extended: '{' + '{جا:وپح|', template: '{' + '{جا:واح|', full: '{' + '{جا:وح|', interface: '{' + '{جا:ورح|' };
			var warnOnRespond = false, warnOnQuickRespond = true, warnOnRemove = true, autoFixLevel = true;
			var quickResponses = [
				[ 'شد', '', 'انجام شد'],
				[ 'معتبر', '', 'نیازمند منابع معتبر'],
				[ 'جزئیات', '', 'درخواست گنگ'],
				[ 'دارای دسترسی', '', 'همیشه قابلیت ویرایش بوده'],
				[ 'منقضی', '', 'حالا می‌توانید ویرایش کنید'],
				[ 'نادرست', '', 'جای نادرست']
			];
			if('undefined' !== typeof ephWarnOnRespond) {
				warnOnRespond = ephWarnOnRespond;
			}
			if('undefined' !== typeof ephWarnOnQuickRespond) {
				warnOnQuickRespond = ephWarnOnQuickRespond;
			}
			if('undefined' !== typeof ephWarnOnRemove) {
				warnOnRemove = ephWarnOnRemove;
			}
			if('undefined' !== typeof ephAutoFixLevel) {
				autoFixLevel = ephAutoFixLevel;
			}
			if('undefined' !== typeof ephQuickResponses) {
				quickResponses = ephQuickResponses;
			}
			function yesno(val, def) {
				if(typeof val === 'string') {
					val = val.toLowerCase();
				}
				if(typeof val === 'undefined' || val === '') {
					return undefined;
				} else if(val === 'yes' || val === 'y' || val === 'true' || val === 1) {
					return true;
				} else if(val === 'no' || val === 'n' || val === 'false' || val === 0) {
					return false;
				}
				return def;
			}
			function getBanner(level, pagename, answered, force, demo) {
				return '{{ویرایش ' + templateLevel[level] + 'حفاظت‌شده' + (pagename !== '' ? '|' + pagename : '') + '|پاسخ‌داده‌شده=' + (answered ? 'بله' : 'خیر') + (force ? '|force=yes' : '') + (demo ? '|demo=yes}}' : '}}');
			}
			function getResponse(level, template, free) {
				return ':' + (template === '' ? '' : responseLevel[level] + template + '}} ') + (free === '' ? '' : free + ' ') + '~~' + "~~\n";
			}
			function makeUniqueString(index) {
				// this looks like a strip marker on purpose
				return "\x7fUNIQ" + Math.random().toString(16).substr(2) + '-editProtectedHelper-' + index + "-QINU\x7f";
			}
			function saveWikitextFromParsoid(parsoidObj, data) {
				var newWikitext, tmp, removerequest = false;
				if(parsoidObj.removerequest) {
					tmp = data.split(parsoidObj.templateMarker);
					removerequest = true;
					newWikitext = tmp[0];
					if(parsoidObj.respondedInPage) {
						tmp = tmp[1].split(parsoidObj.responseMarker);
						newWikitext = newWikitext.replace(/\n+$/, '') + "\n\n" + tmp[1].replace(/^\n+/, '');
					}
				} else {
					var response = getResponse(parsoidObj.form.level.value, parsoidObj.form.responsetemplate.value, parsoidObj.form.responsefree.value);
					var banner = getBanner(parsoidObj.form.level.value, parsoidObj.form.pagetoedit.value, parsoidObj.form.answered.checked, parsoidObj.form.force.checked, parsoidObj.demo);
					// prevent empty response
					if(response == ':~~' + "~~\n") {
						response = '';
					}
					tmp = data.split(parsoidObj.templateMarker);
					newWikitext = tmp[0].replace(/\n*$/, tmp[0].trim().length ? "\n\n" : '') + banner + tmp[1].replace(/^\n*/, "\n");
					if(parsoidObj.respondedInPage) {
						tmp = newWikitext.split(parsoidObj.responseMarker);
						newWikitext = tmp[0].replace(/\n*$/, "\n") + response + tmp[1].replace(/^\n*/, "\n");
					} else {
						newWikitext = newWikitext.replace(/\n*$/, "\n") + response;
					}
				}
				var resultObj = parsoidObj.resultObj, sectionName = parsoidObj.section && parsoidObj.section.text().trim();
				if(sectionName && (sectionName.indexOf(parsoidObj.templateMarker) !== -1 || sectionName.indexOf(parsoidObj.responseMarker) !== -1)) {
					// someone put an edit request template inside the section header, or something like that.
					// don't even try to include a working section link in that case
					sectionName = null;
				}
				//console.log(newWikitext);
				resultObj.text('ذخیره...');
				debugger; // triggers only if debugger is active
				new mw.Api().get( { action: 'query', prop: 'revisions', rvprop: 'timestamp', revids: mw.config.get('wgRevisionId') }).done(function(data) {
					new mw.Api().postWithEditToken( { action: 'edit', pageid: mw.config.get('wgArticleId'), text: newWikitext, summary: (sectionName ? '/' + '* ' + sectionName + ' *' + '/ ' : '') + (removerequest ? 'حذف' : 'پاسخ به') + ' درخواست ویرایش ([[WP:EPH|EPH]])', notminor: true, nocreate: true, basetimestamp: data.query.pages[mw.config.get('wgArticleId')].revisions[0].timestamp } ).done(function(result) {
						if(typeof(result.edit.newrevid) === 'undefined' || typeof(result.edit.oldrevid) === 'undefined') {
							resultObj.css('color', 'red').text("خطا: بازخورد ای‌پی‌آی اطلاعات لازم را حذف کرده‌است. لطفاً تاریخچه را بررسی کنید تا از ذخیره ویرایش مطمئن شوید. کنسول ممکن است شامل جزئیاتی باشد.");
						} else {
							resultObj.css('color', 'green').text('موفقیت‌آمیز: بارگذاری تفاوت...');
							if( window.editProtectedHelperReloadAfter ) {
								window.location.reload( /* forcedReload */ true );
							} else {
								location.href = mw.config.get('wgScript') + '?diff=' + result.edit.newrevid + '&oldid=' + result.edit.oldrevid;
							}
						}
					}).fail(function(err) {
						resultObj.css('color', 'red').text('خطا: ' + err + '. کنسول ممکن است شامل جزئیاتی باشد.');
					}).always(console.log);
				});
			}
			function convertModifiedDom(e) {
				var parsoidObj, nextRequestBeforeHeader = false;
				if(warnOnRespond && !confirm('آیا از پاسخ به این درخواست ویرایش مطمئن هستید؟')) {
					return false;
				}
				$('.editrequest button').prop('disabled', true);
				parsoidObj = e.data;
				parsoidObj.resultObj.text('آماده‌سازی ویکی‌متن تازه...');
				$(parsoidObj).before(parsoidObj.templateMarker);
				$('h1,h2,h3,h4,h5,h6,.editrequest', parsoidDom).each(function() {
					var obj = $(this);
					if(!obj.hasClass('editrequest')) {
						// a heading
						if(obj.closest('[typeof="mw:Transclusion"]').length) {
							// it's from a template transclusion. ignore
							return true;
						}
						if(obj.add(parsoidObj)[0] === this) {
							// before our banner. set as our section header (tentatively) and otherwise ignore
							parsoidObj.section = obj;
							return true;
						}
					} else if (obj.add(parsoidObj)[0] === this) {
						// not after our banner. ignore
						return true;
					} else {
						nextRequestBeforeHeader = true;
					}
					obj.before(parsoidObj.responseMarker);
					parsoidObj.respondedInPage = true;
					return false;
				});
				if(parsoidObj.removerequest && !nextRequestBeforeHeader && $(parsoidObj).prev().is(parsoidObj.section)) {
					// if the section header is immediately before a request being removed, remove it too
					parsoidObj.section.remove();
				}
				$('[about="' + $(parsoidObj).attr('about').replace('\\', '\\\\').replace('"', '\\"') + '"]', parsoidDom).remove();
				$.ajax({
					type: 'POST',
					url: '/api/rest_v1/transform/html/to/wikitext/' + encodeURIComponent(mw.config.get('wgPageName')) + '/' + mw.config.get('wgRevisionId'),
					headers: {
						Accept: 'text/plain; charset=utf-8; profile="mediawiki.org/specs/wikitext/1.0.0"',
						'Api-User-Agent': 'editProtectedHelper (https://en.wikipedia.org/wiki/User:Jackmcbarn/editProtectedHelper)',
						'If-Match': gEtag
					},
					data: { html: parsoidDom.documentElement.outerHTML },
					success: function(data) { return saveWikitextFromParsoid(parsoidObj, data); }
				});
			}
			function appendForm(obj, level, pagename, answered, force, parsoidObj) {
				if(browserHasDataCorruptionBug) {
					$(obj).append('<div style="color:red;font-weight:bold">WARNING: Your browser has a bug which will cause corruption of pages that it edits with Parsoid. See <a href="https://www.mediawiki.org/wiki/User:Catrope/IE_bugs#style_attributes_are_aggressively_normalized.2C_causing_data_loss">here</a> for details. You are responsible for any damage to pages that this causes.</div>');
				}
				var form = $('<form class="editProtectedHelper" style="display: none" />');
				form.append('<style scoped>.mw-ui-input { background-color: white; }</style>');
				form.append('<label>سطح: <select name="level" class="mw-ui-input mw-ui-input-inline"><option value="semi"' + selectedLevel[level][0] + '>نیمه‌حفاطت‌شده</option><option value="extended"' + selectedLevel[level][1] + '>حفاظت‌شده پایدار</option><option value="template"' + selectedLevel[level][2] + '>الگوی حفاظت‌شده</option><option value="full"' + selectedLevel[level][3] + '>کاملاً حفاظت‌شده</option><option value="interface"' + selectedLevel[level][4] + '>رابط حفاظت‌شده</option></select></label> ');
				if(force) {
					form.append('<label>تشخیص خودکار سطح حفاظت را غیرفعال کن (اگر لازم شد استفاده کنید): <input type="checkbox" name="force" checked="checked" /></label> ' );
				} else {
					form.append('<input type="checkbox" name="force" style="display: none" />' ); // if this is off and you want to turn it on, do it with firebug or something. otherwise people will use this when they shouldn't
				}
				var label = $('<label>صفحه‌ای که باید ویرایش شود: </label>');
				label.append($('<input type="text" name="pagetoedit" class="mw-ui-input mw-ui-input-inline" />').attr('value', pagename !== '<!-- صفحه‌ای که باید ویرایش شود -->' ? pagename : ''));
				form.append(label);
				form.append(' <label>پاسخ‌داده‌شده: <input type="checkbox" name="answered"' + (answered ? ' checked="checked"' : '') + ' /></label><br />پاسخ: ');
				var select = $('<select name="responsetemplate" class="mw-ui-input" />');
				templateResponses.forEach(function(r) {
					select.append($('<option />').attr('value', r[0]).text(r[1]));
				});
				form.append(select);
				form.append('<textarea name="responsefree" class="mw-ui-input" placeholder="پاسخ سفارشی را در اینجا وارد کنید. امضا به‌طور خودکار افزوده می‌شود."></textarea> ~~' + '~~ ');
				var resultObj = $('<span></span>');
				var button = $('<button type="button" class="mw-ui-button mw-ui-constructive">ثبت</button>').click(parsoidObj, convertModifiedDom);
				form.append(button);
				form.append(' ');
				$(obj).append(form);
				var buttons = $('<div />');
				buttons.append($('<button type="button" class="mw-ui-button mw-ui-progressive">پاسخ</button>').click(function(){
					buttons.hide();
					$(obj).closest('.editrequest').removeClass('mbox-small');
					form.show();
				}))
				.append(' ')
				.append($('<button type="button" class="mw-ui-button mw-ui-destructive">حذف درخواست</button>').click(function(){
					if(!warnOnRemove || confirm('آیا از حذف کامل درخواست از این صفحه اطمینان دارید؟ به‌طور کلی، چنین کاری نباید روی درخواست‌های دارای حسن نیت انجام شود؛ حتی اگر خالی باشند. فقط در زمانی باید چنین کرد که یک درخواست در یک صفحه توسط یک کاربر چند بار تکرار شده‌باشد یا به دلیل منطقی دیگری نیاز به حذف آن باشد.')) {
						warnOnRespond = false;
						parsoidObj.removerequest = true;
						button.click();
					}
				}));
				if(!answered) {
					quickResponses.forEach(function(r){
						buttons.append(' ').append($('<button type="button" class="mw-ui-button mw-ui-constructive" />').text(r[2]).click(function(){
							if(!warnOnQuickRespond || confirm('آیا از پاسخ به این درخواست ویرایش مطمئن هستید؟')) {
								warnOnRespond = false;
								parsoidObj.form.answered.checked = true;
								parsoidObj.form.responsetemplate.value = r[0];
								parsoidObj.form.responsefree.value = r[1];
								button.click();
							}
						}));
					});
				}
				$(obj).append(buttons);
				$(obj).append(resultObj);
				parsoidObj.form = form[0];
				parsoidObj.resultObj = resultObj;
			}
			function parsoidSetupFieldsForTemplate(index) {
				var obj = $(this);
				var data_mw = obj.attr('data-mw');
				if(data_mw === undefined) {
					console.log("data-mw attribute در درخواست پیدا نشد " + index + ". این احتمالاً ناشی از این است که یک یا چند الگو تگ‌های اچ‌تی‌ام‌ال را باز کرده ولی آن‌ها را نبسته‌اند.");
					return;
				}
				data_mw = JSON.parse(data_mw);
				var templateName = data_mw.parts[0].template.target.wt;
				var level = obj.attr('data-origlevel');
				if(autoFixLevel) {
					switch(this.id) {
						case 'editsemiprotected':
							level = 'semi';
							break;
						case 'editextendedprotected':
							level = 'extended';
							break;
						case 'edittemplateprotected':
							level = 'template';
							break;
						case 'editprotected':
							level = 'full';
							break;
						case 'editinterfaceprotected':
							level = 'interface';
					}
				}
				var params = [];
				for(var key in data_mw.parts[0].template.params) {
					params[key] = data_mw.parts[0].template.params[key].wt;
				}
				
				// this only runs on numerical parameters
				params.forEach(function(value, key) {
					if(/=/.test(value)) {
						params[key] = key + '=' + value;
					}
				});
				
				var pagename = params.join('|').replace(/^\|+|\|+$/g, '').replace(/\|+/g, '|');
				var answered = yesno(params.ans || params.answered, true);
				this.demo = yesno(params.demo);
				var force = yesno(params.force);
				this.params = params;
				this.templateMarker = makeUniqueString(2 * index);
				this.responseMarker = makeUniqueString(2 * index + 1);
				appendForm(selector[index], level, pagename, answered, force, this);
			}
			function onParsoidDomReceived(data, textStatus, jqXHR) {

				// Grab the ETag header and store it in the global
				// gEtag for later use
				var headers = jqXHR.getAllResponseHeaders().split( "\r\n" );
				for( var i = 0, n = headers.length; i < n; i++ ) {
					if( headers[i].substring( 0, headers[i].indexOf( ":" ) ) === "etag" ) {
						gEtag = headers[i].substring( headers[i].indexOf( ":" ) + 2 );
						break;
					}
				}

				parsoidDom = new DOMParser().parseFromString(data, 'text/html');
				if(!parsoidDom) {
					// blech. Safari.
					parsoidDom = document.implementation.createHTMLDocument('');
					parsoidDom.documentElement.innerHTML = data;
				}
				var parsoidSelector = $('.editrequest', parsoidDom);
				if(selector.length != parsoidSelector.length) {
					console.log('Sanity check failed: ' + selector.length + ' edit requests exist in the page but only ' + parsoidSelector.length + ' were found in Parsoid\'s output.');
					return;
				}
				parsoidSelector.each(parsoidSetupFieldsForTemplate);
			}
			if(selector.length) {
				mw.loader.load('mediawiki.api.edit');
				mw.loader.load('mediawiki.ui.button');
				mw.loader.load('mediawiki.ui.input');
				$.ajax({
					url: '/api/rest_v1/page/html/' + encodeURIComponent(mw.config.get('wgPageName')) + '/' + mw.config.get('wgRevisionId'),
					headers: {
						Accept: 'text/html; charset=utf-8; profile="https://www.mediawiki.org/wiki/Specs/HTML/2.0.0"',
						'Api-User-Agent': 'editProtectedHelper (https://en.wikipedia.org/wiki/User:Jackmcbarn/editProtectedHelper)'
					},
					success: onParsoidDomReceived
				});
			}
		});
	});
}
// </nowiki>