MediaWiki:Common.js/chatLogView.js

/*

simulate chat room with archived logs - currently in experimental stages

affects:  installation: Chat Logs Viewer Entry Point



/* defie signle object to functions */ ChatLogView = {}; ChatLogView.lastDate = null;

/* markup starts here */ // Chat Logs Viewer Entry Point $("#chat-log-view").replaceWith(' \n\ \t Search for chat logs \n\ \t\n\ \t\t\n\ \t\t\n\ \t\t\t -- Pick a Month -- \n\ \t\t\tJanuary \n\ \t\t\tFebruary \n\ \t\t\tMarch \n\ \t\t\tApril \n\ \t\t\tMay \n\ \t\t\tJune \n\ \t\t\tJuly \n\ \t\t\tAugust \n\ \t\t\tSeptember \n\ \t\t\tOctober \n\ \t\t\tNovember \n\ \t\t\t<option value="December">December \n\ \t\t \n\ \t\t<select name="chat-logs-form-dd">\n\ \t\t\t -- Pick a Day -- \n\ \t\t\t 01 \n\ \t\t\t 02 \n\ \t\t\t 03 \n\ \t\t\t 04 \n\ \t\t\t 05 \n\ \t\t\t 06 \n\ \t\t\t 07 \n\ \t\t\t 08 \n\ \t\t\t 09 \n\ \t\t\t 10 \n\ \t\t\t 11 \n\ \t\t\t 12 \n\ \t\t\t 13 \n\ \t\t\t 14 \n\ \t\t\t 15 \n\ \t\t\t 16 \n\ \t\t\t 17 \n\ \t\t\t 18 \n\ \t\t\t 19 \n\ \t\t\t 20 \n\ \t\t\t 21 \n\ \t\t\t 22 \n\ \t\t\t 23 \n\ \t\t\t 24 \n\ \t\t\t 25 \n\ \t\t\t 26 \n\ \t\t\t 27 \n\ \t\t\t 28 \n\ \t\t\t 29 \n\ \t\t\t 30 \n\ \t\t\t 31 \n\ \t\t \n\ \t\t<select name="chat-logs-form-yy">\n\ \t\t\t -- Pick a Year -- \n\ \t\t\t 2014 \n\ \t\t\t 2013 \n\ \t\t\t 2012 \n\ \t\t \n\ \t\t \n\ \t\t<input type="button" value="Go" id="chat-logs-form-go" />\n\ \t \n\ \n\ Results \n\ \n\ \t \n\ \t</ul>\n\ ');

/* functions start here */

// escape regex - by CoolAJ86 http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex#answer-6969486 ChatLogView.escape = function(s) { return s.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); }

// avatar loader ChatLogView.getAvatars = function(users) { $.getJSON("/api.php?action=query&format=json&list=users&ususers=" + users.join("|"), function(data) {		var a = data.query.users,			b = [];		for (var i = 0; i < a.length; i++) {			b.push(a[i].userid);			if (i + 1 == a.length) {				var getAvatarUrls = function(ids) {					$.getJSON("/api/v1/User/Details?ids=" + ids.splice(0,50).join(","), function(data) { window.FOO = data; // ALERT var items = data.items; for (var i = 0; i < items.length; i++) { console.log("Setting avatar image to " + items[i].title + "."); $('#chat-logs-container img.avatar[data-user="' + items[i].title.replace(/_/g," ") + '"]').each(function {								$(this)									.attr("src", items[i].avatar)									.removeAttr("data-user").									error(function { $(this).attr(											"src",											$(this).attr("src").split("?")[0] + "?cb=" + new Date.getTime										); });							});							if (i + 1 == items.length) { if (ids.length == 0) { $("#chat-logs-container > div").html(""); } else { getAvatarUrls(ids); }							}						}					});				}				getAvatarUrls(b);			}		}	}); }

