User:Ale jrb/Scripts/csdhelper.js

/* ============================================== *\

  • CSD Helper - JavaScript CSD Script
  • for Wikipedia
  • Created by Alex Barley User:Ale_jrb
  • Tracker: User:Ale_jrb/Scripts
  • You are advised to import this script to your
  • monobook.js page - AVOID CREATING YOUR OWN
  • VERSION WHERE POSSIBLE.
  • Instructions for this script can be found at
  • User:Ale_jrb/Scripts - refer to this for
  • setting details.

\* ============================================== */

// NB. this script relies on User:Ale_jrb/Scripts/waLib.js.

// the following settings are used in this script:

if (csdhDisplayAlways == null) var csdhDisplayAlways = false; // whether to display CSDH even if the page is not tagged

if (notifyByDefaultDec == null) var notifyByDefaultDec = true; // whether to check the 'notify tagger' box by default when declining a speedy deletion request

if (notifyByDefaultDel == null) var notifyByDefaultDel = false; // whether to check the 'notify tagger' box by default when changing a speedy deletion rationale

if (notifyByDefaultPrd == null) var notifyByDefaultPrd = true; // whether to check the 'notify tagger' box by default when converting a speedy deletion to PROD

if (notifyByDefaultNew == null) var notifyByDefaultNew = true; // whether to check the 'use newbie message' box by default

if (notifyLimit == null) var notifyLimit = 12; // how many revisions should be retrieved when determining who tagged the page

if (notifyTemplate == null) var notifyTemplate = 'User:Ale_jrb/Scripts/CSDHelper'; // the template that should be substituted for notification messages

if (csdhDoRedirect == null) var csdhDoRedirect = true;

if (redirectAfterDel == null) var redirectAfterDel = mw.config.get ( 'wgScript' ) + '?title=Category:Candidates_for_speedy_deletion&action=purge#Pages_in_category'; // where to redirect after deletion

if (myDeleteReasons == null) var myDeleteReasons = []; // any addition speedy deletion reasons to add to the list

if (logOnDecline == null) var logOnDecline = false;

if (logOnDeclinePath == null) var logOnDeclinePath = '';

if (overwriteDeclineReasons == null)var overwriteDeclineReasons = false; // whether to overwrite the in-build decline reasons with the user defined ones

if (overwriteDeleteReasons == null) var overwriteDeleteReasons = false; // whether to overwrite the in-build delete reasons with the user defined ones

if (myDeclineReasons == null) var myDeclineReasons = []; // any addition speedy deletion decline reasons to add to the list

if (myDeclineListing == null) var myDeclineListing = '%CRITERION%: %REASON%'; // the appearance of the option in the drop-down box

if (myDeclineSummary == null) var myDeclineSummary = 'Speedy deletion %ACTION%. Criterion %CRITERION% does not apply: %REASON%'; // the summary to use when removing a deletion tag from a page because it has been declined or contested

if (myDeclineSummarySpecial == null)var myDeclineSummarySpecial = 'Speedy deletion %ACTION%. %REASON%'; // the summary to use when removing a deletion tag from a page IN A SEPCIAL CASE. NOTE: %CRITERION% will be blank!

// Top-level helpers

function isPageTagged() {

return document.getElementById('delete-criterion') != null;

}

function isPageContested() {

const contestString = 'speedy deletion of this page is contested.';

return document.body.innerHTML.indexOf(contestString) > -1;

}

function shouldDisplayCsdh() {

// Always exclude certain pages

if (mw.config.get('wgNamespaceNumber') == 10 ||

document.getElementById('noarticletext') ||

document.getElementById('newarticletext'))

{

return false;

}

// Otherwise perform display checks

return csdhDisplayAlways || isPageTagged() || isPageContested();

}

function launchCsdh() {

if (shouldDisplayCsdh()) {

// Launch controller.

this.control = new csdH_controller;

this.control.attachLinks();

return true;

}

}

// Core

