User:DannyS712/SelectiveDeleter.js
Appearance
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
// <nowiki>
// Quick script to carry out selective deletion
// @author DannyS712
$(() => {
const SelectiveDeleter = {};
window.SelectiveDeleter = SelectiveDeleter;
SelectiveDeleter.load = function () {
if ( mw.config.get( 'wgAction' ) === 'history' ) {
mw.loader.using(
[ 'mediawiki.util', 'oojs-ui-widgets' ],
function () {
var button = new OO.ui.ButtonInputWidget( {
label: 'Selectively delete',
flags: [ 'destructive' ]
} );
$('.mw-history-compareselectedversions:first input').after( button.$element );
button.on( 'click', function () {
var revIds = [];
$('#pagehistory li:has(input[type=checkbox]:checked)').each( function () {
console.log( $( this ).attr( 'data-mw-revid' ) );
revIds.push( $( this ).attr( 'data-mw-revid' ) );
} );
var url = mw.util.getUrl(
'Special:BlankPage/SelectiveDeleter',
{
page: mw.config.get( 'wgRelevantPageName' ),
ids: revIds.join( ',' )
}
);
console.log( url );
location.href = url;
} );
}
);
}
if ( mw.config.get( 'wgNamespaceNumber' ) === -1 ) {
const page = mw.config.get( 'wgCanonicalSpecialPageName' );
if ( page === 'Blankpage' ) {
const page2 = mw.config.get( 'wgTitle' ).split( '/' );
if ( page2[1] && page2[1] === 'SelectiveDeleter' ) {
window.SelectiveDeleter.init();
}
}
}
};
SelectiveDeleter.init = function () {
window.document.title = 'Selective Deletion';
$( '#firstHeading' ).text( 'Selective Deletion' );
mw.loader.using(
[ 'mediawiki.api', 'mediawiki.util', 'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows' ],
SelectiveDeleter.run
);
};
SelectiveDeleter.onErrHandler = function () {
// Shared error handler
alert( 'Something went wrong' );
console.log( arguments );
};
SelectiveDeleter.run = function () {
mw.util.addCSS( `
.SelectiveDeleter-bad {
color: #F00;
}
.SelectiveDeleter-good {
color: #0F0;
}
#SelectiveDeleter-results {
white-space: pre;
}
` );
var pageWidget = new OO.ui.TextInputWidget( {
value: mw.util.getParamValue( 'page' )
} );
var pageLayout = new OO.ui.FieldLayout(
pageWidget,
{ label: 'Page to selectively delete revisions from' }
);
var revIdsToDelete = mw.util.getParamValue( 'ids' );
if ( revIdsToDelete === null ) {
revIdsToDelete = '';
}
var revIdsWidget = new OO.ui.MultilineTextInputWidget( {
value: revIdsToDelete.split(',').join('\n'),
rows: 5
} );
var revIdsLayout = new OO.ui.FieldLayout(
revIdsWidget,
{ label: 'Revision ids for the revisions to selectively delete' }
);
var submit = new OO.ui.ButtonInputWidget( {
label: 'Delete',
flags: [
'primary',
'progressive'
]
} );
submit.on( 'click', function () {
var submittedValues = {
page: pageWidget.value,
revIds: revIdsWidget.value
};
console.log( submittedValues );
SelectiveDeleter.onSubmit( submittedValues );
} );
$( window ).on( 'keypress', function ( e ) {
// press enter to start
if ( e.which == 13 ) {
submit.simulateLabelClick();
}
} );
var fieldSet = new OO.ui.FieldsetLayout( {
label: 'Selectively delete specific revisions by deleting the page and undeleting the other revisions'
} );
fieldSet.addItems( [
pageLayout,
revIdsLayout,
new OO.ui.FieldLayout( submit )
] );
var $results = $( '<div>' )
.attr( 'id', 'SelectiveDeleter-results' );
$( '#mw-content-text' ).empty().append(
fieldSet.$element,
$( '<hr>' ),
$results
);
};
SelectiveDeleter.onSubmit = function ( inputs ) {
console.log( inputs );
$( '#SelectiveDeleter-results' ).empty();
var $progress = $( '<div>' )
.attr( 'id', 'SelectiveDeleter-progress' );
$( '#SelectiveDeleter-results' ).append( $progress );
var revIdsToDelete = inputs.revIds.split( "\n" );
if ( revIdsToDelete.length === 0 ) {
SelectiveDeleter.addProgressLine( 'No rev ids to delete!', 'bad' );
return;
}
SelectiveDeleter.addProgressLine( 'Getting page info from API for page: ' + inputs.page );
var mwApi = new mw.Api();
mwApi.get( {
action: 'query',
prop: 'revisions',
titles: [ inputs.page ],
rvlimit: 500,
formatversion: 2
} ).then(
function ( response ) {
console.log( response );
if ( response.continue ) {
SelectiveDeleter.addProgressLine(
'There were too many revisions, more than 500!',
'bad'
);
return;
}
var pageInfo = response.query.pages[0];
if ( pageInfo.missing ) {
SelectiveDeleter.addProgressLine(
'The page does not exist! Just selectively undelete manually...',
'bad'
);
return;
}
var allRevisions = pageInfo.revisions;
var foundRevIdsToDelete = [];
var foundRevsToKeep = [];
var timestampsToKeep = [];
allRevisions.forEach( function ( rev ) {
if ( revIdsToDelete.indexOf( rev.revid.toString() ) !== -1 ) {
foundRevIdsToDelete.push( rev.revid );
} else {
foundRevsToKeep.push( rev );
timestampsToKeep.push( rev.timestamp );
}
} );
console.log( 'Found to delete:', foundRevIdsToDelete );
console.log( 'Found to keep:', foundRevsToKeep );
if ( revIdsToDelete.length !== foundRevIdsToDelete.length ) {
SelectiveDeleter.addProgressLine(
'Uh oh, something went wrong with revision ids - are they all from the correct page? The revisions to delete were: ',
'bad'
);
SelectiveDeleter.addProgressLine( '\t' + revIdsToDelete.join( ',' ), 'bad' );
SelectiveDeleter.addProgressLine( 'And the ones the script found to delete were: ', 'bad' );
SelectiveDeleter.addProgressLine( '\t' + foundRevIdsToDelete.join( ',' ), 'bad' );
return;
}
if ( foundRevsToKeep.length === 0 ) {
SelectiveDeleter.addProgressLine(
'Uh oh, no revisions found to keep... maybe just delete the page entirely?',
'bad'
);
return;
}
SelectiveDeleter.addProgressLine(
'Found ' + foundRevsToKeep.length + ' revisions to keep',
'good'
);
mwApi.postWithEditToken( {
action: 'delete',
title: inputs.page,
reason: 'Preparing for selecting undeletion'
} ).then(
function ( response2 ) {
console.log( response2 );
SelectiveDeleter.addProgressLine( 'Page deleted!', 'good' );
mwApi.postWithEditToken( {
action: 'undelete',
title: inputs.page,
timestamps: timestampsToKeep,
reason: 'Selectively undeleting'
} ).then(
function ( response3 ) {
console.log( response3 );
SelectiveDeleter.addProgressLine( 'Page undeleted!', 'good' );
},
SelectiveDeleter.onErrHandler
);
},
SelectiveDeleter.onErrHandler
);
},
SelectiveDeleter.onErrHandler
);
};
SelectiveDeleter.addProgressLine = function ( text, type ) {
type = type || '';
var lineClass = '';
if ( type === 'good' ) {
lineClass = 'SelectiveDeleter-good';
} else if ( type === 'bad' ) {
lineClass = 'SelectiveDeleter-bad';
}
$( '#SelectiveDeleter-results' ).append(
$( '<p>' )
.text( text )
.addClass( lineClass )
);
};
});
$( document ).ready( () => {
mw.loader.using(
[ 'mediawiki.user' ],
function () {
mw.user.getGroups(
function ( groups ) {
if ( groups.indexOf( 'sysop' ) !== -1 ) {
SelectiveDeleter.load();
}
}
);
}
);
} );
// </nowiki>