User:BryghtShadow/ChatTimetamps.js

// ==UserScript== // @name       ChatHistory // @namespace  wikia // @include    http* // @grant      none // @version    1 // ==/UserScript==

/** * Applies timestamps to inline-alert messages. * * In the simulation code, I haven't really got a decent inline message * @Author: BryghtShadow * * @param chatTimestampFormat	- format of output * @param chatTimestampDate	- format of input * @param chatTimestampFreq	- frequency of stamping in milliseconds. * * @TODO: https://www.mediawiki.org/w/index.php?title=Localisation&oldid=597928#Using_messages_in_JavaScript * See if that is possible, so that all effort isn't put into JS resources. */ //(function ($, mw) { //jQuery(document).ready(function ($) { var myCspn, mySkin, chatTimestampFormat, chatTimestampDate, chatTimestampFreq, months, weekdays; console.log("ChatTimetamps.js: " + new Date(2012, 16, 11)); // Configs chatTimestampFormat = "H:i, j M Y"; chatTimestampDate = "now"; chatTimestampFreq = 200; // jsfiddle connot see wg namespace. if (typeof wgCanonicalSpecialPageName === "undefined") { myCspn = "Chat"; } else { myCspn = wgCanonicalSpecialPageName; }	if (typeof skin === "undefined") { mySkin = "oasis"; } else { mySkin = skin; }	if (myCspn !== "Chat" || mySkin !== "oasis") { console.log("Not on chat, or not using oasis. Exiting"); return; }	if (typeof wgMonthNames === 'undefined') { months = ["", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; } else { months = wgMonthNames; }	weekdays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; function padStr(i) { return ((i < 10) ? "0" : "") + i;	} /* This simulates incoming messages.*/ /*	$(".press").bind("click", function {		console.log("Simulating incoming inline-alerts");		$("#txt").append($(document.createElement("p")).addClass("inline-alert").text("~ Inline-alert with random id of " + Math.round(100*Math.random(100)) + " ~"));	}); */	/** http://stackoverflow.com/a/315767 */ function getDaysInMonth(month, year) { return new Date(year, month, 0).getDate; }	/** http://stackoverflow.com/a/8175905 */ function isLeapYear(year) { return (new Date(year, 1, 29).getMonth === 1) ? 1 : 0;	}	/** http://phpjs.org/functions/strtotime/ */ function strtotime(str, now) { // http://kevin.vanzonneveld.net // +  original by: Caio Ariede (http://caioariede.com) // +  improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // +     input by: David // +  improved by: Caio Ariede (http://caioariede.com) // +  improved by: Brett Zamir (http://brett-zamir.me) // +  bugfixed by: Wagner B. Soares // +  bugfixed by: Artur Tchernychev // +  input by: wookie // %       note 1: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones) // *    example 1: strtotime('+1 day', 1129633200); // *    returns 1: 1129719600 // *    example 2: strtotime('+1 week 2 days 4 hours 2 seconds', 1129633200); // *    returns 2: 1130425202 // *    example 3: strtotime('last month', 1129633200); // *    returns 3: 1127041200 // *    example 4: strtotime('2009-05-04 08:30:00'); // *    returns 4: 1241418600 var i,		l, match, s, parse = ''; str = (str + ).replace(/\s{2,}|^\s|\s$/g, ' ').replace(/[\t\r\n]/g, ); // unecessary spaces and chars if (str === 'now') { return now === null || isNaN(now) ? new Date.getTime / 1000 | 0 : now | 0; } else if (!isNaN(parse = Date.parse(str))) { return parse / 1000 | 0; } else if (now) { now = new Date(now * 1000); // Accept PHP-style seconds } else { now = new Date; }		str = str.toLowerCase; var __is = { day : { 'sun' : 0, 'mon' : 1, 'tue' : 2, 'wed' : 3, 'thu' : 4, 'fri' : 5, 'sat' : 6 },			mon : [ 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec' ]		};		var monSwitchDefault = function (m) { var day = __is.day[m[1].substring(0, 3)]; if (typeof day !== 'undefined') { var diff = day - now.getDay; if (diff === 0) { diff = 7 * num; } else if (diff > 0) { if (m[0] === 'last') { diff -= 7; }				} else { if (m[0] === 'next') { diff += 7; }				}				now.setDate(now.getDate + diff); now.setHours(0, 0, 0, 0); // when jumping to a specific last/previous day of week, PHP sets the time to 00:00:00 }		};		var process = function (m) { var ago = (m[2] && m[2] === 'ago'); var num = (num = m[0] === 'last' ? -1 : 1) * (ago ? -1 : 1); switch (m[0]) { case 'last': case 'next': switch (m[1].substring(0, 3)) { case 'yea': now.setFullYear(now.getFullYear + num); break; case 'wee': now.setDate(now.getDate + (num * 7)); break; case 'day': now.setDate(now.getDate + num); break; case 'hou': now.setHours(now.getHours + num); break; case 'min': now.setMinutes(now.getMinutes + num); break; case 'sec': now.setSeconds(now.getSeconds + num); break; case 'mon': if (m[1] === "month") { now.setMonth(now.getMonth + num); break; }					monSwitchDefault(m); // fall through break; // JSFiddle's JSLint does not like fallthrough into default. default: monSwitchDefault(m); }				break; default: if (/\d+/.test(m[0])) { num *= parseInt(m[0], 10); switch (m[1].substring(0, 3)) { case 'yea': now.setFullYear(now.getFullYear + num); break; case 'mon': now.setMonth(now.getMonth + num); break; case 'wee': now.setDate(now.getDate + (num * 7)); break; case 'day': now.setDate(now.getDate + num); break; case 'hou': now.setHours(now.getHours + num); break; case 'min': now.setMinutes(now.getMinutes + num); break; case 'sec': now.setSeconds(now.getSeconds + num); break; }				} else { return false; }				break; }			return true; };		match = str.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/); if (match !== null) { if (!match[2]) { match[2] = '00:00:00'; } else if (!match[3]) { match[2] += ':00'; }			s = match[1].split(/-/g); s[1] = __is.mon[s[1] - 1] || s[1]; s[0] = +s[0]; s[0] = (s[0] >= 0 && s[0] <= 69) ? '20' + (s[0] < 10 ? '0' + s[0] : s[0] + '') : (s[0] >= 70 && s[0] <= 99) ? '19' + s[0] : s[0] + ''; return parseInt(this.strtotime(s[2] + ' ' + s[1] + ' ' + s[0] + ' ' + match[2]) + (match[4] ? match[4] / 1000 : ''), 10); }		var regex = '([+-]?\\d+\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)' + '|(last|next)\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))' + '(\\sago)?'; match = str.match(new RegExp(regex, 'gi')); // Brett: seems should be case insensitive per docs, so added 'i'		if (match === null) { return false; }		for (i = 0, l = match.length; i < l; i++) { if (!process(match[i].split(' '))) { return false; }		}		return now.getTime / 1000 | 0; }	/** Attempt to mirror the functionality of http://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23time */ function time { var args, fmt, now, d, i, result; args = arguments; fmt = args[0]; if (fmt === undefined) { return fmt; }		now = (args.length > 1) ? args[1] : new Date; result = ''; d = { "year" : now.getUTCFullYear, "month" : now.getUTCMonth + 1, "date" : now.getUTCDate, "day" : now.getUTCDay, "hours" : now.getUTCHours, "minutes" : now.getUTCMinutes, "seconds" : now.getUTCSeconds };		d.Y = d.year; d.y = d.year % 100; d.L = isLeapYear(d.year); d.o = 'o'; //ISO-8601 year number. d.n = d.month; d.m = padStr(d.month); d.M = months[d.month].slice(0, 3); d.F = months[d.month]; d.W = 'W'; //ISO 8601 week number, zero-padded. d.j = d.date; d.d = padStr(d.date); d.z = (new Date(d.year, d.month, d.date) - new Date(d.year, 0, 1)) / 86400000; d.D = weekdays[d.day].slice(0, 3); d.l = weekdays[d.day]; d.N = (d.day === 0) ? d.day + 1 : d.day; d.w = d.day; d.a = (d.hours >= 12) ? 'pm' : 'am'; d.A = (d.hours >= 12) ? 'PM' : 'AM'; d.g = (d.hours % 12); d.h = padStr(d.hours % 12); d.G = d.hours; d.H = padStr(d.hours); d.i = padStr(d.minutes); d.s = padStr(d.seconds); d.U = Math.floor(now / 1000); d.t = getDaysInMonth(d.month, d.year); d.c = now.toISOString.slice(0, "YYYY-MM-DDTHH:mm:ss".length) + "+00:00"; d.r = d.D + ", " + d.j + " " + d.M + " " + d.Y + " " + d.H + ":" + d.i + ":" + d.S + "+00:00"; for (i = 0; i < fmt.length; i++) { result += (d[fmt[i]] === undefined) ? fmt[i] : d[fmt[i]]; }		return result; }

/**	 * Continuously check the DOM for inline-alerts that haven't been timestamped. * Note: Until Wikia provides timestamps in their inline-alerts, there isn't much else we can do. */	function myScript { setInterval(function {			var now,			t;			now = new Date;			t = time(chatTimestampFormat, new Date(strtotime(chatTimestampDate, now)));			// Output the time to a #clock, useful for debug.			// $("#clock").text("Config time = " + t + ", utc = " + now.toUTCString);			$('.inline-alert:not(:has(span))').append($(document.createElement("span")).text(t).addClass("date"));		}, chatTimestampFreq); }	/** Document is ready, so run the script! ^_^ */	$(document).ready(myScript); //myScript; //} ( jQuery, mediaWiki ) ); //});