User:Evad37/TFDcloser/sandbox.js

// //global vars var TFDpath = "Wikipedia:Templates for discussion/Log/";

/* == Main function == */ $( function($) {

// Only run in TFD/subpages, excluding holding cell var thispage = mw.config.get( 'wgPageName' ); if ( !thispage.includes("Templates_for_discussion") || thispage.includes("Templates_for_discussion/Holding_cell") ) { 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 = false; console.log("isSysop: " + isSysop); TFDpath = "User:Evad37/sandbox/Wikipedia:Templates for discussion/Log/"; } /* ##### 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 template = $(":first-child", this).text;		if (!template) {							// section header wasn't a link			template = $(this).text;			$(this).wrapInner(" ");				// wrap with span so it can be styled later		}		var templatee = mw.util.wikiUrlencode(template);			// "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 tfd 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 }			if ( nom_page.includes("Templates_for_discussion/Holding_cell") ) return;

//Check for collapsed list, and pop out a non-visible copy if found //var $collapsedlist = $(this).parent.next.next.find("ul"); //if ($collapsedlist.length > 0) { //	$collapsedlistitems = $collapsedlist.children.clone; //	$collapsedlistitems.css( "display", "none" ) //	$(this).parent.next.append( $collapsedlistitems ).after( " &thinsp;... collapsed list detected (" + $collapsedlistitems.length + " templates) " ); //}

//Check if this is a multi-template dicussion var $templates = $(this).parent.nextUntil("h4").find("li > span[id].plainlinks.nourlexpansion.1x").filter(":first-child").children("a").filter(":first-child"); console.log("$templates = "); console.log($templates); var templates = new Array($templates.length); $templates.each(function( ii ) {				templates[ii] = $(this).text;			}); console.log("templates ="); console.log(templates); var closing_options; if ( templates.length > 1) { // This is a multi-discussion templates_e = templates.map(function(tname) {					var te = mw.util.wikiUrlencode(tname).replace(/,/g,"__COMMA__"); //"pretty"-encode, then encode commas encoded as __COMMA__					return te;				}); closing_options = "Closing options: " + " [qD] " + " [Delete/other] " + " [qK] " + " [Keep/other] " + " [Other close] " + " [Relist] ";

} else if (templates[0] === undefined || !checkNS(template, 10)) { // sanity check templatee = mw.util.wikiUrlencode($(this).html.replace(/<[^>]*>/g,""));   //this is actually the section header closing_options = "No templates detected. [Close] ";

} else { // not a multi-discussion closing_options = "Closing options: " + " [qD] " + " [<a style='cursor:pointer;' onclick=close_tfd('" + templatee + "','" + nom_page + "','" + editsection + "','" + "delete" + "') title='Delete, or other close that will result in the template being deleted (e.g. Review, Convert, Substitute)'>Delete/other</a>] " + " [<a style='cursor:pointer;' onclick=multi_process_close_tfd('" + templatee + "','" + nom_page + "'," + null + ",'" + editsection + "','" + "Keep." + "','" + "keep" + "') title='QuickKeep'>qK</a>] " + " [<a style='cursor:pointer;' onclick=close_tfd('" + templatee + "','" + nom_page + "','" + editsection + "','" + "keep" + "') title='Keep, or other close that will result in the template being kept (e.g. Redirect, No Consensus)'>Keep/other</a>] " + " [<a style='cursor:pointer;' onclick=close_tfd('" + templatee + "','" + nom_page + "','" + editsection + "','" + "relist" + "') title='Relist discussion'>Relist</a>] "; }			$(this).append("<span id=XFDClosing_" + templatee + " style='font-size:85%;margin-left:13px;font-weight:normal;'>" + closing_options + " "); }	}); });

});

/* == CLOSING-related functions == */

/* -- Close single-TFD section (prompting for result/commment) -- */ function close_tfd(_templatename, _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_tfd(_templatename, _pagetitle, null, _sectionnum, result_comment, _action); } }

/* -- Close mulit-TFD section (prompting for result/commment) -- */ //Get comment function multi_close_tfd(_templatearray, _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_tfd(_templatearray, _pagetitle, _sectionheader, _sectionnum, result_comment, _action); } }

