User:Evad37/FFDcloser.js and User:Evad37/FFDcloser/sandbox.js: Difference between pages

(Difference between pages)
Page 1
Page 2
Content deleted Content added
Remove functionality, superseded by XFDcloser (WP:XFDC). Source code remains available through the page history.
Tag: Replaced
 
m Fix requested on WP:IANB
 
Line 1: Line 1:
// <nowiki>
/*
//global vars
This script has been superseded by XFDcloser ([[WP:XFDC]]). Please use that script instead:
var FFDpath = "Wikipedia:Files for discussion/";
https://en.wikipedia.org/wiki/User:Evad37/XFDcloser


/* == Main function == */
This page is kept so that the source code remains available through page history:
$( function($) {
https://en.wikipedia.org/w/index.php?title=User:Evad37/FFDcloser.js&action=history

*/
// Only run in FFD/subpages
var thispage = mw.config.get( 'wgPageName' );
if ( !thispage.includes("Files_for_discussion") ) {
return;
}

$.getScript('https://en.wikipedia.org/w/index.php?title=User:Evad37/XFDcloserCommon.js&action=raw&ctype=text/javascript', function () {
// Make sure [[User:Evad37/XFDcloserCommon.js]] is loaded!

setSysopStatus();

/* ##### Sandbox usage only (remove when updating main script) ##### */
if ( mw.config.get("wgUserName") === "Evad37" ) {
isSysop = true;
console.log("isSysop: " + isSysop);
FFDpath = "User:Evad37/sandbox/Files for discussion/";
}
/* ##### End of sandbox usage only (remove when updating main script) ##### */

// Add links to actions
$("h4 > span.mw-headline ").each(function( index ) {
$(".mw-headline-number", this).prependTo($(this).parent()); //fix for "Auto-number headings" preference
var file = $(":first-child", this).text();
if (!file) { // section header wasn't a link
file = $(this).text();
$(this).wrapInner("<span></span>"); // wrap with span so it can be styled later
}
var filee = mw.util.wikiUrlencode(file); // "pretty"-encoded

//Check if already closed
var discussion_element_class = $(this).parent().next().attr("class");
if ( discussion_element_class ) { //only closed discussion have element with any class set
$(this).parent().addClass("boilerplate ffd vfd xfd-closed"); //add classes to enable hiding of closed section headers
} else {
var sectionlink = $(this).next().find("a").not(".mw-editsection-visualeditor").attr('href');
var editsection = sectionlink.split("section=")[1];
if ( editsection.search("T")<0 ) { //if true, we're on the subpage
nom_page = thispage;
} else { //if false, section is transcluded from a subpage
nom_page = sectionlink.split("title=")[1].split("&")[0];
editsection = editsection.substr(2); //remove "T-" from section number
}

//Check for collapsed list, and pop out a non-visible copy if found
var $collapsedlist = $(this).parent().next().next().find("dl");
if ($collapsedlist.length > 0) {
$collapsedlistitems = $collapsedlist.children().clone();
$collapsedlistitems.css( "display", "none" )
$(this).parent().next().append( $collapsedlistitems ).after( "<span style='font-size:85%;padding-left:1em;'>&thinsp;... collapsed list detected (" + $collapsedlistitems.length + " files)</span>" );
}

//Fix for linebreaks between list items
var $siblinglists = $(this).parent().next().nextUntil("p, h4", "dl");
if ($siblinglists.length > 0) {
$siblinglistsitems = $siblinglists.children().clone();
$siblinglistsitems.css( "display", "none" )
$(this).parent().next().append( $siblinglistsitems);
}

//Check if this is a multi-file dicussion
var $fileslist = $(this).parent().next().children(); //<dd> elements
var $filesspans = $(":first-child", $fileslist); //1st <span> of each <dd>
var $files = $(":first-child", $filesspans).text();
var files = $files.split("File:").slice(1);
var closing_options;
if ( files.length > 1) {
//This is a multi-discussion
files_e = files.map(function(fname) {
var f = "File:" + fname;
var fe = mw.util.wikiUrlencode(f).replace(/,/g,"__COMMA__"); //"pretty"-encode, then encode commas encoded as __COMMA__
return fe;
});
//console.log( files_e );
closing_options = "Closing options: " +
"<span style='margin-left:5px;'>[<a style='cursor:pointer;' onclick=multi_process_close_ffd('" + files_e + "','" + nom_page + "','" + filee + "','" + editsection + "','" + "Delete" + "','" + "delete" + "') title='QuickDelete'>qDel</a>]</span>" +
"<span style='margin-left:13px;'>[<a style='cursor:pointer;' onclick=multi_close_ffd('" + files_e + "','" + nom_page + "','" + filee + "','" + editsection + "','" + "delete" + "') title='Delete with comments'>Delete</a>]</span>" +
"<span style='margin-left:13px;'>[<a style='cursor:pointer;' onclick=multi_process_close_ffd('" + files_e + "','" + nom_page + "','" + filee + "','" + editsection + "','" + "Keep" + "','" + "keep" + "') title='quickKeep'>qKeep</a>]</span>" +
"<span style='margin-left:13px;'>[<a style='cursor:pointer;' onclick=multi_close_ffd('" + files_e + "','" + nom_page + "','" + filee + "','" + editsection + "','" + "other" + "') title='Other close with comments'>Other close</a>]</span>" +
"<span style='margin-left:13px;'>[<a style='cursor:pointer;' onclick=multi_close_ffd('" + files_e + "','" + nom_page + "','" + filee + "','" + editsection + "','" + "relist" + "') title='Relist discussion'>Relist</a>]</span>";

} else if (!checkNS(file, 6)) {
//sanity check
filee = mw.util.wikiUrlencode($(this).html().replace(/<[^>]*>/g,"")); //this is actually the section header
closing_options = "No files detected. <span style='margin-left:13px;'>[<a style='cursor:pointer;' onclick=multi_close_ffd('" + filee + "','" + nom_page + "','" + filee + "','" + editsection + "','" + "close_only" + "') title='Close with comments'>Close</a>]</span>";

} else {
//not a multi-discussion
closing_options = "Closing options: " +
"<span style='margin-left:5px;'>[<a style='cursor:pointer;' onclick=multi_process_close_ffd('" + filee + "','" + nom_page + "'," + null + ",'" + editsection + "','" + "Delete" + "','" + "delete" + "') title='QuickDelete'>qDel</a>]</span>" +
"<span style='margin-left:13px;'>[<a style='cursor:pointer;' onclick=close_ffd('" + filee + "','" + nom_page + "','" + editsection + "','" + "delete" + "') title='Delete with comments'>Delete</a>]</span>" +
"<span style='margin-left:13px;'>[<a style='cursor:pointer;' onclick=multi_process_close_ffd('" + filee + "','" + nom_page + "'," + null + ",'" + editsection + "','" + "Keep" + "','" + "keep" + "') title='quickKeep'>qKeep</a>]</span>" +
"<span style='margin-left:13px;'>[<a style='cursor:pointer;' onclick=close_ffd('" + filee + "','" + nom_page + "','" + editsection + "','" + "other" + "') title='Other close with comments'>Other close</a>]</span>" +
"<span style='margin-left:13px;'>[<a style='cursor:pointer;' onclick=close_ffd('" + filee + "','" + nom_page + "','" + editsection + "','" + "relist" + "') title='Relist discussion'>Relist</a>]</span>";
}
$(this).append("<span id=XFDClosing_" + filee + " style='font-size:85%;margin-left:13px;font-weight:normal;'>" + closing_options + "</span>");
}
});
});

});

