Jump to content

User:SD0001/hide-reverted-edits.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by SD0001 (talk | contribs) at 18:42, 5 October 2021 (avoid declaring function() in top-level as these become accessible outside the script). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
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.
/**
 * Script to provide a button on page histories
 * which when clicked shows a sanitized version of the history
 * with reverted edits (and their reversions) removed
 *
 */
 
$.ready.then(function() {

	if (mw.config.get('wgAction') !== 'history') return;

	// bool: are the reverts currently hidden or not?
	var hidingReverts;

	if (/&hidereverted=y/.test(window.location.href)) {
		hideRevertedEdits();
		fixLinks(true);
		hidingReverts = true;
	} else {
		hidingReverts = false;
	}
	
	$('<button>')
		.addClass('reverted-edits-showhide')
		.addClass('mw-ui-button')
		.text(hidingReverts ? 'Show reverted edits' : 'Hide reverted edits')
		.css('margin-left', '3px')
		.on('click', function(e) {
			e.preventDefault();

			if (!hidingReverts) {
				hideRevertedEdits();
				$('.reverted-edits-showhide').text('Show reverted edits');
			} else {
				$('#pagehistory li').show();
				$('.reverted-edits-showhide').text('Hide reverted edits');
			}
			hidingReverts = !hidingReverts;
			fixLinks(hidingReverts);

		}).insertAfter('.mw-history-compareselectedversions input');

});

