User:EchidnaLives/AFCRHs.js

// forked from User:Enterprisey/AFCRHS.js // see that page for attribution

// (function {   if (mw.config.get("wgPageName").indexOf('Wikipedia:Articles_for_creation/Redirects_and_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 = ' (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.wikipedia.org/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 = $(' Reviewing AfC redirect requests '); 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 = $(''); var $thisSubListElement = $(''); 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($('')                           .attr('href', mw.config.get("wgArticlePath").replace("$1", encodeURIComponent(afcHelper_RedirectSubmissions[k].to)))                            .attr('target', '_blank')                            .text(afcHelper_RedirectSubmissions[k].to)); } else { $thisSubListElement.append('no target given: '); }               }                var $fromList = $('').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 = "no title specified, check the request details"; var reasonAndSource = $(''); if(afcHelper_RedirectSubmissions[k].reason) reasonAndSource.append('Reason: ' + afcHelper_RedirectSubmissions[k].reason + ''); if(afcHelper_RedirectSubmissions[k].source) reasonAndSource.append('Source: ' + afcHelper_RedirectSubmissions[k].source + '');

var googleSearchUrl = 'http://www.google.com/search?q="' +                           encodeURIComponent(toarticle) + '"+-wikipedia.org'; $fromList.append($('')                       .append('From: ' + toarticle + ' ( ' +                            'Google &middot; what links here) ')                        .append(reasonAndSource)                        .append($(' ').attr('for', 'afcHelper_redirect_action_' + from.id).text('Action: '))                        .append(afcHelper_generateSelectObject('afcHelper_redirect_action_' + from.id, ACTIONS,                            afcHelper_redirect_makeActionChange(from.id)))                        .append($(' ').attr('id', 'afcHelper_redirect_extra_' + from.id)));                }            } else {                var subId = afcHelper_RedirectSubmissions[k].id; $thisSubListElement.append('Category submission: ') .append($('')                       .attr('href', '/wiki/' + afcHelper_RedirectSubmissions[k].title)                        .attr('title', afcHelper_RedirectSubmissions[k].title)                        .text(afcHelper_RedirectSubmissions[k].title)) .append(' ') .append($(' ').attr('for', 'afcHelper_redirect_action_' + subId).text('Action: ')) .append(afcHelper_generateSelectObject('afcHelper_redirect_action_' + subId, ACTIONS, afcHelper_redirect_makeActionChange(subId))) .append($(' ').attr('id', 'afcHelper_redirect_extra_' + subId)); }           $thisSubList.append($thisSubListElement); $messageDiv.append($thisSubList); } // end loop over sections $messageDiv.append($(' ')           .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('From: '); $extra.append($(' ')           		.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 + ' <label for="afcHelper_redirect_to_' + id + '">To: <input type="text" ' + 'name="afcHelper_redirect_to_' + id + '" id="afcHelper_redirect_to_' + id + '" value="' + afcHelper_escapeHtmlChars(afcHelper_Submissions[id].to) + '" />'); $extra.html($extra.html + ' <label for="afcHelper_redirect_append_' + id + '">Template to append: (<a href="https://en.wikipedia.org/wiki/Wikipedia:TMR" target="_blank">Help</a>) '); $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: <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 + ' <label for="afcHelper_redirect_parents_' + id + '">Parent categories (comma-separated): ' + '<input type="text" size="100" id="afcHelper_redirect_parents_' + id + '" name="afcHelper_redirect_parents_' + id + '" value="' + afcHelper_escapeHtmlChars(afcHelper_Submissions[id].parents) + '" />'); $extra.append(' '); $extra.append($(' ', {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> '); $extra.html($extra.html + ' <input type="checkbox" name="afcHelper_redirect_container_' + id + '"'); }           $extra.html($extra.html + ' <label for="afcHelper_redirect_comment_' + id + '">Comment: ' + '<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: ' + 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: ' + 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 + ' <label for="afcHelper_redirect_comment_' + id + '">Comment: ' + '<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: ' + '<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">Done (<a href="' + mw.config.get("wgArticlePath").replace("$1", encodeURI(afcHelper_RedirectPageName)) + '?action=purge" title="' + afcHelper_RedirectPageName + '">Reload page</a>)</li> '); 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 = ''; if (sub.container) { cattext += '\n'; }                   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; var redirecttext = '#REDIRECT \[\[' + redirect.to + '\]\]\n\n'; 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 + " &rarr; " + 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 + " &rarr; " + 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.wikipedia.org\/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 =  + 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 = $(' ') .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 = $( ' ' )                .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, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");   }

/**    * 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"> ' ); 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 + ' '); 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">Edit failed on <a href="' + wgArticlePath.replace("$1", encodeURI(title)) + '" title="' + title + '">' + title + '</a>. 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">Edit failed on <a href="' + wgArticlePath.replace("$1", encodeURI(title)) + '" title="' + title + '">' + title + '</a>. Error info: The article already exists!');                   else                        $('#afcHelper_edit' + jqEsc(title)).html('<span class="afcHelper_notice">Edit failed on <a href="' + wgArticlePath.replace("$1", encodeURI(title)) + '" title="' + title + '">' + title + '</a>. 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">Patrolling failed on <a href="' + wgArticlePath.replace("$1", encodeURI(title)) + '" title="' + title + '">' + title + '</a> 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">Patrolling failed on <a href="' + wgArticlePath.replace("$1", encodeURI(title)) + '" title="' + title + '">' + title + '</a>. 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; });   }); }); //