/* == Close FFD section (prompting for RESULT commment) == */

//Get comment
function close_ffd(_filename, _pagetitle, _sectionnum, _action) {
var prompt_text;
if ( _action === "relist" ) {
prompt_text = "Enter relist comment (optional)";
} else {
prompt_text = "Enter result and comment";
}
var result_comment = prompt(prompt_text);
if ( result_comment !== null ) {
multi_process_close_ffd(_filename, _pagetitle, null, _sectionnum, result_comment, _action);
}
}

/* -- Close mulit-FFD section (prompting for RESULT commment) -- */
//Get comment
function multi_close_ffd(_filearray, _pagetitle, _sectionheader, _sectionnum, _action) {
var prompt_text;
if ( _action === "relist" ) {
prompt_text = "Enter relist comment (optional)";
} else {
prompt_text = "Enter result and comment";
}
var result_comment = prompt(prompt_text);
if ( result_comment !== null ) {
multi_process_close_ffd(_filearray, _pagetitle, _sectionheader, _sectionnum, result_comment, _action);
}
}


/* == Multi-Process close == */
function multi_process_close_ffd(filename, pagetitle, sectionheader, sectionnum, resultcomment, action) {

//-Wikitext used for close
var editsum_file_or_section, file_or_null, _anchor, ffd_close_top, ffd_close_bottom, ffd_close_editsum;
if (sectionheader) {
editsum_file_or_section = "\"" + sectionheader + "\"";
file_or_null = null;
_anchor = sectionheader;
} else {
editsum_file_or_section = "for [[:" + filename + "]]";
file_or_null = filename;
_anchor = filename;
}

// Wikitext used for close
if (isSysop) {
sig = "~~" + "~~";
} else {
sig = "<small>[[Wikipedia:NACD|(non-admin closure)]]</small> ~~" + "~~";
}
// Figure out if/where bold markup should be added
var bolding_info = adjustCommentBolding(resultcomment);
var bold1 = bolding_info[0];
var bold2 = bolding_info[1];
resultcomment = bolding_info[2];

//reset msg_array, deliver started message
//msg_array = [];
//console.log("_anchor = " + _anchor);
deliverMsg( _anchor, "Started closing...", "working" );

if (action == "relist") {
//get today's date
var d = new Date();
var mmm = getMonthName(d.getUTCMonth());
todays_subpage = d.getUTCFullYear() + " " + mmm + " " + d.getUTCDate();
ffd_close_top = "{" + "{subst:ffd top|'''Relisted'''}" + "} on [[" + FFDpath + todays_subpage + "#" + _anchor + "]]}" + "}";
ffd_close_bottom = "{" + "{subst:ffd bottom}" + "}";
ffd_close_editsum = "Closing discussion " + editsum_file_or_section + " as relisted on [[" + FFDpath + todays_subpage + "#" + _anchor + "|" + todays_subpage + "]] (using [[User:Evad37/FFDcloser|FFDcloser]])";
} else {
ffd_close_top = "{" + "{subst:ffd top|" + bold1 + resultcomment + bold2 + "}" + "} " + sig;
ffd_close_bottom = "{" + "{subst:ffd bottom}" + "}";
ffd_close_editsum = "Closing discussion " + editsum_file_or_section + " as " + resultcomment + " (using [[User:Evad37/FFDcloser|FFDcloser]])";
}

//-Get page content and remove {Closing} template if present
new mw.Api().get( {
action: 'query',
titles: pagetitle,
prop: [ 'revisions', 'info' ],
rvprop: 'content',
indexpageids: 1,
rawcontinue: ''
} ).done( function( result, jqXHR ) {
var p_id = result.query.pageids;
var p_contents = result.query.pages[ p_id ].revisions[ 0 ][ '*' ];
var sections_array = p_contents.split("====");
var section_heading = sections_array[((sectionnum-1)*2-1)];
var section_contents = sections_array[((sectionnum-1)*2)].replace(/{{closing}}/gi, "");
var updated_section = "====" + section_heading + "====" + "\n" + ffd_close_top + section_contents + ffd_close_bottom;

//Add relisted discusssions to current day's FFD page
if (action == "relist") {
var ffdlinks = section_contents.match(/^:<span class="plainlinks nourlexpansion lx"[^\n]*/gim).join("\n");
if ( ffdlinks ) {
updated_section = "====" + section_heading + "====" + "\n" + ffd_close_top + "\n" + ffdlinks + ffd_close_bottom;
} else {
updated_section = "====" + section_heading + "====" + "\n" + ffd_close_top + ffd_close_bottom;
}
deliverMsg( _anchor, "Adding discussion to today's FFD subpage...", "working" );
var old_disc = "====" + section_heading + "====" + "\n" + section_contents.replace(/^\n+/,"");
relist_disc(file_or_null, old_disc, resultcomment, todays_subpage, sectionheader, _anchor);
} else {
updated_section = "====" + section_heading + "====" + "\n" + ffd_close_top + section_contents + ffd_close_bottom;
}

//-Perform edit to close FFD discussion
new mw.Api().postWithToken( 'edit', {
action: 'edit',
title: pagetitle,
section: sectionnum,
text: updated_section,
summary: ffd_close_editsum
} ).done( function( result, jqXHR ) {

//-If successful, mark as closed & move onto next actions (deletes, or update ffd's if relisted, or do old ffd housekeepings)
var file_array, i, ii, last_one;
if (sectionheader) {
file_array = filename.split(","); // filename is a csv string (multiple items)
for (i = 0; i < file_array.length; i++) {
file_array[i] = decodeURIComponent(file_array[i]).replace(/__COMMA__/g,","); //unencode commas from __COMMA__
}
} else {
file_array = [decodeURIComponent(filename)]; // filename is a string (single item)
}
var file_array_length = file_array.length;

if ( action == "delete" ) {
//Delete:
markClosed(_anchor, resultcomment);
deliverMsg( _anchor, "Deleting...", "working" );
for (ii = 0; ii < file_array_length; ii++) {
if (ii == file_array_length-1) {
last_one = true;
} else {
last_one = false;
}
delete_file(file_array[ii], "["+"["+pagetitle+"#"+_anchor+"]"+"]", _anchor, last_one);
}

} else if ( action == "relist" ) {
//Relist:
markClosed(_anchor, "Relisted at <a href=//en.wikipedia.org/wiki/" + FFDpath.replace(/\s/g,"_") + todays_subpage.replace(/\s/g,"_") + "#" + _anchor +">" + FFDpath + todays_subpage + "#" + _anchor + "</a>", true);
deliverMsg( _anchor, "Adding discussion to today's FFD subpage...", "working" );
for (ii = 0; ii < file_array.length; ii++) {
if (ii == file_array_length-1) {
last_one = true;
} else {
last_one = false;
}
update_file_ffd(file_array[ii], todays_subpage, _anchor, last_one);
}

} else if ( action == "close_only" ) {
//Take no further action
markClosed(_anchor, resultcomment);
return;
} else {
//Keep,other:
markClosed(_anchor, resultcomment);
deliverMsg( _anchor, "Updating file description pages...", "working" );
for (ii = 0; ii < file_array_length; ii++) {
if (ii == file_array_length-1) {
last_one = true;
} else {
last_one = false;
}
make_old_ffd(file_array[ii], resultcomment, pagetitle, sectionheader, _anchor, last_one);
}
}
} ).fail( function( code, result ) {
var error_details = apifailed( code, result );
deliverMsg( _anchor, "Could not close discussion " + error_details, "error" );
} );

} ).fail( function( code, result ) {
var error_details = apifailed( code, result );
deliverMsg( _anchor, "Could not read contents of page " + pagetitle + "; could not close discussion " + error_details, "error" );
} );
}

