User:Enterprisey/abusefilter-mass-test.js
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.
if( mw.config.get( "wgPageName" ).indexOf( "Special:AbuseFilter/test" ) === 0 ) {
function makeQueryHelper( api, params, limit ) {
return $.post( window.location, params ).then( function ( html ) {
var parser = new DOMParser();
var doc = parser.parseFromString( html, "text/html" );
var els = Array.prototype.slice.call( doc.querySelector( "ul.special" ).children );
if( els.length < 100 || els.length >= limit ) {
return els;
} else {
params.wpTestPeriodEnd = els[els.length - 1].dataset.mwTs;
return makeQueryHelper( api, params, limit - 100 ).then( function ( data ) {
return els.concat( data );
} );
}
} );
}
function makeQuery() {
$( "#wpFilterForm" ).parents( "fieldset" ).after( $( "<div>", { "class": "mw-changeslist" } ).append( "Loading..." ) );
mw.loader.load( [ 'mediawiki.interface.helpers.styles', 'mediawiki.special.changeslist' ] );
var fieldNames = [
"wpTestUser",
"wpExcludeBots",
"wpTestPeriodStart",
"wpTestPeriodEnd",
"wpTestPage",
"wpEditToken",
"title"
];
var params = {};
for( var i = 0; i < fieldNames.length; i++ ) {
var el = document.querySelector( "form#wpFilterForm input[name='" + fieldNames[i] + "']" );
params[fieldNames[i]] = ( el.type === "checkbox" )
? ( el.checked ? "1" : "0" )
: el.value;
}
params.wpFilterRules = document.querySelector( "#wpFilterRules" ).value;
params.wpTestAction = $( "#mw-input-wpTestAction select" ).find( "option:contains('" +
$( "#mw-input-wpTestAction span[role='textbox']" ).text() + "')" ).attr( "value" );
// We need to tell if we hit the end of the results, which means every query that doesn't hit the end needs to
// return 100 results. We'll do the filtering later.
params.wpShowNegative = "1";
var showNegative = document.querySelector( "form#wpFilterForm input[name='wpShowNegative']" ).checked;
var limit = document.querySelector( "#massTestLimit" ).value || 200;
makeQueryHelper( new mw.Api(), params, limit ).then( function ( elements ) {
var totalNum = elements.length;
var hits = elements.filter( function ( el ) {
return el.className.indexOf( "mw-abusefilter-changeslist-match" ) >= 0;
} );
if( !showNegative ) {
elements = hits;
}
// Group by day
if( elements.length === 0 ) {
$( "#wpFilterForm" ).parents( "fieldset" ).after( "<p>No hits in " + totalNum + " edits.</p>" );
$( "div.mw-changeslist" ).remove();
return;
}
var day = elements[0].dataset.mwTs.substring( 0, 8 ); // YYYYMMDD
var groups = [];
var currentGroup = [];
for( var i = 0; i < elements.length; i++ ) {
var currentDay = elements[i].dataset.mwTs.substring( 0, 8 );
if( day !== currentDay ) {
groups.push( [ day, currentGroup ] );
currentGroup = [];
day = currentDay;
}
currentGroup.push( elements[i] );
}
groups.push( [ day, currentGroup ] );
var monthNames = mw.config.get( "wgMonthNames" );
var els = groups.map( function ( group ) {
var dayName = group[0].substring( 6, 8 ) + " " + monthNames[ parseInt( group[0].substring( 4, 6 ) ) ] +
" " + group[0].substring( 0, 4 );
return [
$( "<h4>" ).text( dayName ),
$( "<ul>", { "class": "special" } ).append( group[1] )
];
} );
els = Array.prototype.concat.apply( [], els );
$( "div.mw-changeslist" ).remove();
$( "#wpFilterForm" ).parents( "fieldset" ).after(
$( "<div>", { "class": "mw-changeslist" } ).append( "<p>" + hits.length + " hit(s) (" + ( 100 * (
hits.length / totalNum ) ).toFixed( 2 ) + "%) out of " + totalNum + " edits</p>", els ) );
} );
return false;
} // end makeQuery
$( function () {
$( "#wpFilterForm fieldset:first" ).append(
"<br />Or ",
$( "<button>", { "class": "oo-ui-inputWidget-input oo-ui-buttonElement-button" } )
.css( { "padding": "0.5em" } )
.text( "Test" )
.click( makeQuery ),
" with <input type='text' id='massTestLimit' /> edits" );
} );
}