MediaWiki:Gadget-friendlytag.js: Perbedaan antara revisi
Konten dihapus Konten ditambahkan
Repo at d9666d4: Update Twinkle from upstream |
Repo at a491314: tracking branch 'upstream/master'; Add untag functionality (#485); fix bug when processing items with type=div; Cleanup regex, put tags under AfD notices, fix prod regex, put under salt and endorsed prod (#579); Remove globalize/India; Put new tags under salt and endorsed prod; Put tags under AfD notices, fix prod detection, tidy regex |
||
Baris 1:
//<nowiki>
(function($) {
Baris 29 ⟶ 28:
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, "Tag", "friendly-tag", "Berikan atau hapus tag pemeliharaan ke artikel" );
}
};
Twinkle.tag.checkedTags = [];
Twinkle.tag.callback = function friendlytagCallback() {
Baris 70 ⟶ 76:
]
});
if (! Twinkle.tag.canRemove) {
var divElement = document.createElement('div');
divElement.innerHTML = 'For removal of existing tags, please open Tag menu from the current version of article';
form.append({
type: 'div',
name: 'untagnotice',
label: divElement
});
}
form.append({
Baris 148 ⟶ 164:
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');
}
}
// 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);
}
};
Twinkle.tag.updateSortOrder = function(e) {
var sortorder = e.target.value;
Twinkle.tag.checkedTags = e.target.form.getChecked("articleTags");
if (!Twinkle.tag.checkedTags) {
Baris 174 ⟶ 235:
}
switch (tag) {
case "
checkbox.subgroup = {
name: 'cleanup',
Baris 183 ⟶ 244:
};
break;
case "
checkbox.subgroup = {
name: 'closeParaphrasing',
Baris 191 ⟶ 252:
};
break;
case "
checkbox.subgroup = {
name: 'copyEdit',
Baris 200 ⟶ 261:
};
break;
case "
checkbox.subgroup = {
name: 'copypaste',
Baris 209 ⟶ 270:
};
break;
case "
checkbox.subgroup = [ {
name: 'expandLanguageLangCode',
Baris 223 ⟶ 284:
];
break;
case "
checkbox.subgroup = [
{
name: 'expertNeeded',
type: 'input',
label: 'Nama ProyekWiki terkait: ',
tooltip: 'Opsional. Berikan nama ProyekWiki yang dapat membantu merekrut pengguna ahli. Jangan berikan awalan "WikiProject" atau "ProyekWiki"
},
{
name: 'expertNeededReason',
type: 'input',
label: 'Alasan: ',
tooltip: 'Short explanation describing the issue. Either Reason or Talk link is required.'
},
name: 'expertNeededTalk',
tooltip: 'Name of the section of this article\'s talk page where the issue is being discussed. Do not give a link, just the name of the section. Either Reason or Talk link is required.'
];
break;
case "
checkbox.subgroup = {
name: 'globalize',
Baris 264 ⟶ 323:
{ label: "{{globalize/France}}: artikel berisi konten yang dibuat terutama dalam sudut pandang masyarakat Peranc", value: "globalize/France" },
{ label: "{{globalize/Germany}}: article deals primarily with the German viewpoint", value: "globalize/Germany" },
{ label: "{{globalize/Middle East}}: article deals primarily with the Middle Eastern viewpoint", value: "globalize/Middle East" },
{ label: "{{globalize/North America}}: article deals primarily with the North American viewpoint", value: "globalize/North America" },
Baris 279 ⟶ 337:
};
break;
case "
checkbox.subgroup = [
{
Baris 301 ⟶ 359:
];
break;
case "
case "
case "
var otherTagName = "
switch (tag)
{
case "
otherTagName = "
break;
case "
otherTagName = "
break;
}
Baris 338 ⟶ 396:
type: 'textarea',
label: 'Alasan penggabungan (akan dikirimkan ke ' +
(tag === "
tooltip: 'Opsional, namun sangat disarankan. Kosongkan jika tidak diinginkan. Hanya tersedia jika nama artikel tunggal diberikan.'
});
}
break;
// case "
case "
case "
checkbox.subgroup = [
{
Baris 354 ⟶ 412:
}
];
// if (tag === "
if (tag === "
checkbox.subgroup.push({
name: 'translationNotify',
Baris 368 ⟶ 426:
});
}
if (mw.config.get('wgNamespaceNumber') === 0) {
checkbox.subgroup.push({
name: 'translationPostAtPNT',
type: 'checkbox',
list: [
{
label: 'List this article at Wikipedia:Pages needing translation into English (PNT)',
checked: true
checkbox.subgroup.push({
name: 'translationComments',
tooltip: 'Optional, and only relevant if "List this article ..." above is checked.'
});
}
case "Notability":
checkbox.subgroup = {
name: 'notability',
Baris 416 ⟶ 472:
}
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 = [];
Twinkle.tag.alreadyPresentTags.forEach( function(tag) {
var description = Twinkle.tag.article.tags[tag];
var checkbox =
{
value: tag,
label: "{{" + tag + "}}" + ( description ? (": " + description) : ""),
checked: true
//, subgroup: { type: 'input', name: 'removeReason', label: 'Reason', tooltip: 'Enter reason for removing this tag' }
// TODO: add option for providing reason for removal
};
checkboxes.push(checkbox);
} );
subdiv.append({
type: "checkbox",
name: "alreadyPresentArticleTags",
list: checkboxes
});
};
Baris 425 ⟶ 505:
$.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({
Baris 434 ⟶ 516:
};
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) {
Baris 451 ⟶ 536:
// alphabetical sort order
else {
if(Twinkle.tag.alreadyPresentTags.length > 0) {
makeCheckboxesForAlreadyPresentTags();
container.append({ type: "header", id: "tagHeader1", label: "Available tags" });
}
var checkboxes = [];
$.each(Twinkle.tag.article.tags, function(tag, description) {
if (Twinkle.tag.alreadyPresentTags.indexOf(tag) === -1) {
checkboxes.push(makeCheckbox(tag, description));
}
});
container.append({
Baris 477 ⟶ 568:
$workarea.find("div").filter(":has(span.quickformDescription)").css({ 'margin-top': '0.4em' });
Morebits.quickForm.getElements(e.target.form, "articleTags").forEach(generateLinks);
if (alreadyPresentTags) {
alreadyPresentTags.forEach(generateLinks);
}
};
/**
* 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]);
};
Baris 501 ⟶ 600:
Twinkle.tag.article.tags = {
"
"
"
"BLP sources": "artikel tokoh yang masih hidup perlu referensi lebih banyak untuk diperiksa",
"BLP unsourced": "artikel tokoh yang masih hidup yang tidak punya referensi",
"
"
"Cleanup bare URLs": "article uses bare URLs for references, which are prone to link rot",
"Cleanup-PR": "article reads like a press release or news release",
"
"Cleanup rewrite": "article may need to be rewritten entirely to comply with Wikipedia's quality standards",
"Cleanup tense": "article is written in an incorrect tense",
"Close paraphrasing": "artikel mengandung parafrasa yang mirip dengan sumber tidak bebas berhak cipta",
"COI": "pembuat artikel memiliki konflik kepentingan",
"
"
"
"
"
"Current": "article documents a current event",
"Disputed": "akurasi aktual isi halaman dipertanyakan",
"Essay-like": "artikel ditulis seperti esai atau opini",
"
"
"External links": "pranala luar artikel tidak mengikuti pedoman dan kebijakan",
"
"
"
"GOCEinuse": "article is currently undergoing a major copy edit by the Guild of Copy Editors",
"History merge": "another page should be history merged into this one",
"Hoax": "artikel berisi informasi palsu",
"
"
"In-universe": "subjek artikel adalah fiksi dan butuh gaya penulisan dari sudut pandang nonfiksi",
"In use": "artikel dalam pengembangan dalam waktu dekat",
"
"
"
"
"Like resume": "article is written like a resume",
"Long plot": "ringkasan alur di artikel terlalu panjang",
"
"Merge": "artikel ini perlu digabungkan ke artikel lain",
"
"
"More citations needed": "article needs additional references or sources for verification",
"
"No footnotes": "artikel punya referensi, namun tidak punya catatan kaki",
"
"Non-free": "artikel mungkin mengandung materi yang berhak cipta yang tidak digunakan sebagaimana mestinya",
"
"Not English": "article is written in a language other than English and needs translation",
"
"Original research": "artikel memiliki penggunaan riset asli klaim yang tidak terperiksa",
"Orphan": "artikel tidak memiliki hubungan dengan artikel lain",
"Over-coverage": "artikel mengandung anggapan atau cakupan tidak sesuai terhadap satu bagian atau lebih",
"Overlinked": "artikel banyak mengandung pranala duplikat dan/atau tidak berhubungan",
"
"Over-quotation": "article contains too many or too-lengthy quotations for an encyclopedic entry",
"Peacock": "artikel mengandung istilah hiperbola yang mempromosikan subjek tanpa informasi lengkap",
"POV": "sudut pandang penulisan artikel tidak netral",
"
"
"
"
"
"Self-published": "artikel mengandung sumber yang mungkin tak sesuai untuk sumber yang diterbitkan oleh diri sendiri",
"
"
"
"
"
"
"Underlinked": "artikel perlu lebih banyak pranala wiki",
"Undue weight": "article lends undue weight to certain ideas, incidents, or controversies",
"Unfocused": "artikel kurang memfokuskan subjek atau punya topik yang lebih dari satu",
"
"Unreliable sources": "sumber artikel mungkin tidak dapat dipercaya",
"Undisclosed paid": "article may have been created or edited in return for undisclosed payments",
"
"
"Weasel": "kenetralan artikel diganggu oleh penggunaan kata bersayap",
"
"Linkrot": "sumber referensi artikel sudah mati, dan penulisannya harus diperbaiki",
"New unreviewed article": "tandai artikel untuk diperiksa nanti",
"News release": "gaya artikel mirip seperti berita",
"Not Indonesian": "artikel tidak ditulis dalam bahasa Indonesia dan perlu diterjemahkan",
"Refimprove": "artikel perlu sumber tambahan untuk diperiksa",
"Tense": "artikel ditulis dalam gaya tidak sesuai",
"Tugas sekolah": "artikel yang sedang digunakan untuk penilaian di sekolah/universitas"
};
Baris 598 ⟶ 699:
"Tag rapikan dan pemeliharaan": {
"Perapian secara umum": [
"
"
"
],
"Mengandung konten yang tidak diinginkan": [
"
"
"
"
],
"Struktur, format, dan pengantar": [
"
"
"
"
"
"
"
"
],
"Perapian terkait isi fiksi": [
"
"
"
"
"
]
},
"Masalah konten secara umum": {
"Kepentingan dan kelayakan": [
"
],
"Gaya penulisan": [
"
"
"
"
"
"
"
"
"
"
"
],
"Makna": [
"
"
"
],
"Detail dan informasi": [
"
"
"
"
],
"Keaktualan": [
"
"
],
"Netralitas, kecondongan dan akurasi faktual": [
"
"COI",
"
"
"
"
"
"POV",
"
"
"
"
],
"Pemeriksaan dan sumber": [
"BLP sources",
"BLP unsourced",
"
"
"
"
"
"
"
"
]
},
"Masalah konten tertentu": {
"Bahasa": [
"
"
"
],
"Pranala dan tautan": [
"
"
"
],
"Teknik pemberian referensi": [
"
"
"
"
],
"Kategori": [
"
"
]
},
"Penggabungan": [
"History "Merge", // these three have a subgroup with several options "
"
],
"Informasi halaman": [
"GOCEinuse",
"
"
"
]
};
// Contains those article tags that *do not* work inside {{multiple issues}}.
Twinkle.tag.multipleIssuesExceptions = [
'Copypaste',
'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
Baris 1.019 ⟶ 1.138:
{ label: '{{Vector version available}}', value: 'Vector version available' }
];
Twinkle.tag.file.replacementList.forEach(function
el.subgroup = {
type: 'input',
Baris 1.027 ⟶ 1.146:
}
});
Twinkle.tag.callbacks = {
// Remove tags that become superfluous with this action
var pageText = pageobj.getPageText().replace(/\{\{\s*([Uu]serspace draft)\s*(\|(?:\{\{[^{}]*\}\}|[^{}])*)?\}\}\s*/g, "");
var summaryText;
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) {
// Finish summary text
summaryText += ' tag' + ( params.tagsToRemove.length > 1 ? 's' : '') + ' from article';
// 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');
}
// avoid truncated summaries
if (summaryText.length > (254 - Twinkle.getPref('summaryAd').length)) {
summaryText = summaryText.replace(/\[\[[^|]+\|([^\]]+)\]\]/g, "$1");
}
pageobj.setPageText(pageText);
pageobj.setEditSummary(summaryText + Twinkle.getPref('summaryAd'));
pageobj.setWatchlist(Twinkle.getFriendlyPref('watchTaggedPages'));
pageobj.setMinorEdit(Twinkle.getFriendlyPref('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== Proposed merge with [[" + params.nonDiscussArticle + "]] ==\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('Proposing to merge [[:' + params.nonDiscussArticle + ']] ' +
(params.mergeTag === 'Merge' ? 'with' : 'into') + ' [[:' + params.discussArticle + ']]' +
Twinkle.getPref('summaryAd'));
talkpage.setWatchlist(Twinkle.getFriendlyPref('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
};
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.setCallbackParameters({
template: params.tags.indexOf('Rough translation') !== -1 ? "duflu" : "needtrans",
lang: params.translationLanguage,
reason: params.translationComments
});
pntPage.load(function friendlytagCallbacksTranslationListPage(pageobj) {
var old_text = pageobj.getPageText();
var params = pageobj.getCallbackParameters();
var statelem = pageobj.getStatusElement();
var templateText = "{{subst:" + params.template + "|pg=" + Morebits.pageNameNorm + "|Language=" +
(params.lang || "uncertain") + "|Comments=" + params.reason.trim() + "}} ~~~~";
var text, summary;
if (params.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" + (params.lang ? (" from " + params.lang) : "") + " requested on ";
}
if (text === old_text) {
statelem.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.lookupCreator(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.patrol();
}
};
/**
* Removes the existing tags that were deselected (if any)
* Calls postRemoval() when done
*/
var removeTags = function removeTags() {
if (params.tagsToRemove.length === 0) {
// finish summary text from adding of tags, in this case where there are
// no tags to be removed
summaryText += ' tag' + ( tags.length > 1 ? 's' : '' ) + ' to article';
postRemoval();
return;
}
Morebits.status.info( 'Info', 'Removing deselected tags that were already present' );
if (params.tags.length > 0) {
summaryText += ( tags.length ? (' tag' + ( tags.length > 1 ? 's' : '' )) : '' ) + ', and removed';
} else {
summaryText = 'Removed';
}
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, tagIndex) {
var tag_re = new RegExp('\\{\\{' + Morebits.pageNameRegex(tag) + '\\s*(\\|[^}]+)?\\}\\}\\n?');
if (tag === 'Globalize') {
// special case to catch occurrences like {{Globalize/UK}}, etc
tag_re = new RegExp('\\{\\{[gG]lobalize/?[^}]*\\}\\}\\n?');
}
if(tag_re.test(pageText)) {
pageText = pageText.replace(tag_re,'');
} else {
getRedirectsFor.push('Template:' + tag);
}
// Producing summary text for current tag removal
if ( tagIndex > 0 ) {
if( tagIndex === (params.tagsToRemove.length - 1) ) {
summaryText += ' and';
} else if ( tagIndex < (params.tagsToRemove.length - 1) ) {
summaryText += ',';
}
}
summaryText += ' {{[[Template:' + tag + '|' + 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"
}, 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;
}
// Executes first: addition of selected tags
summaryText = 'Added';
var tagRe, tagText = '', tags = [], groupableTags = [], groupableExistingTags = [], totalTags;
/**
* 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 === '
pageText += '\n\n{{' + tagName + '|date={{subst:CURRENTMONTHNAME}} {{subst:CURRENTYEAR}}}}';
} else {
if( tagName === '
currentTag += '{{' + params.globalize;
} else {
currentTag +
}
// fill in other parameters, based on the tag
switch( tagName ) {
case '
currentTag += '|reason=' + params.cleanup;
break;
case '
currentTag += '|source=' + params.closeParaphrasing;
break;
case '
if (params.copyEdit) {
currentTag += '|for=' + params.copyEdit;
}
break;
case '
if (params.copypaste) {
currentTag += '|url=' + params.copypaste;
}
break;
case '
currentTag += '|topic=';
currentTag += '|langcode=' + params.expandLanguageLangCode;
Baris 1.097 ⟶ 1.432:
}
break;
case '
if (params.expertNeeded) {
currentTag += '|1=' + params.expertNeeded;
Baris 1.108 ⟶ 1.443:
}
break;
case '
currentTag += '|1=article';
break;
case '
if (params.notability !== 'none' ) {
currentTag += '|' + params.notability;
}
break;
case 'Not Indonesian':
case 'Not English':
case 'Rough translation':
if (params.translationLanguage) {
currentTag += '|1=' + params.translationLanguage;
Baris 1.120 ⟶ 1.461:
}
break;
case '
currentTag += '|originalpage=' + params.histmergeOriginalPage;
if (params.histmergeReason) {
Baris 1.129 ⟶ 1.470:
}
break;
case '
case '
case '
if (params.mergeTarget) {
// normalize the merge target for now and later
Baris 1.142 ⟶ 1.483:
if (!params.discussArticle) {
// discussArticle is the article whose talk page will contain the discussion
params.discussArticle = (tagName === "
// nonDiscussArticle is the article which won't have the discussion
params.nonDiscussArticle = (tagName === "
params.talkDiscussionTitle = 'Diusulkan digabung dengan ' + params.nonDiscussArticle;
}
currentTag += '|discuss=Talk:' + params.discussArticle + '#' + params.talkDiscussionTitle;
}
}
break;
Baris 1.163 ⟶ 1.496:
}
currentTag +
tagText += currentTag;
}
Baris 1.175 ⟶ 1.508:
}
summaryText += ' {{[[
if( tagName === '
summaryText += "Template:" + params.globalize + '|' + params.globalize;
} else {
// if it is a custom tag with a parameter
if( tagName.indexOf("|") !== -1 ) {
tagName = tagName.slice(0,tagName.indexOf("|"));
}
summaryText += (tagName.indexOf(":") !== -1 ? tagName : ("Template:" + tagName + "|" + tagName));
}
summaryText += ']]}}';
};
/**
* 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() {
totalTags = tags.length;
$.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.*\\}\\}\\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\\n(?:\\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|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', 'Ditemukan tag {{' + tag +
'}} di artikel tersebut... membatalkan' );
// 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);
Morebits.status.info( 'Info', 'Menambah tag yang lain ke dalam tag {{multiple issues}}' );
tagText = "";
$.each(groupableTags, addTag);
summaryText += ' tag' + ( groupableTags.length > 1 ? 's' : '' ) + ' (dalam {{[[Template:multiple issues|multiple issues]]}})';
if( tags.length > 0 ) {
}
var miRegex = new RegExp("(\\{\\{\\s*" + miTest[1] + "\\s*(?:\\|(?:\\{\\{[^{}]*\\}\\}|[^{}])*)?)\\}\\}\\s*", "im");
pageText = pageText.replace(miRegex, "$1" + tagText + "}}\n");
tagText = "";
} else if( params.group && !miTest && (groupableExistingTags.length + groupableTags.length) >= 2 ) {
Morebits.status.info( 'Info', 'Mengelompokkan tag yang didukung ke dalam {{multiple issues}}' );
tagText += '{{Multiple issues|\n';
/**
* Adds newly added tags to MI
*/
var addNewTagsToMI = function() {
totalTags = groupableTags.length;
$.each(groupableTags, addTag);
if (groupableTags.length) {
summaryText += '
} else {
summaryText += ' {{[[Template:multiple issues|multiple issues]]}}';
}
if( tags.length > 0 ) {
summaryText += ', dan';
}
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"
}, 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();
}
},
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' );
}
}
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 courtesy [[User:Kephir/gadgets/sagittarius.js]] at [[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
Baris 1.313 ⟶ 1.777:
pageobj.setMinorEdit(Twinkle.getFriendlyPref('markTaggedPagesAsMinor'));
pageobj.setCreateOption('nocreate');
pageobj.save
if( params.patrol ) {
pageobj.patrol();
}
},
Baris 1.529 ⟶ 1.895:
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)] =
Baris 1.537 ⟶ 1.903:
switch (Twinkle.tag.mode) {
case 'article':
params.tagsToRemove = form.getUnchecked('alreadyPresentArticleTags') || [];
params.tagsToRemain = form.getChecked('alreadyPresentArticleTags') || [];
params.group = form.group.checked;
// Validation
(params.tags.indexOf("
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;
Baris 1.554 ⟶ 1.925:
}
}
if( (params.tags.indexOf("
alert( 'Please select only one of {{not Indonesian}} and {{rough translation}}.' );
return;
}
if( params.tags.indexOf('
alert( 'You must specify a page to be merged for the {{history merge}} tag.' );
return;
}
if( params.tags.indexOf('
alert( 'You must specify a reason for the {{cleanup}} tag.' );
return;
}
if( params.tags.indexOf('
alert('You must specify language code for the {{expand language}} tag.');
return;
Baris 1.609 ⟶ 1.980:
}
// 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( 'Setidaknya Anda harus memiliki satu tag!' );
return;
Baris 1.625 ⟶ 1.998:
var wikipedia_page = new Morebits.wiki.page(Morebits.pageNameNorm, "Menandai " + Twinkle.tag.mode);
wikipedia_page.setCallbackParameters(params);
};
})(jQuery);
//</nowiki>
|