User:Mr. Stradivarius/gadgets/UserTalkCleaner.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
$( 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 )
				&& /<!-- Template:FRS message -->/.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();
	}
} );