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