User:BryghtShadow/ChatTimetamps.js

/** *Applies timestamps to inline-alert messages. *@Author: BryghtShadow * *@TODO: See if https://www.mediawiki.org/w/index.php?title=Localisation&oldid=597928#Using_messages_in_JavaScript is possible, * so that all effort isn't put into JS resources. */ //( function ( $, mw ) { jQuery( document ).ready( function ( $ ) { var config, myLib; console.log("ChatTimetamps.js: r" + wgCurRevisionId);

if (wgCanonicalSpecialPageName !== "Chat" || skin !== "oasis") { return; }

function padStr(i) { return ((i < 10) ? "0" : "") + i;   } var months, weekdays; months = (wgMonthNames === undefined && (wgMonthNames.length > 0)) ? wgMonthNames : ["", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; weekdays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];

/* This simulates incoming messages. $(".press").bind("click", function {       var $e = $(document.createElement("p"))            .addClass("inline-alert")            .text("Hello " + Math.round(100*Math.random(100)));        $("#txt").append($e);    }); */

/* 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;   }

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; default: monSwitchDefault(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 }       */      }      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; }

config = [];

config.format = "H:i j M Y"; config.date = "now";

/**    * Continuously check the DOM * for inline-alerts that haven't been timestamped. */   function start { var t = setInterval(function {           var now = new Date;            //$("#clock").text("Current time: "+config.date.toUTCString);            $('.inline-alert:not(:has(span))').append( $(document.createElement("span")) .text(time(config.format, strtotime(config.date, now))) .addClass("date") );       }, 100);    }

//} ( jQuery, mediaWiki ) ); } );