var hideRevertedEdits = function() {

	$('#pagehistory li').each(function(idx) {

		if (this.style.display === 'none') {
			return true; // continue if already hidden. This handles reverts of reverts.
		}

		var $this = $(this);

		var editcomment = $this.find('.comment').text();
		var rgx, reverted_user, last_good_revision;

		// Plain MediaWiki undo with untampered edit summary
		if (rgx = /^Undid revision (\d+) by/.exec(editcomment)) {
			var reverted_rev_id = rgx[1];
			var $reverted_rev = $('[data-mw-revid=' + reverted_rev_id +']');

			// just to confirm that the edit isn't a partial revert, find the byte count changes for the
			// two edits: if they add up to 0, then this is a full revert (in all likelihood)
			var diffbytes1 = parseInt($this.find('[class^=mw-plusminus]').text());
			var diffbytes2 = parseInt($reverted_rev.find('[class^=mw-plusminus]').text());

			if (diffbytes1 + diffbytes2 === 0) {
				$this.hide();
				$reverted_rev.hide();
				log(idx, $this.find('.mw-changeslist-date').text(), 'undo');
			}

		// 'Restore this version' reverts using Twinkle (old) or popups or pending changes reverts
		// TW(old): Reverted to revision 3234343 by ...
		// popups: 	Revert to revision 34234234 by ...
		// PC tool: Revereted 3 pending edits by Foo and Bar to revision 3243432 by ...
		} else if (rgx = /^Revert(?:ed)? (?:\d+ pending edits? by .*?)?to revision (\d+)/.exec(editcomment)) {
			last_good_revision = rgx[1];
			log(idx, $this.find('.mw-changeslist-date').text(), 'restore');

		// 'Restore this version' reverts using Twinkle (new)
		} else if (rgx = /^Restored revision (\d+) by/.exec(editcomment)) {
			last_good_revision = rgx[1];
			log(idx, $this.find('.mw-changeslist-date').text(), 'tw(new) restore');

		// Reverts tagged as "Rollback"
		} else if ($this.find('.mw-tag-marker-mw-rollback').length) {
			reverted_user = $this.next().find('.mw-userlink bdi').text();
		}

		// Twinkle rollbacks
		else if (rgx = /^Reverted (?:good faith|\d+) edits? by (.*?) \(talk\)/.exec(editcomment)) {
			reverted_user = rgx[1];
			log(idx, $this.find('.mw-changeslist-date').text(), 'Twinkle rollback');

		// Old Twinke vandalism rollback
		} else if (rgx = /^Reverted \d+ edits? by (.*?) identified as vandalism/.exec(editcomment)) {
			reverted_user = rgx[1];
			log(idx, $this.find('.mw-changeslist-date').text(), 'Twinkle (old) rollback');

		// STiki vandalism rollbacks, and all reverts using MediaWiki rollback, Huggle, Cluebot have the "Rollback" tag added
		// and hence would have been handled above. The regex checks here are to account for old reverts done before the
		// "Rollback" tag was introduced

		// STiki AGF/normal/vandalism revert
		} else if (rgx = /^Reverted \d+ (?:good faith )?edits? by (.*?) (?:identified as test\/vandalism )?using STiki/.exec(editcomment)) {
			reverted_user = rgx[1];
			log(idx, $this.find('.mw-changeslist-date').text(), 'STiki rollback');

		// normal MediaWiki rollback and Huggle rollback, and redwarn rollback
		// MW/Huggle: Reverted edits by User (talk)
		// RedWarn:   Reverting edit(s) by User (talk)
		} else if (rgx = /^Revert(?:ed|ing) edit\(?s\)? by (.*?) \(talk\)/.exec(editcomment)) {
			reverted_user = rgx[1];
			log(idx, $this.find('.mw-changeslist-date').text(), 'mw/huggle/redwarn rollback');

		// ClueBot
		} else if (['ClueBot NG', 'ClueBot'].includes($this.find('.mw-userlink bdi').text())) {
			reverted_user = /^Reverting possible vandalism by (.*?) to version by/.exec(editcomment)?.[1];
			log(idx, $this.find('.mw-changeslist-date').text(), 'cluebot rollback');

		// XLinkBot
		} else if ($this.find('.mw-userlink bdi').text() === 'XLinkBot') {
			reverted_user = /^BOT--Reverting link addition\(s\) by (.*?) to/.exec(editcomment)?.[1];
			log(idx, $this.find('.mw-changeslist-date').text(), 'xlinkbot rollback');
		}
		
		if (reverted_user) {
	
			// page history shows compressed IPv6 address (with multiple 0's replaced by ::)
			// though rollback edit summaries use the uncompressed form (though with leading 0's removed)
			if (mw.util.isIPv6Address(reverted_user)) {
				reverted_user = reverted_user.replace(/\b(?:0+:){2,}/, ':').toLowerCase();
			}
			$this.hide();
			var $rev = $this.next();
			while ($rev.find('.mw-userlink bdi').text() === reverted_user) {
				$rev.hide();
				$rev = $rev.next();
				if ($rev.length === 0) break; // end of page history (in current view)
			}
		}
		
		if (last_good_revision) {
			
			$this.hide();
			var $rev = $this.next();
			if (parseInt(last_good_revision) > parseInt($rev.attr('data-mw-revid')) ||
				parseInt(last_good_revision) < 100) { // sanity checks
				return true; // revision id given has to be wrong
			}
			while ($rev.attr('data-mw-revid') !== last_good_revision) {
				$rev.hide();
				$rev = $rev.next();
				if ($rev.length === 0) break; // end of page history in current view
			}

		}

	});

}

/**
 * Add or remove "&hidereverted=y" from the targets of links:
 * (newest | oldest) (newer n | older n) (20 | 50 | 100 | 250 | 500)
 */
var fixLinks = function(hidingReverts) {
	if (hidingReverts) {
		if (!/&hidereverted=y/.test($('.mw-numlink').attr('href'))) {
			$('.mw-firstlink, .mw-lastlink, .mw-prevlink, .mw-nextlink, .mw-numlink').each(function() {
				this.href += '&hidereverted=y';
			});
		}
	} else {
		$('.mw-firstlink, .mw-lastlink, .mw-prevlink, .mw-nextlink, .mw-numlink').each(function() {
			this.href = this.href.replace(/&hidereverted=y/, '');
		});
	}
}

var log = function(...args) {
	if (window.hre_debug) console.log(...args);
}