Note: After saving, changes may not occur immediately. Click here to learn how to bypass your browser's cache.
  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Cmd-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (Cmd-Shift-R on a Mac)
  • Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Clear the cache in Tools → Preferences

For details and instructions about other browsers, see Wikipedia:Bypass your cache.

/**
 * Simple script to warn if a page has been edited recently, indicating if
 * it might be "in progress".
 *
 * Configuration via the 'active_page_alert.config' hook:
 *
 * See [[User:Inductiveload/ActivePageAlert]] for instructions
 *
 * _@_install_page = User:Inductiveload/ActivePageAlert.js
 */

( function ( $, mw ) {

	if ( [ 'Special' ].indexOf( mw.config.get( 'wgCanonicalNamespace' ) ) !== -1 ) {
		return;
	}

	var APA = {
		signature: 'active_page_alert',
		cfg: {
			ignoreMinorEdits: true,
			ignoreOwnEdits: true,
			ignoreUsers: [
				/[bB]ot$/
			],
			revLimit: 25,
			globalTimeLimit: 30,
			userLimits: []
		},
		icons: {
			timeWarning: 'https://upload.wikimedia.org/wikipedia/commons/thumb/7/7d/OOjs_UI_icon_clock-warning.svg/20px-OOjs_UI_icon_clock-warning.svg.png',
			timeError: 'https://upload.wikimedia.org/wikipedia/commons/thumb/b/b9/OOjs_UI_icon_clock-destructive.svg/20px-OOjs_UI_icon_clock-destructive.svg.png',
			bot: 'https://upload.wikimedia.org/wikipedia/commons/thumb/7/71/OOjs_UI_icon_robot.svg/20px-OOjs_UI_icon_robot.svg.png'
		}
	};

	var getPageRevs = function ( title ) {

		var params = {
			action: 'query',
			format: 'json',
			formatversion: 2,
			titles: title,
			prop: 'revisions',
			rvprop: 'timestamp|user|flags|comment',
			rvlimit: APA.cfg.revLimit
		};

		return new mw.Api()
			.get( params )
			.then( function ( data ) {
				return data.query.pages[ 0 ].revisions;
			} );
	};

	var addIndicator = function ( url, title ) {
		// eslint-disable-next-line no-jquery/no-global-selector
		$( '.mw-indicators' )
			.append( $( '<img>' )
				.attr( 'src', url )
				.attr( 'title', title )
			);
	};

	var checkRevisions = function () {

		getPageRevs( mw.config.get( 'wgPageName' ) )
			.then( function ( revs ) {

				// e.g. a new page
				if ( !revs ) {
					return;
				}

				var now = Date.now();

				var timeSinceTs = function ( timestamp ) {
					return now - new Date( timestamp );
				};

				var pageStatus = {};

				// default to most recent
				pageStatus.sinceMostRecent = timeSinceTs( revs[ 0 ].timestamp );
				pageStatus.mostRecentEditor = revs[ 0 ].user;

				var recentRev;
				var icon = 'timeWarning';
				var myName = mw.config.get( 'wgUserName' );

				for ( var i = 0; i < revs.length; ++i ) {
					var r = revs[ i ];

					// ignore own edits
					if ( r.user === myName && APA.cfg.ignoreOwnEdits ) {
						continue;
					}

					var since = timeSinceTs( r.timestamp );

					// violates global limit
					if ( since < APA.cfg.globalTimeLimit * 60 * 1000 ) {

						if ( r.minor && APA.cfg.ignoreMinorEdits ) {
							continue;
						}

						for ( var j = 0; j < APA.cfg.ignoreUsers.length; ++j ) {
							if ( APA.cfg.ignoreUsers[ j ].test( r.user ) ) {
								continue;
							}
						}

						recentRev = r;
					} else {
						// check for a specific user config
						for ( var k = 0; k < APA.cfg.userLimits.length; ++k ) {
							var userLimit = APA.cfg.userLimits[ k ];

							if ( ( userLimit.user === r.user ) &&
								( ( userLimit.timeLimit === 0 ) ||
									( since < userLimit.timeLimit * 60 * 1000 ) ) ) {
								// exceeds set limit

								var ignoreMinor = ( userLimit.ignoreMinorEdits !== undefined ) ?
									userLimit.ignoreMinor : APA.cfg.ignoreMinorEdits;

								if ( r.minor && ignoreMinor ) {
									// do nothing
								} else {
									recentRev = r;
									icon = userLimit.icon || 'timeError';
								}
							}
						}
					}

					if ( recentRev ) {
						break;
					}
				}

				if ( recentRev ) {
					var timeAgo = Math.floor( timeSinceTs( recentRev.timestamp ) / ( 60 * 1000 ) );
					addIndicator( APA.icons[ icon ],
						'Edited $1 mins ago by $2: $3'
							.replace( '$1', timeAgo )
							.replace( '$2', recentRev.user )
							.replace( '$3', recentRev.comment )
					);
				}
			} );
	};

	$( function () {
		mw.hook( APA.signature + '.config' ).fire( APA );

		mw.loader.using( [ 'mediawiki.api' ], checkRevisions );
	} );

// eslint-disable-next-line no-undef
}( jQuery, mediaWiki ) );