User:Mr. Stradivarius/gadgets/UserTalkCleaner.js

$( document ).ready( function {	"use strict";

var sectionMatchFuncs = [ // Signpost function ( section, heading, title, body ) { return (				/The Signpost:?:? \d{1,2} \w+ \d{4}/.test( title )				|| /Signpost issue \d+ – \d+ \w+ \d+/.test( title )			); },

// Feedback request service function ( section, heading, title, body ) { return (				/^Please comment on/.test( title )				&& //.test( body )			); },

// Tech news function ( section, heading, title, body ) { return (				/^\[\[m:Special:MyLanguage\/.*[tT]ech [nN]ews.*$/.test( title )				|| /^Tech News: \d{4}-\d+$/.test( title )			); },

// You've got mail function ( section, heading, title, body ) { return (				/^[yY]ou've got mail!?$/.test( title )				|| /^[yY][gG][mM]$/.test( title )			) && body.split( '\n' ).length <= 1; },		// Collaboration newsletter function ( section, heading, title, body ) { return /^\[\[m:Special:MyLanguage\/(?:Global )?Collaboration\/Newsletter\/.*$/.test( title ); },

// Administrators' newsletter function ( section, heading, title, body ) { return /^Administrators' [nN]ewsletter [–-] \w+ \d+/.test(title); }	];

// Split wikitext into sections. Takes arbitrary wikitext as the first // parameter and returns an array of wikitext strings. The wikitext is split // at level 2 headings, and the headings are included in the section // strings. function splitIntoSections( wikitext ) { var i = 0, j = 1, lines = wikitext.split( '\n' ), nLines = lines.length, sections = [];

// This function pushes a subset of lines into the sections array and // joins them with newlines. It takes the beginning and ending indices // of the sub-array as parameters. function pushSection( begin, end ) { sections.push( lines.slice( begin, end ).join( '\n' ) ); }

for ( /* null */ ; j < nLines; j++ ) { if ( /^==[^=].*[^=]==$/.test( lines[ j ] ) ) { // This line is the start of a new section, so push the section // ending with the previous line pushSection( i, j ); i = j;			} }		pushSection( i, nLines ); // Push the final section return sections; }

function removeSections { var sections, isEdited = false, $editBox = $( '#wpTextbox1' ), $editSummary = $( '#wpSummary' );

if ( $editBox.hasClass( 've-dummyTextbox' ) ) { // Bail if we detect the 2017 wikitext editor; supporting this will // require a different method from the classic wikitext editor alert( 'UserTalkCleaner does not support the wikitext editor inside the visual editor.' ); return; }

sections = splitIntoSections( $editBox.val ).filter( function ( section, i ) {			var j, len,				// Match the whole section, the heading, the title, and the body,				// in that order. [^] matches all characters, including newlines.				matches = section.match( /(== *(.*?) *==)\s*\n([^]*?)\s*$/ );

for ( j = 0, len = sectionMatchFuncs.length; j < len; j++ ) { if ( sectionMatchFuncs[ j ].apply( null, matches ) ) { isEdited = true; // The section matched one of the section-matching // functions, so remove it					return false; }			}			return true; } );

if ( !isEdited ) { // Alert the user and exit if we didn't remove any sections alert( 'No sections found to remove' ); return; }

// Replace the edit box text with our new sections $editBox.val( sections.join( '\n' ) );

// Add a custom edit summary $editSummary.prop( 'value', function ( i, summary ) {			if ( summary && !/^\/\*.*\*\/\s*$/.test( summary ) ) {				// Summary is non-blank and is not just an automatic section				// summary				summary += '; ';			}			summary += 'remove automated messages using WP:UTCLEAN';			return summary;		} ); }

function addCleanerPortletLink { var portletLink = mw.util.addPortletLink(			'p-tb',			'#',			'Clean talk page',			't-usertalkcleaner'		); $( portletLink ).click( function ( e ) {			e.preventDefault;			removeSections;		} ); }

if ( mw.config.get( 'wgNamespaceNumber' ) == 3 && $( '#wpTextbox1' ).length ) { addCleanerPortletLink; } } );