User:DaxServer/DiscussionCloser-new.js

// mw.loader.using(['mediawiki.util', 'mediawiki.api', 'mediawiki.Title', 'mediawiki.Uri', '@wikimedia/codex'] ).then( function( require ) {	const Vue = require( 'vue' );	const Codex = require( '@wikimedia/codex' );	const mountPoint = document.body.appendChild( document.createElement( 'div' ) );	const defaultEditSummary = 'Closing discussion';	const api = new mw.Api;	const uri = new mw.Uri;

function generate_template_text(template, status, comment) { var templateText = '\n'; return templateText; }

function dc_make_bottom(template) { var bottom; switch (template) { case "atop": case "atopr": case "atopy": case "atopg": case "subst:RMT": bottom = "abot"; break; case "hat": bottom = "hab"; break; default: bottom = "closed rfc bottom"; break; }		return ``; }

function alreadyClosed(content) { content = content.toLowerCase; return content.includes('{{atop') || content.includes('{{hat') || content.includes('{{abot') || content.includes('{{archive') || content.includes('{{rfctop') || content.includes('{{rfc bottom') || content.includes('{{archive bottom') || content.includes('{{hidden archive bottom') || content.includes('') ;	}

var app = Vue.createMwApp( {		data: function {			return {				section: 0,				showDialog: false,				defaultAction: {					label: 'Cancel'				},				primaryAction: {					label: 'Close discussion',					actionType: 'progressive',				},				radios: [					{						label: 'Generic (blue)',						value: 'atop'					},					{						label: 'Generic (green)',						value: 'atopg'					},					{						label: 'Generic (yellow)',						value: 'atopy'					},					{						label: 'Generic (red)',						value: 'atopr'					},					{						label: 'RfC',						value: 'closed rfc top'					},					{						label: 'Hidden archive',						value: 'hat'					},					{						label: 'Requested move',						value: 'subst:RMT'					},				],				radioValue: Vue.ref( 'atop' ),				status: ,				statusEnabled: true,				comment: ,				editSummary: '',			};		},		template: `							 						{{ radio.label }}     Status     Closing comment   Signature is automatically added.  <cdx-field optionalFlag="(optional)"> <template #label> Edit summary <cdx-text-input v-model="editSummary"></cdx-text-input> <template #help-text> "${defaultEditSummary}" if left blank. </cdx-field> </cdx-dialog> `,		methods: { openDialog(section) { this.showDialog = true; this.section = section; },			closeDialog { this.showDialog = false; },			getSection { return this.section; },			getEditSummary { return this.editSummary.trim.length > 0 ? this.editSummary.trim : defaultEditSummary; },			updateRadioValue(value) { this.statusEnabled = !(value === 'closed rfc top' || value === 'hat' || value === 'subst:RMT'); },			closeDiscussion { const status = this.statusEnabled && this.status.trim.length > 0 ? this.status.trim : ''; const comment = this.comment.trim.length > 0 ? this.comment.trim + ' ~' : ''; const editSummary = this.editSummary.trim.length > 0 ? this.editSummary.trim : defaultEditSummary; const top = `{{${this.radioValue}${status.length > 0 ? `\n| status = ${status}\n` : ''}${comment.length > 0 ? `\n| result = ${comment}\n` : ''}}}`.replace(/\n+/g, '\n'); const bottom = dc_make_bottom(this.radioValue);

let vueApp = this;

api.get({					action:"query",					titles: mw.config.get('wgPageName'),					rvsection: this.section,					prop: "revisions|info",					rvslots: "main",					rvprop: "content",					formatversion: 2,				}).done(function(response) {					const content = response.query.pages[0].revisions[0].slots.main.content;					const discussiontext = content.substring(content.indexOf('\n'));					const title = content.substring(0, content.indexOf('\n'));					const sectiontitle = title.replace(/=/g, ).trim;					var wikitext = title + '\n' + top + discussiontext + '\n' + bottom;					if (this.radioValue === "closed rfc top") {						wikitext = wikitext.replace(/(\r|\n)?{{rfc[^\}]*}}/g, )							.replace(/(\r|\n)?{{[^C]+ClueBot\sIII\/DoNotArchiveUntil\|\d*}}/g, );					} else if (this.radioValue === "subst:RMT") {						wikitext = wikitext.replace(/{{requested move\/dated\|[^}]*?}}\n?/i, );					}

const sectiontitle2 = sectiontitle.replace(/\s/g, '_'); const afterCloseCallback = function(result, sectiontitle) { $("#DC-interface-content").append(result); $('#DC-interface-footer').append(							$(' ').attr('id', 'DC-close').text('Done')						); $('#DC-close').click(function {							$('#DC-modal').remove;							uriReload = uri.clone;							uriReload.fragment = sectiontitle;							window.location.href = uriReload.toString;							window.location.reload;						}); };

var willClose = true; if (alreadyClosed(content)) { willClose = confirm('The discussion may have already been closed. Continue?'); }					if (!willClose) { vueApp.closeDialog; return; }

api.post({						action:"edit",						section: vueApp.section,						title: mw.config.get('wgPageName'),						text: wikitext,						summary: '/* ' + sectiontitle + ' */ ' + editSummary,						token: mw.user.tokens.get("csrfToken")					}).done(function {						uriReload = uri.clone;						uriReload.fragment = sectiontitle2;						window.location.href = uriReload.toString;						window.location.reload;					}); });			},		},		mounted {			// dialogTrigger.addEventListener( 'click', this.openDialog );		},		unMounted {			// dialogTrigger.removeEventListener( this.openDialog );		},	}) .component( 'cdx-button', Codex.CdxButton ) .component( 'cdx-dialog', Codex.CdxDialog ) .component( 'cdx-field', Codex.CdxField ) .component( 'cdx-radio', Codex.CdxRadio ) .component( 'cdx-text-input', Codex.CdxTextInput ) .component( 'cdx-text-area', Codex.CdxTextArea ) .mount(mountPoint) ;

$('div:not(.mw-archivedtalk) > div.mw-heading').each(function(index, value) {		const editSectionUrl = $(this).find('.mw-editsection a:first').attr('href');		const sectionRaw = /&section=(\d+)/.exec(editSectionUrl);		if (sectionRaw === null || typeof sectionRaw[1] === 'undefined') {			return;		}		const sectionHeadingRaw = /mw-heading mw-heading(\d)/.exec($(this).attr('class'));		if (sectionHeadingRaw === null || typeof sectionHeadingRaw[1] === 'undefined' || ![2, 3, 4].includes(parseInt(sectionHeadingRaw[1]))) {			return;		}		const section = parseInt(sectionRaw[1]);		if (isNaN(section)) {			return;		}		const uriFragment = $(this).find('h'+section).attr('id');		$(this).append(' | <a class="DC-closeLink">Close</a> ');		$(this).find('a.DC-closeLink').click(function { app.openDialog(section); });	}); } ); //