User:Evad37/FFDcloser/sandbox.js
Appearance
< User:Evad37 | FFDcloser
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
This user script seems to have a documentation page at User:Evad37/FFDcloser/sandbox. |
// <nowiki>
//global vars
var FFDpath = "Wikipedia:Files for discussion/";
/* == Main function == */
$( function($) {
// Only run in FFD/subpages
var thispage = mw.config.get( 'wgPageName' );
if ( !thispage.includes("Files_for_discussion") ) {
return;
}
$.getScript('https://wiki.riteme.site/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;'> ... 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=//wiki.riteme.site/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("//wiki.riteme.site/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>