MediaWiki:Gadget-revisionPatrol.js

// TODO: Revert to less ugly version once MW allows ES6+

// jshint jquery:true, esversion:5 /* globals require, module, mediaWiki, mw, OO */ 'use strict'; // TODO: Use async once MW allows it $( function {	// Script only works on the history page, diff page, and revision page	var mode = mw.config.get( 'wgAction' );	if ( mode === 'view' ) {		if ( document.querySelector( '.diff' ) ) {			mode = 'diff';		} else if ( document.querySelector( '.mw-revision' ) ) {			mode = 'revision';		}	}	if ( mode !== 'history' && mode !== 'diff' && mode !== 'revision' ) {		return;	}	var api = new mw.Api;	var pageName = mw.config.get( 'wgPageName' ).replace( /_/g, ' ' );	// Get the ids for all the revisions on the page,	// and store their associated element	var lastRevId;	var revElemsById = {};	var totalRevs;	if ( mode === 'history' ) {		var revElems = document.querySelectorAll( '#pagehistory li' );		// TODO: Use for..of once MW allows it		Array.prototype.forEach.call( revElems, function( li ) { lastRevId = li.querySelector( 'input[name=oldid]' ).value; revElemsById[lastRevId] = li; } );		totalRevs = revElems.length;	} else if ( mode === 'diff' ) {		var oldRev = document.querySelector( '#mw-diff-otitle1 > strong' );		lastRevId = mw.util.getParamValue( 'oldid', oldRev.querySelector( 'a' ).href );		revElemsById[lastRevId] = oldRev;		var newRev = document.querySelector( '#mw-diff-ntitle1 > strong' );		revElemsById[mw.config.get( 'wgRevisionId' )] = newRev;		totalRevs = 2;	} else {		lastRevId = mw.config.get( 'wgRevisionId' );		revElemsById[lastRevId] = document.getElementById( 'mw-revision-info' );		totalRevs = 1;	}	// Retrieve the timestamp for the earliest revision on the page	// TODO: Use await once MW allows it	var dateReq = api.get( { action: 'query', titles: pageName, prop: 'revisions', rvprop: 'timestamp', rvstartid: lastRevId, rvendid: lastRevId, formatversion: 2, } ).fail( function( code, data ) { console.error( code, data.error && data.error.info ); } );	dateReq.then( function( resp ) { // Get all the patrols that happened after the last revision var endDate = resp.query.pages[0].revisions[0].timestamp; var patrolQuery = { action: 'query', list: 'logevents', letitle: pageName, letype: 'patrol', leprop: 'details', lestart: endDate, ledir: 'newer', lelimit: 'max', formatversion: 2, };		var makePatrolReq = function( cont ) { // TODO: Use await once MW allows it			var logReq = api.get( Object.assign( patrolQuery, cont ) ) .fail( function( code, data ) {					console.error( code, data.error && data.error.info );				} ); return logReq.then( function( resp ) {				// Mark off patrolled edits as we go, as older history pages may				// take multiple requests before all the patrol entries are checked				// TODO: Use for..of once MW allows it				resp.query.logevents.forEach( function( patrol ) { var revElem = revElemsById[patrol.params.curid]; if ( !revElem ) { return; }					revElem.classList.add(						patrol.params.auto ?							'revisionpatrol-autopatrolled' : 'revisionpatrol-patrolled'					); delete revElemsById[patrol.params.curid]; --totalRevs; } );				cont = resp['continue'];				if ( cont && totalRevs > 0 ) {					return makePatrolReq( cont );				}			} ); };		makePatrolReq.then( function {			// Anything not marked as patrolled still, hasn't been patrolled			// TODO: Use for..of once MW allows it			Object.keys( revElemsById ).forEach( function( revId ) { revElemsById[revId].classList.add( 'revisionpatrol-unpatrolled' ); --totalRevs; } );			// No legends in revision mode :( if ( mode === 'revision' ) { return; }			// Add the patrol icons to the legend var legendElem = document.querySelector( '.mw-history-legend > p' ); var addLegend = function( className, text ) { if ( !document.querySelector( '.revisionpatrol-' + className ) ) { return; }				if ( mode === 'history' && legendElem ) { legendElem.innerHTML += ',  = ' + text.toLowerCase + ' '; } else { var revElems = document.querySelectorAll( '.revisionpatrol-' + className ); // TODO: Use for..of once MW allows it					Array.prototype.forEach.call( revElems, function( revElem ) {						revElem.title = text;					} ); }			};			if ( legendElem ) { legendElem.innerHTML = legendElem.innerHTML.trim.slice( 0, -1 ); }			addLegend( 'patrolled', 'Patrolled edit' ); addLegend( 'autopatrolled', 'Autopatrolled edit' ); addLegend( 'unpatrolled', 'Unpatrolled edit' ); if ( legendElem ) { legendElem.innerHTML += '.'; }		}, function { // Mission failed, we'll get 'em next time mw.notify(				'Failed to retrieve patrol information',				{ title: 'RevisionPatrol', type: 'error', autoHide: false }			); return; } );	}, function {		// Not worth looking through all patrols just for the one page		// If this request failed, the next one probably would too anyway		mw.notify( 'Failed to retrieve revision information', { title: 'RevisionPatrol', type: 'error', autoHide: false } );		return;	} ); } );