/* -- Process the close -- */ function multi_process_close_tfd(templatename, pagetitle, sectionheader, sectionnum, resultcomment, action) {

var editsum_template_or_section, template_or_null, _anchor, tfd_close_top, tfd_close_bottom, tfd_close_editsum, sig; // Add REFUND to "soft delete" resultcomment = resultcomment.trim.replace(/^soft delete\.?$/gi, "soft delete. WP:REFUND applies."); // Wikitext used for close if (sectionheader) { editsum_template_or_section = "\"" + sectionheader + "\""; template_or_null = null; _anchor = sectionheader; } else { editsum_template_or_section = "for " + templatename + ""; template_or_null = templatename; _anchor = templatename; }

deliverMsg( _anchor, "Started closing...", "working" );

if (isSysop) { sig = "" + ""; } else { sig = " (non-admin closure) " + ""; }

// 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]; var rc = bold1 + resultcomment + bold2; var editsum_rc = rc.replace(/'''/g, ""); if (action == "relist") { //get today's date var d = new Date; var mmm = getMonthName(d.getUTCMonth); todays_subpage = d.getUTCFullYear + " " + mmm + " " + d.getUTCDate; tfd_close_top = "{" + "{subst:tfd top|Relisted}" + "} on " + todays_subpage + " " + sig; tfd_close_bottom = "\n{" + "{subst:tfd bottom}" + "}"; tfd_close_editsum = "Relisted discussion " + editsum_template_or_section + " on " + todays_subpage + " (using TFDcloser)"; } else { tfd_close_top = "{" + "{subst:tfd top|" + bold1 + resultcomment + bold2 + "}" + "} " + sig; tfd_close_bottom = "{" + "{subst:tfd bottom}" + "}"; tfd_close_editsum = "Closing discussion " + editsum_template_or_section + " as " + editsum_rc + " (using TFDcloser)"; }

// 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(//gi, "");			var updated_section;

// Add relisted discussions to current day's TFD page if (action == "relist") { var tfdlinks = section_contents.match(/^\*\s*{{\s*Tfd links\s*\|[^\n]*/gim).join("\n"); if ( tfdlinks ) { updated_section = "====" + section_heading + "====" + "\n" + tfd_close_top + "\n" + tfdlinks + tfd_close_bottom; } else { updated_section = "====" + section_heading + "====" + "\n" + tfd_close_top + tfd_close_bottom; }											deliverMsg( _anchor, "Adding discussion to today's TFD subpage...", "working" ); var old_disc = "====" + section_heading + "====" + "\n" + section_contents.replace(/^\n+/,""); relist_tfd_disc(template_or_null, old_disc, resultcomment, todays_subpage, sectionheader, _anchor); } else { updated_section = "====" + section_heading + "====" + "\n" + tfd_close_top + section_contents + tfd_close_bottom; }

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

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

if ( action == "delete" ) { //---Delete:--- markClosed(_anchor, rc); deliverMsg( _anchor, "Waiting...", "working" ); delete_action_prompt(templatename, pagetitle, _anchor);

} else if ( action == "relist" ) { //---Relist:--- markClosed(_anchor, "Relisted on <a href=//en.wikipedia.org/wiki/" + TFDpath.replace(/\s/gi,"_") + todays_subpage.replace(/\s/gi,"_") + "#" + _anchor +">" + todays_subpage + "</a>", true); deliverMsg( _anchor, "Adding discussion to today's TFD subpage...", "working" ); for (ii = 0; ii < template_array.length; ii++) { if (ii == template_array_length-1) { last_one = true; } else { last_one = false; }						update_template_tfd(template_array[ii], todays_subpage, _anchor, last_one); }

} else if ( action == "none_close_only" ) { //---No further action:--- markClosed(_anchor, rc); return;

} else if ( action == "other" ) { //---Other:--- markClosed(_anchor, rc); for (ii = 0; ii < template_array.length; ii++) { window.open("//en.wikipedia.org/w/index.php?title=" + template_array[ii] + "&action=edit", _anchor + ii); }					return;

} else { //---Keep:--- markClosed(_anchor, rc); deliverMsg( _anchor, "Updating template description pages...", "working" ); var rescom = bold1 + resultcomment + bold2; var res = rescom.split("'''")[1].trim.replace(/(?:\.|,|;|:)$/, ""); for (ii = 0; ii < template_array_length; ii++) { if (ii == template_array_length-1) { last_one = true; } else { last_one = false; }

make_old_tfd(template_array[ii], res, 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" ); } ); }

/* == DELETE-relatated functions == */

/* -- Prompt -- */ function delete_action_prompt(template, TFD_page, anchor) {

var log_date = TFD_page.match(/\d{4}_\w*_\d{1,2}/)[0];

var holdingcellbuttons = "<span id='hc_sections'><button onclick=addToHoldingCell('" + template + "',2,'" + anchor + "','" + log_date + "')>Review <button onclick=holdCellMergeSections('" + template + "','" + anchor + "','" + log_date + "')>Merge <button onclick=addToHoldingCell('" + template + "',11,'" + anchor + "','" + log_date + "')>Convert <button onclick=addToHoldingCell('" + template + "',12,'" + anchor + "','" + log_date + "')>Substitute <button onclick=addToHoldingCell('" + template + "',13,'" + anchor + "','" + log_date + "')>Orphan <button onclick=addToHoldingCell('" + template + "',14,'" + anchor + "','" + log_date + "')>Ready for deletion ";

var prompt_msg; if (isSysop) { var delReason = "["+"["+TFD_page+"#"+anchor+"]"+"]"; prompt_msg = "<button onclick=deleteNow('" + template + "','" + delReason + "','" + anchor + "')>Delete Now or choose holding cell section: " + holdingcellbuttons; } else { prompt_msg = "Choose holding cell section: " + holdingcellbuttons; }

deliverMsg( anchor, prompt_msg, "question"); }

function holdCellMergeSections(template, anchor, log_date) { var mergebuttons = "Choose 'Merge' subsection: <button onclick=addToHoldingCell('" + template + "',4,'" + anchor + "','" + log_date + "')>Arts <button onclick=addToHoldingCell('" + template + "',5,'" + anchor + "','" + log_date + "')>Geography, politics and governance <button onclick=addToHoldingCell('" + template + "',6,'" + anchor + "','" + log_date + "')>Religion <button onclick=addToHoldingCell('" + template + "',7,'" + anchor + "','" + log_date + "')>Sports <button onclick=addToHoldingCell('" + template + "',8,'" + anchor + "','" + log_date + "')>Transport <button onclick=addToHoldingCell('" + template + "',9,'" + anchor + "','" + log_date + "')>Other <button onclick=addToHoldingCell('" + template + "',10,'" + anchor + "','" + log_date + "')>Meta "; deliverMsg( anchor, mergebuttons, "question", true); }

/* -- Perform delete action -- */ function deleteNow(template_string, thereason, anchor) {

var ii, isLast;

deliverMsg( anchor, null, null, true);				// clears prompt buttons deliverMsg( anchor, "Deleting...", "working", true );		// clears waiting messages

if ( template_string.includes(",Template:") ) {			// template_string is a csv string (multiple items) template_array = template_string.split(","); for (i = 0; i < template_array.length; i++) { template_array[i] = decodeURIComponent(template_array[i]).replace(/__COMMA__/g,","); //unencode commas from __COMMA__ }	} else {							// template_string is a string (single item) template_array = [decodeURIComponent(template_string)]; }

for (ii = 0; ii < template_array.length; ii++) { if (ii == template_array.length-1) { isLast = true; } else { isLast = false; }				if ( !checkNS(template_array[ii], 10) ) { deliverMsg( anchor, "\"" + template_array[ii] + "\" is not in Template: namespace, TFDcloser will not delete this page", "error", isLast, null, !isLast); return; }		perform_delete(template_array[ii], thereason, anchor, isLast); } }

function perform_delete(template, del_reason, _anchor, _isLast){ new mw.Api.postWithToken( 'delete', {		action: 'delete',		title: template,		reason: del_reason,	} ).done( function( result, jqXHR ) {		deliverMsg( _anchor, "Deleted " + template, "deleted", null, null, true );		if (_isLast) {			deliverMsg( _anchor, null, null, true ); // remove "Deleting..." message		}	} ).fail( function( code, result ) {		var error_details = apifailed( code, result );		deliverMsg( _anchor, "Could not delete " + template + " " + error_details, "warning", null, null, true );		if (_isLast) {			deliverMsg( _anchor, null, null, true ); //remove "Deleting..." message		}	} ); }

/* -- Holding cell -- */ function addToHoldingCell(template_string, holdCellSection, anchor, log_date) {

var i, isLast, delete_param, tag_speedy, section_param, hc_editsum, last_one;

deliverMsg( anchor, null, null, true);					// clears prompt buttons deliverMsg( anchor, "Listing at holding cell...", "working", true );	// clears waiting message

//Build up wikitext for edit

if ( holdCellSection === 14 ) {						// 14 is "Ready for deletion" delete_param = "|delete=1"; tag_speedy = true; } else { delete_param = ""; tag_speedy = false; }	if ( template_string === anchor ) { section_param = ""; } else { section_param = "|section=" + anchor; }	var wikitext_append = ""; if ( template_string.includes(",Template:") ) {				// template_string is a csv string (multiple items) template_array = template_string.split(","); for (i = 0; i < template_array.length; i++) { if (i === template_array.length-1) { last_one = true; } else { last_one = false; }			template_array[i] = decodeURIComponent(template_array[i]).replace(/__COMMA__/g,","); addBeingDeleted(template_array[i], anchor, log_date, last_one, tag_speedy); wikitext_append = wikitext_append + "*{" + "{tfdl|" + template_array[i].replace(/_/g," ").slice(9) + "|" + log_date.replace(/_/g," ") + section_param + delete_param + "}}\n"; hc_editsum = "Listing templates per " + TFDpath + log_date + " (using TFDcloser)"; }	} else {								// template_string is a string (single item) addBeingDeleted(decodeURIComponent(template_string), anchor, log_date, true, tag_speedy); wikitext_append = "*{" + "{tfdl|" + decodeURIComponent(template_string).replace(/_/g," ").slice(9) + "|" + log_date.replace(/_/g," ") + section_param + delete_param + "}}\n"; hc_editsum = "Listing " + decodeURIComponent(template_string) + " per " + TFDpath + log_date + " (using TFDcloser)"; }

// ... make api call to append wikitext to the section ... var holdingcellpagetitle = TFDpath.slice(0,-4) + "Holding cell"; new mw.Api.get( {		action: 'query',		titles: holdingcellpagetitle,		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 ][ '*' ].replace(/====/gi, "==="); //make all headings level 3 so sections can be counted		var sections_array = p_contents.split("===");		var section_heading = sections_array[(holdCellSection*2-1)];		var section_contents = sections_array[(holdCellSection*2)];		 //remove "* None currently" if after end of, or before beginning of, 		section_contents = section_contents.replace(/-->\n*\*\s*None currently/gi, "-->").replace(/\*\s*None currently''\n*<!--/gi, "<!--");		var heading_level;		if ( (4 <= holdCellSection) && ( holdCellSection <= 10) ) {			//Merge subsections			heading_level = "====";		} else { heading_level = "==="; }		var updated_section = heading_level + section_heading + heading_level + "\n" + section_contents.trim + "\n" + wikitext_append;

new mw.Api.postWithToken( 'edit', {			action: 'edit',			title: holdingcellpagetitle,			section: holdCellSection,			text: updated_section,			summary: hc_editsum		} ).done( function( result, jqXHR ) {			deliverMsg( anchor, "Listed at holding cell", "is_done", null, null, true );		} ).fail( function( code, result ) {			var error_details = apifailed( code, result );			deliverMsg( anchor, "Could not edit holding cell " + error_details, "error", null, null, true);		} );

} ).fail( function( code, result ) { var error_details = apifailed( code, result ); deliverMsg( _anchor, "Could not read contents of page " + holdingcellpagetitle + "; could not add templates to holding cell " + error_details, "error", null, null, true); } ); }

/* -- Add Being deleted (or Db-xfd) template -- */ function addBeingDeleted(template, anchor, log_date, last, speedy) {

if ( !checkNS(template, 10) ) { deliverMsg( anchor, "\"" + template + "\" is not in Template: namespace, TFDcloser will not edit this page", "error", last, null, !last); return; }

var updated_content, uc_template, uc_template_name, uc_editsum; if ( speedy ) { uc_template_name = "Db-xfd"; uc_editsum = "G6 Speedy deletion nomination, per close at " + TFDpath + log_date + ""; uc_template = "{" + "{db-xfd|votepage=/Log/" + log_date + "#" + anchor + "}" + "}"; } else { uc_template_name = "Being deleted"; uc_editsum = "Per close at " + TFDpath + log_date + ", added {" + "{being deleted}" + "} (using TFDcloser)"; uc_template = "{" + "{Being deleted|" + log_date + "|" + anchor + "}" + "}"; }

//replace {Template for discussion/dated} or {Tfm/dated} (which may or may not be noincluded) with noincluded {Being deleted} new mw.Api.get( {		action: 'query',		titles: template,		prop: [ 'revisions', 'info' ],		rvprop: 'content',		indexpageids: 1,		rawcontinue: ''	} ).done( function( result, jqXHR ) {		var t_id = result.query.pageids;		var t_contents = result.query.pages[ t_id ].revisions[ 0 ][ '*' ];		if ( t_contents.search(/]*}{2,4}/gi) < 0 ) {			updated_content = "<no" + "include>" + uc_template + "</no" + "include>" + t_contents;		} else {			updated_content = t_contents.replace(/(?: [\n\s]*)*]*}{2,4}(?:[\n\s]*<\/noinclude>)*/gi, "<no" + "include>" + uc_template + "</no" + "include>");		}

//Perform edit new mw.Api.postWithToken( 'edit', {			action: 'edit',			title: template,			text: updated_content,			summary: uc_editsum		} ).done( function( result, jqXHR ) {			deliverMsg(anchor, "{" + "{" + uc_template_name + "}" + "} added to " + template, "is_done", last, null, !last);		} ).fail( function( code, result ) {			var error_details = apifailed( code, result );			deliverMsg(anchor, "Could not add {" + "{" + uc_template_name + "}" + "} to " + template + " " + error_details, "error", last, null, !last);		} );

} ).fail( function( code, result ) { var error_details = apifailed( code, result ); deliverMsg( anchor, template + " not found; could not add {" + "{" + uc_template_name + "}" + "} " + error_details, "warning", last, null, !last); } );

}

/* == KEEP-relatated functions == */

function make_old_tfd(templatename, resultcomment, tfdpage, sectionheader, anchor, last) {

var disc_param, nomdate, templatetalkpage, oldtfd_wikitext;

if ( !checkNS(templatename, 10) ) { deliverMsg( anchor, "\"" + templatename + "\" is not in Template: namespace, TFDcloser will not edit this page or its talk page", "error", lasttemplate, null, !lasttemplate); return; }

if (sectionheader) { disc_param = "|disc=" + sectionheader; } else { disc_param = ""; }

nomdate = tfdpage.split(TFDpath.replace(/\s/gi,"_"))[1].replace(/_/gi," ");          //unencode spaces from _ templatetalkpage = templatename.replace("Template", "Template_talk"); oldtfd_wikitext = "{" + "{oldtfdfull|date=" + nomdate + "|result=" + resultcomment + disc_param + " }" + "}\n";

new mw.Api.postWithToken( 'edit', {		action: 'edit',		title: templatetalkpage,		prependtext: oldtfd_wikitext,		summary: "Old TFD – " + nomdate + ": " + resultcomment + " (using TFDcloser)"	} ).done( function( result, jqXHR ) {		deliverMsg( anchor, "Updated " + templatetalkpage, "is_done", null, null, true );

//Get template description page, remove tfd template new mw.Api.get( {			action: 'query',			titles: templatename,			prop: [ 'revisions', 'info' ],			rvprop: 'content',			indexpageids: 1,			rawcontinue: ''		} ).done( function( result, jqXHR ) {			var t_id = result.query.pageids;			var t_contents = result.query.pages[ t_id ].revisions[ 0 ][ '*' ];			var updated_template_content = t_contents.replace(/(?: [\n\s]*)*]*}{2,4}(?:[\n\s]*<\/noinclude>)*/gi, "");

//Perform edit to remove tfd template new mw.Api.postWithToken( 'edit', {					action: 'edit',					title: templatename,					text: updated_template_content,					summary: "TFD closed as " + resultcomment + " (using TFDcloser)"				} ).done( function( result, jqXHR ) {					deliverMsg( anchor, "Removed (or ) from " + templatename, "is_done", last, null, !last);				} ).fail( function( code, result ) {					var error_details = apifailed( code, result );					deliverMsg( anchor, "Could not remove  (or ) from " + templatename + " " + error_details, "warning", last, null, !last);				} );

} ).fail( function( code, result ) { var error_details = apifailed( code, result ); deliverMsg( anchor, templatename + " not found; could not remove (or ) " + error_details, "warning", last, null, !last); } );

} ).fail( function( code, result ) { var error_details = apifailed( code, result ); deliverMsg( anchor, "Could not edit " + templatetalkpage + " " + error_details, "warning", last, null, !last); } );

}

/* == RELIST-related functions == */

/* -- Relist discussion on current day's TFD subpage -- */ function relist_tfd_disc(templatename, 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 TFDcloser)"; } else { relist_editsum = "Relisting " + templatename + " (using TFDcloser)"; }

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

//Check if any discussion already listed new mw.Api.get( {		action: 'query',		titles: TFDpath + todaysdate,		prop: [ 'revisions', 'info' ],		rvprop: 'content',		indexpageids: 1,		rawcontinue: ''	} ).done( function( result, jqXHR ) {		var _id = result.query.pageids;		var _contents = result.query.pages[ _id ].revisions[ 0 ][ '*' ];		var _h4 = _contents.match("====");		if ( _h4 ) {							// there is at least 1 level 4 heading on page - can prepend to section #2			new mw.Api.postWithToken( 'edit', { action: 'edit', title: TFDpath + todaysdate, section: 2, prependtext: newdiscussion, summary: relist_editsum } ).done( function( result, jqXHR ) { deliverMsg( anchor, null, null, true );		// remove working message window.open("//en.wikipedia.org/wiki/" + TFDpath.replace(/\s/gi,"_") + todaysdate.replace(/\s/gi,"_"), "tfdtoday"); } ).fail( function( code, result ) { var error_details = apifailed( code, result ); deliverMsg( anchor, "Could not relist discussion " + error_details, "error", true);

} );		} else {							// there are no level 4 headings on page - can append to section #1			new mw.Api.postWithToken( 'edit', { action: 'edit', title: TFDpath + todaysdate, section: 1, appendtext: "\n" + newdiscussion, summary: relist_editsum } ).done( function( result, jqXHR ) { deliverMsg( anchor, null, null, true );		// remove working message window.open("//en.wikipedia.org/wiki/" + TFDpath.replace(/\s/gi,"_") + todaysdate.replace(/\s/gi,"_"), "tfdtoday"); } ).fail( function( code, result ) { var error_details = apifailed( code, result ); deliverMsg( anchor, "Could not relist discussion " + error_details, "error", true ); } );		}	} ).fail( function( code, result ) {		var error_details = apifailed( code, result );		deliverMsg( anchor, TFDpath + todaysdate + " not found; could not relist discussion " + error_details, "error", true );	} ); }

/* -- Update template tfd template (after relisting) -- */ function update_template_tfd(templatename, today_subpage, anchor, lasttemplate) { if ( !checkNS(templatename, 10) ) { deliverMsg( anchor, "\"" + templatename + "\" is not in Template: namespace, TFDcloser will not edit this page", "error", lasttemplate, null, !lasttemplate); return; }	new mw.Api.get( {		action: 'query',		titles: templatename,		prop: [ 'revisions', 'info' ],		rvprop: 'content',		indexpageids: 1,		rawcontinue: ''	} ).done( function( result, jqXHR ) {		var template_id = result.query.pageids;		var template_contents = result.query.pages[ template_id ].revisions[ 0 ][ '*' ];		var new_template_contents = template_contents.replace(/Wikipedia:Templates(_|\s){1}for(_|\s){1}discussion\/Log\/\d{4}(_|\s){1}\w*(_|\s){1}\d{1,2}#(?=[^}]*}{2})/gi, "Wikipedia:Templates for discussion/Log/" + today_subpage + "#" );		new mw.Api.postWithToken( 'edit', { action: 'edit', title: templatename, text: new_template_contents, summary: "Updating template: template was relisted (using TFDcloser)" } ).done( function( result, jqXHR ) { deliverMsg( anchor, "Updated (or ) on " + templatename, "is_done", lasttemplate, null, !lasttemplate); } ).fail( function( code, result ) { var error_details = apifailed( code, result ); deliverMsg( anchor, "Could not update (or ) on " + templatename + " " + error_details, "warning", lasttemplate, null, !lasttemplate); } );	} ).fail( function( code, result ) {		var error_details = apifailed( code, result );		deliverMsg( anchor, templatename + " not found; could not update (or ) " + error_details, "warning", lasttemplate, null, !lasttemplate);	} );

} //