/* == Old ffd housekeeping == */
function make_old_ffd(filename, resultcomment, ffdpage, sectionheader, anchor, lastfile) {

var page_param, nomdate, filetalkpage, oldffd_wikitext;

if ( !checkNS(filename, 6) ) {
deliverMsg( anchor, "\"" + filename + "\" is not in File: namespace, FFDcloser will not edit this page or its talk page", "error", lastfile, null, !lastfile);
return;
}

if (sectionheader) {
page_param = "|page=" + sectionheader;
} else {
page_param = "";
}

//Add oldffdfull template to file talk
nomdate = ffdpage.split("Files_for_discussion/")[1].replace(/_/gi," "); //unencode spaces from _
filetalkpage = filename.replace("File", "File_talk");
oldffd_wikitext = "{" + "{oldffdfull|date=" + nomdate + "|result='''" + resultcomment + "'''" + page_param + " }" + "}";

new mw.Api().postWithToken( 'edit', {
action: 'edit',
title: filetalkpage,
prependtext: oldffd_wikitext,
summary: "Old FFD – " + nomdate + ": " + resultcomment + " (using [[User:Evad37/FFDcloser|FFDcloser]])"
} ).done( function( result, jqXHR ) {
deliverMsg( anchor, "Updated " + filetalkpage, "is_done", null, null, true );

//Get file description page, remove ffd template
new mw.Api().get( {
action: 'query',
titles: filename,
prop: [ 'revisions', 'info' ],
rvprop: 'content',
indexpageids: 1,
rawcontinue: ''
} ).done( function( result, jqXHR ) {
// console.log(result);
var f_id = result.query.pageids;
var f_contents = result.query.pages[ f_id ].revisions[ 0 ][ '*' ];
var updated_filedesc = f_contents.replace(/{{ffd[^}}]*}}/gi, "");

//Perform edit to remove ffd template
new mw.Api().postWithToken( 'edit', {
action: 'edit',
title: filename,
text: updated_filedesc,
summary: "FFD closed as " + resultcomment + " (using [[User:Evad37/FFDcloser|FFDcloser]])"
} ).done( function( result, jqXHR ) {
deliverMsg( anchor, "Removed {{ffd}} from " + filename, "is_done", null, null, true );
if (lastfile === true) {
deliverMsg( anchor, null, null, true ); //remove working message
}
} ).fail( function( code, result ) {
var error_details = apifailed( code, result );
deliverMsg( anchor, "Could not remove {{ffd}} from " + filename + " " + error_details, "warning", null, null, true );
if (lastfile === true) {
deliverMsg( anchor, null, null, true ); //remove working message
}
} );

} ).fail( function( code, result ) {
var error_details = apifailed( code, result );
deliverMsg( anchor, filename + " not found; could not remove {{ffd}} " + error_details, "warning", null, null, true );
if (lastfile === true) {
deliverMsg( anchor, null, null, true ); //remove working message
}
} );

} ).fail( function( code, result ) {
var error_details = apifailed( code, result );
deliverMsg( anchor, "Could not edit " + filetalkpage + " " + error_details, "warning", null, null, true );
if (lastfile === true) {
deliverMsg( anchor, null, null, true ); //remove working message
}
} );

}


