//<nowiki>
(function() {
if (mw.config.get("wgPageName").indexOf('Wikipedia:Articles_for_creation/Redirects') === -1 && mw.config.get("wgPageName").indexOf('Wikipedia:Articles_for_creation/Categories') === -1) {
return;
}
var afcHelper_RedirectPageName = mw.config.get("wgPageName").replace(/_/g, ' ');
var afcHelper_RedirectSubmissions = new Array();
var afcHelper_RedirectSections = new Array();
var afcHelper_advert = ' ([[User:Enterprisey/AFCRHS|AFCRHS.js]])';
var afcHelper_numTotal = 0;
var afcHelper_AJAXnumber = 0;
var afcHelper_Submissions = new Array();
var needsupdate = new Array();
var afcHelper_redirectDecline_reasonhash = {
'exists': 'The title you suggested already exists on Wikipedia',
'blank': 'We cannot accept empty submissions',
'notarget': ' A redirect cannot be created unless the target is an existing article. Either you have not specified the target, or the target does not exist',
'unlikely': 'The title you suggested seems unlikely. Could you provide a source showing that it is a commonly used alternate name?',
'notredirect': 'This request is not a redirect request',
'custom': ''
};
var afcHelper_categoryDecline_reasonhash = {
'exists': 'The category you suggested already exists on Wikipedia',
'blank': 'We cannot accept empty submissions',
'unlikely': 'It seems unlikely that there are enough pages to support this category',
'notcategory': 'This request is not a category request',
'custom': ''
};
function afcHelper_redirect_init() {
pagetext = afcHelper_getPageText(afcHelper_RedirectPageName);
// cleanup the wikipedia links for preventing stuff like https://en.wiki.x.io/w/index.php?diff=576244067&oldid=576221437
pagetext = afcHelper_cleanuplinks(pagetext);
// first, strip out the parts before the first section.
var section_re = /==.*?==/;
pagetext = pagetext.substring(pagetext.search(section_re));
// then split it into the rest of the sections
afcHelper_RedirectSections = pagetext.match(/^==.*?==$((\r?\n?)(?!==[^=]).*)*/img);
// parse the sections.
for (var i = 0; i < afcHelper_RedirectSections.length; i++) {
var closed = /(\{\{\s*afc(?!\s+comment)|This is an archived discussion)/i.test(afcHelper_RedirectSections[i]);
if (!closed) {
// parse.
var header = afcHelper_RedirectSections[i].match(section_re)[0];
if (header.search(/Redirect request/i) !== -1) {
var wikilink_re = /\[\[(\s*[^=]*?)*?\]\]/g;
var links = header.match(wikilink_re);
if (!links) continue;
for (var l = 0; l < links.length; l++) {
links[l] = links[l].replace(/[\[\]]/g, '');
if (links[l].charAt(0) === ':') links[l] = links[l].substring(1);
}
var re = /Target of redirect:\s*\[\[([^\[\]]*)\]\]/i;
re.test(afcHelper_RedirectSections[i]);
var to = $.trim(RegExp.$1);
var reasonRe = /Reason:[ \t]*?(.+)/i;
var reasonMatch = reasonRe.exec(afcHelper_RedirectSections[i]);
var reason = reasonMatch && reasonMatch[1].trim() ? reasonMatch[1] : null;
var sourceRe = /Source.*?:[ \t]*?(.+)/i;
var sourceMatch = sourceRe.exec(afcHelper_RedirectSections[i]);
var source = sourceMatch && sourceMatch[1].trim() ? sourceMatch[1] : null;
var submission = {
type: 'redirect',
from: new Array(),
section: i,
to: to,
title: to,
reason: reason,
source: source
};
for (var j = 0; j < links.length; j++) {
var sub = {
type: 'redirect',
to: to,
id: afcHelper_numTotal,
title: links[j],
action: ''
};
submission.from.push(sub);
afcHelper_Submissions.push(sub);
afcHelper_numTotal++;
}
afcHelper_RedirectSubmissions.push(submission);
} else if (header.search(/Category request/i) !== -1) {
// Find a wikilink in the header, and assume it's the category to create
var category_name = /\[\[[^\[\]]+\]\]/.exec(header);
if (!category_name) continue;
category_name = category_name[0];
category_name = category_name.replace(/[\[\]]/g, '');
category_name = category_name.replace(/Category\s*:\s*/gi, 'Category:');
if (category_name.charAt(0) === ':') category_name = category_name.substring(1);
// Figure out the parent categories
var request_text = afcHelper_RedirectSections[i].substring(header.length);
// We only want categories listed under the "Parent category/categories" heading,
// *NOT* any categories listed under "Example pages which belong to this category".
var idx_of_parent_heading = request_text.indexOf('Parent category/categories');
if (idx_of_parent_heading >= 0 ) {
request_text = request_text.substring(idx_of_parent_heading);
}
var parent_cats = [];
var parent_cat_match = null;
var parent_cat_regex = /\[\[\s*:\s*(Category:[^\]\[]*)\]\]/ig;
do {
parent_cat_match = parent_cat_regex.exec(request_text);
if (parent_cat_match) {
parent_cats.push(parent_cat_match[1]);
}
} while (parent_cat_match);
var submission = {
type: 'category',
title: category_name,
section: i,
id: afcHelper_numTotal,
action: '',
parents: parent_cats.join(',')
};
afcHelper_numTotal++;
afcHelper_RedirectSubmissions.push(submission);
afcHelper_Submissions.push(submission);
}
} // end if (!closed)
} // end loop over sections
// Build the form
var $form = $('<h3>Reviewing AfC redirect requests</h3>');
displayMessage($form);
var $messageDiv = $form.parent();
// now layout the text.
var afcHelper_Redirect_empty = 1;
var ACTIONS = [
{label: 'Accept', value: 'accept'},
{label: 'Decline', value: 'decline'},
{label: 'Comment',value: 'comment'},
{label: 'None', selected: true, value: 'none'}
];
for (var k = 0; k < afcHelper_RedirectSubmissions.length; k++) {
if (afcHelper_RedirectSubmissions[k].to !== undefined)
var submissionname = afcHelper_RedirectSubmissions[k].to.replace(/\s/g,'');
else
var submissionname = "";
var $thisSubList = $('<ul>');
var $thisSubListElement = $('<li>');
if (afcHelper_RedirectSubmissions[k].type === 'redirect') {
$thisSubListElement.append('Redirect(s) to ');
if (!submissionname) {
for (var i = afcHelper_RedirectSubmissions[k].from.length - 1; i >= 0; i--) {
needsupdate.push({
id: afcHelper_RedirectSubmissions[k].from[i].id,
reason: 'notarget'
});
}
} else if (!afcHelper_RedirectSubmissions[k].to) {
for (var i = afcHelper_RedirectSubmissions[k].from.length - 1; i >= 0; i--) {
needsupdate.push({
id: afcHelper_RedirectSubmissions[k].from[i].id,
reason: 'notredirect'
});
}
}
if (afcHelper_RedirectSubmissions[k] === '' || afcHelper_RedirectSubmissions[k] === ' ') {
$thisSubListElement.append('Empty submission \#' + afcHelper_Redirect_empty);
afcHelper_Redirect_empty++;
} else {
if (submissionname.length > 0) {
$thisSubListElement.append($('<a>')
.attr('href', mw.config.get("wgArticlePath").replace("$1", encodeURIComponent(afcHelper_RedirectSubmissions[k].to)))
.attr('target', '_blank')
.text(afcHelper_RedirectSubmissions[k].to));
} else {
$thisSubListElement.append('<b>no target given</b>: ');
}
}
var $fromList = $('<ul>').appendTo($thisSubListElement);
for (var l = 0; l < afcHelper_RedirectSubmissions[k].from.length; l++) {
var from = afcHelper_RedirectSubmissions[k].from[l];
var toarticle = from.title;
if (toarticle.replace(/\s*/gi, "").length == 0) toarticle = "<b>no title specified</b>, check the request details";
var reasonAndSource = $('<ul>');
if(afcHelper_RedirectSubmissions[k].reason)
reasonAndSource.append('<li>Reason: ' + afcHelper_RedirectSubmissions[k].reason + '</li>');
if(afcHelper_RedirectSubmissions[k].source)
reasonAndSource.append('<li>Source: ' + afcHelper_RedirectSubmissions[k].source + '</li>');
var googleSearchUrl = 'http://www.google.com/search?q="' +
encodeURIComponent(toarticle) + '"+-wikipedia.org';
$fromList.append($('<li>')
.append('From: ' + toarticle + ' (<small><a href=\'' + googleSearchUrl + '\'" target="_blank">' +
'Google</a> <b>·</b> <a href="https://en.wiki.x.io/wiki/Special:WhatLinksHere/' +
encodeURIComponent(toarticle) + '" target="_blank">what links here</a>)</small><br/>')
.append(reasonAndSource)
.append($('<label>').attr('for', 'afcHelper_redirect_action_' + from.id).text('Action: '))
.append(afcHelper_generateSelectObject('afcHelper_redirect_action_' + from.id, ACTIONS,
afcHelper_redirect_makeActionChange(from.id)))
.append($('<div>').attr('id', 'afcHelper_redirect_extra_' + from.id)));
}
} else {
var subId = afcHelper_RedirectSubmissions[k].id;
$thisSubListElement.append('Category submission: ')
.append($('<a>')
.attr('href', '/wiki/' + afcHelper_RedirectSubmissions[k].title)
.attr('title', afcHelper_RedirectSubmissions[k].title)
.text(afcHelper_RedirectSubmissions[k].title))
.append('<br />')
.append($('<label>').attr('for', 'afcHelper_redirect_action_' + subId).text('Action: '))
.append(afcHelper_generateSelectObject('afcHelper_redirect_action_' + subId, ACTIONS,
afcHelper_redirect_makeActionChange(subId)))
.append($('<div>').attr('id', 'afcHelper_redirect_extra_' + subId));
}
$thisSubList.append($thisSubListElement);
$messageDiv.append($thisSubList);
} // end loop over sections
$messageDiv.append($('<button>')
.attr('id', 'afcHelper_redirect_done_button')
.attr('name', 'afcHelper_redirect_done_button')
.text('Done')
.click(afcHelper_redirect_performActions));
for (var y = 0; y < needsupdate.length; y++){
$('#afcHelper_redirect_action_'+needsupdate[y].id).attr('value', 'decline');
afcHelper_redirect_onActionChange(needsupdate[y].id);
$('#afcHelper_redirect_decline_'+needsupdate[y].id).attr('value', needsupdate[y].reason);
}
}
function afcHelper_redirect_makeActionChange(id) {
return function() { afcHelper_redirect_onActionChange(id); };
}
function afcHelper_redirect_onActionChange(id) {
console.log("Entering afcHelper_redirect_onActionChange, id = " + id);
var $extra = $("#afcHelper_redirect_extra_" + id);
var selectValue = $("#afcHelper_redirect_action_" + id).val();
$extra.html(''); // Blank it first
if (selectValue === 'accept') {
if (afcHelper_Submissions[id].type === 'redirect') {
$extra.append('<label for="afcHelper_redirect_from_' + id + '">From: </label>');
$extra.append($('<input>')
.attr('type', 'text')
.attr('name', 'afcHelper_redirect_from_' + id)
.attr('id', 'afcHelper_redirect_from_' + id)
.attr('value', afcHelper_escapeHtmlChars(afcHelper_Submissions[id].title)));
$extra.html($extra.html() + ' <br /><label for="afcHelper_redirect_to_' + id + '">To: </label><input type="text" ' + 'name="afcHelper_redirect_to_' + id + '" id="afcHelper_redirect_to_' + id + '" value="' + afcHelper_escapeHtmlChars(afcHelper_Submissions[id].to) + '" />');
$extra.html($extra.html() + '<br /><label for="afcHelper_redirect_append_' + id + '">Template to append: (<a href="https://en.wiki.x.io/wiki/Wikipedia:TMR" target="_blank">Help</a>)</label>');
$extra.html($extra.html() + afcHelper_generateSelect('afcHelper_redirect_append_' + id, [
{
label: 'None',
selected: true,
value: 'none'
}, {
labelAndValue: 'Frequently used',
disabled: true
},
{ labelAndValue: 'R from alternative language' },
{ labelAndValue: 'R from alternative name' },
{ labelAndValue: 'R from modification' },
{ labelAndValue: 'R to section' },
{ labelAndValue: 'R from diacritic' },
{ labelAndValue: 'R to diacritic' },
{
labelAndValue: 'From – abbreviation, capitalisation, and grammar',
disabled: true
},
{ labelAndValue: 'R from acronym' },
{ labelAndValue: 'R from initialism' },
{ labelAndValue: 'R from CamelCase' },
{ labelAndValue: 'R from miscapitalisation' },
{ labelAndValue: 'R from other capitalisation' },
{ labelAndValue: 'R from modification' },
{ labelAndValue: 'R from plural' },
{
label: 'From parts of speach',
value: 'From parts of speach',
disabled: true
},
{ labelAndValue: 'R from adjective' },
{ labelAndValue: 'R from adverb' },
{ labelAndValue: 'R from common noun' },
{ labelAndValue: 'R from gerund' },
{ labelAndValue: 'R from proper noun' },
{ labelAndValue: 'R from verb' },
{
labelAndValue: 'From – spelling',
disabled: true
},
{ labelAndValue: 'R from alternative spelling' },
{ labelAndValue: 'R from misspelling' },
{ labelAndValue: 'R from American English' },
{ labelAndValue: 'R from British English' },
{ labelAndValue: 'R from ASCII-only' },
{ labelAndValue: 'R from diacritic' },
{ labelAndValue: 'R from ligature' },
{ labelAndValue: 'R from stylization' },
{ labelAndValue: 'R from alternative transliteration' },
{ labelAndValue: 'R from Wade–Giles romanization' },
{
labelAndValue: 'From alternative names, general',
disabled: true
},
{ labelAndValue: 'R from alternative language' },
{ labelAndValue: 'R from alternative name' },
{ labelAndValue: 'R from former name' },
{ labelAndValue: 'R from historic name' },
{ labelAndValue: 'R from incomplete name' },
{ labelAndValue: 'R from incorrect name' },
{ labelAndValue: 'R from letter–word combination' },
{ labelAndValue: 'R from long name' },
{ labelAndValue: 'R from portmanteau' },
{ labelAndValue: 'R from predecessor company name' },
{ labelAndValue: 'R from short name' },
{ labelAndValue: 'R from sort name' },
{ labelAndValue: 'R from less specific name' },
{ labelAndValue: 'R from more specific name' },
{ labelAndValue: 'R from antonym' },
{ labelAndValue: 'R from eponym' },
{ labelAndValue: 'R from synonym' },
{ labelAndValue: 'R from Roman numerals' },
{
labelAndValue: 'From alternative names, geography',
disabled: true
},
{ labelAndValue: 'R from Canadian settlement name' },
{ labelAndValue: 'R from name and country' },
{ labelAndValue: 'R from city and state' },
{ labelAndValue: 'R from city and province' },
{ labelAndValue: 'R from more specific geographic name' },
{ labelAndValue: 'R from postal abbreviation' },
{ labelAndValue: 'R from postal code' },
{ labelAndValue: 'R from US postal abbreviation' },
{
labelAndValue: 'From alternative names, organisms',
disabled: true
},
{ labelAndValue: 'R from scientific abbreviation' },
{ labelAndValue: 'R from scientific name' },
{ labelAndValue: 'R from alternative scientific name' },
{ labelAndValue: 'R from monotypic taxon' },
{
labelAndValue: 'From alternative names, people',
disabled: true
},
{ labelAndValue: 'R from birth name' },
{ labelAndValue: 'R from given name' },
{ labelAndValue: 'R from married name' },
{ labelAndValue: 'R from name with title' },
{ labelAndValue: 'R from non-neutral name' },
{ labelAndValue: 'R from personal name' },
{ labelAndValue: 'R from pseudonym' },
{ labelAndValue: 'R from relative' },
{ labelAndValue: 'R from spouse' },
{ labelAndValue: 'R from surname' },
{
labelAndValue: 'From alternative names, technical',
disabled: true
},
{ labelAndValue: 'R from Bluebook abbreviation' },
{ labelAndValue: 'R from brand name' },
{ labelAndValue: 'R from drug trade name' },
{ labelAndValue: 'R from file name' },
{ labelAndValue: 'R from Java package name' },
{ labelAndValue: 'R from MathSciNet abbreviation' },
{ labelAndValue: 'R from molecular formula' },
{ labelAndValue: 'R from NLM abbreviation' },
{ labelAndValue: 'R from product name' },
{ labelAndValue: 'R from slogan' },
{ labelAndValue: 'R from symbol' },
{ labelAndValue: 'R from systematic abbreviations' },
{ labelAndValue: 'R from technical name' },
{ labelAndValue: 'R from trademark' },
{
labelAndValue: 'From – navigation',
disabled: true
},
{ labelAndValue: 'R from file metadata link' },
{ labelAndValue: 'R mentioned in hatnote' },
{ labelAndValue: 'R from shortcut' },
{ labelAndValue: 'R from template shortcut' },
{
labelAndValue: 'From disambiguations',
disabled: true
},
{ labelAndValue: 'R from ambiguous term' },
{ labelAndValue: 'R from incomplete disambiguation' },
{ labelAndValue: 'R from incorrect disambiguation' },
{ labelAndValue: 'R from other disambiguation' },
{ labelAndValue: 'R from predictable disambiguation' },
{ labelAndValue: 'R from unnecessary disambiguation' },
{
labelAndValue: 'From mergers, duplicates, and moves',
disabled: true
},
{ labelAndValue: 'R from duplicated article' },
{ labelAndValue: 'R with history' },
{ labelAndValue: 'R from merge' },
{ labelAndValue: 'R from move' },
{ labelAndValue: 'R with old history' },
{
labelAndValue: 'From fiction',
disabled: true
},
{ labelAndValue: 'R from fictional character' },
{ labelAndValue: 'R from fictional element' },
{ labelAndValue: 'R from fictional location' },
{
labelAndValue: 'From related info',
disabled: true
},
{ labelAndValue: 'R from album' },
{ labelAndValue: 'R from animal' },
{ labelAndValue: 'R from book' },
{ labelAndValue: 'R from catchphrase' },
{ labelAndValue: 'R from domain name' },
{ labelAndValue: 'R from top-level domain' },
{ labelAndValue: 'R from film' },
{ labelAndValue: 'R from gender' },
{ labelAndValue: 'R from legislation' },
{ labelAndValue: 'R from list topic' },
{ labelAndValue: 'R from member' },
{ labelAndValue: 'R from person' },
{ labelAndValue: 'R from phrase' },
{ labelAndValue: 'R from quotation' },
{ labelAndValue: 'R from related word' },
{ labelAndValue: 'R from school' },
{ labelAndValue: 'R from song' },
{ labelAndValue: 'R from subtopic' },
{ labelAndValue: 'R from team' },
{ labelAndValue: 'R from work' },
{ labelAndValue: 'R from writer' },
{ labelAndValue: 'R from Unicode' },
{
labelAndValue: 'To – grammar, punctuation, and spelling',
disabled: true
},
{ labelAndValue: 'R to acronym' },
{ labelAndValue: 'R to initialism' },
{ labelAndValue: 'R to ASCII-only title' },
{ labelAndValue: 'R to diacritic' },
{ labelAndValue: 'R to ligature' },
{ labelAndValue: 'R to plural' },
{
labelAndValue: 'To alternative names',
disabled: true
},
{ labelAndValue: 'R to former name' },
{ labelAndValue: 'R to historic name' },
{ labelAndValue: 'R to joint biography' },
{ labelAndValue: 'R to name with title' },
{ labelAndValue: 'R to monotypic taxon' },
{ labelAndValue: 'R to scientific name' },
{ labelAndValue: 'R to systematic name' },
{ labelAndValue: 'R to technical name' },
{
labelAndValue: 'To – navigation and disambiguation',
disabled: true
},
{ labelAndValue: 'R to anchor' },
{ labelAndValue: 'R to anthroponymy page' },
{ labelAndValue: 'R to disambiguation page' },
{ labelAndValue: 'R to list entry' },
{ labelAndValue: 'R to section' },
{
labelAndValue: 'To miscellaneous',
disabled: true
},
{ labelAndValue: 'R to decade' },
{ labelAndValue: 'R to related topic' },
{ labelAndValue: 'R to subpage' },
{ labelAndValue: 'R to subtopic' },
{ labelAndValue: 'R to TV episode list entry' },
{
label: 'Custom - prompt me',
value: 'custom'
}
]));
} else {
// now Categories
$extra.html('<label for="afcHelper_redirect_name_' + id + '">Category name: </label><input type="text" size="100" ' + 'name="afcHelper_redirect_name_' + id + '" id="afcHelper_redirect_name_' + id + '" value="' + afcHelper_escapeHtmlChars(afcHelper_Submissions[id].title) + '" />');
$extra.html($extra.html() + '<br /><label for="afcHelper_redirect_parents_' + id + '">Parent categories (comma-separated):</label>' + '<input type="text" size="100" id="afcHelper_redirect_parents_' + id + '" name="afcHelper_redirect_parents_' + id + '" value="' + afcHelper_escapeHtmlChars(afcHelper_Submissions[id].parents) + '" />');
$extra.append('<br />');
$extra.append($('<input>', {type: 'checkbox', name: 'afcHelper_redirect_container_' + id, id: 'afcHelper_redirect_container_' + id}));
$extra.append('<label for="afcHelper_redirect_container_' + id + '">This is a <a href="/wiki/Wikipedia:Container_category" title="Wikipedia:Container category">container category</a></label>');
$extra.html($extra.html() + '<br /><input type="checkbox" name="afcHelper_redirect_container_' + id + '"');
}
$extra.html($extra.html() + '<br /><label for="afcHelper_redirect_comment_' + id + '">Comment:</label>' + '<input type="text" size="100" id="afcHelper_redirect_comment_' + id + '" name="afcHelper_redirect_comment_' + id + '"/>');
} else if (selectValue === 'decline') {
if (afcHelper_Submissions[id].type === 'redirect') {
$extra.html('<label for="afcHelper_redirect_decline_' + id + '">Reason for decline: </label>' + afcHelper_generateSelect('afcHelper_redirect_decline_' + id, [
{
label: 'Already exists',
value: 'exists'
}, {
label: 'Blank request',
value: 'blank'
}, {
label: 'No valid target specified',
value: 'notarget'
}, {
label: 'Unlikely search term',
value: 'unlikely'
}, {
label: 'Not a redirect request',
value: 'notredirect'
}, {
label: 'Custom - reason below',
selected: true,
value: 'custom'
}]));
} else {
// now Categories
$extra.html('<label for="afcHelper_redirect_decline_' + id + '">Reason for decline: </label>' + afcHelper_generateSelect('afcHelper_redirect_decline_' + id, [{
label: 'Already exists',
value: 'exists'
}, {
label: 'Blank request',
value: 'blank'
}, {
label: 'Unlikely category',
value: 'unlikely'
}, {
label: 'Not a category request',
value: 'notcategory'
}, {
label: 'Custom - reason below',
selected: true,
value: 'custom'
}]));
}
$extra.html($extra.html() + '<br/><label for="afcHelper_redirect_comment_' + id + '">Comment: </label>' + '<input type="text" size="100" id="afcHelper_redirect_comment_' + id + '" name="afcHelper_redirect_comment_' + id + '"/>');
} else if (selectValue === 'none'){
// for categories and redirects!
$extra.html('');
} else {
$extra.html($extra.html() + '<label for="afcHelper_redirect_comment_' + id + '">Comment: </label>' + '<input type="text" size="100" id="afcHelper_redirect_comment_' + id + '" name="afcHelper_redirect_comment_' + id + '"/>');
}
}
function afcHelper_redirect_performActions() {
// Load all of the data.
for (var i = 0; i < afcHelper_Submissions.length; i++) {
var action = $("#afcHelper_redirect_action_" + i).val();
afcHelper_Submissions[i].action = action;
if (action === 'none') continue;
if (action === 'accept') {
if (afcHelper_Submissions[i].type === 'redirect') {
afcHelper_Submissions[i].title = $("#afcHelper_redirect_from_" + i).val();
afcHelper_Submissions[i].to = $("#afcHelper_redirect_to_" + i).val();
afcHelper_Submissions[i].append = $("#afcHelper_redirect_append_" + i).val();
if (afcHelper_Submissions[i].append === 'custom') {
afcHelper_Submissions[i].append = prompt("Please enter the template to append to " + afcHelper_Submissions[i].title + ". Do not include the curly brackets.");
}
if (afcHelper_Submissions[i].append === 'none' || afcHelper_Submissions[i].append === null) afcHelper_Submissions[i].append = '';
else afcHelper_Submissions[i].append = '\{\{' + afcHelper_Submissions[i].append + '\}\}';
} else {
afcHelper_Submissions[i].title = $("#afcHelper_redirect_name_" + i).val();
afcHelper_Submissions[i].parents = $("#afcHelper_redirect_parents_" + i).val();
afcHelper_Submissions[i].container = $("#afcHelper_redirect_container_" + i).is(':checked');
}
} else if (action === 'decline') {
afcHelper_Submissions[i].reason = $('#afcHelper_redirect_decline_' + i).val();
}
afcHelper_Submissions[i].comment = $("#afcHelper_redirect_comment_" + i).val();
}
// Data loaded. Show progress screen and get WP:AFC/R page text.
displayMessage('<ul id="afcHelper_status"></ul><ul id="afcHelper_finish"></ul>');
var addStatus = function ( status ) { $('#afcHelper_status').append( status ); };
$('#afcHelper_finish').html($('#afcHelper_finish').html() + '<span id="afcHelper_finished_wrapper"><span id="afcHelper_finished_main" style="display:none"><li id="afcHelper_done"><b>Done (<a href="' + mw.config.get("wgArticlePath").replace("$1", encodeURI(afcHelper_RedirectPageName)) + '?action=purge" title="' + afcHelper_RedirectPageName + '">Reload page</a>)</b></li></span></span>');
pagetext = afcHelper_getPageText(afcHelper_RedirectPageName, addStatus);
var totalaccept = 0;
var totaldecline = 0;
var totalcomment = 0;
// traverse the submissions and locate the relevant sections.
addStatus('<li>Processing ' + afcHelper_RedirectSubmissions.length + ' submission' +
(afcHelper_RedirectSubmissions.length === 1 ? '' : 's') + '...</li>');
for (var i = 0; i < afcHelper_RedirectSubmissions.length; i++) {
var sub = afcHelper_RedirectSubmissions[i];
if (pagetext.indexOf(afcHelper_RedirectSections[sub.section]) === -1) {
// Someone has modified the section in the mean time. Skip.
addStatus('<li>Skipping ' + sub.title + ': Cannot find section. Perhaps it was modified in the mean time?</li>');
continue;
}
var text = afcHelper_RedirectSections[sub.section];
var startindex = pagetext.indexOf(afcHelper_RedirectSections[sub.section]);
var endindex = startindex + text.length;
// First deal with cats. These are easy.
if (sub.type === 'category') {
if (sub.action === 'accept') {
var cattext = '<!--Created by WP:AFC -->';
if (sub.container) {
cattext += '\n{{Container category}}';
}
if (sub.parents !== '') {
cattext = sub.parents
.split(',')
.map(function(cat){ return '\[\[' + cat + '\]\]'; })
.join('\n');
}
afcHelper_editPage(sub.title, cattext, 'Created via \[\[WP:AFC|Articles for Creation\]\] (\[\[WP:WPAFC|you can help!\]\])', true);
var talktext = '\{\{subst:WPAFC/article|class=Cat\}\}';
var talktitle = sub.title.replace(/Category:/gi, 'Category talk:');
afcHelper_editPage(talktitle, talktext, 'Placing WPAFC project banner', true);
var header = text.match(/==[^=]*==/)[0];
text = header + "\n\{\{AfC-c|a\}\}\n" + text.substring(header.length);
if (sub.comment !== '') text += '\n*\{\{subst:afc category|accept|2=' + sub.comment + '\}\} \~\~\~\~\n';
else text += '\n*\{\{subst:afc category\}\} \~\~\~\~\n';
text += '\{\{AfC-c|b\}\}\n';
totalaccept++;
} else if (sub.action === 'decline') {
var header = text.match(/==[^=]*==/)[0];
var reason = afcHelper_categoryDecline_reasonhash[sub.reason];
if (reason === '') reason = sub.comment;
else if (sub.comment !== '') reason = reason + ': ' + sub.comment;
if (reason === '') {
$('afcHelper_status').html($('#afcHelper_status').html() + '<li>Skipping ' + sub.title + ': No decline reason specified.</li>');
continue;
}
text = header + "\n\{\{AfC-c|d\}\}\n" + text.substring(header.length);
if (sub.comment === '') text += '\n*\{\{subst:afc category|' + sub.reason + '\}\} \~\~\~\~\n';
else text += '\n*\{\{subst:afc category|decline|2=' + reason + '\}\} \~\~\~\~\n';
text += '\{\{AfC-c|b\}\}\n';
totaldecline++;
} else if (sub.action === 'comment') {
if (sub.comment !== '') text += '\n\n\{\{afc comment|1=' + sub.comment + ' \~\~\~\~\}\}\n';
totalcomment++;
}
} else {
// redirects......
var acceptcomment = '';
var declinecomment = '';
var othercomment = '';
var acceptcount = 0,
declinecount = 0,
commentcount = 0,
hascomment = false;
for (var j = 0; j < sub.from.length; j++) {
var redirect = sub.from[j];
if (redirect.action === 'accept') {
var redirecttext = '#REDIRECT \[\[' + redirect.to + '\]\]\n' + redirect.append;
afcHelper_editPage(redirect.title, redirecttext, 'Redirected page to \[\[' + redirect.to + '\]\] via \[\[WP:AFC|Articles for Creation\]\] (\[\[WP:WPAFC|you can help!\]\])', true);
if ((redirect.title.toLowerCase().indexOf('talk:') < 0) && (redirect.title.indexOf('WT:') < 0)) {
var talktext = '\{\{subst:WPAFC/redirect\}\}';
var talktitle;
if (redirect.title.indexOf(':') >= 0) {
if (redirect.title.indexOf('WP:') == 0) {
talktitle = redirect.title.replace('WP:', 'WT:');
} else {
talktitle = redirect.title.replace(':', ' talk:');
}
} else {
talktitle = 'Talk:' + redirect.title;
}
afcHelper_editPage(talktitle, talktext, 'Placing WPAFC project banner', true);
}
acceptcomment += redirect.title + " → " + redirect.to;
if (redirect.comment !== '') {
acceptcomment += ': ' + redirect.comment;
hascomment = true;
} else {
acceptcomment += '. ';
}
acceptcount++;
} else if (redirect.action === 'decline') {
var reason = afcHelper_redirectDecline_reasonhash[redirect.reason];
if (reason === '') reason = redirect.comment;
else if (redirect.comment !== '') reason = reason + ': ' + redirect.comment;
if (reason === '') {
$('#afcHelper_status').html($('#afcHelper_status').html() + '<li>Skipping ' + redirect.title + ': No decline reason specified.</li>');
continue;
}
declinecomment += ((redirect.reason === 'blank' || redirect.reason === 'notredirect') ? reason + ". " : redirect.title + " → " + redirect.to + ": " + reason + ". ");
declinecount++;
} else if (redirect.action === 'comment') {
othercomment += redirect.title + ": " + redirect.comment + ". ";
commentcount++;
}
}
var reason = '';
if (acceptcount > 0) reason += '\n*\{\{subst:afc redirect|accept|2=' + acceptcomment + ' Thank you for your contributions to Wikipedia!\}\} \~\~\~\~';
if (declinecount > 0) reason += '\n*\{\{subst:afc redirect|decline|2=' + declinecomment + '\}\} \~\~\~\~';
if (commentcount > 0) reason += '\n*\{\{afc comment|1=' + othercomment + '\~\~\~\~\}\}';
reason += '\n';
if (!hascomment && acceptcount === sub.from.length) {
if (acceptcount > 1) reason = '\n*\{\{subst:afc redirect|all\}\} \~\~\~\~\n';
else reason = '\n*\{\{subst:afc redirect\}\} \~\~\~\~\n';
}
if (acceptcount + declinecount + commentcount > 0) {
if (acceptcount + declinecount === sub.from.length) {
// Every request disposed of. Close.
var header = text.match(/==[^=]*==/)[0];
if (acceptcount > declinecount) text = header + "\n\{\{AfC-c|a\}\}\n" + text.substring(header.length);
else text = header + "\n\{\{AfC-c|d\}\}\n" + text.substring(header.length);
text += reason;
text += '\{\{AfC-c|b\}\}\n';
} else text += reason + '\n';
}
totalaccept += acceptcount;
totaldecline += declinecount;
totalcomment += commentcount;
}
pagetext = pagetext.substring(0, startindex) + text + pagetext.substring(endindex);
}
var summary = "Updating submission status:";
if (totalaccept > 0) summary += " accepting " + totalaccept + " request" + (totalaccept > 1 ? 's' : '');
if (totaldecline > 0) {
if (totalaccept > 0) summary += ',';
summary += " declining " + totaldecline + " request" + (totaldecline > 1 ? 's' : '');
}
if (totalcomment > 0) {
if (totalaccept > 0 || totaldecline > 0) summary += ',';
summary += " commenting on " + totalcomment + " request" + (totalcomment > 1 ? 's' : '');
}
afcHelper_editPage(afcHelper_RedirectPageName, pagetext, summary, false);
// Display the "Done" text only after all ajax requests are completed
$(document).ajaxStop(function () {
$("#afcHelper_finished_main").css("display", "");
});
}
/**
* Gets the text of a page.
* @param {string} The title of the page to get.
* @param {function} A function that takes a HTML string to report status.
*/
function afcHelper_getPageText(title, addStatus) {
var addStatus = typeof addStatus !== 'undefined' ? addStatus : function ( status ) {};
addStatus('<li id="afcHelper_get' + jqEsc(title) + '">Getting <a href="' +
mw.config.get("wgArticlePath").replace("$1", encodeURI(title)) + '" title="' + title + '">' +
title + '</a></li>');
var request = {
'action': 'query',
'prop': 'revisions',
'rvprop': 'content',
'format': 'json',
'indexpageids': true,
'titles' : title
};
var response = JSON.parse(
$.ajax({
url: mw.util.wikiScript('api'),
data: request,
async: false
})
.responseText
);
pageid = response['query']['pageids'][0];
if (pageid === "-1") {
addStatus('The page <a class="new" href="' + mw.config.get("wgArticlePath").replace("$1", encodeURI(title)) +
'" title="' + title + '">' + title + '</a> does not exist');
return '';
}
var newtext = response['query']['pages'][pageid]['revisions'][0]['*'];
addStatus('<li id="afcHelper_get' + jqEsc(title) + '">Got <a href="' +
mw.config.get("wgArticlePath").replace("$1", encodeURI(title)) + '" title="' + title + '">' + title + '</a></li>');
return newtext;
}
function afcHelper_cleanuplinks(text) {
// Convert external links to Wikipedia articles to proper wikilinks
var wikilink_re = /(\[){1,2}(?:https?:)?\/\/(en.wiki.x.io\/wiki|enwp.org)\/([^\s\|\]\[]+)(\s|\|)?((?:\[\[[^\[\]]*\]\]|[^\]\[])*)(\]){1,2}/gi;
var temptext = text;
var match;
while (match = wikilink_re.exec(temptext)) {
var pagename = decodeURI(match[3].replace(/_/g,' '));
var displayname = decodeURI(match[5].replace(/_/g,' '));
if (pagename === displayname) displayname = '';
var replacetext = '[[' + pagename + ((displayname) ? '|' + displayname : '') + ']]';
pagetext = pagetext.replace(match[0],replacetext);
}
return text;
}
function afcHelper_generateSelect(title, options) {
return afcHelper_generateSelectObject(title, options).prop('outerHTML');
}
function afcHelper_generateSelectObject(title, options, onchange) {
var $select = $('<select>')
.attr('name', title)
.attr('id', title);
if ( onchange !== null ) {
$select.change(onchange);
}
options.forEach( function ( option ) {
if ( option.labelAndValue ) {
option.value = option.labelAndValue;
option.label = option.labelAndValue;
}
var $option = $( '<option>' )
.appendTo( $select )
.val( afcHelper_escapeHtmlChars( option.value) )
.text( option.label );
if ( option.selected ) $option.attr( 'selected', 'selected' );
if ( option.disabled ) $option.attr( 'disabled', 'disabled' );
} );
return $select;
}
function afcHelper_escapeHtmlChars(original) {
return original.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
}
/**
* The old mw.util.jsMessage function before https://gerrit.wikimedia.org/r/#/c/17605/, which
* introduced the silly auto-hide function. Also with the original styles.
* Add a little box at the top of the screen to inform the user of
* something, replacing any previous message.
* Calling with no arguments, with an empty string or null will hide the message
* Taken from [[User:Timotheus Canens/displaymessage.js]]
*
* @param message {mixed} The DOM-element, jQuery object or HTML-string to be put inside the message box.
* @param className {String} Used in adding a class; should be different for each call
* to allow CSS/JS to hide different boxes. null = no class used.
* @return {Boolean} True on success, false on failure.
*/
function displayMessage( message, className ){
if ( !arguments.length || message === '' || message === null ) {
$( '#display-message' ).empty().hide();
return true; // Emptying and hiding message is intended behaviour, return true
} else {
// We special-case skin structures provided by the software. Skins that
// choose to abandon or significantly modify our formatting can just define
// an mw-js-message div to start with.
var $messageDiv = $( '#display-message' );
if ( !$messageDiv.length ) {
$messageDiv = $( '<div id="display-message" style="margin:1em;padding:0.5em 2.5%;border:solid 1px #ddd;background-color:#fcfcfc;font-size: 0.8em"></div>' );
if ( mw.util.$content.length ) {
mw.util.$content.prepend( $messageDiv );
} else {
return false;
}
}
if ( className ) {
$messageDiv.prop( 'class', 'display-message-' + className );
}
if ( typeof message === 'object' ) {
$messageDiv.empty();
$messageDiv.append( message );
} else {
$messageDiv.html( message );
}
$messageDiv.slideDown();
return true;
}
}
function jqEsc(expression) {
return expression.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~ ]/g, '');
}
function afcHelper_editPage(title, newtext, summary, createonly, nopatrol) {
var wgArticlePath = mw.config.get('wgArticlePath');
summary += afcHelper_advert;
$("#afcHelper_finished_wrapper").html('<span id="afcHelper_AJAX_finished_' + afcHelper_AJAXnumber + '" style="display:none">' + $("#afcHelper_finished_wrapper").html() + '</span>');
var func_id = afcHelper_AJAXnumber;
afcHelper_AJAXnumber++;
$('#afcHelper_status').html($('#afcHelper_status').html() + '<li id="afcHelper_edit' + jqEsc(title) + '">Editing <a href="' + wgArticlePath.replace("$1", encodeURI(title)) + '" title="' + title + '">' + title + '</a></li>');
var request = {
'action': 'edit',
'title': title,
'text': newtext,
'summary': summary,
};
if (createonly) request.createonly = true;
var api = new mw.Api();
api.postWithEditToken(request)
.done(function ( data ) {
if ( data && data.edit && data.edit.result && data.edit.result == 'Success' ) {
$('#afcHelper_edit' + jqEsc(title)).html('Saved <a href="' + wgArticlePath.replace("$1", encodeURI(title)) + '" title="' + title + '">' + title + '</a>');
} else {
$('#afcHelper_edit' + jqEsc(title)).html('<span class="afcHelper_notice"><b>Edit failed on <a href="' + wgArticlePath.replace("$1", encodeURI(title)) + '" title="' + title + '">' + title + '</a></b></span>. Error info: ' + JSON.stringify(data));
window.console && console.error('Edit failed on %s (%s). Error info: %s', wgArticlePath.replace("$1", encodeURI(title)), title, JSON.stringify(data));
}
} )
.fail( function ( error ) {
if (createonly && error == "articleexists")
$('#afcHelper_edit' + jqEsc(title)).html('<span class="afcHelper_notice"><b>Edit failed on <a href="' + wgArticlePath.replace("$1", encodeURI(title)) + '" title="' + title + '">' + title + '</a></b></span>. Error info: The article already exists!');
else
$('#afcHelper_edit' + jqEsc(title)).html('<span class="afcHelper_notice"><b>Edit failed on <a href="' + wgArticlePath.replace("$1", encodeURI(title)) + '" title="' + title + '">' + title + '</a></b></span>. Error info: ' + error);
})
.always( function () {
$("#afcHelper_AJAX_finished_" + func_id).css("display", '');
});
if (!nopatrol) {
/* We patrol by default */
if ($('.patrollink').length) {
// Extract the rcid token from the "Mark page as patrolled" link on page
var patrolhref = $('.patrollink a').attr('href');
var rcid = mw.util.getParamValue('rcid', patrolhref);
if (rcid) {
$('#afcHelper_status').html($('#afcHelper_status').html() + '<li id="afcHelper_patrol' + jqEsc(title) + '">Marking <a href="' + wgArticlePath.replace("$1", encodeURI(title)) + '" title="' + title + '">' + title + ' as patrolled</a></li>');
var patrolrequest = {
'action': 'patrol',
'format': 'json',
'rcid': rcid
};
api.postWithToken('patrol', patrolrequest)
.done(function ( data ) {
if ( data ) {
$('#afcHelper_patrol' + jqEsc(title)).html('Marked <a href="' + wgArticlePath.replace("$1", encodeURI(title)) + '" title="' + title + '">' + title + '</a> as patrolled');
} else {
$('#afcHelper_patrol' + jqEsc(title)).html('<span class="afcHelper_notice"><b>Patrolling failed on <a href="' + wgArticlePath.replace("$1", encodeURI(title)) + '" title="' + title + '">' + title + '</a></b></span> with an unknown error');
window.console && console.error('Patrolling failed on %s (%s) with an unknown error.', wgArticlePath.replace("$1", encodeURI(title)), title);
}
} )
.fail( function ( error ) {
$('#afcHelper_patrol' + jqEsc(title)).html('<span class="afcHelper_notice"><b>Patrolling failed on <a href="' + wgArticlePath.replace("$1", encodeURI(title)) + '" title="' + title + '">' + title + '</a></b></span>. Error info: ' + error);
});
}
}
}
}
// From http://stackoverflow.com/a/6323598/1757964
function allMatches ( regex, string ) {
var matches = [],
match;
do {
match = regex.exec( string );
if ( match ) {
matches.push( match );
}
} while ( match );
return matches;
}
mw.loader.using(['mediawiki.api', 'mediawiki.util'], function() {
// Create portlet link
var redirectportletLink = mw.util.addPortletLink('p-cactions', '#', 'Review AFC/R', 'ca-afcrhs', 'Review', 'a');
// Bind click handler
$(redirectportletLink).click(function(e) {
e.preventDefault();
// clear variables for the case somebody is clicking on "review" multiple times
afcHelper_RedirectSubmissions.length = 0;
afcHelper_RedirectSections.length = 0;
afcHelper_numTotal = 0;
afcHelper_Submissions.length = 0;
needsupdate.length = 0;
afcHelper_redirect_init();
});
});
})();
//</nowiki>