function csdH_controller() {

csdHController = this;

this.notifyExempt = new Array('SDPatrolBot','Ale jrb 2'); // these editors are exempt from being notified (if they added the tag, notification will fail)

csdHController.deleteRegex = /[\s]*\{\{(?:db|speedy ?delet(?:e|ion)|speedy|d|rm|del(?:ete)? ?(?:because)?|csd|nn|[GARFCUTPX][0-9]{1,2})(?:-(?:.+?))?(?:\|(?:.+?))?\}\}[\s]*/gi;

csdHController.hangonRegex = /[\s]*\{\{(?:hang|hold)(?: |-)?oo?n(?:\|.+?)?\}\}[\s]*/gi;

csdHController.doNotifyDec = '';

csdHController.doNotifyDel = '';

csdHController.doNotifyPrd = '';

if (notifyByDefaultDec == true) csdHController.doNotifyDec = ' checked';

if (notifyByDefaultDel == true) csdHController.doNotifyDel = ' checked';

if (notifyByDefaultPrd == true) csdHController.doNotifyPrd = ' checked';

if (notifyByDefaultNew == true) csdHController.doNotifyNew = ' checked';

if (waUser.isSysop == true) {

csdHController.isSysop = 'yes';

csdHController.decAction = 'declined';

} else {

csdHController.isSysop = 'no';

csdHController.decAction = 'contested';

}

// default arrays - it's fine to edit these, but if you simply wish to add additional decline reasons, use the

// setting for additional options described above.

this.declineReasons = new Array(

['G1', 'Not nonsense - there is meaningful content'],

['G2', 'Not a test page'],

['G3', 'Not blatantly vandalism or a hoax'],

['G4', 'Not previously been deleted via a deletion discussion'],

['G5', 'Not created by a banned user, or the page does not violate the user\'s ban'],

['G6', 'Deletion of this page may be controversial or is under discussion'],

['G7', 'Author has not requested deletion, or other users have added substantial content'],

['G8', 'Does not rely on a page that does not exist'],

['G9', 'G9 can only be used at the request of, or by, the Wikimedia Foundation'],

['G10', 'Not blatantly an attack page or negative, unsourced BLP'],

['G11', 'Not unambiguously promotional'],

['G12', 'Not an unambiguous copyright infringement, or there is other content to save'],

['G13', 'Page is not a draft, or has been edited in the last six months'],

['G14', 'Page is not a disambiguation page, or disambiguates two or more extant pages'],

['A1', 'There is sufficient context to identify the subject of the article'],

['A2', 'The article is in English, or does not exist at a foreign project'],

['A3', 'Contains sufficient content to be a stub'],

['A7', 'The article makes a credible assertion of importance or significance, sufficient to pass A7'],

['A7', 'A7 does not apply to schools'],

['A7', 'A7 does not apply to software'],

['A9', 'The article makes a credible assertion of importance or significance, or is not a musical recording'],

['A10', 'Page title is a plausible redirect, or it does not substantially duplicate the other topic'],

['A11', 'Subject is not obviously invented by the page creator'],

['R2', 'Does not redirect to a different or incorrect namespace'],

['R3', 'Is a plausible, useful redirect or is not a redirect at all'],

['R3', 'Not a recently created redirect - consider WP:RfD'],

['R4', 'Not the same name as a Commons file or redirect'],

['R4', 'Has incoming file links - consider WP:RfD'],

['F1', 'File is used, or it is not a lower-quality version of an existing image'],

['F2', 'File is neither corrupt, missing, or empty'],

['F3', 'File has a suitable license'],

['F4', 'File has the necessary licensing information'],

['F5', 'File is used, or it has a free license'],

['F6', 'File has a use rationale'],

['F7', 'File has a valid fair-use claim'],

['F8', 'File is not identical to the Commons version, or has been marked as "Keep local"'],

['F9', 'Not an unambiguous copyright infringement'],

['F11', 'Evidence of permission has been given'],

['C1', 'Category is populated or is otherwise allowed to be empty'],

['C4', 'Category is not unused'],

['T5', 'Not an unused template subpage'],

['U1', 'Not a user page'],

['U1', 'Does not apply to user talk pages'],

['U2', 'User does exist, or this is not a user page'],

['U5', 'Not a blatant misuse of Wikipedia as a webhost']

);

this.deleteReasons = new Array(

['N/A', 'You must select a rationale...'],

['G1', 'Patent nonsense, meaningless, or incomprehensible'],

['G2', 'Test page'],

['G3', 'Vandalism'],

['G3', 'Vandalism - blatant hoax or misinformation'],

['G4', 'Recreation of a page that was deleted per a deletion discussion'],

['G5', 'Creation by a banned user in violation of ban'],

['G6', 'Housekeeping and routine (non-controversial) cleanup'],

['G7', 'One author who has requested deletion or blanked the page'],

['G8', 'Page dependent on a deleted or nonexistent page'],

['G8', 'Talk page of a deleted page'],

['G10', 'Attack page or negative unsourced BLP that serves no purpose but to threaten or disparage its subject'],

['G11', 'Unambiguous advertising or promotion'],

['G12', 'Unambiguous copyright infringement'],

['G13', 'Abandoned Draft or Article for creation — to retrieve it, see WP:REFUND/G13'],

['G14', 'Disambiguation page that disambiguates only one page and whose title ends in (disambiguation) or disambiguates zero extant pages'],

['A1', 'Not enough context to identify article\'s subject'],

['A2', 'Article in a foreign language that exists on another project'],

['A3', 'Article that has no meaningful, substantive content'],

['A7', 'No indication that the article may meet the guidelines for inclusion'],

['A7', 'Article about a real person, which does not credibly indicate the importance or significance of the subject'],

['A7', 'Article about a band, singer, musician, or musical ensemble that does not credibly indicate the importance or significance of the subject'],

['A7', 'Article about a web site, blog, web forum, webcomic, podcast, browser game, or similar web content, which does not credibly indicate the importance or significance of the subject'],

['A7', 'Article about a company, corporation, organization, or group which does not credibly indicate the importance or significance of the subject'],

['A7', 'Article about a group or club, which does not credibly indicate the importance or significance of the subject'],

['A7', 'Article about an organized event, which does not credibly indicate the importance or significance of the subject'],

['A7', 'Article about an individual animal, which does not credibly indicate the importance or significance of the subject'],

['A9', 'Article about a musical recording, which does not credibly indicate the importance or significance of the subject and where the artist has no article'],

['A10', 'Article where the only content is already existing in another article and where a redirect to the existing article would be implausible'],

['A11', 'Article about a subject that was obviously invented by the creator or someone they know and which does not credibly indicate the importance or significance of the subject'],

['R2', 'Cross-namespace redirect from mainspace'],

['R3', 'Recently-created, implausible redirect'],

['R4', 'File redirect with no incoming file links and the same name as a file or redirect at Wikimedia Commons'],

['F1', 'Redundant file (also on Wikipedia)'],

['F2', 'Corrupt or empty file, or a file description page for a file on Commons'],

['F3', 'File licensed as "for non-commercial use only", "no derivative use", "for Wikipedia use only", "used with permission", or GFDL 1.2 only.'],

['F4', 'Lack of licensing information'],

['F5', 'Unused non-free media file for more than 7 days'],

['F6', 'Non-free media file with no non-free use rationale'],

['F7', 'Invalid fair-use rationale'],

['F8', 'Media file available on Commons'],

['F9', 'Media file copyright violation without credible claim of fair use or permission'],

['F11', 'No evidence of permission for more than 7 days'],

['C1', 'Empty category'],

['C4', 'Unused maintenance category'],

['T5', 'Unused template subpage'],

['U1', 'User request to delete pages in own userspace'],

['U2', 'Userpage or subpage of a nonexistent user'],

['U3', 'Non-free gallery'],

['U5', 'Blatant use of Wikipedia as a web host by user with no or very few edits']

);

// Handle user defined content...

// declining

if (overwriteDeclineReasons == true) {

this.declineReasons.length = 0;

this.declineReasons = myDeclineReasons;

} else {

this.declineReasons = this.declineReasons.concat(myDeclineReasons);

}

// deleting

if (overwriteDeleteReasons == true) {

this.deleteReasons.length = 0;

this.deleteReasons = myDeleteReasons;

} else {

this.deleteReasons = this.deleteReasons.concat(myDeleteReasons);

}

// append necessary options to decline reasons

var declineReasonsEnd = new Array(

['INVALID', 'The reason given is not a valid speedy deletion criterion'], // don't touch this

['DONTPROVIDE', 'No reason given.'], // don't touch this

['OTHER', 'Other - provide your own reason below'] // don't touch this

);

this.declineReasons = this.declineReasons.concat(declineReasonsEnd);

// GUI

function getStandardElements() {

if (!(isPageTagged() || isPageContested())) {

return '';

}

let result =

'

Decline Speedy
' +

'

Change to PROD
' +

'';

return result;

}

function getSysopElements() {

if (!waUser.isSysop) {

return '';

}

let result =

'

Delete Page
' +

'';

return result;

}

function getCoreElements() {

let result =

'

' +

'

Handle Speedy Deletion
' +

'

What do you want to do to this page?
' +

'

' +

getSysopElements() +

getStandardElements() +

'

' +

'

';

return result;

}

this.showcsdHWindow = function() {

// grab position of button

var offsetL = 0;

var offsetT = 0;

var thisObject = document.getElementById('ca-speedy');

if (thisObject.offsetParent) {

do {

offsetL += thisObject.offsetLeft;

offsetT += thisObject.offsetTop;

} while (thisObject = thisObject.offsetParent);

}

// build window to show user

if (this.interface == null) {

this.interface = new wa_window(document.getElementById('content'));

this.visible = true;

this.csdHelperLink.ele_obj.setAttribute('class', 'selected');

this.interface.win_content = getCoreElements();

} else {

this.interface.win_content = getCoreElements();

if (this.visible == true) {

this.csdHelperLink.ele_obj.setAttribute('class', '');

this.interface.win_disp = 'none';

this.interface.applyAll();

this.visible = false;

return true;

} else {

this.csdHelperLink.ele_obj.setAttribute('class', 'selected');

this.interface.win_disp = 'block';

this.interface.win_height = 170;

this.interface.applyAll();

this.visible = true;

return true;

}

}

if ( mw.config.get ( 'skin' ) == 'vector' ) {

this.interface.win_left = offsetL - 17;

this.interface.win_top = offsetT + 39;

} else {

this.interface.win_left = document.getElementById('ca-speedy').offsetLeft - 17;

this.interface.win_top = -1;

}

this.interface.win_width = 600;

this.interface.win_height = 170;

this.interface.win_bg = '#fff';

this.interface.win_bd = '#aaaaaa';

this.interface.win_bd_wd = 1;

this.interface.applyAll();

}

this.declinePage = function() {

// build the selection options

var declineOptions = ''; var optionSelected = false;

for (var i = 0; i < this.declineReasons.length; i++) {

var selected = '';

// determine whether this option should be selected

if (optionSelected == false) {

if (document.getElementById('delete-criterion') != null) { // if this matches the criterion provided, select it.

if (document.getElementById('delete-criterion').innerHTML == this.declineReasons[i][0]) { selected = ' selected '; optionSelected = true; }

if ( (this.declineReasons[i][0] == 'INVALID') && (optionSelected == false) ) { selected = ' selected '; optionSelected = true; }

} else { // if no criterion was selected, wait until 'other' is selected.

if (this.declineReasons[i][0] == 'OTHER') { selected = ' selected '; optionSelected = true; }

}

}

// build the visible message for use in the drop-down.

var tempVisible = myDeclineListing.replace(/%CRITERION%/gi, this.declineReasons[i][0]); tempVisible = tempVisible.replace(/%REASON%/gi, this.declineReasons[i][1]);

declineOptions += ''+tempVisible+'';

}

if ( mw.config.get ( 'skin' ) == 'vector' ) { var skinPos = '3'; } else { var skinPos = '10'; }

this.interface.win_content = ''+

'

Decline Speedy Deletion
'+

'

Select the reason for declining the deletion from the list. This text will be used as the edit summary.
'+

''+

'

Or provide your own reason and summary below.
'+

''+

'

'+

'

notify tagger
'+

'

use newbie message
'+

'

'+

'';

this.interface.applyAll();

}

this.declineDo = function(callback) {

// get page content

if (!callback) var callback = 0;

switch (callback) {

default:

// main vars

csdHController.declineText = document.getElementById('declineText').value;

csdHController.declineSel = document.getElementById('declineReason').selectedIndex;

csdHController.declineNotify = document.getElementById('notifyTagger').checked;

csdHController.notifyNewbie = document.getElementById('notifyNewbie').checked;

if ((csdHController.declineText == '') && (csdHController.declineSel == csdHController.declineReasons.length-1)) {

// if no reason is typed, byt 'Other' is selected, use the 'No reason provided' option.

csdHController.declineSel = csdHController.declineReasons.length - 2;

}

csdHController.declineCategory = csdHController.declineReasons[csdHController.declineSel][0];

csdHController.declineReason = csdHController.declineReasons[csdHController.declineSel][1];

// build all messages

if ( (csdHController.declineCategory == 'INVALID') || (csdHController.declineCategory == 'DONTPROVIDE') ) { // if it's a 'special' case, use the 'special' summary

var tempSummary = myDeclineSummarySpecial;

tempSummary = tempSummary.replace(/%ACTION%/gi, csdHController.decAction); tempSummary = tempSummary.replace(/%REASON%/gi, csdHController.declineReason);

csdHController.editSummary = tempSummary;

} else if (csdHController.declineCategory == 'OTHER') { // if they've typed a reason, use that

var tempSummary = myDeclineSummarySpecial;

tempSummary = tempSummary.replace(/%ACTION%/gi, csdHController.decAction); tempSummary = tempSummary.replace(/%REASON%/gi, csdHController.declineText);

csdHController.editSummary = tempSummary;

} else { // otherwise, use the 'normal' summary

var tempSummary = myDeclineSummary;

tempSummary = tempSummary.replace(/%ACTION%/gi, csdHController.decAction); tempSummary = tempSummary.replace(/%CRITERION%/gi, csdHController.declineCategory); tempSummary = tempSummary.replace(/%REASON%/gi, csdHController.declineReason);

csdHController.editSummary = tempSummary;

}

csdHController.editSummary += ' (CSDH)';

// start

this.interface.win_content = ''+

'

Working...
'+

'

Please wait while CSDHelper performs the requested operations. This can take several seconds.
'+

'

- Retrieving existing content...
'+

'

'+

'';

this.interface.applyAll();

csdHController.pageReq = new wa_mediawikiApi();

csdHController.pageReq.onCompleteAction = function() { csdHController.declineDo('1'); };

csdHController.pageReq.getPage(mw.config.get('wgPageName'), notifyLimit, 'user|content');

break;

case '1':

document.getElementById('workingStatus').innerHTML += '- Removing tags...
';

csdHController.pageContent = csdHController.pageReq.data['page']['revisions'][0]['content'];

var regReplace = csdHController.deleteRegex;

csdHController.pageContent = csdHController.pageContent.replace(regReplace, '');

var regReplace = csdHController.hangonRegex;

csdHController.pageContent = csdHController.pageContent.replace(regReplace, '');

csdHController.newContent = csdHController.pageContent; // grab a record of that

document.getElementById('workingStatus').innerHTML += '- Updating page...
';

csdHController.editReq = new wa_mediawikiApi();

csdHController.editReq.onCompleteAction = function() { csdHController.declineDo('2'); };

csdHController.editReq.editPage(mw.config.get('wgPageName'), csdHController.newContent, csdHController.editSummary, false, 'text');

break;

case '2':

// check for notify

if ( (csdHController.declineNotify == true) || (logOnDecline == true) ) {

document.getElementById('workingStatus').innerHTML += '- Determining user who tagged page...
';

var tags = 0; csdHController.tagger = '';

var revisionCount = csdHController.pageReq.data['page']['revisions'].length;

var limit = Math.min(notifyLimit, revisionCount);

for (var i = 0; i < limit; i++) {

var thisPage = csdHController.pageReq.data['page']['revisions'][i]['content'];

// count tags

var regTest = csdHController.deleteRegex;

var k = 1; var count = 0;

while (k != null) {

k = regTest.exec(thisPage);

if (k != null) count++;

}

regTest.lastIndex = 0;

// check if we have fewer than last time (1 was added on that rev)

if (count < tags) {

csdHController.tagger = csdHController.pageReq.data['page']['revisions'][i - 1]['user'];

break;

} else {

tags = count;

}

}

if (csdHController.tagger == '') { document.getElementById('workingStatus').innerHTML += '- Could not determine tagger: will not log or notify. Finished.
'; break; }

for (var i = 0; i < csdHController.notifyExempt.length; i++) {

if (csdHController.tagger == csdHController.notifyExempt[i]) {

document.getElementById('workingStatus').innerHTML += '- Tagger ('+csdHController.tagger+') is on the tagger exempt list, and will not be notified. Finished.
';

if (logOnDecline == true) { csdHController.declineNotify = false; csdHController.declineDo('3'); } else { return true; }

}

}

if ( (logOnDecline == true) && (logOnDeclinePath != '') ) { csdHController.declineDo('3'); } else { csdHController.declineDo('5'); }

} else { window.location.reload(true); csdHController.showcsdHWindow(); }

break;

case '3':

// log decline action where relevant

document.getElementById('workingStatus').innerHTML += '- Logging decline action to \''+logOnDeclinePath+'\' - retrieving page... ';

csdHController.pageReq = new wa_mediawikiApi();

csdHController.pageReq.onCompleteAction = function() { csdHController.declineDo('4'); };

csdHController.pageReq.getPage(logOnDeclinePath, 1, 'content');

break;

case '4':

// we have retrieved the data regarding the log page; move to edit it

document.getElementById('workingStatus').innerHTML += 'modifying page...
';

//var logOnDeclinePath = logOnDeclinePath.replace(/ /g,'_');

// check whether there is existing content

var pageData = csdHController.pageReq.data['page'];

if (pageData['status'] == 'OK') {

var oldContent = pageData['revisions'][0]['content'];

if ( oldContent === '' ) oldContent = "

class=\"sortable wikitable\" style=\"font-size: 80%;\" border=\"2\" cellpadding=\"1\" background:#f9f9f9;\"|\n
\n! style=\"text-align: left\" | Article\n! Tagger\n! Criterion\n! Decline reason\n! Date\n
";

} else {

var oldContent = "

class=\"sortable wikitable\" style=\"font-size: 80%;\" border=\"2\" cellpadding=\"1\" background:#f9f9f9;\"|\n
\n! style=\"text-align: left\" | Article\n! Tagger\n! Criterion\n! Decline reason\n! Date\n
";

}

// message

var pageName = mw.config.get('wgPageName').replace(/_/g, ' ');

var reason = (csdHController.declineCategory == 'OTHER') ? csdHController.declineText : csdHController.declineReason;

var crit = document.getElementById('delete-criterion').innerHTML;

var message = "|-\n| :" + pageName + " || " + csdHController.tagger + " || CSD " + crit + " || " +reason + " || " + "~~" + "~~" + "~\n";

// add the new row to the table

var newContent = oldContent.replace('|}', message + '|}');

// build vars

var editSummary = 'Adding :' + pageName + ' to speedy decline log (CSDH)';

// perform the edit

csdHController.editReq = new wa_mediawikiApi();

csdHController.editReq.onCompleteAction = function() { csdHController.declineDo('5'); };

csdHController.editReq.editPage(logOnDeclinePath, newContent, editSummary, true, 'text');

break;

case '5':

// check notify

if (csdHController.declineNotify != true) { window.location.reload(true); csdHController.showcsdHWindow(); break; }

// output

document.getElementById('workingStatus').innerHTML += '- Tagged by \''+csdHController.tagger+'\' - notifying user...
';

// edit summary

csdHController.editSummary = 'Notifying about '+csdHController.decAction+' speedy deletion (CSDH)';

// decide whether to use newbie message

if (csdHController.notifyNewbie) { var useNewbie = 'yes'; } else { var useNewbie = 'no'; }

// fix message - handle other special case

if (csdHController.declineCategory == 'OTHER') csdHController.declineReason = csdHController.declineText;

// fix message - handle punctuation at the end of the message (it must be added if absent).

var p = csdHController.declineReason.substr(csdHController.declineReason.length - 1);

if ( (p != '.') && (p != '!') && (p != '?') ) csdHController.declineReason += '.';

// message

var message = '== Speedy deletion '+csdHController.decAction+': :'+mw.config.get('wgPageName').replace(/_/g, ' ')+' =='+"\n"+'{{subst:'+notifyTemplate+'|action=decline|page='+mw.config.get('wgPageName').replace(/_/g, ' ')+'|tagger='+csdHController.tagger+'|declinetext='+csdHController.declineReason+'|admin='+csdHController.isSysop+'|newbie='+useNewbie+'}} ~~'+'~~';

csdHController.saveReq = new wa_mediawikiApi();

csdHController.saveReq.onCompleteAction = function() { window.location.reload(true); csdHController.showcsdHWindow(); };

csdHController.saveReq.editPage('User_talk:'+csdHController.tagger, message, csdHController.editSummary, false, 'appendtext');

break;

}

}

this.prodPage = function() {

var prodOptions = '';

var content = document.getElementById('bodyContent');

var regTest = /criteria for speedy deletion<\/a><\/i> because (.*?)\.<\/b> For valid criteria,/i

var rationale = regTest.exec(content);

if (rationale != null) { rationale = rationale[1]; } else { rationale = ''; }

this.interface.win_content = ''+

'

Convert to PROD
'+

'

You are asserting that the page cannot be speedy deleted, but can be deleted by proposed deletion. '+

'Enter the reason for deletion below - if the tagger provided one, it will be filled automatically.

'+

''+

'

notify tagger of conversion
'+

'use newbie message

'+

'

'+

'

'+

'';

this.interface.applyAll();

}

this.prodDo = function(callback) {

if (!callback) var callback = 0;

switch (callback) {

default:

csdHController.prodReason = document.getElementById('prodReason').value;

csdHController.prodNotify = document.getElementById('notifyTagger').checked;

csdHController.notifyNewbie = document.getElementById('notifyNewbie').checked;

this.interface.win_content = ''+

'

Working...
'+

'

Please wait while CSDHelper performs the requested operations. This can take several seconds.
'+

'

'+

'

'+

'';

this.interface.applyAll();

if (csdHController.prodNotify == true) {

document.getElementById('workingStatus').innerHTML += '- Searching for tagger...
';

if (notifyLimit > 15) notifyLimit = 15;

csdHController.pageReq = new wa_mediawikiApi();

csdHController.pageReq.onCompleteAction = function() { csdHController.prodDo('1'); };

csdHController.pageReq.getPage(mw.config.get('wgPageName'), notifyLimit + 1, 'content|user');

} else {

csdHController.pageReq = new wa_mediawikiApi();

csdHController.pageReq.onCompleteAction = function() { csdHController.prodDo('3'); };

csdHController.pageReq.getPage(mw.config.get('wgPageName'), 1, 'content|user');

}

break;

case '1':

var tags = 0; csdHController.tagger = '';

var revisionCount = csdHController.pageReq.data['page']['revisions'].length;

var limit = Math.min(notifyLimit, revisionCount);

for (var i = 0; i < limit; i++) {

var thisPage = csdHController.pageReq.data['page']['revisions'][i]['content'];

// count tags

var regTest = csdHController.deleteRegex;

var k = 1; var count = 0;

while (k != null) {

k = regTest.exec(thisPage);

if (k != null) count ++;

}

regTest.lastIndex = 0;

// check if we have fewer than last time (1 was added on that rev)

if (count < tags) {

csdHController.tagger = csdHController.pageReq.data['page']['revisions'][i - 1]['user'];

break;

} else {

tags = count;

}

}

if (csdHController.tagger == '') { document.getElementById('workingStatus').innerHTML += '- Could not determine tagger. Moving to tag page...
'; csdHController.prodDo('3'); break; }

for (var i = 0; i < csdHController.notifyExempt.length; i ++) {

if (csdHController.tagger == csdHController.notifyExempt[i]) {

document.getElementById('workingStatus').innerHTML += '- Tagger ('+csdHController.tagger+') is on the tagger exempt list, and will not be notified. Moving to tag page...
';

csdHController.prodDo('3');

return true;

}

}

csdHController.prodDo('2');

break;

case '2': // notify tagger

document.getElementById('workingStatus').innerHTML += '- Tagged by \''+csdHController.tagger+'\' - notifying user...
';

// edit summary

csdHController.editSummary = 'Notifying about speedy deletion converted to PROD (CSDH)';

// decide whether to use newbie message

if (csdHController.notifyNewbie) { var useNewbie = 'yes'; } else { var useNewbie = 'no'; }

// message

var message = '== Speedy deletion converted to PROD: :'+mw.config.get('wgPageName').replace(/_/g, ' ')+' =='+"\n"+'{{subst:'+notifyTemplate+'|action=convert|page='+mw.config.get('wgPageName').replace(/_/g, ' ')+'|tagger='+csdHController.tagger+'|admin='+csdHController.isSysop+'|newbie='+useNewbie+'}} ~~'+'~~';

csdHController.notifyReq = new wa_mediawikiApi();

csdHController.notifyReq.onCompleteAction = function() { csdHController.prodDo('3'); };

csdHController.notifyReq.editPage('User_talk:'+csdHController.tagger, message, csdHController.editSummary, false, 'appendtext');

break;

case '3':

document.getElementById('workingStatus').innerHTML += '- Converting tags...
';

csdHController.pageContent = csdHController.pageReq.data['page']['revisions'][0]['content'];

var regReplace = csdHController.deleteRegex;

csdHController.pageContent = csdHController.pageContent.replace(regReplace, '');

var regReplace = csdHController.hangonRegex;

csdHController.pageContent = csdHController.pageContent.replace(regReplace, '');

if (csdHController.prodReason != 'nn') { csdHController.pageContent = '{'+'{subst:prod|'+csdHController.prodReason+'}'+'}\n' + csdHController.pageContent; } else {

csdHController.pageContent = '{'+'{subst:prod-nn}'+'}\n' + csdHController.pageContent; }

csdHController.newContent = csdHController.pageContent; // grab a record of that

csdHController.editSummary = 'Speedy deletion converted to PROD (CSDH)';

document.getElementById('workingStatus').innerHTML += '- Updating page...
';

csdHController.editReq = new wa_mediawikiApi();

csdHController.editReq.onCompleteAction = function() { window.location.reload(true); csdHController.showcsdHWindow(); };

csdHController.editReq.editPage(mw.config.get('wgPageName'), csdHController.newContent, csdHController.editSummary, false, 'text');

break;

}

}

this.deletePage = function() {

// build the selection options

var deleteOptions = ''; var optionSelected = false;

for (var i = 0; i < this.deleteReasons.length; i++) {

var selected = '';

if ( (document.getElementById('delete-criterion') != null) && (optionSelected == false) ) {

if (document.getElementById('delete-criterion').innerHTML == this.deleteReasons[i][0]) { csdHController.initialRationale = this.deleteReasons[i][0]; selected = ' selected'; optionSelected = true; }

} else {

if (this.deleteReasons[i][0] == 'N/A') { selected = ' selected '; optionSelected = true; }

}

// general

var visibleReasoning = this.deleteReasons[i][1].replace(/\[\[(?:.*?\|)(.+?)\]\]/g, '$1');

deleteOptions += '';

}

if (document.getElementById('delete-criterion') == null) { var displayTagCommand = 'display: none;'; } else { var displayTagCommand = 'display: block;'; }

this.interface.win_content = ''+

'

Perform Speedy Deletion
'+

'

Select the reason for deletion from the list. The rationale specified by the tagger is automatically selected. If you select a reason that does not '+

'match the tag, will be given the option of notifying the tagger.

'+

''+

'

'+

'

'+

'

'+

'';

this.interface.applyAll();

}

this.deleteDo = function(callback) {

if (!callback) var callback = 0;

switch (callback) {

default:

csdHController.deleteSel = document.getElementById('deleteReason').selectedIndex;

csdHController.deleteNotify = document.getElementById('notifyTagger').checked;

csdHController.notifyNewbie = document.getElementById('notifyNewbie').checked;

if (document.getElementById('delete-criterion') == null) {

csdHController.allowDelNotify = false;

} else { csdHController.allowDelNotify = (csdHController.deleteReasons[csdHController.deleteSel][0] != document.getElementById('delete-criterion').innerHTML); }

this.interface.win_content = ''+

'

Working...
'+

'

Please wait while CSDHelper performs the requested operations. This can take several seconds.
'+

'

'+

'

'+

'';

this.interface.applyAll();

if ((csdHController.deleteNotify == true) && (csdHController.allowDelNotify == true)) {

document.getElementById('workingStatus').innerHTML += '- Searching for tagger...
';

if (notifyLimit > 15) notifyLimit = 15;

csdHController.pageReq = new wa_mediawikiApi();

csdHController.pageReq.onCompleteAction = function() { csdHController.deleteDo('1'); };

csdHController.pageReq.getPage(mw.config.get('wgPageName'), notifyLimit + 1, 'content|user');

} else { csdHController.deleteDo('3'); }

break;

case '1':

var tags = 0; csdHController.tagger = '';

var revisionCount = csdHController.pageReq.data['page']['revisions'].length;

var limit = Math.min(notifyLimit, revisionCount);

for (var i = 0; i < limit; i++) {

var thisPage = csdHController.pageReq.data['page']['revisions'][i]['content'];

// count tags

var regTest = csdHController.deleteRegex;

var k = 1; var count = 0;

while (k != null) {

k = regTest.exec(thisPage);

if (k != null) count ++;

}

regTest.lastIndex = 0;

// check if we have fewer than last time (1 was added on that rev)

if (count < tags) {

csdHController.tagger = csdHController.pageReq.data['page']['revisions'][i - 1]['user'];

break;

} else {

tags = count;

}

}

if (csdHController.tagger == '') { document.getElementById('workingStatus').innerHTML += '- Could not determine tagger. Moving to deletion...
'; csdHController.deleteDo('3'); break; }

for (var i = 0; i < csdHController.notifyExempt.length; i ++) {

if (csdHController.tagger == csdHController.notifyExempt[i]) {

document.getElementById('workingStatus').innerHTML += '- Tagger ('+csdHController.tagger+') is on the tagger exempt list, and will not be notified. Moving to deletion...
';

csdHController.deleteDo('3');

return true;

}

}

csdHController.deleteDo('2');

break;

case '2': // notify tagger

document.getElementById('workingStatus').innerHTML += '- Tagged by \''+csdHController.tagger+'\' - notifying user...
';

// edit summary

csdHController.editSummary = 'Notifying about altered speedy deletion rationale (CSDH)';

// decide whether to use newbie message

if (csdHController.notifyNewbie) { var useNewbie = 'yes'; } else { var useNewbie = 'no'; }

// message

var message = '== Altered speedy deletion rationale: :'+mw.config.get('wgPageName').replace(/_/g, ' ')+' =='+"\n"+'{{subst:'+notifyTemplate+'|action=change|page='+mw.config.get('wgPageName').replace(/_/g, ' ')+'|tagger='+csdHController.tagger+'|newbie='+useNewbie+'}} ~~'+'~~';

csdHController.notifyReq = new wa_mediawikiApi();

csdHController.notifyReq.onCompleteAction = function() { csdHController.deleteDo('3'); };

csdHController.notifyReq.editPage('User_talk:'+csdHController.tagger, message, csdHController.editSummary, false, 'appendtext');

break;

case '3':

// perform the edit

document.getElementById('workingStatus').innerHTML += '- Deleting page...
';

var deleteReason = ''+csdHController.deleteReasons[csdHController.deleteSel][0]+': ' + csdHController.deleteReasons[csdHController.deleteSel][1] + ' (CSDH)';

csdHController.deleteReq = new wa_mediawikiApi();

csdHController.deleteReq.onCompleteAction = function(callback) {

if ((callback == null) || (callback == false) || (mw.config.get('wgNamespaceNumber') != 0)) {

// No talk page

if (csdhDoRedirect) {

window.location = redirectAfterDel;

} else {

window.location.reload(true);

}

csdHController.showcsdHWindow();

} else {

// Talk page exists

csdHController.talkpageId = callback;

document.getElementById('workingStatus').innerHTML = ''+

'Warning: this page now has an orphaned talk page. Do you wish to delete it under G8?

'+

'

'+

'';

}

};

csdHController.deleteReq.performAction('delete', mw.config.get('wgPageName'), deleteReason);

break;

case '4':

// delete the talk page - get the title

var talkPage = 'Talk:' + mw.config.get('wgPageName');

csdHController.deleteReq = new wa_mediawikiApi();

csdHController.deleteReq.onCompleteAction = function() { window.location = redirectAfterDel; csdHController.showcsdHWindow(); };

csdHController.deleteReq.performAction('delete', talkPage, 'G8: Talk page of deleted page. (CSDH)');

break;

}

}

this.displayError = function() {

this.interface.win_content = ''+

'

An error occurred...
'+

'

'+

'';

this.interface.applyAll();

}

this.attachLinks = function() {

this.csdHelperLink = new wa_element('li');

this.csdHelperLink.ele_obj.id = 'ca-speedy';

this.csdHelperLink.addScriptEvent('click', function() { csdHController.showcsdHWindow(); });

if ( mw.config.get ( 'skin' ) == 'vector' ) {

this.csdHelperLink.ele_obj.innerHTML = 'Speedy';

this.csdHelperLink.attach(document.getElementById('ca-talk'), 'after');

} else {

this.csdHelperLink.ele_obj.innerHTML = 'speedy';

this.csdHelperLink.attach(document.getElementById('ca-move'), 'before');

}

};

}

// -- run program

function launchCsdHelper() {

// lib proto

wa_window.prototype = new wa_document;

wa_element.prototype = new wa_document;

// run

launchCsdh();

}

$.getScript("https://en.wikipedia.org/w/index.php?title=User:Ale_jrb/Scripts/waLib.js&type=text/javascript&action=raw", function() {

$(document).ready(launchCsdHelper);

});