/* == Delete file == */
function delete_file(filename, thereason, anchor, lastfile) {
if ( !checkNS(filename, 6) ) {
deliverMsg( anchor, "\"" + filename + "\" is not in File: namespace, FFDcloser will not delete this page", "error", lastfile, null, !lastfile);
return;
}
new mw.Api().postWithToken( 'delete', {
action: 'delete',
title: filename,
reason: thereason,
} ).done( function( result, jqXHR ) {
deliverMsg( anchor, "Deleted " + filename, "deleted", null, null, true );
if (lastfile === true) {
deliverMsg( anchor, null, null, true ); //remove "Deleting..." message
}
} ).fail( function( code, result ) {
var error_details = apifailed( code, result );
deliverMsg( anchor, "Could not delete " + filename + " " + error_details, "warning", null, null, true );
if (lastfile === true) {
deliverMsg( anchor, null, null, true ); //remove "Deleting..." message
}
} );

}


/* == Relist discussion == */
function relist_disc(filename, discussion, relistcomment, todaysdate, sectionheader, anchor) {

var relist_editsum, relists, num_relists, rc_if_any, newdiscussion;

//Edit summary varies based on if sectionheader is defined or not
if ( sectionheader ) {
relist_editsum = "Relisting \"" + sectionheader + "\" (using [[User:Evad37/FFDcloser|FFDcloser]])";
} else {
relist_editsum = "Relisting [[:" + filename + "]] (using [[User:Evad37/FFDcloser|FFDcloser]])";
}

//Check for number of relists, append {relist} template
relists = discussion.match("[[Wikipedia:Deletion process#Relisting discussions|Relisted]]");
if ( relists ) {
num_relists = relists.length + 1;
} else {
num_relists = 1;
}
if ( relistcomment !== "" ) {
rc_if_any = relistcomment;
} else {
rc_if_any = "";
}
newdiscussion = discussion + "\n{" + "{subst:Relist|" + rc_if_any + "|" + num_relists + "}}\n";

//Can append to end of daily subpage
new mw.Api().postWithToken( 'edit', {
action: 'edit',
title: FFDpath + todaysdate,
appendtext: "\n" + newdiscussion,
summary: relist_editsum
} ).done( function( result, jqXHR ) {
window.open("//en.wikipedia.org/wiki/" + FFDpath + todaysdate, "ffdtoday");
} ).fail( function( code, result ) {
var error_details = apifailed( code, result );
deliverMsg( anchor, "Could not relist discussion " + error_details, "error", true );
} );

}