// creator ChatLogView.getLogs = function(dd,mm,yy) { $("div#chat-logs-container > div").html('<img src="http://upload.wikimedia.org/wikipedia/commons/2/2a/Loading_Key.gif" />'); var logPagePath = (String(dd).length == 1 ? String("0" + dd) : String(dd)) + "_" + mm + "_" + yy; $.getJSON("/api.php?action=query&format=json&prop=revisions&titles=Club_Penguin_Wiki:Chat/Logs/" + logPagePath + "&rvprop=content&cb=" + new Date.getTime, function(data) {		var cotentRawObject = data.query.pages;		if (typeof cotentRawObject["-1"] === "object") {			// logs for the inserted value don't exist			$("div#chat-logs-container > div").html(' Chat logs for ' + mm + ' ' + dd + ', ' + yy + ' don\'t exist. Please try a different date');		} else {			// chat logs exist - find the content and process it			// usage of web workers might be better than executing on the same page			for (var pageid in cotentRawObject) {				var contentRaw = cotentRawObject[pageid].revisions[0]["*"],					content = contentRaw.split('<pre class=\"ChatLog\">\n')[1].split('\n<\/pre>')[0],					contentArray = content.split("\n"),					results = [],					users = [];				for (var i = 0; i < contentArray.length; i++) {					if (["</pr",""].indexOf(contentArray[i]) > -1) {						// problem with the log itself - do nothing					} else if (contentArray[i].substr(6).indexOf("-!-") === 0) {						// this is an inline alert (with traditional time stamps)						results.push('<li class="inline-alert">' + contentArray[i].substr(10) + '</li>');					} else if (contentArray[i].search(/\[\d{4,}-\d\d-\d\d \d\d\:\d\d\:\d\d\] -\!- /) === 0) {						// this is an inline alert (with modern time stamps) results.push('<li class="inline-alert">' + contentArray[i].substr(26) + '</li>'); } else if (contentArray[i].search(/\[\d{4,}-\d\d-\d\d \d\d\:\d\d\:\d\d\] +\* /) == 0) { // this is a parsed /me message var parsedMeMsg = contentArray[i].substr(contentArray[i].search(/\*/) + 2), checkMeUsername = function(NAME) { if (content.search(new RegExp("\\[\\d{4,}-\\d\\d-\\d\\d \\d\\d\\:\\d\\d\\:\\d\\d\\] -\\!- " + ChatLogView.escape(NAME) + " has (joined|left) Special\\:Chat")) > -1) { return NAME; } else if (NAME.length == 0) { results.push('<li class="inline-alert">LINE ERROR - /ME COMMAND - AT INDEX ' + i + '</li>'); } else { return checkMeUsername(NAME.split(" ").splice(0, NAME.split(" ").length - 1).join(" ")); }							},							time = contentArray[i].search(/[012][0-9]\:[0-5][0-9]/) == 0 ? /* traditional time format */ contentArray[i].substr(0,5) : contentArray[i].substr(12,5), user = checkMeUsername(parsedMeMsg), message = contentArray[i].substr(contentArray[i].search("] * " + user) + 1), clearMessage = message.substr(/^\[[\d- \:]+\] +/.exec(message)[0].length),							markup = '<li data-user="' + user + '">\n' +										'\t<img width="28" height="28" class="avatar" data-user="' + user + '" />\n' +										'\t ' + time + ' \n' +										'\t ' + user + ' \n' +										'\t ' + clearMessage + ' \n' +									'</li>';						results.push(markup);						if (users.indexOf(encodeURIComponent(user.replace(/ /g, "_"))) === -1) {							users.push(encodeURIComponent(user.replace(/ /g, "_"))); // add user to the user array if hasn't been added yet						}					} else {						// this is an ordinary message, or also an unparsed /me message, for some reason						var time = contentArray[i].search(/[012][0-9]\:[0-5][0-9]/) == 0 ? /* traditional time format */ contentArray[i].substr(0,5) : contentArray[i].substr(12,5),							user = contentArray[i].split("&lt;")[1].split("&gt;")[0], // might cause problems if the user has a & in his name							message = contentArray[i].substr(contentArray[i].search("&gt; ") + 5),							markup = '<li data-user="' + user + '">\n' +										'\t<img width="28" height="28" class="avatar" data-user="' + user + '" />\n' +										'\t ' + time + ' \n' +										'\t ' + user + ' \n' +										'\t ' + message + ' \n' +									'</li>';						results.push(markup);						if (users.indexOf(encodeURIComponent(user.replace(/ /g, "_"))) === -1) {							users.push(encodeURIComponent(user.replace(/ /g, "_"))); // add user to the user array if hasn't been added yet						}					}					if (i + 1 == contentArray.length) {						$("div#chat-logs-container ul").html(results.join("\n"));						$("div#chat-logs-container > div").prepend(' Starts updating avatars...');						console.log("Starts avatar replacing.");						ChatLogView.getAvatars(users);					}				}			}		}	}); }

