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();

}

} );