Jump to content

User:Evad37/TimestampDiffs.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Evad37 (talk | contribs) at 11:17, 27 November 2019 (.). 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.
/***************************************************************************************************
 TimestampDiffs --- by Evad37
 > Links timestamp to diffs on discussion pages
----------------------------------------------------------------------------------------------------
***************************************************************************************************/
/* jshint esversion: 5, laxbreak: true, undef: true, maxerr: 999*/
/* globals console, window, $, mw, OO, extraJs */
// <nowiki>

$.when(
	// Resource loader modules
	mw.loader.using([
		'mediawiki.util', 'mediawiki.api', 'mediawiki.Uri',
		'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows'
	]),
	// Page ready
	$.ready
).then(function() {
	var config = {
		scriptVersion: "1.0.0",
		mw: mw.config.get(['wgNamespaceNumber', 'wgPageName']),
		wgMonthNames: ["", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
	};
	var isTalkPage = config.mw.wgNamespaceNumber %2 === 1;
	var isProjectPage = config.mw.wgNamespaceNumber === 4;
	if( !isTalkPage && !isProjectPage ) {
		// only operate in Special: namespace
		return;
	}

	var portletLink = mw.util.addPortletLink('p-tb', '#', 'TimestampDiffs', 'tb-tsdiffs');

	$(portletLink).click(function(e) {
		e.preventDefault();
		$(portletLink).hide();

		var API = new mw.Api( {
			ajax: {
				headers: { 
					'Api-User-Agent': 'TimestampDiffs/' + config.scriptVersion + 
						' ( https://en.wikipedia.org/wiki/User:Evad37/TimestampDiffs )'
				}
			}
		} );

		var messagesPromise = API.get( {
			action: 'query',
			meta: 'allmessages',
			ammessages: [ "Diff" ],
			amenableparser: 1,
			amargs: mw.config.get('wgUserName')
		} ).then(function(response) {
			var messages = {};
			response.query.allmessages.forEach(function(message) {
				messages[message.normalizedname] = message['*'];
			});
			return messages;
		});

		var revisionsPromise = API.get({
			action: "query",
			format: "json",
			prop: "revisions",
			titles: config.mw.wgPageName,
			indexpageids: 1,
			rvprop: "timestamp|ids",
			rvlimit: "500"
		}).then(function(response) {
			var id = response.query.pageids[0];
			return response.query.pages[id].revisions;
		});

		var dateFromSigTimestamp = function(sigTimestamp) {
			var pattern = /(\d\d\:\d\d), (\d{1,2}) (\w+) (\d\d\d\d) \(UTC\)/;
			var parts = pattern.exec(sigTimestamp);
			if ( parts === null ) {
				return NaN;
			}
			var year = parts[4];
			var monthIndex = config.wgMonthNames.indexOf(parts[3]);
			if ( monthIndex === -1 ) {
				return NaN;
			}
			var month = ( monthIndex < 10 )
				? '0' +  monthIndex
				: monthIndex;
			var day = ( parts[2].length === 1 )
				? '0' + parts[2]
				: parts[2];
			var time = 'T' + parts[1] + 'Z';
			var iso8601DateString = year + '-' + month + '-' + day + time;
			return Date.parse(iso8601DateString) && new Date(iso8601DateString);
		};
		/**
		 * 
		 * @param {string[]|number[]} array 
		 * @returns {string[]|number[]} array with only unique values
		 * e.g. `uniqueArray(["apple", "apple", "orange"])` returns `["apple", "orange"]`
		 */
		function uniqueArray(array) {
			if (!array || !Array.isArray(array) || array.length === 0)
				return [];
			var seen = {};
			var unique = [];
			array.forEach(function(item) {
				if (!seen[item]) {
					unique.push(item);
					seen[item] = true;
				}
			});
			return unique;
		}

		$.when(messagesPromise, revisionsPromise).then(function(messages, revisions) {
			mw.util.$content.find(':contains(" (UTC)")').not(':has(:contains(" (UTC)"))').each(function() {
				var $el = $(this);
				var htmlString = $el.html();
				var timestamps = htmlString.match(/\d\d\:\d\d, \d{1,2} \w+ \d\d\d\d \(UTC\)/);
				if (timestamps.length === 0) {
					return;
				}
				uniqueArray(timestamps).forEach(function(timestamp) {
					var rev = revisions.find(function(revision) {
						return dateFromSigTimestamp(timestamp).getTime() === new Date(revision.timestamp.replace(/\:\d\dZ/,":00Z")).getTime();
					});
					if (!rev) {
						return;
					}
					var linkedTimestamp = $('<a>')
						.text(timestamp)
						.attr({
							"href": mw.util.getUrl("Special:Diff/"+rev.revid),
							"title": messages.diff
						})
						.html();
					htmlString.replace(
						new RegExp(mw.util.escapeRegExp(timestamp),'g'),
						linkedTimestamp
					);
				});
				$el.html(htmlString);
			});
		}).catch(function(code, err) {
			console.error("TimestampDiffs", {"code": code, "error": err});
		});
	});
});
// </nowiki>