/* function trigger */ $("#chat-logs-form-go").click(function {	if ( $('select[name="chat-logs-form-dd"]').val == "none" || $('select[name="chat-logs-form-mm"]').val == "none" || $('select[name="chat-logs-form-yy"]').val == "none" ) {		$("img#chat-logs-form-error").show;		$("form#chat-logs-form select").each(function { if ($(this).val == "none") { $(this).css("border", "2px solid #c00"); } else { $(this).removeAttr("style"); }		});	} else if (ChatLogView.lastDate === $('[name="chat-logs-form-yy"]').val + $('[name="chat-logs-form-mm"]').val + $('[name="chat-logs-form-dd"]').val) {		$("div#chat-logs-container > div").html(' The date that you tried to trigger is currently displayed. Please pick a different date.');	} else {		$("img#chat-logs-form-error").hide;		$("form#chat-logs-form select[style]").removeAttr("style");		ChatLogView.lastDate = $('[name="chat-logs-form-yy"]').val + $('[name="chat-logs-form-mm"]').val + $('[name="chat-logs-form-dd"]').val;		ChatLogView.getLogs( $('select[name="chat-logs-form-dd"]').val, $('select[name="chat-logs-form-mm"]').val, $('select[name="chat-logs-form-yy"]').val );	} });

/* style the results */ mw.util.addCSS(	'#chat-logs-container {\n' +		'\tmax-height: 482px;\n' +		'\toverflow-y: scroll;\n' + 		'\tborder: 1px solid #ccc;\n' +	'}\n' +	'#chat-logs-container .time {\n' +		'\tcolor: #9c9c9c;\n' +		'\tfloat: right;\n' + 		'\tfont-size: 12px;\n' +	'}\n' +	'#chat-logs-container ul {\n' +		'\tlist-style: none;\n' +		'\tmargin: 0px;\n' +		'\tpadding-top: 5px;\n' +		'\tpadding-bottom: 5px;\n' +	'}\n' +	'#chat-logs-container li {\n' +		'\tword-wrap: break-word;\n' +		'\tmin-height: 32px;\n' +		'\tpadding: 18px 15px 16px 55px;\n' +		'\tposition: relative;\n' +	'}\n' +	'#chat-logs-container img.avatar {\n' +		'\tborder: 1px solid #ccc;\n' +		'\tleft: 15px;\n' +		'\tposition: absolute;\n' +		'\ttop: 20px;\n' +	'}\n' +	'#chat-logs-container img.avatar:not([src]) {\n' +		'\t-webkit-box-shadow: 0 0 2px 2px #cc0000;\n' +		'\tbox-shadow: 0 0 2px 2px #cc0000;\n' +	'}\n' +	'#chat-logs-container li.continued img.avatar {\n' + '\tdisplay: none;\n' + '}\n' + '#chat-logs-container .username {\n' + '\tdisplay: block;\n' + '\tfont-weight: bold;\n' + '}\n' + '#chat-logs-container .message {\n' + '\tdisplay: white-space: pre-line;\n' + '}' +	'#chat-logs-container .message.me-message {\n' + '\tcolor: #9c9c9c;\n' + '\tcolor: #9c9c9c;\n' + '}' +	'#chat-logs-container .inline-alert {\n' + '\tcolor: #9c9c9c;\n' + '\tfont-weight: bold;\n' + '\tmin-height: 0;\n' + '\tpadding-bottom: 10px;\n' + '\tpadding-top: 10px;\n' + '\ttext-align: center;\n' + '}' +	'#chat-logs-container .inline-alert:before {\n' + '\tcontent: "~ ";' + '}' +	'#chat-logs-container .inline-alert:after {\n' + '\tcontent: " ~";' + '}' +	'#chat-logs-container > div {' + '\tpadding-top: 10px;' + '}' );