مدیاویکی:Gadget-friendlytag-2020.js
پرش به ناوبری
پرش به جستجو
نکته: پس از انتشار ممکن است برای دیدن تغییرات نیاز باشد که حافظهٔ نهانی مرورگر خود را پاک کنید.
- فایرفاکس / سافاری: کلید Shift را نگه دارید و روی دکمهٔ Reload کلیک کنید، یا کلیدهای Ctrl-F5 یا Ctrl-R را با هم فشار دهید (در رایانههای اپل مکینتاش کلیدهای ⌘-R)
- گوگل کروم: کلیدهای Ctrl+Shift+R را با هم فشار دهید (در رایانههای اپل مکینتاش کلیدهای ⌘-Shift-R)
- اینترنت اکسپلورر/ Edge: کلید Ctrl را نگهدارید و روی دکمهٔ Refresh کلیک کنید، یا کلیدهای Ctrl-F5 را با هم فشار دهید
- اپرا: Ctrl-F5 را بفشارید.
// <nowiki>
(function($) {
/*
****************************************
*** friendlytag.js: Tag module
****************************************
* Mode of invocation: Tab ("Tag")
* Active on: Existing articles and drafts; file pages with a corresponding file
* which is local (not on Commons); all redirects
*/
Twinkle.tag = function friendlytag() {
// redirect tagging
if (Morebits.wiki.isPageRedirect()) {
Twinkle.tag.mode = 'redirect';
Twinkle.addPortletLink(Twinkle.tag.callback, 'برچسب', 'friendly-tag', 'تغییرمسیر برچسب'); // localized
// file tagging
} else if (mw.config.get('wgNamespaceNumber') === 6 && !document.getElementById('mw-sharedupload') && document.getElementById('mw-imagepage-section-filehistory')) {
Twinkle.tag.mode = 'file';
Twinkle.addPortletLink(Twinkle.tag.callback, 'برچسب', 'friendly-tag', 'زدن برچسبهای نگهداری به پرونده'); // localized
// article/draft article tagging
} else if ([0, 118].indexOf(mw.config.get('wgNamespaceNumber')) !== -1 && mw.config.get('wgCurRevisionId')) {
Twinkle.tag.mode = 'article';
// Can't remove tags when not viewing current version
Twinkle.tag.canRemove = (mw.config.get('wgCurRevisionId') === mw.config.get('wgRevisionId')) &&
// Disabled on latest diff because the diff slider could be used to slide
// away from the latest diff without causing the script to reload
!mw.config.get('wgDiffNewId');
Twinkle.addPortletLink(Twinkle.tag.callback, 'برچسب', 'friendly-tag', 'افزودن یا حذف برچسبهای نگهداری مقاله'); // localized
}
};
Twinkle.tag.checkedTags = [];
Twinkle.tag.callback = function friendlytagCallback() {
var Window = new Morebits.simpleWindow(630, Twinkle.tag.mode === 'article' ? 500 : 400);
Window.setScriptName('Twinkle');
// anyone got a good policy/guideline/info page/instructional page link??
Window.addFooterLink('Twinkle help', 'WP:TW/DOC#tag');
var form = new Morebits.quickForm(Twinkle.tag.callback.evaluate);
form.append({
type: 'input',
label: 'پالایش سریع: ', // localized
name: 'quickfilter',
size: '30px',
event: function twinkletagquickfilter() {
// flush the DOM of all existing underline spans
$allCheckboxDivs.find('.search-hit').each(function(i, e) {
var label_element = e.parentElement;
// This would convert <label>Hello <span class=search-hit>wo</span>rld</label>
// to <label>Hello world</label>
label_element.innerHTML = label_element.textContent;
});
if (this.value) {
$allCheckboxDivs.hide();
$allHeaders.hide();
var searchString = this.value;
var searchRegex = new RegExp(mw.util.escapeRegExp(searchString), 'i');
$allCheckboxDivs.find('label').each(function () {
var label_text = this.textContent;
var searchHit = searchRegex.exec(label_text);
if (searchHit) {
var range = document.createRange();
var textnode = this.childNodes[0];
range.selectNodeContents(textnode);
range.setStart(textnode, searchHit.index);
range.setEnd(textnode, searchHit.index + searchString.length);
var underline_span = $('<span>').addClass('search-hit').css('text-decoration', 'underline')[0];
range.surroundContents(underline_span);
this.parentElement.style.display = 'block'; // show
}
});
} else {
$allCheckboxDivs.show();
$allHeaders.show();
}
}
});
switch (Twinkle.tag.mode) {
case 'article':
Window.setTitle('Article maintenance tagging');
form.append({
type: 'select',
name: 'sortorder',
label: 'مشاهده این فهرست:', // localized
tooltip: 'میتوانید ترتیب پیشفرض نمایش را در ترجیحات توینکل خود تغییر دهید (وپ:توینکل تر).', // localized
event: Twinkle.tag.updateSortOrder,
list: [
{ type: 'option', value: 'cat', label: 'بر پایه رده', selected: Twinkle.getPref('tagArticleSortOrder') === 'cat' }, // localized
{ type: 'option', value: 'alpha', label: 'بهترتیب الفبا', selected: Twinkle.getPref('tagArticleSortOrder') === 'alpha' } // localized
]
});
if (!Twinkle.tag.canRemove) {
var divElement = document.createElement('div');
divElement.innerHTML = 'برای حذف برچسبهای موجود، لطفاً منوی برچسب را از نسخهٔ کنونی مقاله باز کنید'; // localized
form.append({
type: 'div',
name: 'untagnotice',
label: divElement
});
}
form.append({
type: 'div',
id: 'tagWorkArea',
className: 'morebits-scrollbox',
style: 'max-height: 28em'
});
form.append({
type: 'checkbox',
list: [
{
label: 'گروهبندی برچسبها در {{مشکلات متعدد}}، در صورت امکان', // localized
value: 'group',
name: 'group',
tooltip: 'در صورتی که در حال افزودن دو یا چند الگویی که توسط {{مشکلات متعدد}} پشتیبانی میشوند هستید و این گزینه نیز انتخاب شدهاست، تمامی الگوهای پشتیبانیشده در درون الگوی {{مشکلات متعدد}} گروهبندی خواهند شد.', // localized
checked: Twinkle.getPref('groupByDefault')
}
]
});
form.append({
type: 'input',
label: 'دلیل',
name: 'reason',
tooltip: 'دلیل اختیاری برای پیوستشدن به خلاصه ویرایش. ذکر دلیل بههنگام حذف برچسبها توصیه میشود.', // localized
size: '60px'
});
break;
case 'file':
Window.setTitle('File maintenance tagging');
form.append({ type: 'header', label: 'برچسبهای مشکلات مجوز و منبعدهی' }); // localized
form.append({ type: 'checkbox', name: 'fileTags', list: Twinkle.tag.file.licenseList });
form.append({ type: 'header', label: 'برچسبهای مرتبط با ویکیانبار' }); // localized
form.append({ type: 'checkbox', name: 'fileTags', list: Twinkle.tag.file.commonsList });
form.append({ type: 'header', label: 'برچسبهای تمیزکاری' }); // localized
form.append({ type: 'checkbox', name: 'fileTags', list: Twinkle.tag.file.cleanupList });
form.append({ type: 'header', label: 'برچسبهای کیفیت تصویر' }); // localized
form.append({ type: 'checkbox', name: 'fileTags', list: Twinkle.tag.file.qualityList });
form.append({ type: 'header', label: 'برچسبهای جایگزینی' }); // localized
form.append({ type: 'checkbox', name: 'fileTags', list: Twinkle.tag.file.replacementList });
if (Twinkle.getPref('customFileTagList').length) {
form.append({ type: 'header', label: 'برچسبهای سفارشی' }); // localized
form.append({ type: 'checkbox', name: 'fileTags', list: Twinkle.getPref('customFileTagList') });
}
break;
case 'redirect':
Window.setTitle('Redirect tagging');
form.append({ type: 'header', label: 'Spelling, misspelling, tense and capitalization templates' });
form.append({ type: 'checkbox', name: 'redirectTags', list: Twinkle.tag.spellingList });
form.append({ type: 'header', label: 'الگوهای نام جایگزین' }); // localized
form.append({ type: 'checkbox', name: 'redirectTags', list: Twinkle.tag.alternativeList });
form.append({ type: 'header', label: 'الگوهای تغییرمسیر گوناگون و مدیریتی' }); // localized
form.append({ type: 'checkbox', name: 'redirectTags', list: Twinkle.tag.administrativeList });
if (Twinkle.getPref('customRedirectTagList').length) {
form.append({ type: 'header', label: 'برچسبهای سفارشی' }); // localized
form.append({ type: 'checkbox', name: 'redirectTags', list: Twinkle.getPref('customRedirectTagList') });
}
break;
default:
alert('Twinkle.tag: unknown mode ' + Twinkle.tag.mode);
break;
}
if (document.getElementsByClassName('patrollink').length) {
form.append({
type: 'checkbox',
list: [
{
label: 'علامت زدن صفحه بهعنوان گشتخورده/بازبینیشده', // localized
value: 'patrolPage',
name: 'patrolPage',
checked: Twinkle.getPref('markTaggedPagesAsPatrolled')
}
]
});
}
form.append({ type: 'submit', className: 'tw-tag-submit' });
var result = form.render();
Window.setContent(result);
Window.display();
// for quick filter:
$allCheckboxDivs = $(result).find('[name$=Tags]').parent();
$allHeaders = $(result).find('h5');
result.quickfilter.focus(); // place cursor in the quick filter field as soon as window is opened
result.quickfilter.autocomplete = 'off'; // disable browser suggestions
result.quickfilter.addEventListener('keypress', function(e) {
if (e.keyCode === 13) { // prevent enter key from accidentally submitting the form
e.preventDefault();
return false;
}
});
if (Twinkle.tag.mode === 'article') {
Twinkle.tag.alreadyPresentTags = [];
if (Twinkle.tag.canRemove) {
// Look for existing maintenance tags in the lead section and put them in array
// All tags are HTML table elements that are direct children of .mw-parser-output,
// except when they are within {{multiple issues}}
$('.mw-parser-output').children().each(function parsehtml(i, e) {
// break out on encountering the first heading, which means we are no
// longer in the lead section
if (e.tagName === 'H2') {
return false;
}
// The ability to remove tags depends on the template's {{ambox}} |name=
// parameter bearing the template's correct name (preferably) or a name that at
// least redirects to the actual name
// All tags have their first class name as "box-" + template name
if (e.className.indexOf('box-') === 0) {
if (e.classList[0] === 'box-Multiple_issues') {
$(e).find('.ambox').each(function(idx, e) {
var tag = e.classList[0].slice(4).replace(/_/g, ' ');
Twinkle.tag.alreadyPresentTags.push(tag);
});
return true; // continue
}
var tag = e.classList[0].slice(4).replace(/_/g, ' ');
Twinkle.tag.alreadyPresentTags.push(tag);
}
});
// {{Uncategorized}} and {{Improve categories}} are usually placed at the end
if ($('.box-Uncategorized').length) {
Twinkle.tag.alreadyPresentTags.push('Uncategorized');
}
if ($('.box-Improve_categories').length) {
Twinkle.tag.alreadyPresentTags.push('Improve categories');
}
}
// Add status text node after Submit button
var statusNode = document.createElement('small');
statusNode.id = 'tw-tag-status';
Twinkle.tag.status = {
// initial state; defined like this because these need to be available for reference
// in the click event handler
numAdded: 0,
numRemoved: 0
};
$('button.tw-tag-submit').after(statusNode);
// fake a change event on the sort dropdown, to initialize the tag list
var evt = document.createEvent('Event');
evt.initEvent('change', true, true);
result.sortorder.dispatchEvent(evt);
} else {
// Redirects and files: Add a link to each template's description page
Morebits.quickForm.getElements(result, Twinkle.tag.mode + 'Tags').forEach(generateLinks);
}
};
// $allCheckboxDivs and $allHeaders are defined globally, rather than in the
// quickfilter event function, to avoid having to recompute them on every keydown
var $allCheckboxDivs, $allHeaders;
Twinkle.tag.updateSortOrder = function(e) {
var form = e.target.form;
var sortorder = e.target.value;
Twinkle.tag.checkedTags = form.getChecked('articleTags') || [];
var container = new Morebits.quickForm.element({ type: 'fragment' });
// function to generate a checkbox, with appropriate subgroup if needed
var makeCheckbox = function(tag, description) {
var checkbox = { value: tag, label: '{{' + tag + '}}: ' + description };
if (Twinkle.tag.checkedTags.indexOf(tag) !== -1) {
checkbox.checked = true;
}
switch (tag) {
case 'Cleanup':
checkbox.subgroup = {
name: 'cleanup',
type: 'input',
label: 'دلیل مشخص برای اینکه چرا به تمیزکاری نیاز است: ', // localized
tooltip: 'الزامی.', // localized
size: 35
};
break;
case 'Close paraphrasing':
checkbox.subgroup = {
name: 'closeParaphrasing',
type: 'input',
label: 'منبع: ', // localized
tooltip: 'منبعی که بهطور نزدیک بازنویسی شدهاست' // localized
};
break;
case 'Copy edit':
checkbox.subgroup = {
name: 'copyEdit',
type: 'input',
label: '"این مقاله ممکن است نیازمند ویرایستاری باشد..." ', // localized
tooltip: 'بهعنوان مثال، "املای یکپارچه". انتخابی.', // localized
size: 35
};
break;
case 'Copypaste':
checkbox.subgroup = {
name: 'copypaste',
type: 'input',
label: 'نشانی منبع: ', // localized
tooltip: 'اگر مشخص است.', // localized
size: 50
};
break;
case 'Expand language':
checkbox.subgroup = [ {
name: 'expandLanguageLangCode',
type: 'input',
label: 'شناسه زبان: ', // localized
tooltip: 'شناسهٔ زبانی که مقاله باید از روی آن گسترش دادهشود' // localized
}, {
name: 'expandLanguageArticle',
type: 'input',
label: 'عنوان مقاله: ', // localized
tooltip: 'عنوان مقالهای که گسترش از روی آن انجام میشود، بدون پیشوند میانویکی' // localized
}
];
break;
case 'Expert needed':
checkbox.subgroup = [
{
name: 'expertNeeded',
type: 'input',
label: 'عنوان ویکیپروژهٔ مرتبط: ', // localized
tooltip: 'بهطور انتخابی، نام ویکیپروژهای که میتواند به جذب یک کاربر باتجربه کمک کند را وارد کنید. بدون پیشوند «ویکیپروژه».' // localized
},
{
name: 'expertNeededReason',
type: 'input',
label: 'دلیل: ', // localized
tooltip: 'توضیح کوتاه برای توصیف مشکل. پیوند به دلیل یا بحث الزامی است.' // localized
},
{
name: 'expertNeededTalk',
type: 'input',
label: 'ریسهٔ بحث: ', // localized
tooltip: 'عنوان بخشی از صفحهٔ بحث این مقاله که بحث دربارهٔ مشکل در آن جریان دارد. نیاز به درج پیوند نیست، تنها عنوان بخش را وارد کنید. پیوند به دلیل یا بحث الزامی است.' // localized
}
];
break;
case 'Globalize':
checkbox.subgroup = {
name: 'globalizeRegion',
type: 'input',
label: 'منطقه یا کشورِ بیش از اندازه معرفیشده' // localized
};
break;
case 'History merge':
checkbox.subgroup = [
{
name: 'histmergeOriginalPage',
type: 'input',
label: 'مقالهٔ دیگر: ', // localized
tooltip: 'عنوان صفحهای که میتواند در این مقاله ادغام شود (الزامی).' // localized
},
{
name: 'histmergeReason',
type: 'input',
label: 'دلیل: ', // localized
tooltip: 'توضیح کوتاه که دلیل نیاز به ادغام تاریخچه را بیان کند. بهتر است با عبارت «زیرا» آغاز شده و با یک نقطه پایان یابد.' // localized
},
{
name: 'histmergeSysopDetails',
type: 'input',
label: 'جزئیات بیشتر: ', // localized
tooltip: 'برای موارد پیچیده، راهنماییهای بیشتری را در اختیار مدیر بررسیکننده قرار دهید.' // localized
}
];
break;
case 'Merge':
case 'Merge from':
case 'Merge to':
var otherTagName = 'Merge';
switch (tag) {
case 'Merge from':
otherTagName = 'Merge to';
break;
case 'Merge to':
otherTagName = 'Merge from';
break;
// no default
}
checkbox.subgroup = [
{
name: 'mergeTarget',
type: 'input',
label: 'مقاله(های) دیگر: ', // localized
tooltip: 'اگر قصد دارید مقالههای متعدد را مشخص کنید، آنها را با نویسهٔ لوله از هم جدا کنید: مقالهٔ اول|مقالهٔ دوم' // localized
},
{
name: 'mergeTagOther',
type: 'checkbox',
list: [
{
label: 'مقالهٔ دیگر را با یک برچسب {{' + otherTagName + '}} مشخص کنید', // localized
checked: true,
tooltip: 'فقط در صورتی که تنها عنوان یک مقاله وارد شدهباشد، در دسترس است.' // localized
}
]
}
];
if (mw.config.get('wgNamespaceNumber') === 0) {
checkbox.subgroup.push({
name: 'mergeReason',
type: 'textarea',
label: 'دلیل اصلی برای ادغام (بر روی صفحهٔ بحث' +
(tag === 'Merge to' ? 'the other article\'s' : 'this article\'s') + ' قرار خواهد گرفت):', // localized
tooltip: 'انتخابی، اما بهشدت توصیهشده. در صورت عدم تمایل، خالی بگذارید. فقط در صورتی که تنها عنوان یک مقاله وارد شدهباشد، در دسترس است.' // localized
});
}
break;
case 'Not English':
case 'Rough translation':
checkbox.subgroup = [
{
name: 'translationLanguage',
type: 'input',
label: 'زبان مقاله (اگر مشخص است): ', // localized
tooltip: 'برای راهنمایی، مرور [[en:WP:LRC]] را در نظر داشتهباشید. اگر مقاله را در صفحهٔ مقالههای نیازمند ترجمه فهرست میکنید، لطفاً از خالیگذاشتن این جعبه خودداری کنید؛ مگر آنکه کاملاً نامطمؤن باشید.' // localized
}
];
if (tag === 'Not English') {
checkbox.subgroup.push({
name: 'translationNotify',
type: 'checkbox',
list: [
{
label: 'اطلاعرسانی به سازندهٔ مقاله', // localized
checked: true,
tooltip: "الگوی {{uw-notenglish}} را در صفحهٔ بحث سازندهٔ مقاله قرار میدهد." // localized
}
]
});
}
if (mw.config.get('wgNamespaceNumber') === 0) {
checkbox.subgroup.push({
name: 'translationPostAtPNT',
type: 'checkbox',
list: [
{
label: 'فهرستکردن این مقاله در ویکیپدیا:صفحههای نیازمند ترجمه به فارسی (PNT)', // localized
checked: true
}
]
});
checkbox.subgroup.push({
name: 'translationComments',
type: 'textarea',
label: 'توضیح بیشتر برای ارسال به ویکیپدیا:صفحههای نیازمند ترجمه به فارسی', // localized
tooltip: 'انتخابی، و متناسب تنها در صورتی که "فهرستکردن این مقاله..." در بالا انتخاب شدهباشد.' // localized
});
}
break;
case 'Notability':
checkbox.subgroup = {
name: 'notability',
type: 'select',
list: [
{ label: "{{سرشناسی}}: موضوع مقاله ممکن است رهنمود اصلی سرشناسی را احراز نکند", value: 'none' }, // localized
{ label: '{{سرشناسی|دانشگاهیان}}: رهنمود سرشناسی دانشگاهیان', value: 'Academics' }, // localized
{ label: '{{سرشناسی|اجرام آسمانی}}: رهنمود سرشناسی اجرام آسمانی', value: 'Astro' }, // localized
{ label: '{{سرشناسی|افراد}}: رهنمود سرشناسی زندگینامه افراد', value: 'Biographies' }, // localized
{ label: '{{سرشناسی|کتابها}}: رهنمود سرشناسی کتاب', value: 'Books' }, // localized
{ label: '{{سرشناسی|سازمانها}}: رهنمودهای سرشناسی شرکتها و سازمانها', value: 'Companies' }, // localized
{ label: '{{سرشناسی|رویدادها}}: رهنمود سرشناسی برای رویدادها', value: 'Events' }, // localized
{ label: '{{سرشناسی|فیلمها}}: رهنمود سرشناسی فیلمها', value: 'Films' }, // localized
{ label: '{{سرشناسی|مکان}}: رهنمود سرشناسی ویژگیهای جغرافیایی', value: 'Geographic' }, // localized
{ label: '{{سرشناسی|فهرستها}}: رهنمود سرشناسی فهرستهای مسقل', value: 'Lists' }, // localized
{ label: '{{سرشناسی|موسیقی}}: رهنمود سرشناسی موسیقی', value: 'Music' }, // localized
{ label: '{{سرشناسی|نوواژهها}}: رهنمود سرشناسی نوواژهها', value: 'Neologisms' }, // localized
{ label: '{{سرشناسی|عددها}}: رهنمود سرشناسی عددها', value: 'Numbers' }, // localized
{ label: '{{سرشناسی|محصولات}}: رهنمود سرشناسی محصولات و خدمات', value: 'Products' }, // localized
{ label: '{{سرشناسی|ورزشها}}: رهنمود سرشناسی ورزشها', value: 'Sports' }, // localized
{ label: '{{سرشناسی|تلویزیون}}: رهنمود سرشناسی برنامههای تلویزیونی', value: 'Television' }, // localized
{ label: '{{سرشناسی|وب}}: رهنمود سرشناسی مجتوای وب', value: 'Web' } // localized
]
};
break;
default:
break;
}
return checkbox;
};
var makeCheckboxesForAlreadyPresentTags = function() {
container.append({ type: 'header', id: 'tagHeader0', label: 'Tags already present' });
var subdiv = container.append({ type: 'div', id: 'tagSubdiv0' });
var checkboxes = [];
var unCheckedTags = e.target.form.getUnchecked('alreadyPresentArticleTags') || [];
Twinkle.tag.alreadyPresentTags.forEach(function(tag) {
var description = Twinkle.tag.article.tags[tag];
var checkbox =
{
value: tag,
label: '{{' + tag + '}}' + (description ? ': ' + description : ''),
checked: unCheckedTags.indexOf(tag) === -1,
style: 'font-style: italic'
};
checkboxes.push(checkbox);
});
subdiv.append({
type: 'checkbox',
name: 'alreadyPresentArticleTags',
list: checkboxes
});
};
if (sortorder === 'cat') { // categorical sort order
// function to iterate through the tags and create a checkbox for each one
var doCategoryCheckboxes = function(subdiv, array) {
var checkboxes = [];
$.each(array, function(k, tag) {
var description = Twinkle.tag.article.tags[tag];
if (Twinkle.tag.alreadyPresentTags.indexOf(tag) === -1) {
checkboxes.push(makeCheckbox(tag, description));
}
});
subdiv.append({
type: 'checkbox',
name: 'articleTags',
list: checkboxes
});
};
if (Twinkle.tag.alreadyPresentTags.length > 0) {
makeCheckboxesForAlreadyPresentTags();
}
var i = 1;
// go through each category and sub-category and append lists of checkboxes
$.each(Twinkle.tag.article.tagCategories, function(title, content) {
container.append({ type: 'header', id: 'tagHeader' + i, label: 'عنوان' }); // localized
var subdiv = container.append({ type: 'div', id: 'tagSubdiv' + i++ });
if (Array.isArray(content)) {
doCategoryCheckboxes(subdiv, content);
} else {
$.each(content, function(subtitle, subcontent) {
subdiv.append({ type: 'div', label: [ Morebits.htmlNode('b', subtitle) ] });
doCategoryCheckboxes(subdiv, subcontent);
});
}
});
} else { // alphabetical sort order
if (Twinkle.tag.alreadyPresentTags.length > 0) {
makeCheckboxesForAlreadyPresentTags();
container.append({ type: 'header', id: 'tagHeader1', label: 'برچسبهای قابل استفاده' }); // localized
}
var checkboxes = [];
$.each(Twinkle.tag.article.tags, function(tag, description) {
if (Twinkle.tag.alreadyPresentTags.indexOf(tag) === -1) {
checkboxes.push(makeCheckbox(tag, description));
}
});
container.append({
type: 'checkbox',
name: 'articleTags',
list: checkboxes
});
}
// append any custom tags
if (Twinkle.getPref('customTagList').length) {
container.append({ type: 'header', label: 'برچسبهای سفارشی' }); // localized
container.append({ type: 'checkbox', name: 'articleTags',
list: Twinkle.getPref('customTagList').map(function(el) {
el.checked = Twinkle.tag.checkedTags.indexOf(el.value) !== -1;
return el;
})
});
}
var $workarea = $(form).find('#tagWorkArea');
var rendered = container.render();
$workarea.empty().append(rendered);
// for quick filter:
$allCheckboxDivs = $workarea.find('[name$=Tags]').parent();
$allHeaders = $workarea.find('h5, .quickformDescription');
form.quickfilter.value = ''; // clear search, because the search results are not preserved over mode change
form.quickfilter.focus();
// style adjustments
$workarea.find('h5').css({ 'font-size': '110%' });
$workarea.find('h5:not(:first-child)').css({ 'margin-top': '1em' });
$workarea.find('div').filter(':has(span.quickformDescription)').css({ 'margin-top': '0.4em' });
var alreadyPresentTags = Morebits.quickForm.getElements(form, 'alreadyPresentArticleTags');
if (alreadyPresentTags) {
alreadyPresentTags.forEach(generateLinks);
}
// in the unlikely case that *every* tag is already on the page
var notPresentTags = Morebits.quickForm.getElements(form, 'articleTags');
if (notPresentTags) {
notPresentTags.forEach(generateLinks);
}
// tally tags added/removed, update statusNode text
var statusNode = document.getElementById('tw-tag-status');
$('[name=articleTags], [name=alreadyPresentArticleTags]').click(function() {
if (this.name === 'articleTags') {
Twinkle.tag.status.numAdded += this.checked ? 1 : -1;
} else if (this.name === 'alreadyPresentArticleTags') {
Twinkle.tag.status.numRemoved += this.checked ? -1 : 1;
}
var firstPart = 'Adding ' + Twinkle.tag.status.numAdded + ' tag' + (Twinkle.tag.status.numAdded > 1 ? 's' : '');
var secondPart = 'Removing ' + Twinkle.tag.status.numRemoved + ' tag' + (Twinkle.tag.status.numRemoved > 1 ? 's' : '');
statusNode.textContent =
(Twinkle.tag.status.numAdded ? ' ' + firstPart : '') +
(Twinkle.tag.status.numRemoved ? (Twinkle.tag.status.numAdded ? '; ' : ' ') + secondPart : '');
});
};
/**
* Adds a link to each template's description page
* @param {Morebits.quickForm.element} checkbox associated with the template
*/
var generateLinks = function(checkbox) {
var link = Morebits.htmlNode('a', '>');
link.setAttribute('class', 'tag-template-link');
var tagname = checkbox.values;
link.setAttribute('href', mw.util.getUrl(
(tagname.indexOf(':') === -1 ? 'Template:' : '') +
(tagname.indexOf('|') === -1 ? tagname : tagname.slice(0, tagname.indexOf('|')))
));
link.setAttribute('target', '_blank');
$(checkbox).parent().append(['\u00A0', link]);
};
// Tags for ARTICLES start here
Twinkle.tag.article = {};
// A list of all article tags, in alphabetical order
// To ensure tags appear in the default "categorized" view, add them to the tagCategories hash below.
Twinkle.tag.article.tags = {
'Advert': 'مشابه یک متن تبلیغاتی نوشته شدهاست', // localized
'All plot': 'تقریباً بهطور کامل یک خلاصهٔ طرح است', // localized
'Autobiography': 'خودزندگینامه است و احتمالاً بیطرفانه نوشته نشدهاست', // localized
'BLP sources': 'زندگینامه زندگان که برای تأییدپذیری نیامند منابع بیشتر است', // localized
'BLP unsourced': 'زندگینامهٔ زندگان که هیچ منبعی ندارد (برای مقالههای جدید، از حذف زماندار زندگینامه زندگان اسفاده کنید)', // localized
'Citation style': 'از سبک یادکرد مبهم یا متناقض برخوردار است', // localized
'Cleanup': 'نیازمند تمیزکاری است', // localized
'Cleanup bare URLs': 'از پیوندهای عریان برای ارجاع استفاده میکند، که مستعد خرابشدن پیوند است', // localized
'Cleanup-PR': 'مشابه یک انتشار مطبوعاتی یا مقالهٔ خبری نوشته شدهاست', // localized
'Cleanup reorganize': "برای سازگار شدن با رهنمودهای قالببندی ویکیپدیا، نیازمند سازماندهی مجدد است", // localized
'Cleanup rewrite': "برای سازگار شدن با استانداردهای کیفی ویکیپدیا× نیازمند بازنویسی عمده است", // localized
'Cleanup tense': 'از رهنمودهای استفاده از زمانهای مختلف افعال پیروی نمیکند.', // localized
'Close paraphrasing': 'دربردارندهٔ بازنویسی نزدیگ از یک منبع غرآزاد دارای حق تکثیر است', // localized
'COI': 'سازنده یا مشارکتکنندهٔ عمده ممکن است دارای تعارض منافع باشد', // localized
'Condense': 'تعداد زیاد عنوانهای بخش که محتوا را پراکنده کردهاند', // localized
'Confusing': 'گیجکننده و مبهم', // localized
'Context': 'زمینهٔ ناکافی برای کسانی که با موضوع آشنا نیستند', // localized
'Copy edit': 'نیازمند ویراستاری دستور زبان، سبک، انسجام، لحن، یا آوانگاری', // localized
'Copypaste': 'بهنظر میرسد از جای دیگری کپیکاری شدهاست', // localized
'Current': 'دربردارندهٔ یک رویداد روز است', // localized
'Dead end': 'مقاله به هیچ مقالهٔ دیگری پیوند ندارد', // localized
'Disputed': 'دقت در بیان حقایق مورد سؤال است', // localized
'Essay-like': 'همانند یک تفکر شخصی، انشای شخصی یا مقالهٔ استدلالی نوشته شدهاست', // localized
'Expand language': 'لازم است که با ترجمهٔ متن از یک مقاله به زبان دیگر، گسترش یابد', // localized
'Expert needed': 'نیازمند توجه از سوی یک فرد آشنا با موضوع است', // localized
'External links': 'پیوندهای به بیرون ممکن است از سیاستها یا رهنمودهای محتوایی پیروی نکنند', // localized
'Fanpov': "از دیدگاه یک طرفدار نوشته شدهاست", // localized
'Fiction': 'وجه تمایز میان حقایق و حکایتها مشخص نیست', // localized
'Globalize': 'نمایانگر وجههٔ جهانی موضوع نیست', // localized
'GOCEinuse': 'currently undergoing a major copy edit by the Guild of Copy Editors',
'History merge': 'تاریخچهٔ یک صفحهٔ دیگر میتواند در تاریخچهٔ این صفحه ادغام شود', // localized
'Hoax': 'کل یا بخشی از آن ممکن است شامل کلکزنی باشد', // localized
'Improve categories': 'نیازمند ردههای تخصصی بیشتر است', // localized
'Incomprehensible': 'فهمیدن آن بسیار سخت یا غیرقابل درک است', // localized
'In-universe': 'موضوع، تخیلی است و برای ارائهٔ یک دیدگاه غیرخیالی، نیازمند بازنویسی است', // localized
'In use': 'برای مدتی کوتاه تحت ویرایش عمده است', // localized
'Lead missing': 'فاقد بخش آغازین است', // localized
'Lead rewrite': 'بخش آغازین برای سازگار شدن با رهنمودها، نیازمند بازنویسی است', // localized
'Lead too long': 'بخش آغازین نسبت به طول کلی مقاله بسیار بلند است', // localized
'Lead too short': 'بخش آغازین بسیار کوتاه است و برای بیان خلاصهای از نکتههای کلیدی، نیازمند گسترش است', // localized
'Like resume': 'همانند یک رزومه نوشته شدهاست', // localized
'Long plot': 'خلاصهٔ طرح بسیار بلند است یا دارای جزئیات بیش از اندازه است', // localized
'Manual': 'همانند یک دفترچهٔ راهنما نوشته شدهاست', // localized
'Merge': 'لازم است با یک مقالهٔ مشخص دیگر ادغام شود', // localized
'Merge from': 'یک مقالهٔ مشخص دیگر باید در این مقاله ادغام شود', // localized
'Merge to': 'لازم است که در یک مقالهٔ مشخص دیگر ادغام شود', // localized
'More citations needed': 'برای تأییدپذیری، نیازمند منابع و ارجاعهای بیشتر است', // localized
'More footnotes': 'چند ارجاع دارد، اما یادکردهای درونخطی آن کافی نیستند', // localized
'No footnotes': 'دارای ارجاع است، اما فاقد یادکرد درونخطی است', // localized
'No plot': 'نیازمند خلاصهٔ طرح است', // localized
'Non-free': 'ممکن است بیش از اندازه یا بهطور نادرست از محتوای دارای حق تکثیر استفاده کردهباشد', // localized
'Notability': 'موضوع ممکن است رهنمود اصلی سرشناسی را احراز نکند', // localized
'Not English': 'written in a language other than English and needs translation',
'One source': 'بهطور گسترده یا تنها به یک منبع متکی است', // localized
'Original research': 'شامل تحقیق دست اول است', // localized
'Orphan': 'از هیچ مقالهٔ دیگری به آن پیوند داده نشدهاست', // localized
'Over-coverage': 'جانبداری گسترده یا پوشش نامتناسب بهسمت یک یا چند منطقهٔ مشخص', // localized
'Overlinked': 'پیوندهای تکراری و/یا نامرتبط زیاد به مقالههای دیگر', // localized
'Overly detailed': 'مقدار بیش از اندازه از جزئیات پیچیده', // localized
'Over-quotation': 'گفتاوردهای خیلی زیاد یا خیلی طولانی برای یک مدخل دانشنامهای', // localized
'Peacock': 'شامل جملهبندی است که بدون افزودن اطلاعات، موضوع را به شیوهای انتزاعی تبلیغ میکند', // localized
'POV': 'به دیدگاه بیطرف پایبند نیست', // localized
'Primary sources': 'بیش از اندازه بر ارجاع به منابع اولیه متکی است و نیازمند ارجاع به منابع ثانویه است', // localized
'Prose': 'در قالب یک فهرست نوشته شدهاست، اما در صورتی که به نثر درآید، بهتر خوانده میشود', // localized
'Recentism': 'دارای دید یکطرفه به رویدادهای اخیر است', // localized
'Rough translation': 'ترجمهٔ ضعیف از یک زبان دیگر', // localized
'Sections': 'نیازمند تقسیم به چند بخش بر پایه موضوع است', // localized
'Self-published': 'دارای ارجاعهای بیش از اندازه و نامناسب به منابع خود چاپکرده است', // localized
'Sources exist': 'موضوع سرشناس، منابعی موجود هستند که میتوانند به مقاله افزوده شوند', // localized
'Technical': 'بهاندازهای فنی است که درک آن برای بیشتر مخاطبان سخت است', // localized
'Third-party': 'بهشدت به منابعی اتکا دارد که بهطور نزدیکی با موضوع مرتبط هستند', // localized
'Tone': 'لحن یا سبک نوشتار بازتابدهندهٔ لحن دانشنامهای بهکار رفته در ویکیپدیا نیست', // localized
'Too few opinions': 'ممکن است دربردارندهٔ تمامی دیدگاههای قابل توجه نباشد', // localized
'Uncategorized': 'در هیچ ردهای قرار نگرفتهاست', // localized
'Under construction': 'در فرایند گسترش یا بازسازی عمده است', // localized
'Underlinked': 'نیازمند ویکیپیوندهای بیشتر به مقالههای دیگر است', // localized
'Undue weight': 'به بعضی ایدهها، وقایع یا حواشی، وزن بیمورد دادهاست', // localized
'Unfocused': 'فاقد تمرکز است، یا در مورد بیش از یک موضوع است', // localized
'Unreferenced': 'به هیچ منبعی استناد نمیکند', // localized
'Unreliable sources': 'بعضی منابع ممکن است قابل اعتماد نباشند', // localized
'Undisclosed paid': 'ممکن است در برابر دستمزد فاشنشده ایجاد یا ویرایش شدهباشد', // localized
'Update': 'نیازمند افزودن اطلاعات بهروز بیشتر است', // localized
'Very long': 'به اندازهای طولانی است که خواندن و گشتن در آن سخت است', // localized
'Weasel': 'بهدلیل استفاده از الفاظ طفرهآمیز، بیطرفی و اثباتپذیری آن بهخطر افتادهاست' // localized
};
// A list of tags in order of category
// Tags should be in alphabetical order within the categories
// Add new categories with discretion - the list is long enough as is!
Twinkle.tag.article.tagCategories = {
'Cleanup and maintenance tags': {
'General cleanup': [
'Cleanup', // has a subgroup with text input
'Cleanup rewrite',
'Copy edit' // has a subgroup with text input
],
'Potentially unwanted content': [
'Close paraphrasing',
'Copypaste', // has a subgroup with text input
'External links',
'Non-free'
],
'Structure, formatting, and lead section': [
'Cleanup reorganize',
'Condense',
'Lead missing',
'Lead rewrite',
'Lead too long',
'Lead too short',
'Sections',
'Very long'
],
'Fiction-related cleanup': [
'All plot',
'Fiction',
'In-universe',
'Long plot',
'No plot'
]
},
'General content issues': {
'Importance and notability': [
'Notability' // has a subgroup with subcategories
],
'Style of writing': [
'Advert',
'Cleanup tense',
'Essay-like',
'Fanpov',
'Like resume',
'Manual',
'Cleanup-PR',
'Over-quotation',
'Prose',
'Technical',
'Tone'
],
'Sense (or lack thereof)': [
'Confusing',
'Incomprehensible',
'Unfocused'
],
'Information and detail': [
'Context',
'Expert needed',
'Overly detailed',
'Undue weight'
],
'Timeliness': [
'Current',
'Update'
],
'Neutrality, bias, and factual accuracy': [
'Autobiography',
'COI',
'Disputed',
'Hoax',
'Globalize',
'Over-coverage',
'Peacock',
'POV',
'Recentism',
'Too few opinions',
'Undisclosed paid',
'Weasel'
],
'Verifiability and sources': [
'BLP sources',
'BLP unsourced',
'More citations needed',
'One source',
'Original research',
'Primary sources',
'Self-published',
'Sources exist',
'Third-party',
'Unreferenced',
'Unreliable sources'
]
},
'Specific content issues': {
'Language': [
'Not English', // has a subgroup with several options
'Rough translation', // has a subgroup with several options
'Expand language'
],
'Links': [
'Dead end',
'Orphan',
'Overlinked',
'Underlinked'
],
'Referencing technique': [
'Citation style',
'Cleanup bare URLs',
'More footnotes',
'No footnotes'
],
'Categories': [
'Improve categories',
'Uncategorized'
]
},
'Merging': [
'History merge',
'Merge', // these three have a subgroup with several options
'Merge from',
'Merge to'
],
'Informational': [
'GOCEinuse',
'In use',
'Under construction'
]
};
// Contains those article tags that *do not* work inside {{multiple issues}}.
Twinkle.tag.multipleIssuesExceptions = [
'Copypaste',
'Current', // Works but not intended for use in MI
'Expand language',
'GOCEinuse',
'History merge',
'Improve categories',
'In use',
'Merge',
'Merge from',
'Merge to',
'Not English',
'Rough translation',
'Uncategorized',
'Under construction'
];
// Tags for REDIRECTS start here
Twinkle.tag.spellingList = [
{
label: '{{R from acronym}}: تغییرمسیر از یک سرنام (مانند فحن) به قالب گسترشیافتهٔ آن', // localized
value: 'R from acronym'
},
{
label: '{{R from alternative spelling}}: تغییرمسیر از یک عنوان با تلفظ متفاوت', // localized
value: 'R from alternative spelling'
},
{
label: '{{R from initialism}}: تغییرمسیر از یک سرواژه (مانند BBC) به قالب گسترشیافتهٔ آن', // localized
value: 'R from initialism'
},
{
label: '{{R from ASCII-only}}: redirect from a title in only basic ASCII to the formal article title, with differences that are not diacritical marks (accents, umlauts, etc.) or ligatures', // localized
value: 'R from ASCII-only'
},
{
label: '{{R from member}}: تغییرمسیر از عضو یک گروه به عنوان مرتبط مانند خود گروه، سازمان یا تیمی که در آن عضویت دارد', // localized
value: 'R from member'
},
{
label: '{{R from misspelling}}: تغییرمسیر از یک آوانگاری اشتباه یا خطای نشانهگذاری', // localized
value: 'R from misspelling'
},
{
label: '{{R from modification}}: تغییرمسیر از اعمال تغییر بر عنوان هدف، مثلاً مرتبسازی مجدد واژگان', // localized
value: 'R from modification'
},
{
label: '{{R from other capitalisation}}: redirect from a title with another method of capitalisation',
value: 'R from other capitalisation'
},
{
label: '{{R from plural}}: تغییرمسیر از یک واژهٔ جمع بستهشده به معادل مفرد', // localized
value: 'R from plural'
},
{
label: '{{R from related word}}: تغییرمسیر از یک واژهٔ مرتبط', // Localized
value: 'R from related word'
},
{
label: '{{R to list entry}}: تغییرمسیر به یک مقاله از نوع «فهرستی از موجودیتهای جزئی» که شامل توضیحات مختصری در مورد موضوعاتی است که سرشناسی کافی برای داشتن مقالهٔ مستقل را ندارند', // localized
value: 'R to list entry'
},
{
label: '{{تغییرمسیر به بخش}}: مشابه {{R to list entry}}، اما برای زمانی که فهرست بخشبندی شدهاست، مانند فهرستی از شخصیتها در یک دنیای خیالی.', // localized
value: 'R to section'
},
{
label: '{{R with possibilities}}: تغییرمسیر از یک عنوان اختصاصیتر به یک مقالهٔ عمومیتر و با جزئیات کمتر، که میتواند و بایست که گسترش پیدا کند', // Localized
value: 'R with possibilities'
}
];
Twinkle.tag.alternativeList = [
{
label: '{{تغییرمسیر از زبانی دیگر}}: تغییرمسیر از یک نام فارسی به نامی به زبان دیگر، یا برعکس', // localized
value: 'R from alternative language',
subgroup: [
{
name: 'altLangFrom',
type: 'input',
label: 'از زبان (شناسه دوحرفی): ', // localized
tooltip: 'شناسهٔ دوحرفی زبانی که عنوان تغییرمسیر به آن زبان نوشته شدهاست را وارد کنید؛ مانند fa برای فارسی و en برای انگلیسی' // localized
},
{
name: 'altLangTo',
type: 'input',
label: 'به زبان (شناسه دوحرفی): ', // localized
tooltip: 'شناسهٔ دوحرفی زبانی که عنوان هدف به آن زبان نوشته شدهاست را وارد کنید؛ مانند fa برای فارسی و en برای انگلیسی' // localized
},
{
name: 'altLangInfo',
type: 'div',
label: $.parseHTML('<p>برای فهرستی از شناسههای زبانها، <a href="/wiki/Wp:Template_messages/Redirect_language_codes">en:Wikipedia:Template messages/Redirect language codes</a></p> را ببینید') // localized
}
]
},
{
label: '{{R from alternative name}}: تغییرمسیر از عنوانی که نام دیگر، نام مستعار، نام خودمانی یا نام مترادف است', // localized
value: 'R from alternative name'
},
{
label: '{{R from former name}}: تغییرمسیر از نام یا عنوان کاری سابق', // localized
value: 'R from former name'
},
{
label: '{{R from historic name}}: تغییرمسیر از نامی دیگر با پیشینهٔ تاریخی قابل توجه مانند یک منطقه، ایالت، شهر یا نظایر آن، که دیگر با آن نام یا عنوان شناخته نمیشود', // localized
value: 'R from historic name'
},
{
label: '{{R from incorrect name}}: تغییرمسیر از یک نام اشتباه که برای استفاده در عنوان، مناسب نیست', // localized
value: 'R from incorrect name'
},
{
label: '{{R from long name}}: تغییرمسیر از عنوانی که شامل نام کامل یا کاملتر است', // localized
value: 'R from long name'
},
{
label: '{{R from molecular formula}}: تغییرمسیر از یک فرمول مولکولی/شیمیایی به نام فنی یا بدیهی آن', // localized
value: 'R from molecular formula'
},
{
label: '{{R from name and country}}: تغییرمسیر از نام اختصاصی به نام مختصرتر', // localized
value: 'R from name and country'
},
{
label: '{{R from phrase}}: تغییرمسیر از یک اصطلاح به یک مقالهٔ مرتبط عمومیتر که موضوع را پوشش میدهد', // localized
value: 'R from phrase'
},
{
label: '{{R from scientific name}}: تغییرمسیر از نام علمی به نام رایج', // localized
value: 'R from scientific name'
},
{
label: '{{R from short name}}: تغییرمسیر از عنوانی که صورت کوتاهشدهٔ نام کامل یک شخص، یک عنوان کتاب، یا عنوان کاملتر دیگری است', // localized
value: 'R from short name'
},
{
label: '{{R from subtopic}}: تغییرمسیر از عنوانی که موضوعی فرعی از مقالهٔ مقصد است', // localized
value: 'R from subtopic'
},
{
label: '{{R from surname}}: تغییرمسیر از عنوانی که لقب است', // localized
value: 'R from surname'
},
{
label: '{{R to diacritic}}: تغییرمسیر به عنوان مقاله با حرکتگذاری (تلفظ، دونقطه، و غیره)', // localized
value: 'R to diacritic'
},
{
label: '{{R to related topic}}: تغییرمسیر به یک مقاله دربارهٔ یک موضوع مشابه', // localized
value: 'R to related topic'
},
{
label: '{{R to scientific name}}: تغییرمسیر از یک نام رایج به نام علمی', // localized
value: 'R to scientific name'
}
];
Twinkle.tag.administrativeList = [
{
label: '{{R from ambiguous term}}: تغییرمسیر از یک نام صفحهٔ مبهم به صفحهای که آن را ابهامزدایی میکند. این الگو هرگز نباید در صفحهای که «(ابهامزدایی)» را در عنوانش دارد، نمایش یابد، بهجای آن از تغییرمسیر به صفحه ابهامزدایی استفاده کنید', // localized
value: 'R from ambiguous term'
},
{
label: '{{R from CamelCase}}: تغییرمسیر از یک عنوان با نگارش شتری', // localized
value: 'R from CamelCase'
},
{
label: '{{R to decade}}: تغییرمسیر از یک سال به مقالهٔ دهه', // localized
value: 'R to decade'
},
{
label: '{{R to disambiguation page}}: تغییرمسیر به یک صفحه ابهامزدایی', // localized
value: 'R to disambiguation page'
},
{
label: '{{R from duplicated article}}: تغییرمسیر به یک مقالهٔ مشابه جهت حفظ تاریخچهٔ ویرایش آن', // localized
value: 'R from duplicated article'
},
{
label: '{{R from file metadata link}}: تغییرمسیر یک ویکیپیوند ایجادشده از EXIF، XMP، یا اطلاعات دیگر (مثلاً بخش «فراداده» در بعضی از صفحههای توضیحات تصویر)', // localized
value: 'R from file metadata link'
},
{
label: '{{R with history}}: تغییرمسیر از یک صفحه با تاریخچهٔ قابل توجه، که جهت حفظ محتوا و انتسابها نگهداری شدهاست', // localized
value: 'R with history'
},
{
label: '{{R from incomplete disambiguation}}: تغییرمسیر از نام یک صفحه که بیش از آن دارای ابهام است که بتواند عنوان یک نوشتار قرار گیرد و باید به یک صفحهٔ ابهامزدایی مناسب تغییرمسیر یابد.', // localized
value: 'R from incomplete disambiguation'
},
{
label: '{{تغییرمسیر حاصل از ادغام}}: تغییرمسیر از یک صفحهٔ ادغامشده جهت حفظ تاریخچهٔ ویرایشی آن', // localized
value: 'R from merge'
},
{
label: '{{R from other disambiguation}}: تغییرمسیر از نام یک صفحه با یک واژه ابهامزدایی جایگزین', // localized
value: 'R from other disambiguation'
},
{
label: '{{R printworthy}}: تغییرمسیر از عنوانی که میتواند در یک نسخهٔ چاپشده یا نسخهٔ سیدی/دیویدی ویکیپدیا کمککننده باشد', // localized
value: 'R printworthy'
},
{
label: '{{R from school}}: تغییرمسیر از مقالهٔ یک مدرسه دارای اطلاعات کمی بودهاست', // localized
value: 'R from school'
},
{
label: '{{R from shortcut}}: تغییرمسیر از یک میانبر ویکیپدیا', // localized
value: 'R from shortcut'
},
{
label: '{{R from sort name}}: تغییرمسیر از نام مرتبسازی هدف، مثلاً عنوانی که بهجای نام کوچک، با نام خانوادگی شروع میشود', // localized
value: 'R from sort name'
},
{
label: '{{R unprintworthy}}: تغییرمسیر از عنوانی که «نمیتواند» در یک نسخهٔ چاپشده یا نسخهٔ سیدی/دیویدی ویکیپدیا کمککننده باشد', // localized
value: 'R unprintworthy'
}
];
// maintenance tags for FILES start here
Twinkle.tag.file = {};
Twinkle.tag.file.licenseList = [
{ label: '{{Bsr}}: source info consists of bare image URL/generic base URL only', value: 'Bsr' },
{ label: '{{نیازمند نسخه کوچکتر}}: تصویر مورد استفادهٔ منصفانه با وضوح بالا (یا کلیپ صوتی بسیار بلند و غیره)', value: 'Non-free reduce' }, // localized
{ label: '{{نسخههای غیر آزاد یتیم}}: رسانههای استفادهٔ منصفانه با اصلاحات قدیمی که نیازمند حذف هستند', value: 'subst:orfurrev' } // localized
];
Twinkle.tag.file.commonsList = [
{ label: '{{انتقال به ویکیانبار}}: رسانههای آزاد که باید به ویکیانبار منتقل شوند', value: 'Copy to Commons' }, // localized
{ label: '{{به ویکیانبار انتقال ندهید}} (مشکل مالکیت عمومی): پرونده در ایالات متحده در مالکیت عمومی قرار دارد، اما در کشور مبدأ خود، خیر.', value: 'Do not move to Commons' }, // localized
{
label: '{{به ویکیانبار انتقال ندهید}} (دلیل دیگر)', // localized
value: 'Do not move to Commons_reason',
subgroup: {
type: 'input',
name: 'DoNotMoveToCommons',
label: 'دلیل: ', // localized
tooltip: 'دلیلی ارائه دهید که چرا نباید این تصویر را به ویکیانبار انتقال داد (الزامی)' // localized
}
},
{
label: '{{نسخه محلی حفظ شود}}: درخواست برای نگهداشتن نسخهٔ محلی از یک پروندهٔ انبار', // localized
value: 'Keep local',
subgroup: {
type: 'input',
name: 'keeplocalName',
label: 'نام تصویر در انبار در صورت تفاوت داشتن: ', // localized
tooltip: 'نام تصویر در ویکیانبار (اگر با نام محلی متفاوت است)، بدون پیشوند «پرونده:»:' // localized
}
},
{
label: '{{موجود در انبار}}: پرونده به انبار کپی شدهاست', // localized
value: 'subst:ncd',
subgroup: {
type: 'input',
name: 'ncdName',
label: 'نام تصویر در انبار در صورت تفاوت داشتن: ', // localized
tooltip: 'نام تصویر در ویکیانبار (اگر با نام محلی متفاوت است), ، بدون پیشوند «پرونده:»:' // localized
}
}
];
Twinkle.tag.file.cleanupList = [
{ label: '{{Artifacts}}: پروندهٔ PNG شامل مصنوعات فشردهسازی باقیمانده', value: 'Artifacts' }, // localized
{ label: '{{Bad font}}: پروندهٔ SVG استفادهکننده از فونتهایی که در سرور بندانگشتی موجود نیستند', value: 'Bad font' }, // localized
{ label: '{{Bad format}}: پروندهٔ PDF/DOC/... باید به یک فرمت کاربردیتر تبدیل شود', value: 'Bad format' }, // localized
{ label: '{{Bad GIF}}: پروندهٔ GIF که باید در فرمت PNG، JPEG، یا SVG باشد', value: 'Bad GIF' }, // localized
{ label: '{{Bad JPEG}}: پروندهٔ JPEG که باید در فرمت PNG یا SVG باشد', value: 'Bad JPEG' }, // localized
{ label: '{{Bad SVG}}: پروندهٔ SVG شامل جلوههای شطرنجی', value: 'Bad SVG' }, // localized
{ label: '{{Bad trace}}: پروندهٔ SVG ترسیمشده بهصورت خودکار که نیازمند تمیزکاری است', value: 'Bad trace' }, // localized
{
label: '{{تمیزکاری تصویر}}: تمیزکاری عمومی', value: 'Cleanup image', // localized
subgroup: {
type: 'input',
name: 'cleanupimageReason',
label: 'دلیل: ', // localized
tooltip: 'دلیل نیاز به تمیزکاری را وارد کنید (الزامی)' // localized
}
},
{ label: '{{ClearType}}: تصویر (نه نماگرفت) با تصحیح فرکانس ClearType', value: 'ClearType' }, // localized
{ label: '{{واترمارک تصویر}}: تصویر شامل واترمارک نمایان یا پنهان است', value: 'Imagewatermark' }, // localized
{ label: '{{NoCoins}}: تصویر استفادهکننده از سکه برای نشاندادن مقیاس', value: 'NoCoins' }, // localized
{ label: '{{Overcompressed JPEG}}: پروندهٔ JPEG با سطح بالایی از مصنوعات', value: 'Overcompressed JPEG' }, // localized
{ label: '{{Opaque}}: پسزمینهٔ مات که باید شفاف باشد', value: 'Opaque' }, // localized
{ label: '{{نیازمند حذف کادر}}: کادر نالازم، فضای سفید و غیره.', value: 'Remove border' }, // localized
{
label: '{{تغییرنام پرونده}}: نام پرونده با توجه به معیار درجشده در [[وپ:بت]] باید تغییر یابد', // localized
value: 'Rename media',
subgroup: [
{
type: 'input',
name: 'renamemediaNewname',
label: 'نام جدید: ', // localized
tooltip: 'نام جدید برای تصویر را وارد کنید (اختیاری)' // localized
},
{
type: 'input',
name: 'renamemediaReason',
label: 'دلیل: ', // localized
tooltip: 'دلیل تغییر نام را وارد کنید (اختیاری)' // localized
}
]
},
{ label: '{{Should be PNG}}: پروندهٔ GIF یا JPEG که باید lossless باشد', value: 'Should be PNG' }, // localized
{
label: '{{باید اسویجی باشد}}: پروندهٔ PNG، GIF یا JPEG که باید گرافیکی بُرداری باشد', value: 'Should be SVG', // localized
subgroup: {
name: 'svgCategory',
type: 'select',
list: [
{ label: '{{باید اسویجی باشد|other}}', value: 'other' }, // localized
{ label: '{{باید اسویجی باشد|alphabet}}: character images, font examples, etc.', value: 'alphabet' }, // localized
{ label: '{{باید اسویجی باشد|chemical}}: chemical diagrams, etc.', value: 'chemical' }, // localized
{ label: '{{باید اسویجی باشد|circuit}}: electronic circuit diagrams, etc.', value: 'circuit' }, // localized
{ label: '{{باید اسویجی باشد|coat of arms}}: coats of arms', value: 'coat of arms' }, // localized
{ label: '{{باید اسویجی باشد|diagram}}: diagrams that do not fit any other subcategory', value: 'diagram' }, // localized
{ label: '{{باید اسویجی باشد|emblem}}: emblems, free/libre logos, insignias, etc.', value: 'emblem' }, // localized
{ label: '{{باید اسویجی باشد|fair use}}: fair-use images, fair-use logos', value: 'fair use' }, // localized
{ label: '{{باید اسویجی باشد|flag}}: flags', value: 'flag' }, // localized
{ label: '{{باید اسویجی باشد|graph}}: visual plots of data', value: 'graph' }, // localized
{ label: '{{باید اسویجی باشد|logo}}: logos', value: 'logo' }, // localized
{ label: '{{باید اسویجی باشد|map}}: maps', value: 'map' }, // localized
{ label: '{{باید اسویجی باشد|music}}: musical scales, notes, etc.', value: 'music' }, // localized
{ label: '{{باید اسویجی باشد|physical}}: "realistic" images of physical objects, people, etc.', value: 'physical' }, // localized
{ label: '{{باید اسویجی باشد|symbol}}: miscellaneous symbols, icons, etc.', value: 'symbol' } // localized
]
}
},
{ label: '{{Should be text}}: image should be represented as text, tables, or math markup', value: 'Should be text' } // localized
];
Twinkle.tag.file.qualityList = [
{ label: '{{Image-blownout}}', value: 'Image-blownout' },
{ label: '{{Image-out-of-focus}}', value: 'Image-out-of-focus' },
{
label: '{{Image-Poor-Quality}}', value: 'Image-Poor-Quality',
subgroup: {
type: 'input',
name: 'ImagePoorQualityReason',
label: 'دلیل: ', // localized
tooltip: 'دلیل اینکه چرا این تصویر خوب نیست (الزامی)' // localized
}
},
{ label: '{{Image-underexposure}}', value: 'Image-underexposure' },
{
label: '{{Low quality chem}}: ساختارهای شیمیایی مورد اختلاف', value: 'Low quality chem', // localized
subgroup: {
type: 'input',
name: 'lowQualityChemReason',
label: 'دلیل: ', // localized
tooltip: 'دلیل اینکه چرا نمودار مورد اختلاف است (الزامی)' // localized
}
}
];
Twinkle.tag.file.replacementList = [
{ label: '{{Obsolete}}: نسخهٔ بهبودیافته موجود است', value: 'Obsolete' }, // localized
{ label: '{{PNG version available}}', value: 'نسخهٔ پیانجی موجود است' }, // localized
{ label: '{{Vector version available}}', value: 'نسخهٔ وکتور موجود است' } // localized
];
Twinkle.tag.file.replacementList.forEach(function(el) {
el.subgroup = {
type: 'input',
label: 'پروندهٔ جایگزین: ', // localized
tooltip: 'نام پروندهای که جایگزین این پرونده میشود را وارد کنید (الزامی)', // localized
name: el.value.replace(/ /g, '_') + 'File'
};
});
Twinkle.tag.callbacks = {
article: function articleCallback(pageobj) {
// Remove tags that become superfluous with this action
var pageText = pageobj.getPageText().replace(/\{\{\s*([Uu]serspace draft)\s*(\|(?:\{\{[^{}]*\}\}|[^{}])*)?\}\}\s*/g, '');
var params = pageobj.getCallbackParameters();
/**
* Saves the page following the removal of tags if any. The last step.
* Called from removeTags()
*/
var postRemoval = function() {
if (params.tagsToRemove.length) {
// Remove empty {{multiple issues}} if found
pageText = pageText.replace(/\{\{(multiple ?issues|article ?issues|mi)\s*\|\s*\}\}\n?/im, '');
// Remove single-element {{multiple issues}} if found
pageText = pageText.replace(/\{\{(?:multiple ?issues|article ?issues|mi)\s*\|\s*(\{\{[^}]+\}\})\s*\}\}/im, '$1');
}
// Build edit summary
var makeSentence = function(array) {
if (array.length < 3) {
return array.join(' and ');
}
var last = array.pop();
return array.join(', ') + ', and ' + last;
};
var makeTemplateLink = function(tag) {
var text = '{{[[';
// if it is a custom tag with a parameter
if (tag.indexOf('|') !== -1) {
tag = tag.slice(0, tag.indexOf('|'));
}
text += tag.indexOf(':') !== -1 ? tag : 'Template:' + tag + '|' + tag;
return text + ']]}}';
};
var summaryText;
var addedTags = params.tags.map(makeTemplateLink);
var removedTags = params.tagsToRemove.map(makeTemplateLink);
if (addedTags.length) {
summaryText = 'Added ' + makeSentence(addedTags);
summaryText += removedTags.length ? '; and removed ' + makeSentence(removedTags) : '';
} else {
summaryText = 'Removed ' + makeSentence(removedTags);
}
summaryText += ' tag' + (addedTags.length + removedTags.length > 1 ? 's' : '');
if (params.reason) {
summaryText += ': ' + params.reason;
}
// avoid truncated summaries
if (summaryText.length > (499 - Twinkle.getPref('summaryAd').length)) {
summaryText = summaryText.replace(/\[\[[^|]+\|([^\]]+)\]\]/g, '$1');
}
pageobj.setPageText(pageText);
pageobj.setEditSummary(summaryText + Twinkle.getPref('summaryAd'));
pageobj.setWatchlist(Twinkle.getPref('watchTaggedPages'));
pageobj.setMinorEdit(Twinkle.getPref('markTaggedPagesAsMinor'));
pageobj.setCreateOption('nocreate');
pageobj.save(function() {
// special functions for merge tags
if (params.mergeReason) {
// post the rationale on the talk page (only operates in main namespace)
var talkpageText = '\n\n== ' + params.talkDiscussionTitleLinked + ' ==\n\n';
talkpageText += params.mergeReason.trim() + ' ~~~~';
var talkpage = new Morebits.wiki.page('Talk:' + params.discussArticle, 'Posting rationale on talk page');
talkpage.setAppendText(talkpageText);
talkpage.setEditSummary('/* ' + params.talkDiscussionTitle + ' */ new section' + Twinkle.getPref('summaryAd'));
talkpage.setWatchlist(Twinkle.getPref('watchMergeDiscussions'));
talkpage.setCreateOption('recreate');
talkpage.append();
}
if (params.mergeTagOther) {
// tag the target page if requested
var otherTagName = 'Merge';
if (params.mergeTag === 'Merge from') {
otherTagName = 'Merge to';
} else if (params.mergeTag === 'Merge to') {
otherTagName = 'Merge from';
}
var newParams = {
tags: [otherTagName],
tagsToRemove: [],
tagsToRemain: [],
mergeTarget: Morebits.pageNameNorm,
discussArticle: params.discussArticle,
talkDiscussionTitle: params.talkDiscussionTitle,
talkDiscussionTitleLinked: params.talkDiscussionTitleLinked
};
var otherpage = new Morebits.wiki.page(params.mergeTarget, 'Tagging other page (' +
params.mergeTarget + ')');
otherpage.setCallbackParameters(newParams);
otherpage.load(Twinkle.tag.callbacks.article);
}
// post at WP:PNT for {{not English}} and {{rough translation}} tag
if (params.translationPostAtPNT) {
var pntPage = new Morebits.wiki.page('Wikipedia:Pages needing translation into English',
'Listing article at Wikipedia:Pages needing translation into English');
pntPage.setFollowRedirect(true);
pntPage.load(function friendlytagCallbacksTranslationListPage(pageobj) {
var old_text = pageobj.getPageText();
var template = params.tags.indexOf('Rough translation') !== -1 ? 'duflu' : 'needtrans';
var lang = params.translationLanguage;
var reason = params.translationComments;
var templateText = '{{subst:' + template + '|pg=' + Morebits.pageNameNorm + '|Language=' +
(lang || 'uncertain') + '|Comments=' + reason.trim() + '}} ~~~~';
var text, summary;
if (template === 'duflu') {
text = old_text + '\n\n' + templateText;
summary = 'Translation cleanup requested on ';
} else {
text = old_text.replace(/\n+(==\s?Translated pages that could still use some cleanup\s?==)/,
'\n\n' + templateText + '\n\n$1');
summary = 'Translation' + (lang ? ' from ' + lang : '') + ' requested on ';
}
if (text === old_text) {
pageobj.getStatusElement().error('failed to find target spot for the discussion');
return;
}
pageobj.setPageText(text);
pageobj.setEditSummary(summary + ' [[:' + Morebits.pageNameNorm + ']]' + Twinkle.getPref('summaryAd'));
pageobj.setCreateOption('recreate');
pageobj.save();
});
}
if (params.translationNotify) {
pageobj.lookupCreation(function(innerPageobj) {
var initialContrib = innerPageobj.getCreator();
// Disallow warning yourself
if (initialContrib === mw.config.get('wgUserName')) {
innerPageobj.getStatusElement().warn('You (' + initialContrib + ') created this page; skipping user notification');
return;
}
var userTalkPage = new Morebits.wiki.page('User talk:' + initialContrib,
'Notifying initial contributor (' + initialContrib + ')');
var notifytext = '\n\n== Your article [[' + Morebits.pageNameNorm + ']]==\n' +
'{{subst:uw-notenglish|1=' + Morebits.pageNameNorm +
(params.translationPostAtPNT ? '' : '|nopnt=yes') + '}} ~~~~';
userTalkPage.setAppendText(notifytext);
userTalkPage.setEditSummary('Notice: Please use English when contributing to the English Wikipedia.' +
Twinkle.getPref('summaryAd'));
userTalkPage.setCreateOption('recreate');
userTalkPage.setFollowRedirect(true);
userTalkPage.append();
});
}
});
if (params.patrol) {
pageobj.triage();
}
};
/**
* Removes the existing tags that were deselected (if any)
* Calls postRemoval() when done
*/
var removeTags = function removeTags() {
if (params.tagsToRemove.length === 0) {
postRemoval();
return;
}
Morebits.status.info('Info', 'Removing deselected tags that were already present');
var getRedirectsFor = [];
// Remove the tags from the page text, if found in its proper name,
// otherwise moves it to `getRedirectsFor` array earmarking it for
// later removal
params.tagsToRemove.forEach(function removeTag(tag) {
var tag_re = new RegExp('\\{\\{' + Morebits.pageNameRegex(tag) + '\\s*(\\|[^}]+)?\\}\\}\\n?');
if (tag_re.test(pageText)) {
pageText = pageText.replace(tag_re, '');
} else {
getRedirectsFor.push('Template:' + tag);
}
});
if (!getRedirectsFor.length) {
postRemoval();
return;
}
// Remove tags which appear in page text as redirects
var api = new Morebits.wiki.api('Getting template redirects', {
'action': 'query',
'prop': 'linkshere',
'titles': getRedirectsFor.join('|'),
'redirects': 1, // follow redirect if the class name turns out to be a redirect page
'lhnamespace': '10', // template namespace only
'lhshow': 'redirect',
'lhlimit': 'max' // 500 is max for normal users, 5000 for bots and sysops
}, function removeRedirectTag(apiobj) {
$(apiobj.responseXML).find('page').each(function(idx, page) {
var removed = false;
$(page).find('lh').each(function(idx, el) {
var tag = $(el).attr('title').slice(9);
var tag_re = new RegExp('\\{\\{' + Morebits.pageNameRegex(tag) + '\\s*(\\|[^}]*)?\\}\\}\\n?');
if (tag_re.test(pageText)) {
pageText = pageText.replace(tag_re, '');
removed = true;
return false; // break out of $.each
}
});
if (!removed) {
Morebits.status.warn('Info', 'Failed to find {{' +
$(page).attr('title').slice(9) + '}} on the page... excluding');
}
});
postRemoval();
});
api.post();
};
if (!params.tags.length) {
removeTags();
return;
}
var tagRe, tagText = '', tags = [], groupableTags = [], groupableExistingTags = [];
// Executes first: addition of selected tags
/**
* Updates `tagText` with the syntax of `tagName` template with its parameters
* @param {number} tagIndex
* @param {string} tagName
*/
var addTag = function articleAddTag(tagIndex, tagName) {
var currentTag = '';
if (tagName === 'Uncategorized' || tagName === 'Improve categories') {
pageText += '\n\n{{' + tagName + '|date={{subst:CURRENTMONTHNAME}} {{subst:CURRENTYEAR}}}}';
} else {
currentTag += '{{' + tagName;
// fill in other parameters, based on the tag
switch (tagName) {
case 'Cleanup':
currentTag += '|reason=' + params.cleanup;
break;
case 'Close paraphrasing':
currentTag += '|source=' + params.closeParaphrasing;
break;
case 'Copy edit':
if (params.copyEdit) {
currentTag += '|for=' + params.copyEdit;
}
break;
case 'Copypaste':
if (params.copypaste) {
currentTag += '|url=' + params.copypaste;
}
break;
case 'Expand language':
currentTag += '|topic=';
currentTag += '|langcode=' + params.expandLanguageLangCode;
if (params.expandLanguageArticle !== null) {
currentTag += '|otherarticle=' + params.expandLanguageArticle;
}
break;
case 'Expert needed':
if (params.expertNeeded) {
currentTag += '|1=' + params.expertNeeded;
}
if (params.expertNeededTalk) {
currentTag += '|talk=' + params.expertNeededTalk;
}
if (params.expertNeededReason) {
currentTag += '|reason=' + params.expertNeededReason;
}
break;
case 'Globalize':
currentTag += '|1=article';
if (params.globalizeRegion) {
currentTag += '|2=' + params.globalizeRegion;
}
break;
case 'News release':
currentTag += '|1=article';
break;
case 'Notability':
if (params.notability !== 'none') {
currentTag += '|' + params.notability;
}
break;
case 'Not English':
case 'Rough translation':
if (params.translationLanguage) {
currentTag += '|1=' + params.translationLanguage;
}
if (params.translationPostAtPNT) {
currentTag += '|listed=yes';
}
break;
case 'History merge':
currentTag += '|originalpage=' + params.histmergeOriginalPage;
if (params.histmergeReason) {
currentTag += '|reason=' + params.histmergeReason;
}
if (params.histmergeSysopDetails) {
currentTag += '|details=' + params.histmergeSysopDetails;
}
break;
case 'Merge':
case 'Merge to':
case 'Merge from':
params.mergeTag = tagName;
// normalize the merge target for now and later
params.mergeTarget = Morebits.string.toUpperCaseFirstChar(params.mergeTarget.replace(/_/g, ' '));
currentTag += '|' + params.mergeTarget;
// link to the correct section on the talk page, for article space only
if (mw.config.get('wgNamespaceNumber') === 0 && (params.mergeReason || params.discussArticle)) {
if (!params.discussArticle) {
// discussArticle is the article whose talk page will contain the discussion
params.discussArticle = tagName === 'Merge to' ? params.mergeTarget : mw.config.get('wgTitle');
// nonDiscussArticle is the article which won't have the discussion
params.nonDiscussArticle = tagName === 'Merge to' ? mw.config.get('wgTitle') : params.mergeTarget;
var direction = '[[' + params.nonDiscussArticle + ']]' + (params.mergeTag === 'Merge' ? ' with ' : ' into ') + '[[' + params.discussArticle + ']]';
params.talkDiscussionTitleLinked = 'Proposed merge of ' + direction;
params.talkDiscussionTitle = params.talkDiscussionTitleLinked.replace(/\[\[(.*?)\]\]/g, '$1');
}
currentTag += '|discuss=Talk:' + params.discussArticle + '#' + params.talkDiscussionTitle;
}
break;
default:
break;
}
currentTag += '|date={{subst:CURRENTMONTHNAME}} {{subst:CURRENTYEAR}}}}\n';
tagText += currentTag;
}
};
/**
* Adds the tags which go outside {{multiple issues}}, either because
* these tags aren't supported in {{multiple issues}} or because
* {{multiple issues}} is not being added to the page at all
*/
var addUngroupedTags = function() {
$.each(tags, addTag);
// Smartly insert the new tags after any hatnotes or
// afd, csd, or prod templates or hatnotes. Regex is
// extra complicated to allow for templates with
// parameters and to handle whitespace properly.
pageText = pageText.replace(
new RegExp(
// leading whitespace
'^\\s*' +
// capture template(s)
'(?:((?:\\s*' +
// AfD is special, as the tag includes html comments before and after the actual template
'(?:<!--.*AfD.*\\n\\{\\{(?:Article for deletion\\/dated|AfDM).*\\}\\}\\n<!--.*(?:\\n<!--.*)?AfD.*(?:\\s*\\n))?|' + // trailing whitespace/newline needed since this subst's a newline
// begin template format
'\\{\\{\\s*(?:' +
// CSD
'db|delete|db-.*?|speedy deletion-.*?|' +
// PROD
'(?:proposed deletion|prod blp)\\/dated(?:\\s*\\|(?:concern|user|timestamp|help).*)+|' +
// various hatnote templates
'about|correct title|dablink|distinguish|for|other\\s?(?:hurricaneuses|people|persons|places|uses(?:of)?)|redirect(?:-acronym)?|see\\s?(?:also|wiktionary)|selfref|short description|the' +
// not a hatnote, but sometimes under a CSD or AfD
'|salt|proposed deletion endorsed' +
// end main template name, optionally with a number (such as redirect2)
')\\d*\\s*' +
// template parameters
'(\\|(?:\\{\\{[^{}]*\\}\\}|[^{}])*)?' +
// end template format
'\\}\\})+' +
// end capture
'(?:\\s*\\n)?)' +
// trailing whitespace
'\\s*)?',
'i'), '$1' + tagText
);
removeTags();
};
// Separate tags into groupable ones (`groupableTags`) and non-groupable ones (`tags`)
params.tags.forEach(function(tag) {
tagRe = new RegExp('\\{\\{' + tag + '(\\||\\}\\})', 'im');
// regex check for preexistence of tag can be skipped if in canRemove mode
if (Twinkle.tag.canRemove || !tagRe.exec(pageText)) {
// condition Twinkle.tag.article.tags[tag] to ensure that its not a custom tag
// Custom tags are assumed non-groupable, since we don't know whether MI template supports them
if (Twinkle.tag.article.tags[tag] && Twinkle.tag.multipleIssuesExceptions.indexOf(tag) === -1) {
groupableTags.push(tag);
} else {
tags.push(tag);
}
} else {
if (tag === 'Merge from' || tag === 'History merge') {
tags.push(tag);
} else {
Morebits.status.warn('Info', 'Found {{' + tag +
'}} on the article already...excluding');
// don't do anything else with merge tags
if (['Merge', 'Merge to'].indexOf(tag) !== -1) {
params.mergeTarget = params.mergeReason = params.mergeTagOther = null;
}
}
}
});
// To-be-retained existing tags that are groupable
params.tagsToRemain.forEach(function(tag) {
if (Twinkle.tag.multipleIssuesExceptions.indexOf(tag) === -1) {
groupableExistingTags.push(tag);
}
});
var miTest = /\{\{(multiple ?issues|article ?issues|mi)(?!\s*\|\s*section\s*=)[^}]+\{/im.exec(pageText);
if (miTest && groupableTags.length > 0) {
Morebits.status.info('Info', 'Adding supported tags inside existing {{multiple issues}} tag');
tagText = '';
$.each(groupableTags, addTag);
var miRegex = new RegExp('(\\{\\{\\s*' + miTest[1] + '\\s*(?:\\|(?:\\{\\{[^{}]*\\}\\}|[^{}])*)?)\\}\\}\\s*', 'im');
pageText = pageText.replace(miRegex, '$1' + tagText + '}}\n');
tagText = '';
addUngroupedTags();
} else if (params.group && !miTest && (groupableExistingTags.length + groupableTags.length) >= 2) {
Morebits.status.info('Info', 'Grouping supported tags inside {{multiple issues}}');
tagText += '{{Multiple issues|\n';
/**
* Adds newly added tags to MI
*/
var addNewTagsToMI = function() {
$.each(groupableTags, addTag);
tagText += '}}\n';
addUngroupedTags();
};
var getRedirectsFor = [];
// Reposition the tags on the page into {{multiple issues}}, if found with its
// proper name, else moves it to `getRedirectsFor` array to be handled later
groupableExistingTags.forEach(function repositionTagIntoMI(tag) {
var tag_re = new RegExp('(\\{\\{' + Morebits.pageNameRegex(tag) + '\\s*(\\|[^}]+)?\\}\\}\\n?)');
if (tag_re.test(pageText)) {
tagText += tag_re.exec(pageText)[1];
pageText = pageText.replace(tag_re, '');
} else {
getRedirectsFor.push('Template:' + tag);
}
});
if (!getRedirectsFor.length) {
addNewTagsToMI();
return;
}
var api = new Morebits.wiki.api('Getting template redirects', {
'action': 'query',
'prop': 'linkshere',
'titles': getRedirectsFor.join('|'),
'redirects': 1,
'lhnamespace': '10', // template namespace only
'lhshow': 'redirect',
'lhlimit': 'max' // 500 is max for normal users, 5000 for bots and sysops
}, function replaceRedirectTag(apiobj) {
$(apiobj.responseXML).find('page').each(function(idx, page) {
var found = false;
$(page).find('lh').each(function(idx, el) {
var tag = $(el).attr('title').slice(9);
var tag_re = new RegExp('(\\{\\{' + Morebits.pageNameRegex(tag) + '\\s*(\\|[^}]*)?\\}\\}\\n?)');
if (tag_re.test(pageText)) {
tagText += tag_re.exec(pageText)[1];
pageText = pageText.replace(tag_re, '');
found = true;
return false; // break out of $.each
}
});
if (!found) {
Morebits.status.warn('Info', 'Failed to find the existing {{' +
$(page).attr('title').slice(9) + '}} on the page... skip repositioning');
}
});
addNewTagsToMI();
});
api.post();
} else {
tags = tags.concat(groupableTags);
addUngroupedTags();
}
},
redirect: function redirect(pageobj) {
var params = pageobj.getCallbackParameters(),
pageText = pageobj.getPageText(),
tagRe, tagText = '', summaryText = 'Added',
tags = [], i;
for (i = 0; i < params.tags.length; i++) {
tagRe = new RegExp('(\\{\\{' + params.tags[i] + '(\\||\\}\\}))', 'im');
if (!tagRe.exec(pageText)) {
tags.push(params.tags[i]);
} else {
Morebits.status.warn('Info', 'Found {{' + params.tags[i] +
'}} on the redirect already...excluding');
}
}
var addTag = function redirectAddTag(tagIndex, tagName) {
tagText += '\n{{' + tagName;
if (tagName === 'R from alternative language') {
if (params.altLangFrom) {
tagText += '|from=' + params.altLangFrom;
}
if (params.altLangTo) {
tagText += '|to=' + params.altLangTo;
}
}
tagText += '}}';
if (tagIndex > 0) {
if (tagIndex === (tags.length - 1)) {
summaryText += ' and';
} else if (tagIndex < (tags.length - 1)) {
summaryText += ',';
}
}
summaryText += ' {{[[:' + (tagName.indexOf(':') !== -1 ? tagName : 'Template:' + tagName + '|' + tagName) + ']]}}';
};
tags.sort();
$.each(tags, addTag);
// Check for all Rcat shell redirects (from #433)
if (pageText.match(/{{(?:redr|this is a redirect|r(?:edirect)?(?:.?cat.*)?[ _]?sh)/i)) {
// Regex inspired by [[User:Kephir/gadgets/sagittarius.js]] ([[Special:PermaLink/831402893]])
var oldTags = pageText.match(/(\s*{{[A-Za-z ]+\|)((?:[^|{}]*|{{[^}]*}})+)(}})\s*/i);
pageText = pageText.replace(oldTags[0], oldTags[1] + tagText + oldTags[2] + oldTags[3]);
} else {
// Fold any pre-existing Rcats into taglist and under Rcatshell
var pageTags = pageText.match(/\n{{R(?:edirect)? .*?}}/img);
var oldPageTags = '';
if (pageTags) {
pageTags.forEach(function(pageTag) {
var pageRe = new RegExp(pageTag, 'img');
pageText = pageText.replace(pageRe, '');
oldPageTags += pageTag;
});
}
pageText += '\n{{Redirect category shell|' + tagText + oldPageTags + '\n}}';
}
summaryText += (tags.length > 0 ? ' tag' + (tags.length > 1 ? 's' : '') : '') + ' to redirect';
// avoid truncated summaries
if (summaryText.length > (499 - Twinkle.getPref('summaryAd').length)) {
summaryText = summaryText.replace(/\[\[[^|]+\|([^\]]+)\]\]/g, '$1');
}
pageobj.setPageText(pageText);
pageobj.setEditSummary(summaryText + Twinkle.getPref('summaryAd'));
pageobj.setWatchlist(Twinkle.getPref('watchTaggedPages'));
pageobj.setMinorEdit(Twinkle.getPref('markTaggedPagesAsMinor'));
pageobj.setCreateOption('nocreate');
pageobj.save();
if (params.patrol) {
pageobj.triage();
}
},
file: function friendlytagCallbacksFile(pageobj) {
var text = pageobj.getPageText();
var params = pageobj.getCallbackParameters();
var summary = 'Adding ';
// Add maintenance tags
if (params.tags.length) {
var tagtext = '', currentTag;
$.each(params.tags, function(k, tag) {
// when other commons-related tags are placed, remove "move to Commons" tag
if (['Keep local', 'subst:ncd', 'Do not move to Commons_reason', 'Do not move to Commons',
'Now Commons'].indexOf(tag) !== -1) {
text = text.replace(/\{\{(mtc|(copy |move )?to ?commons|move to wikimedia commons|copy to wikimedia commons)[^}]*\}\}/gi, '');
}
currentTag = '{{' + (tag === 'Do not move to Commons_reason' ? 'Do not move to Commons' : tag);
switch (tag) {
case 'subst:ncd':
if (params.ncdName !== '') {
currentTag += '|1=' + params.ncdName;
}
break;
case 'Keep local':
if (params.keeplocalName !== '') {
currentTag += '|1=' + params.keeplocalName;
}
break;
case 'Rename media':
if (params.renamemediaNewname !== '') {
currentTag += '|1=' + params.renamemediaNewname;
}
if (params.renamemediaReason !== '') {
currentTag += '|2=' + params.renamemediaReason;
}
break;
case 'Cleanup image':
currentTag += '|1=' + params.cleanupimageReason;
break;
case 'Image-Poor-Quality':
currentTag += '|1=' + params.ImagePoorQualityReason;
break;
case 'Low quality chem':
currentTag += '|1=' + params.lowQualityChemReason;
break;
case 'Vector version available':
text = text.replace(/\{\{((convert to |convertto|should be |shouldbe|to)?svg|badpng|vectorize)[^}]*\}\}/gi, '');
/* falls through */
case 'PNG version available':
/* falls through */
case 'Obsolete':
currentTag += '|1=' + params[tag.replace(/ /g, '_') + 'File'];
break;
case 'Do not move to Commons_reason':
currentTag += '|reason=' + params.DoNotMoveToCommons;
break;
case 'subst:orfurrev':
// remove {{non-free reduce}} and redirects
text = text.replace(/\{\{\s*(Template\s*:\s*)?(Non-free reduce|FairUseReduce|Fairusereduce|Fair Use Reduce|Fair use reduce|Reduce size|Reduce|Fair-use reduce|Image-toobig|Comic-ovrsize-img|Non-free-reduce|Nfr|Smaller image|Nonfree reduce)\s*(\|(?:\{\{[^{}]*\}\}|[^{}])*)?\}\}\s*/ig, '');
currentTag += '|date={{subst:date}}';
break;
case 'Copy to Commons':
currentTag += '|human=' + mw.config.get('wgUserName');
break;
case 'Should be SVG':
currentTag += '|' + params.svgCategory;
break;
default:
break; // don't care
}
currentTag += '}}\n';
tagtext += currentTag;
summary += '{{' + tag + '}}, ';
});
if (!tagtext) {
pageobj.getStatusElement().warn('User canceled operation; nothing to do');
return;
}
text = tagtext + text;
}
pageobj.setPageText(text);
pageobj.setEditSummary(summary.substring(0, summary.length - 2) + Twinkle.getPref('summaryAd'));
pageobj.setWatchlist(Twinkle.getPref('watchTaggedPages'));
pageobj.setMinorEdit(Twinkle.getPref('markTaggedPagesAsMinor'));
pageobj.setCreateOption('nocreate');
pageobj.save();
if (params.patrol) {
pageobj.triage();
}
}
};
Twinkle.tag.callback.evaluate = function friendlytagCallbackEvaluate(e) {
var form = e.target;
var params = {};
if (form.patrolPage) {
params.patrol = form.patrolPage.checked;
}
// Don't return null if there aren't any available tags
params.tags = form.getChecked(Twinkle.tag.mode + 'Tags') || [];
// Save values of input fields into params object. This works as quickform input
// fields within subgroups of elements with name 'articleTags' (say) have their
// name attribute as 'articleTags.' + name of the subgroup element
var name_prefix = Twinkle.tag.mode + 'Tags.';
$(form).find("[name^='" + name_prefix + "']:not(div)").each(function(idx, el) {
// el are the HTMLInputElements, el.name gives the name attribute
params[el.name.slice(name_prefix.length)] =
el.type === 'checkbox' ? form[el.name].checked : form[el.name].value;
});
switch (Twinkle.tag.mode) {
case 'article':
params.tagsToRemove = form.getUnchecked('alreadyPresentArticleTags') || [];
params.tagsToRemain = form.getChecked('alreadyPresentArticleTags') || [];
params.reason = form.reason.value.trim();
params.group = form.group.checked;
// Validation
if ((params.tags.indexOf('Merge') !== -1) || (params.tags.indexOf('Merge from') !== -1) ||
(params.tags.indexOf('Merge to') !== -1)) {
if (((params.tags.indexOf('Merge') !== -1) + (params.tags.indexOf('Merge from') !== -1) +
(params.tags.indexOf('Merge to') !== -1)) > 1) {
alert('Please select only one of {{merge}}, {{merge from}}, and {{merge to}}. If several merges are required, use {{merge}} and separate the article names with pipes (although in this case Twinkle cannot tag the other articles automatically).');
return;
}
if (!params.mergeTarget) {
alert('Please specify the title of the other article for use in the merge template.');
return;
}
if ((params.mergeTagOther || params.mergeReason) && params.mergeTarget.indexOf('|') !== -1) {
alert('Tagging multiple articles in a merge, and starting a discussion for multiple articles, is not supported at the moment. Please turn off "tag other article", and/or clear out the "reason" box, and try again.');
return;
}
}
if ((params.tags.indexOf('Not English') !== -1) && (params.tags.indexOf('Rough translation') !== -1)) {
alert('Please select only one of {{not English}} and {{rough translation}}.');
return;
}
if (params.tags.indexOf('History merge') !== -1 && params.histmergeOriginalPage.trim() === '') {
alert('You must specify a page to be merged for the {{history merge}} tag.');
return;
}
if (params.tags.indexOf('Cleanup') !== -1 && params.cleanup.trim() === '') {
alert('You must specify a reason for the {{cleanup}} tag.');
return;
}
if (params.tags.indexOf('Expand language') !== -1 && params.expandLanguageLangCode.trim() === '') {
alert('You must specify language code for the {{expand language}} tag.');
return;
}
break;
case 'file':
if (params.tags.indexOf('Cleanup image') !== -1 && params.cleanupimageReason === '') {
alert('You must specify a reason for the cleanup tag.');
return;
}
if (params.tags.indexOf('Image-Poor-Quality') !== -1 && params.ImagePoorQualityReason === '') {
alert('You must specify a reason for the {{Image-Poor-Quality}} tag');
return;
}
if (params.tags.indexOf('Low Quality Chem') !== -1 && params.lowQualityChemReason === '') {
alert('You must specify a reason for the {{Low Quality Chem}} tag');
return;
}
if ((params.tags.indexOf('Obsolete') !== -1 && params.ObsoleteFile === '') ||
(params.tags.indexOf('PNG version available') !== -1 && params.PNG_version_availableFile === '') ||
(params.tags.indexOf('Vector version available') !== -1 && params.Vector_version_availableFile === '')
) {
alert('You must specify the replacement file name for a tag in the Replacement tags list');
return;
}
if (params.tags.indexOf('Do not move to Commons_reason') !== -1 && params.DoNotMoveToCommons === '') {
alert('You must specify a reason for the {{Do not move to Commons}} tag');
return;
}
break;
case 'redirect':
break;
default:
alert('Twinkle.tag: unknown mode ' + Twinkle.tag.mode);
break;
}
// File/redirect: return if no tags selected
// Article: return if no tag is selected and no already present tag is deselected
if (params.tags.length === 0 && (Twinkle.tag.mode !== 'article' || params.tagsToRemove.length === 0)) {
alert('You must select at least one tag!');
return;
}
Morebits.simpleWindow.setButtonsEnabled(false);
Morebits.status.init(form);
Morebits.wiki.actionCompleted.redirect = Morebits.pageNameNorm;
Morebits.wiki.actionCompleted.notice = 'Tagging complete, reloading article in a few seconds';
if (Twinkle.tag.mode === 'redirect') {
Morebits.wiki.actionCompleted.followRedirect = false;
}
var wikipedia_page = new Morebits.wiki.page(Morebits.pageNameNorm, 'Tagging ' + Twinkle.tag.mode);
wikipedia_page.setCallbackParameters(params);
wikipedia_page.load(Twinkle.tag.callbacks[Twinkle.tag.mode]);
};
})(jQuery);
// </nowiki>