Jump to content
 







Main menu
   


Navigation  



Main page
Contents
Current events
Random article
About Wikipedia
Contact us
Donate
 




Contribute  



Help
Learn to edit
Community portal
Recent changes
Upload file
 








Search  

































Create account

Log in
 









Create account
 Log in
 




Pages for logged out editors learn more  



Contributions
Talk
 

















User:Ale jrb/Scripts/csdhelper.js: Difference between revisions

















User page
Talk
 

















Read
View source
View history
 








Tools
   


Actions  



Read
View source
View history
 




General  



What links here
Related changes
User contributions
User logs
View user groups
Upload file
Special pages
Permanent link
Page information
Get shortened URL
Download QR code
 




Print/export  



Download as PDF
Printable version
 
















Appearance
   

 





Help
 

From Wikipedia, the free encyclopedia
 

< User:Ale jrb | Scripts

Browse history interactively
 Previous edit
Content deleted Content added
new part of G13 criterion
Remove F10 as deprecated
 
(36 intermediate revisions by 12 users not shown)
Line 17: Line 17:

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

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

// the following settings are used in this script:

// 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 (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 (notifyByDefaultDel == null) var notifyByDefaultDel = false; // whether to check the 'notify tagger' box by default when changing a speedy deletion rationale

Line 22: Line 23:

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

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 (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 (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 (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 = new Array(); // any addition speedy deletion reasons to add to the list

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



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

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

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

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 (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 (overwriteDeleteReasons == null) var overwriteDeleteReasons = false; // whether to overwrite the in-build delete reasons with the user defined ones

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

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 (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 (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!

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

//main script

function csdHelper() {

function isPageTagged() {

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

this.launch = function() {

}

// launch helper. check whether there is a deletion tag on this page.


if ((document.getElementById('delete-criterion') != null) || (document.body.innerHTML.indexOf('speedy deletion of this page is contested.') > -1)) {

function isPageContested() {

if (wgNamespaceNumber == 10) { return false; // do nothing!

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

} else {

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

// all checks OK :).

}

// launch controller.


this.control = new csdH_controller;


this.control.attachLinks();

function shouldDisplayCsdh() {

return true;

// Always exclude certain pages

}

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

} else { return false; /* do nothing!*/ }

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() {

function csdH_controller() {

csdHController = this;

csdHController = this;

Line 59: Line 78:

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

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)(?:-(?:.+?))?(?:\|(?:.+?))?\}\}[\s]*/gi;

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.hangonRegex = /[\s]*\{\{(?:hang|hold)(?: |-)?oo?n(?:\|.+?)?\}\}[\s]*/gi;

csdHController.doNotifyDec = ''; csdHController.doNotifyDel = ''; csdHController.doNotifyPrd = '';

csdHController.doNotifyDec = '';

csdHController.doNotifyDel = '';

csdHController.doNotifyPrd = '';


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

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

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

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

Line 68: Line 90:

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

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

if (waUser.isSysop == true) { csdHController.isSysop = 'yes'; csdHController.decAction = 'declined'; } else { csdHController.isSysop = 'no'; csdHController.decAction = 'contested'; }

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

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

Line 85: Line 113:

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

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

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

['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'],

['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'],

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

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

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

['A5', 'The article has not been transwikied to another project'],

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

['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 schools'],

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

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

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

['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'],

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

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

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

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

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

['R4', 'Not the same name as a [[WP:Wikimedia Commons|Commons]] file or redirect'],

['R4', 'Has incoming [[Wikipedia:File link|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'],

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

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

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

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

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

['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(

this.deleteReasons = new Array(

Line 116: Line 163:

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

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

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

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

['G11', 'Unambiguous [[WP:ADS|advertising]] or promotion'],

['G11', 'Unambiguous [[WP:PROMO|advertising]] or promotion'],

['G12', 'Unambiguous [[WP:C|copyright infringement]]'],

['G12', 'Unambiguous [[WP:C|copyright infringement]]'],

['G13', 'Rejectedorunsubmitted Articles for creation page that has not been edited in over six months'],

['G13', 'Abandoned Draftor[[WP:AFC|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'],

['G13', 'Redirects from [[Wikipedia:Articles for creation|AfC]] titles to mainspace articles created more than six months ago'],

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

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

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

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

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

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

['A5', 'Article that has been transwikied to another project'],

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

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

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

['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 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 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 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 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 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 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 indicate the importance or significance of the subject and where the artist has no article'],

['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'],

['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-[[WP:NS|namespace]] [[WP:R|redirect]] from mainspace'],

['R2', 'Cross-[[WP:NS|namespace]] [[WP:R|redirect]] from mainspace'],

['R3', 'Recently-created, implausible [[WP:R|redirect]]'],

['R3', 'Recently-created, implausible [[WP:R|redirect]]'],

['R4', 'File [[WP:R|redirect]] with no incoming [[Wikipedia:File link|file links]] and the same name as a file or redirect at [[WP:Wikimedia Commons|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 [[WP:FUR|non-free use rationale]]'],

['F7', '[[WP:NFCC|Invalid]] fair-use rationale'],

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

['F9', 'Media file [[WP:COPYVIO|copyright violation]] without credible claim of [[Wikipedia:Non-free content|fair use]] or permission'],

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

['C1', 'Empty category'],

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

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

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

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

['U3', '[[WP:NFC|Non-free]] [[Help:Gallery|gallery]]']

['U3', '[[WP:NFC|Non-free]] [[Help:Gallery|gallery]]'],

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

);

);


// Handle user defined content...

// Handle user defined content...

// declining

// declining

if (overwriteDeclineReasons == true) {

if (overwriteDeclineReasons == true) {

this.declineReasons.length = 0; this.declineReasons = myDeclineReasons;

this.declineReasons.length = 0;

this.declineReasons = myDeclineReasons;

} else {

} else {

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

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

}

}


// deleting

// deleting

if (overwriteDeleteReasons == true) {

if (overwriteDeleteReasons == true) {

this.deleteReasons.length = 0; this.deleteReasons = myDeleteReasons;

this.deleteReasons.length = 0;

this.deleteReasons = myDeleteReasons;

} else {

} else {

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

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

}

}


// append necessary options to decline reasons

// append necessary options to decline reasons

var declineReasonsEnd = new Array(

var declineReasonsEnd = new Array(

Line 167: Line 232:

// main GUI function

// GUI

function getStandardElements() {

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

return '';

}


let result =

'<div style="margin: auto; width: 80%; cursor: pointer; background: #dfdfdf; border: 1px solid #cfcfcf; height: 16px; margin-top: 20px;" onclick="csdHController.declinePage();" onmouseover="this.style.border = \'1px solid #333333\';" onmouseout="this.style.border = \'1px solid #cfcfcf\';">Decline Speedy</div>' +

'<div style="margin: auto; width: 80%; cursor: pointer; background: #dfdfdf; border: 1px solid #cfcfcf; height: 16px; margin-top: 5px;" onclick="csdHController.prodPage();" onmouseover="this.style.border = \'1px solid #333333\';" onmouseout="this.style.border = \'1px solid #cfcfcf\';">Change to PROD</div>' +

'';

return result;

}


function getSysopElements() {

if (!waUser.isSysop) {

return '';

}


let result =

'<div style="margin: auto; width: 95%; cursor: pointer; background: #dfdfdf; border: 1px solid #cfcfcf; height: 22px; margin-top: 20px;" onclick="csdHController.deletePage();" onmouseover="this.style.border = \'1px solid #333333\';" onmouseout="this.style.border = \'1px solid #cfcfcf\';">Delete Page</div>' +

'';


return result;

}


function getCoreElements() {

let result =

'<div>' +

'<div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">Handle Speedy Deletion</div>' +

'<div style="font-size: 11px; margin-left: 7px;">What do you want to do to this page?</div>' +

'<div style="font-size: 11px; text-align: center; width: 100%;">' +

getSysopElements() +

getStandardElements() +

'</div>' +

'</div>';


return result;

}


this.showcsdHWindow = function() {

this.showcsdHWindow = function() {

// grab position of button

// grab position of button

var offsetL = 0, offsetT = 0, thisObject = document.getElementById('ca-speedy');

var offsetL = 0;

var offsetT = 0;

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

if ( thisObject.offsetParent ) {

if (thisObject.offsetParent) {

do {

do {

offsetL += thisObject.offsetLeft;

offsetL += thisObject.offsetLeft;

offsetT += thisObject.offsetTop;

offsetT += thisObject.offsetTop;

} while ( thisObject = thisObject.offsetParent );

} while (thisObject = thisObject.offsetParent);

}

}

// build window to show user

// build window to show user

if (waUser.isSysop == true) { var showSys = '<div style="margin: auto; width: 95%; cursor: pointer; background: #dfdfdf; border: 1px solid #cfcfcf; height: 22px; margin-top: 20px;" onclick="csdHController.deletePage();" onmouseover="this.style.border = \'1px solid #333333\';" onmouseout="this.style.border = \'1px solid #cfcfcf\';">Delete Page</div>' } else { var showSys = ''; }

if (this.interface == null) {

if (this.interface == null) {

this.interface = new wa_window(document.getElementById('content')); this.visible = true; this.csdHelperLink.ele_obj.setAttribute('class', 'selected');

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

this.visible = true;

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


this.interface.win_content = ''+

this.interface.win_content = getCoreElements();

'<div><div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">Handle Speedy Deletion</div>'+

'<div style="font-size: 11px; margin-left: 7px;">What do you want to do to this page?</div>'+

'<div style="font-size: 11px; text-align: center; width: 100%;">'+

showSys+

'<div style="margin: auto; width: 80%; cursor: pointer; background: #dfdfdf; border: 1px solid #cfcfcf; height: 16px; margin-top: 20px;" onclick="csdHController.declinePage();" onmouseover="this.style.border = \'1px solid #333333\';" onmouseout="this.style.border = \'1px solid #cfcfcf\';">Decline Speedy</div>'+

'<div style="margin: auto; width: 80%; cursor: pointer; background: #dfdfdf; border: 1px solid #cfcfcf; height: 16px; margin-top: 5px;" onclick="csdHController.prodPage();" onmouseover="this.style.border = \'1px solid #333333\';" onmouseout="this.style.border = \'1px solid #cfcfcf\';">Change to PROD</div>'+

'</div>'+

'';

} else {

} else {

this.interface.win_content = ''+

this.interface.win_content = getCoreElements();

'<div><div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">Handle Speedy Deletion</div>'+

'<div style="font-size: 11px; margin-left: 7px;">What do you want to do to this page?</div>'+

'<div style="font-size: 11px; text-align: center; width: 100%;">'+

showSys+

'<div style="margin: auto; width: 80%; cursor: pointer; background: #dfdfdf; border: 1px solid #cfcfcf; height: 16px; margin-top: 20px;" onclick="csdHController.declinePage();" onmouseover="this.style.border = \'1px solid #333333\';" onmouseout="this.style.border = \'1px solid #cfcfcf\';">Decline Speedy</div>'+

'<div style="margin: auto; width: 80%; cursor: pointer; background: #dfdfdf; border: 1px solid #cfcfcf; height: 16px; margin-top: 5px;" onclick="csdHController.prodPage();" onmouseover="this.style.border = \'1px solid #333333\';" onmouseout="this.style.border = \'1px solid #cfcfcf\';">Change to PROD</div>'+

'</div>'+

'';

if (this.visible == true) {

if (this.visible == true) {

Line 315: Line 407:

csdHController.pageReq = new wa_mediawikiApi();

csdHController.pageReq = new wa_mediawikiApi();

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

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

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

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

break;

break;

Line 332: Line 424:

csdHController.editReq = new wa_mediawikiApi();

csdHController.editReq = new wa_mediawikiApi();

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

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

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

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

break;

break;

Line 341: Line 433:

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

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

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

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

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

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

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

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

Line 350: Line 443:

while (k != null) {

while (k != null) {

k = regTest.exec(thisPage);

k = regTest.exec(thisPage);

if (k != null) count ++;

if (k != null) count++;

}

}

regTest.lastIndex = 0;

regTest.lastIndex = 0;

Line 364: Line 457:

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

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

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

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

if (csdHController.tagger == csdHController.notifyExempt[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.<br />';

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

Line 401: Line 494:

// message

// message

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

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

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

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

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

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

Line 410: Line 503:

// build vars

// build vars

var editSummary = 'Adding [[' + pageName + ']] to speedy decline log ([[User:Ale_jrb/Scripts|CSDH]])';

var editSummary = 'Adding [[:' + pageName + ']] to speedy decline log ([[User:Ale_jrb/Scripts|CSDH]])';

// perform the edit

// perform the edit

Line 438: Line 531:

// message

// message

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

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 = new wa_mediawikiApi();

Line 492: Line 585:

csdHController.pageReq = new wa_mediawikiApi();

csdHController.pageReq = new wa_mediawikiApi();

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

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

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

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

} else {

} else {

csdHController.pageReq = new wa_mediawikiApi();

csdHController.pageReq = new wa_mediawikiApi();

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

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

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

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

}

}

break;

break;

Line 503: Line 596:

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

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

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

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

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

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

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

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

Line 547: Line 642:

// message

// message

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

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 = new wa_mediawikiApi();

Line 573: Line 668:

csdHController.editReq = new wa_mediawikiApi();

csdHController.editReq = new wa_mediawikiApi();

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

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

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

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

break;

break;

}

}

Line 648: Line 743:

csdHController.pageReq = new wa_mediawikiApi();

csdHController.pageReq = new wa_mediawikiApi();

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

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

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

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

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

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

break;

break;

Line 655: Line 750:

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

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

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

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

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

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

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

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

Line 699: Line 796:

// message

// message

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

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 = new wa_mediawikiApi();

Line 713: Line 810:

csdHController.deleteReq = new wa_mediawikiApi();

csdHController.deleteReq = new wa_mediawikiApi();

csdHController.deleteReq.onCompleteAction = function(callback) {

csdHController.deleteReq.onCompleteAction = function(callback) {

if ( (callback == null) || (callback == false) || (wgNamespaceNumber != 0) ) { // no talk page

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

// No talk page

if (csdhDoRedirect) {

window.location = redirectAfterDel; csdHController.showcsdHWindow();

window.location = redirectAfterDel;

} else { // talk page exists

} else {

csdHController.talkpageId = callback;

window.location.reload(true);

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

}

'<strong>Warning: this page now has an orphaned talk page. Do you wish to delete it under G8?</strong><br /><br />'+

csdHController.showcsdHWindow();

'<div style="width: 100%; text-align: center;"><a href="#" onclick="document.getElementById(\'workingStatus\').innerHTML = \'- Deleting talk page...<br />\'; csdHController.deleteDo(\'4\');">Delete</a> | <a href="#" onclick="window.location = redirectAfterDel; csdHController.showcsdHWindow(); ">Ignore</a></div>'+

} else {

'';

}

// Talk page exists

csdHController.talkpageId = callback;

};

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

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

'<strong>Warning: this page now has an orphaned talk page. Do you wish to delete it under G8?</strong><br /><br />'+

'<div style="width: 100%; text-align: center;"><a href="#" onclick="document.getElementById(\'workingStatus\').innerHTML = \'- Deleting talk page...<br />\'; csdHController.deleteDo(\'4\');">Delete</a> | <a href="#" onclick="window.location = redirectAfterDel; csdHController.showcsdHWindow(); ">Ignore</a></div>'+

'';

}

};

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

break;

break;

case '4':

case '4':

// delete the talk page - get the title

// delete the talk page - get the title

var talkPage = 'Talk:' + wgPageName;

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

csdHController.deleteReq = new wa_mediawikiApi();

csdHController.deleteReq = new wa_mediawikiApi();

Line 746: Line 850:

this.attachLinks = function() {

this.attachLinks = function() {

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

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

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

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

Line 765: Line 867:


// -- run program

// -- run program

function launchCsdHelper () {

function launchCsdHelper() {

// lib proto

// lib proto

wa_window.prototype = new wa_document;

wa_window.prototype = new wa_document;

wa_element.prototype = new wa_document;

wa_element.prototype = new wa_document;

// init object

// run

launchCsdh();

var obj_csdHelper = new csdHelper;

obj_csdHelper.launch ();

return true;

}

}



importScript ( 'User:Ale_jrb/Scripts/waLib.js' );

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

hookEvent ( 'load', launchCsdHelper );

$(document).ready(launchCsdHelper);

});


Latest revision as of 14:15, 13 February 2023

/* ============================================== *\
** 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 [[WP:Wikimedia Commons|Commons]] file or redirect'],
          ['R4',   'Has incoming [[Wikipedia:File link|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'],
          
          ['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',   '[[WP:PN|Patent nonsense]], meaningless, or incomprehensible'],
          ['G2',   'Test page'],
          ['G3',   '[[WP:VANDAL|Vandalism]]'],
          ['G3',   '[[WP:VANDAL|Vandalism]] - blatant hoax or misinformation'],
          ['G4',   'Recreation of a page that was [[WP:DEL|deleted]] per a [[WP:XFD|deletion discussion]]'],
          ['G5',   'Creation by a [[WP:BAN|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',  '[[WP:ATP|Attack page]] or negative unsourced [[WP:BLP|BLP]] that serves no purpose but to threaten or disparage its subject'],
          ['G11',  'Unambiguous [[WP:PROMO|advertising]] or promotion'],
          ['G12',  'Unambiguous [[WP:C|copyright infringement]]'],
          ['G13',  'Abandoned Draft or [[WP:AFC|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-[[WP:NS|namespace]] [[WP:R|redirect]] from mainspace'],
          ['R3',   'Recently-created, implausible [[WP:R|redirect]]'],
          ['R4',   'File [[WP:R|redirect]] with no incoming [[Wikipedia:File link|file links]] and the same name as a file or redirect at [[WP:Wikimedia Commons|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 [[WP:FUR|non-free use rationale]]'],
          ['F7',  '[[WP:NFCC|Invalid]] fair-use rationale'],
          ['F8',  'Media file available on Commons'],
          ['F9',  'Media file [[WP:COPYVIO|copyright violation]] without credible claim of [[Wikipedia:Non-free content|fair use]] or permission'],
          ['F11',  'No evidence of permission for more than 7 days'],
          
          ['C1',  'Empty category'],
          
          ['U1',   'User request to delete pages in own userspace'],
          ['U2',   'Userpage or subpage of a nonexistent user'],
          ['U3',   '[[WP:NFC|Non-free]] [[Help:Gallery|gallery]]'],
          ['U5',      'Blatant use of [[WP:NOTWEBHOST|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 [[WP:CSD|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 =
   '<div style="margin: auto; width: 80%; cursor: pointer; background: #dfdfdf; border: 1px solid #cfcfcf; height: 16px; margin-top: 20px;" onclick="csdHController.declinePage();" onmouseover="this.style.border = \'1px solid #333333\';" onmouseout="this.style.border = \'1px solid #cfcfcf\';">Decline Speedy</div>' +
   '<div style="margin: auto; width: 80%; cursor: pointer; background: #dfdfdf; border: 1px solid #cfcfcf; height: 16px; margin-top:  5px;" onclick="csdHController.prodPage();" onmouseover="this.style.border = \'1px solid #333333\';" onmouseout="this.style.border = \'1px solid #cfcfcf\';">Change to PROD</div>' +
   '';
  
  return result;
 }

 function getSysopElements() {
  if (!waUser.isSysop) {
   return '';
  }

  let result =
   '<div style="margin: auto; width: 95%; cursor: pointer; background: #dfdfdf; border: 1px solid #cfcfcf; height: 22px; margin-top: 20px;" onclick="csdHController.deletePage();" onmouseover="this.style.border = \'1px solid #333333\';" onmouseout="this.style.border = \'1px solid #cfcfcf\';">Delete Page</div>' +
   '';

  return result;
 }

 function getCoreElements() {
  let result =
   '<div>' +
    '<div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">Handle Speedy Deletion</div>' +
    '<div style="font-size: 11px; margin-left: 7px;">What do you want to do to this page?</div>' +
    '<div style="font-size: 11px; text-align: center; width: 100%;">' +
     getSysopElements() +
     getStandardElements() +
    '</div>' +
   '</div>';

  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 += '<option'+selected+'>'+tempVisible+'</option>';
  }
  
  if ( mw.config.get ( 'skin' ) == 'vector' ) { var skinPos = '3'; } else { var skinPos = '10'; }
  this.interface.win_content = ''+
        '<div><div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">Decline Speedy Deletion</div>'+
        '<div style="font-size: 11px; margin-left: 7px; padding: 0px;">Select the reason for declining the deletion from the list. This text will be used as the edit summary.</div>'+
        '<select id="declineReason" style="font-size: 11px; margin-left: 9px;" onchange="document.getElementById(\'declineText\').value = \'\'">'+declineOptions+'</select>'+
        '<div style="font-size: 11px; margin-left: 7px; margin-top: 8px; padding: 0px;">Or provide your own reason and summary below.</div>'+
        '<input id="declineText" style="margin-left: 9px; font-size: 11px; width: 576px;" type="text" onkeyup="document.getElementById(\'declineReason\').selectedIndex = csdHController.declineReasons.length-1;" />'+
        '<div style="margin-top: 13px; float: right; margin-right: 300px; font-size: 11px; ">-- <a href="#" onclick="csdHController.declineDo();">decline speedy deletion</a> --</div>'+
        '<div style="margin-top: '+skinPos+'px; font-size: 11px; margin-left: 20px; vertical-align: middle; padding: 0px;">notify tagger <input id="notifyTagger"'+csdHController.doNotifyDec+' style="position: relative; top: 3px; " type="checkbox" /></div>'+
        '<div style="margin-top: '+skinPos+'px; font-size: 11px; margin-left: 20px; vertical-align: middle; padding: 0px;">use newbie message <input id="notifyNewbie"'+csdHController.doNotifyNew+' style="position: relative; top: 3px; " type="checkbox" /></div>'+
        '</div>'+
        '';
  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 += ' ([[User:Ale_jrb/Scripts|CSDH]])';
    
    // start
    this.interface.win_content = ''+
        '<div><div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">Working...</div>'+
        '<div style="font-size: 11px; margin-left: 7px;">Please wait while CSDHelper performs the requested operations. This can take several seconds.</div>'+
        '<div id="workingStatus" style="font-size: 11px; margin-left: 15px;">- Retrieving existing content...<br /></div>'+
        '</div>'+
        '';
    
    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...<br />';
    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...<br />';
    
    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...<br />';
     
     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.<br />'; 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.<br />';
       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...<br />';
    //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 + "]] || [[User:" + csdHController.tagger + "|" + csdHController.tagger + "]] || [[WP:CSD#" + crit + "|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 ([[User:Ale_jrb/Scripts|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...<br />';
   
    // edit summary
    csdHController.editSummary = 'Notifying about '+csdHController.decAction+' speedy deletion ([[User:Ale_jrb/Scripts|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> <i>For valid criteria,/i
  var rationale = regTest.exec(content);
  if (rationale != null) { rationale = rationale[1]; } else { rationale = ''; }
  
  this.interface.win_content = ''+
        '<div><div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">Convert to PROD</div>'+
        '<div style="font-size: 11px; margin-left: 7px;">You are asserting that the page cannot be speedy deleted, but <em>can</em> be deleted by proposed deletion. '+
        'Enter the reason for deletion below - if the tagger provided one, it will be filled automatically.</div>'+
        '<input id="prodReason" style="margin-left: 9px; font-size: 11px; width: 576px;" type="text" value="'+rationale+'" />'+
        '<div id="notifyTaggerDiv" style="margin-top: 10px; font-size: 11px; margin-left: 20px; float: left; vertical-align: middle;">notify tagger of conversion <input id="notifyTagger"'+csdHController.doNotifyPrd+' style="position: relative; top: 3px; " type="checkbox" /><br />'+
        'use newbie message <input id="notifyNewbie"'+csdHController.doNotifyNew+' style="position: relative; top: 3px; " type="checkbox" /></div>'+
        '<div style="margin: auto; margin-top: 13px; font-size: 11px; width: 200px; text-align: center;">-- <a href="#" onclick="csdHController.prodDo();">convert to PROD</a> --</div>'+
        '</div>'+
        '';
  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 = ''+
        '<div><div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">Working...</div>'+
        '<div style="font-size: 11px; margin-left: 7px;">Please wait while CSDHelper performs the requested operations. This can take several seconds.</div>'+
        '<div id="workingStatus" style="font-size: 11px; margin-left: 15px;"></div>'+
        '</div>'+
        '';
    
    this.interface.applyAll();
   
    if (csdHController.prodNotify == true) {
     document.getElementById('workingStatus').innerHTML += '- Searching for tagger...<br />';
     
     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...<br />'; 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...<br />';
      csdHController.prodDo('3');
      return true;
     }
    }
    
    csdHController.prodDo('2');
    break;
    
   case '2': // notify tagger
    document.getElementById('workingStatus').innerHTML += '- Tagged by \''+csdHController.tagger+'\' - notifying user...<br />';
   
    // edit summary
    csdHController.editSummary = 'Notifying about speedy deletion converted to PROD ([[User:Ale_jrb/Scripts|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...<br />';
    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 ([[User:Ale_jrb/Scripts|CSDH]])';
    
    document.getElementById('workingStatus').innerHTML += '- Updating page...<br />';
    
    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 += '<option value="'+i+'"'+selected+'>'+this.deleteReasons[i][0]+': '+visibleReasoning+'</option>';
  }
  
  if (document.getElementById('delete-criterion') == null) { var displayTagCommand = 'display: none;'; } else { var displayTagCommand = 'display: block;'; }
  
  this.interface.win_content = ''+
        '<div><div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">Perform Speedy Deletion</div>'+
        '<div style="font-size: 11px; margin-left: 7px;">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.</div>'+
        '<select id="deleteReason" style="font-size: 11px; margin-left: 9px; width: 576px;" onchange="'+
         'if (document.getElementById(\'delete-criterion\') != null) {'+
          'if (csdHController.deleteReasons[document.getElementById(\'deleteReason\').selectedIndex][0] != document.getElementById(\'delete-criterion\').innerHTML) { '+
           'if (csdHController.deleteReasons[document.getElementById(\'deleteReason\').selectedIndex][0] == \'N/A\') { document.getElementById(\'notifyTaggerDiv\').style.display = \'none\'; } else { document.getElementById(\'notifyTaggerDiv\').style.display = \'block\'; }'+
          '} else {'+
           'document.getElementById(\'notifyTaggerDiv\').style.display = \'none\'; '+
          '}'+
         '} else { document.getElementById(\'notifyTaggerDiv\').style.display = \'none\'; }'+
         
         'if (csdHController.deleteReasons[document.getElementById(\'deleteReason\').selectedIndex][0] == \'N/A\') {'+
          'document.getElementById(\'performDeletionDiv\').style.display = \'none\'; '+
         '} else {'+
          'document.getElementById(\'performDeletionDiv\').style.display = \'block\'; '+
         '}'+
        '">'+deleteOptions+'</select>'+
        '<div id="notifyTaggerDiv" style="display: none; margin-top: 10px; font-size: 11px; margin-left: 20px; float: left; vertical-align: middle;">notify tagger of rationale change <input id="notifyTagger"'+csdHController.doNotifyDel+' style="position: relative; top: 3px; " type="checkbox" /><br />'+
        'use newbie message <input id="notifyNewbie"'+csdHController.doNotifyNew+' style="position: relative; top: 3px; " type="checkbox" /></div>'+
        '<div id="performDeletionDiv" style="margin: auto; margin-top: 13px; font-size: 11px; width: 200px; text-align: center; '+displayTagCommand+'">-- <a href="#" onclick="csdHController.deleteDo();">perform speedy deletion</a> --</div>'+
        '</div>'+
        '';
  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 = ''+
        '<div><div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">Working...</div>'+
        '<div style="font-size: 11px; margin-left: 7px;">Please wait while CSDHelper performs the requested operations. This can take several seconds.</div>'+
        '<div id="workingStatus" style="font-size: 11px; margin-left: 15px;"></div>'+
        '</div>'+
        '';
    
    this.interface.applyAll();
   
    if ((csdHController.deleteNotify == true) && (csdHController.allowDelNotify == true)) {
     document.getElementById('workingStatus').innerHTML += '- Searching for tagger...<br />';
     
     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...<br />'; 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...<br />';
      csdHController.deleteDo('3');
      return true;
     }
    }
    
    csdHController.deleteDo('2');
    break;
    
   case '2': // notify tagger
    document.getElementById('workingStatus').innerHTML += '- Tagged by \''+csdHController.tagger+'\' - notifying user...<br />';
   
    // edit summary
    csdHController.editSummary = 'Notifying about altered speedy deletion rationale ([[User:Ale_jrb/Scripts|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...<br />';
    var deleteReason = '[[WP:CSD#'+csdHController.deleteReasons[csdHController.deleteSel][0]+'|'+csdHController.deleteReasons[csdHController.deleteSel][0]+']]: ' + csdHController.deleteReasons[csdHController.deleteSel][1] + ' ([[User:Ale_jrb/Scripts|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 = ''+
       '<strong>Warning: this page now has an orphaned talk page. Do you wish to delete it under G8?</strong><br /><br />'+
       '<div style="width: 100%; text-align: center;"><a href="#" onclick="document.getElementById(\'workingStatus\').innerHTML = \'- Deleting talk page...<br />\'; csdHController.deleteDo(\'4\');">Delete</a> | <a href="#" onclick="window.location = redirectAfterDel; csdHController.showcsdHWindow(); ">Ignore</a></div>'+
      '';
     }
    };
    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, '[[WP:CSD#G8|G8]]: Talk page of deleted page. ([[User:Ale_jrb/Scripts|CSDH]])');
    break;
  }
 }
 
 this.displayError = function() {
  this.interface.win_content = ''+
        '<div><div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">An error occurred...</div>'+
        '</div>'+
        '';
  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 = '<span><a href="#" title="handle speedy deletion">Speedy</a></span>';
   this.csdHelperLink.attach(document.getElementById('ca-talk'), 'after');
  } else {
   this.csdHelperLink.ele_obj.innerHTML = '<a href="#" title="handle speedy deletion">speedy</a>';
   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);
});

Retrieved from "https://en.wikipedia.org/w/index.php?title=User:Ale_jrb/Scripts/csdhelper.js&oldid=1139126287"





This page was last edited on 13 February 2023, at 14:15 (UTC).

Text is available under the Creative Commons Attribution-ShareAlike License 4.0; additional terms may apply. By using this site, you agree to the Terms of Use and Privacy Policy. Wikipedia® is a registered trademark of the Wikimedia Foundation, Inc., a non-profit organization.



Privacy policy

About Wikipedia

Disclaimers

Contact Wikipedia

Code of Conduct

Developers

Statistics

Cookie statement

Mobile view



Wikimedia Foundation
Powered by MediaWiki