/* == Update file ffd template (after relisting) == */
function update_file_ffd(filename, today_subpage, anchor, lastfile) {
if ( !checkNS(filename, 6) ) {
deliverMsg( anchor, "\"" + filename + "\" is not in File: namespace, FFDcloser will not edit this page", "error", lastfile, null, !lastfile);
return;
}
new mw.Api().get( {
action: 'query',
titles: filename,
prop: [ 'revisions', 'info' ],
rvprop: 'content',
indexpageids: 1,
rawcontinue: ''
} ).done( function( result, jqXHR ) {
var file_id = result.query.pageids;
var file_contents = result.query.pages[ file_id ].revisions[ 0 ][ '*' ];
var new_file_contents = file_contents.replace(/{{\s*ffd\s*\|\s*log\s*=\s*[^|}}]*/gi, "{{ffd|log=" + today_subpage );
new mw.Api().postWithToken( 'edit', {
action: 'edit',
title: filename,
text: new_file_contents,
summary: "Updating {{ffd}} template: file was relisted (using [[User:Evad37/FFDcloser|FFDcloser]])"
} ).done( function( result, jqXHR ) {
deliverMsg( anchor, "Updated {{ffd}} on " + filename, "is_done", null, null, true );
if (lastfile === true) {
deliverMsg( anchor, null, null, true ); //remove working message
}
} ).fail( function( code, result ) {
var error_details = apifailed( code, result );
deliverMsg( anchor, "Could not update {{ffd}} on " + filename + " " + error_details, "warning", null, null, true );
if (lastfile === true) {
deliverMsg( anchor, null, null, true ); //remove working message
}
} );
} ).fail( function( code, result ) {
var error_details = apifailed( code, result );
deliverMsg( anchor, filename + " not found; could not update {{ffd}} " + error_details, "warning", null, null, true );
if (lastfile === true) {
deliverMsg( anchor, null, null, true ); //remove working message
}
} );

}
// </nowiki>