2016-09-22 17:15:40 +00:00
|
|
|
window.irc = {
|
|
|
|
socketUp: false,
|
2016-09-23 07:38:47 +00:00
|
|
|
primaryFrame: null,
|
2016-09-25 18:48:35 +00:00
|
|
|
config: {
|
|
|
|
colors: true,
|
|
|
|
sharedInput: false,
|
|
|
|
timestamps: true,
|
|
|
|
timestampFormat: "HH:mm:ss",
|
|
|
|
colorNicknames: true,
|
2016-09-28 18:00:57 +00:00
|
|
|
colorNicklist: false,
|
2016-09-29 13:47:24 +00:00
|
|
|
scrollOnResize: true,
|
|
|
|
scrollOnFocus: true,
|
2016-09-28 18:00:57 +00:00
|
|
|
theme: "default"
|
2016-09-25 18:48:35 +00:00
|
|
|
},
|
2016-09-23 14:26:31 +00:00
|
|
|
serverData: {},
|
2016-09-23 21:38:09 +00:00
|
|
|
serverChatQueue: {},
|
2016-09-24 12:25:47 +00:00
|
|
|
chatType: "simple",
|
2016-09-29 13:47:24 +00:00
|
|
|
documentTitle: "TeemantIRC",
|
2016-09-22 17:15:40 +00:00
|
|
|
};
|
|
|
|
|
2016-09-25 18:48:35 +00:00
|
|
|
window.clientdom = {connector: {}, settings: {}};
|
2016-09-23 12:36:56 +00:00
|
|
|
|
2016-09-24 12:25:47 +00:00
|
|
|
window.colorizer = {
|
|
|
|
get_random_color: function(nickname) {
|
2016-09-28 18:00:57 +00:00
|
|
|
let themefunc = window.themes.available[irc.config.theme].nick_pallete;
|
|
|
|
|
2016-09-24 12:25:47 +00:00
|
|
|
Math.seedrandom(nickname);
|
2016-09-28 18:00:57 +00:00
|
|
|
let h = rand(themefunc.H[0], themefunc.H[1]);
|
|
|
|
let s = rand(themefunc.S[0], themefunc.S[1]);
|
|
|
|
let l = rand(themefunc.L[0], themefunc.L[1]);
|
2016-09-24 12:25:47 +00:00
|
|
|
return 'hsl(' + h + ',' + s + '%,' + l + '%)';
|
2016-09-25 18:48:35 +00:00
|
|
|
},
|
|
|
|
strip: function(message) {
|
|
|
|
return message.replace(/(\x03\d{0,2}(,\d{0,2})?)/g, '').replace(/[\x0F\x02\x16\x1F]/g, '');
|
2016-09-24 12:25:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-25 15:21:28 +00:00
|
|
|
let urlParams = {};
|
|
|
|
|
2016-09-23 09:47:12 +00:00
|
|
|
/*********************\
|
|
|
|
|** **|
|
|
|
|
|** UTILITIES **|
|
|
|
|
|** **|
|
|
|
|
\*********************/
|
|
|
|
|
2016-09-22 17:15:40 +00:00
|
|
|
window.validators = {};
|
|
|
|
|
|
|
|
window.validators.iporhost = function(str) {
|
|
|
|
let valid = false;
|
|
|
|
|
|
|
|
if(str.match(/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/i)) {
|
|
|
|
valid = true;
|
|
|
|
} else if (str.match(/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/i)) {
|
|
|
|
valid = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return valid;
|
|
|
|
}
|
|
|
|
|
|
|
|
window.validators.nickname = function(str) {
|
|
|
|
if(str.match(/[a-z_\-\[\]\\^{}|`][a-z0-9_\-\[\]\\^{}|`]*/i)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-09-26 15:41:48 +00:00
|
|
|
window.validators.escapeHTML = function(str) {
|
|
|
|
return str.replace(/\</g, '<').replace(/\>/, '>');
|
|
|
|
}
|
|
|
|
|
2016-09-23 09:47:12 +00:00
|
|
|
Date.prototype.format = function (format, utc){
|
|
|
|
var date = this;
|
|
|
|
var MMMM = ["\x00", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
|
|
var MMM = ["\x01", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
|
|
var dddd = ["\x02", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
|
|
|
var ddd = ["\x03", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
|
|
function ii(i, len) { var s = i + ""; len = len || 2; while (s.length < len) s = "0" + s; return s; }
|
|
|
|
|
|
|
|
var y = utc ? date.getUTCFullYear() : date.getFullYear();
|
|
|
|
format = format.replace(/(^|[^\\])yyyy+/g, "$1" + y);
|
|
|
|
format = format.replace(/(^|[^\\])yy/g, "$1" + y.toString().substr(2, 2));
|
|
|
|
format = format.replace(/(^|[^\\])y/g, "$1" + y);
|
|
|
|
|
|
|
|
var M = (utc ? date.getUTCMonth() : date.getMonth()) + 1;
|
|
|
|
format = format.replace(/(^|[^\\])MMMM+/g, "$1" + MMMM[0]);
|
|
|
|
format = format.replace(/(^|[^\\])MMM/g, "$1" + MMM[0]);
|
|
|
|
format = format.replace(/(^|[^\\])MM/g, "$1" + ii(M));
|
|
|
|
format = format.replace(/(^|[^\\])M/g, "$1" + M);
|
|
|
|
|
|
|
|
var d = utc ? date.getUTCDate() : date.getDate();
|
|
|
|
format = format.replace(/(^|[^\\])dddd+/g, "$1" + dddd[0]);
|
|
|
|
format = format.replace(/(^|[^\\])ddd/g, "$1" + ddd[0]);
|
|
|
|
format = format.replace(/(^|[^\\])dd/g, "$1" + ii(d));
|
|
|
|
format = format.replace(/(^|[^\\])d/g, "$1" + d);
|
|
|
|
|
|
|
|
var H = utc ? date.getUTCHours() : date.getHours();
|
|
|
|
format = format.replace(/(^|[^\\])HH+/g, "$1" + ii(H));
|
|
|
|
format = format.replace(/(^|[^\\])H/g, "$1" + H);
|
|
|
|
|
|
|
|
var h = H > 12 ? H - 12 : H == 0 ? 12 : H;
|
|
|
|
format = format.replace(/(^|[^\\])hh+/g, "$1" + ii(h));
|
|
|
|
format = format.replace(/(^|[^\\])h/g, "$1" + h);
|
|
|
|
|
|
|
|
var m = utc ? date.getUTCMinutes() : date.getMinutes();
|
|
|
|
format = format.replace(/(^|[^\\])mm+/g, "$1" + ii(m));
|
|
|
|
format = format.replace(/(^|[^\\])m/g, "$1" + m);
|
|
|
|
|
|
|
|
var s = utc ? date.getUTCSeconds() : date.getSeconds();
|
|
|
|
format = format.replace(/(^|[^\\])ss+/g, "$1" + ii(s));
|
|
|
|
format = format.replace(/(^|[^\\])s/g, "$1" + s);
|
|
|
|
|
|
|
|
var f = utc ? date.getUTCMilliseconds() : date.getMilliseconds();
|
|
|
|
format = format.replace(/(^|[^\\])fff+/g, "$1" + ii(f, 3));
|
|
|
|
f = Math.round(f / 10);
|
|
|
|
format = format.replace(/(^|[^\\])ff/g, "$1" + ii(f));
|
|
|
|
f = Math.round(f / 10);
|
|
|
|
format = format.replace(/(^|[^\\])f/g, "$1" + f);
|
|
|
|
|
|
|
|
var T = H < 12 ? "AM" : "PM";
|
|
|
|
format = format.replace(/(^|[^\\])TT+/g, "$1" + T);
|
|
|
|
format = format.replace(/(^|[^\\])T/g, "$1" + T.charAt(0));
|
|
|
|
|
|
|
|
var t = T.toLowerCase();
|
|
|
|
format = format.replace(/(^|[^\\])tt+/g, "$1" + t);
|
|
|
|
format = format.replace(/(^|[^\\])t/g, "$1" + t.charAt(0));
|
|
|
|
|
|
|
|
var tz = -date.getTimezoneOffset();
|
|
|
|
var K = utc || !tz ? "Z" : tz > 0 ? "+" : "-";
|
|
|
|
if (!utc)
|
|
|
|
{
|
|
|
|
tz = Math.abs(tz);
|
|
|
|
var tzHrs = Math.floor(tz / 60);
|
|
|
|
var tzMin = tz % 60;
|
|
|
|
K += ii(tzHrs) + ":" + ii(tzMin);
|
|
|
|
}
|
|
|
|
format = format.replace(/(^|[^\\])K/g, "$1" + K);
|
|
|
|
|
|
|
|
var day = (utc ? date.getUTCDay() : date.getDay()) + 1;
|
|
|
|
format = format.replace(new RegExp(dddd[0], "g"), dddd[day]);
|
|
|
|
format = format.replace(new RegExp(ddd[0], "g"), ddd[day]);
|
|
|
|
|
|
|
|
format = format.replace(new RegExp(MMMM[0], "g"), MMMM[M]);
|
|
|
|
format = format.replace(new RegExp(MMM[0], "g"), MMM[M]);
|
|
|
|
|
|
|
|
format = format.replace(/\\(.)/g, "$1");
|
|
|
|
|
|
|
|
return format;
|
|
|
|
};
|
|
|
|
|
2016-09-24 16:09:03 +00:00
|
|
|
irc.whoisMessage = function(whoisData, buffer) {
|
|
|
|
let messages = [];
|
|
|
|
for(let key in whoisData) {
|
|
|
|
switch(key) {
|
|
|
|
case "hostmask":
|
2016-09-26 15:41:48 +00:00
|
|
|
messages.push("<span class='hostmask'>"+whoisData[key]+"</span>: "+validators.escapeHTML(whoisData['realname']));
|
2016-09-24 16:09:03 +00:00
|
|
|
break;
|
|
|
|
case "idleSeconds":
|
|
|
|
let msgs = "is idle for "+whoisData[key]+" seconds";
|
|
|
|
if(whoisData['signonTime'])
|
|
|
|
msgs += ", signed on at "+new Date(parseInt(whoisData['signonTime'])*1000);
|
|
|
|
messages.push(msgs);
|
|
|
|
break;
|
|
|
|
case "loggedIn":
|
|
|
|
case "registered":
|
2016-09-25 13:22:20 +00:00
|
|
|
case "connectingFrom":
|
|
|
|
case "usingModes":
|
2016-09-24 16:09:03 +00:00
|
|
|
case "title":
|
2016-09-26 15:41:48 +00:00
|
|
|
messages.push(validators.escapeHTML(whoisData[key]));
|
2016-09-24 16:09:03 +00:00
|
|
|
break;
|
|
|
|
case "channels":
|
|
|
|
messages.push(whoisData[key].join(" "));
|
|
|
|
break;
|
|
|
|
case "server":
|
|
|
|
let adfd = "is on <span class='server nick'>"+whoisData[key]+"</span>";
|
|
|
|
if(whoisData['server_name'])
|
2016-09-26 15:41:48 +00:00
|
|
|
adfd += " <span class='hostmask'>"+validators.escapeHTML(whoisData['server_name'])+"</span>";
|
2016-09-24 16:09:03 +00:00
|
|
|
messages.push(adfd);
|
|
|
|
break;
|
|
|
|
case "secure":
|
|
|
|
messages.push("is using a secure connection.");
|
|
|
|
break;
|
|
|
|
case "bot":
|
|
|
|
messages.push("is a bot on "+irc.serverData[buffer.server].network);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for(let i in messages) {
|
|
|
|
let mesg = "[<span class='nick'>"+whoisData.nickname+"</span>] "+messages[i];
|
|
|
|
buffer.addMessage(mesg, null, "whois");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-24 12:25:47 +00:00
|
|
|
function rand(min, max) {
|
|
|
|
return parseInt(Math.random() * (max-min+1), 10) + min;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!String.prototype.format) {
|
|
|
|
String.prototype.format = function() {
|
|
|
|
var args = arguments;
|
|
|
|
return this.replace(/{(\d+)}/g, function(match, number) {
|
|
|
|
return typeof args[number] != undefined ? args[number] : match;
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-09-26 14:16:05 +00:00
|
|
|
function remove_str(arr, str) {
|
|
|
|
let index = arr.indexOf(str);
|
|
|
|
|
|
|
|
if(index > -1) {
|
|
|
|
arr.splice(index, 1);
|
|
|
|
return arr;
|
|
|
|
}
|
|
|
|
return arr;
|
|
|
|
};
|
|
|
|
|
|
|
|
function grep(items, callback) {
|
|
|
|
let filtered = [];
|
|
|
|
for (let i in items) {
|
|
|
|
let item = items[i];
|
|
|
|
let cond = callback(item);
|
|
|
|
if (cond) {
|
|
|
|
filtered.push(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return filtered;
|
|
|
|
};
|
|
|
|
|
|
|
|
function match(word, array) {
|
|
|
|
return grep(
|
|
|
|
array,
|
|
|
|
function(w) {
|
|
|
|
return w.toLowerCase().indexOf(word.toLowerCase()) == 0;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-09-23 21:38:09 +00:00
|
|
|
function linkify(text) {
|
|
|
|
// see http://daringfireball.net/2010/07/improved_regex_for_matching_urls
|
|
|
|
let re = /\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/gi;
|
|
|
|
let parsed = text.replace(re, function(url) {
|
|
|
|
// turn into a link
|
|
|
|
let href = url;
|
|
|
|
if (url.indexOf('http') !== 0) {
|
|
|
|
href = 'http://' + url;
|
|
|
|
}
|
2016-09-26 15:41:48 +00:00
|
|
|
return '<a href="' + href + '" target="_blank" rel="nofollow">' + url + '</a>';
|
2016-09-23 21:38:09 +00:00
|
|
|
});
|
|
|
|
return parsed;
|
|
|
|
}
|
|
|
|
|
2016-09-23 07:38:47 +00:00
|
|
|
function removeClass(element, cl) {
|
|
|
|
let classList = element.className.split(" ");
|
2016-09-28 18:00:57 +00:00
|
|
|
|
|
|
|
if(classList.indexOf(cl) != -1)
|
|
|
|
classList.splice(classList.indexOf(cl), 1);
|
|
|
|
|
2016-09-23 07:38:47 +00:00
|
|
|
element.className = classList.join(" ");
|
|
|
|
}
|
|
|
|
|
|
|
|
function addClass(element, cl) {
|
|
|
|
let classList = element.className.split(" ");
|
2016-09-28 18:00:57 +00:00
|
|
|
|
|
|
|
if(classList.indexOf(cl) != -1)
|
|
|
|
return;
|
|
|
|
|
2016-09-23 07:38:47 +00:00
|
|
|
classList.push(cl);
|
|
|
|
element.className = classList.join(" ");
|
|
|
|
}
|
|
|
|
|
2016-09-23 15:42:59 +00:00
|
|
|
function toggleClass(element, cl) {
|
|
|
|
let classList = element.className.split(" ");
|
|
|
|
if(classList.indexOf(cl) != -1)
|
|
|
|
removeClass(element, cl);
|
|
|
|
else
|
|
|
|
addClass(element, cl);
|
|
|
|
}
|
|
|
|
|
2016-09-24 12:25:47 +00:00
|
|
|
function objectGetKey(obj, value) {
|
|
|
|
let key = null;
|
|
|
|
for(let f in obj) {
|
|
|
|
if(obj[f] == value)
|
|
|
|
key = f;
|
|
|
|
}
|
|
|
|
return key;
|
|
|
|
}
|
|
|
|
|
2016-09-23 14:26:31 +00:00
|
|
|
let composer = {
|
|
|
|
message: {
|
|
|
|
simple: function(time, sender, message, type) {
|
|
|
|
let element = document.createElement('div');
|
|
|
|
element.className = "message type_simple m_"+type;
|
|
|
|
|
2016-09-25 18:48:35 +00:00
|
|
|
if(irc.config.timestamps)
|
|
|
|
element.innerHTML += "<span class='timestamp'>"+time.format(irc.config.timestampFormat)+"</span> ";
|
|
|
|
|
|
|
|
if(irc.config.colors)
|
|
|
|
message = colorizer.stylize(message);
|
|
|
|
else
|
|
|
|
message = colorizer.strip(message);
|
2016-09-23 14:26:31 +00:00
|
|
|
|
2016-09-23 21:38:09 +00:00
|
|
|
message = linkify(message);
|
|
|
|
|
2016-09-23 14:26:31 +00:00
|
|
|
switch(type) {
|
2016-09-24 12:25:47 +00:00
|
|
|
case "mode":
|
2016-09-25 09:07:27 +00:00
|
|
|
element.innerHTML += "<span class='asterisk'>ℹ</span> <span class='actionee nick'>"+sender+"</span> ";
|
|
|
|
element.innerHTML += "<span class='content'>"+message+"</span>";
|
|
|
|
break;
|
2016-09-23 14:26:31 +00:00
|
|
|
case "action":
|
2016-09-25 09:07:27 +00:00
|
|
|
element.innerHTML += "<span class='asterisk'>⚡</span> <span class='actionee nick'>"+sender+"</span> ";
|
2016-09-23 14:26:31 +00:00
|
|
|
element.innerHTML += "<span class='content'>"+message+"</span>";
|
|
|
|
break;
|
|
|
|
case "part":
|
|
|
|
case "quit":
|
|
|
|
case "kick":
|
2016-09-24 12:25:47 +00:00
|
|
|
element.innerHTML += "<span class='arrowout'>⬅</span> <span class='content'><span class='actionee nick'>"+sender+"</span>";
|
2016-09-23 14:26:31 +00:00
|
|
|
element.innerHTML += " "+message+"</span>";
|
|
|
|
break;
|
|
|
|
case "join":
|
2016-09-24 12:25:47 +00:00
|
|
|
element.innerHTML += "<span class='arrowin'>➡</span> <span class='content'><span class='actionee nick'>"+sender+"</span>";
|
2016-09-23 14:26:31 +00:00
|
|
|
element.innerHTML += " "+message+"</span>";
|
|
|
|
break;
|
2016-10-01 19:42:17 +00:00
|
|
|
case "ctcp_response":
|
|
|
|
element.innerHTML += "<span class='asterisk'>ℹ</span> CTCP response from <span class='actionee nick'>"+sender+"</span> ";
|
|
|
|
element.innerHTML += "<span class='content'>"+message+"</span>";
|
|
|
|
break;
|
|
|
|
case "ctcp_request":
|
|
|
|
element.innerHTML += "<span class='asterisk'>ℹ</span> CTCP request to <span class='actionee nick'>"+sender+"</span> ";
|
|
|
|
element.innerHTML += "<span class='content'>"+message+"</span>";
|
|
|
|
break;
|
2016-09-23 14:26:31 +00:00
|
|
|
default:
|
|
|
|
if(sender) {
|
|
|
|
element.innerHTML += "<span class='sender'>"+sender+"</span> <span class='content'>"+message+"</span>";
|
|
|
|
} else {
|
|
|
|
element.innerHTML += "<span class='content'>"+message+"</span>";
|
|
|
|
addClass(element, "no_sender");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2016-09-24 12:25:47 +00:00
|
|
|
|
2016-09-25 18:48:35 +00:00
|
|
|
if(irc.config.colorNicknames == true) {
|
|
|
|
if(sender) {
|
|
|
|
let sndr1 = element.querySelector('.sender');
|
|
|
|
if(sndr1)
|
|
|
|
sndr1.style.color = colorizer.get_random_color(sndr1.innerHTML);
|
|
|
|
}
|
2016-09-24 12:25:47 +00:00
|
|
|
|
2016-09-25 18:48:35 +00:00
|
|
|
let sndr2 = element.querySelectorAll('.nick');
|
|
|
|
if(sndr2.length > 0)
|
|
|
|
for(let a in sndr2)
|
|
|
|
if(sndr2[a] && sndr2[a]['style'])
|
|
|
|
sndr2[a].style.color = colorizer.get_random_color(sndr2[a].innerHTML);
|
|
|
|
}
|
2016-09-23 14:26:31 +00:00
|
|
|
return element;
|
|
|
|
}
|
2016-09-28 18:00:57 +00:00
|
|
|
},
|
|
|
|
theme_selection: function(name, theme) {
|
|
|
|
let btn = document.createElement('div');
|
|
|
|
btn.className = "theme_button theme_"+theme.type;
|
|
|
|
let sampler = document.createElement('div');
|
|
|
|
sampler.className = "sampler";
|
|
|
|
sampler.style['background-color'] = theme.colorSamples.background;
|
|
|
|
let toolbar = document.createElement('span');
|
|
|
|
toolbar.className = "s_toolbar";
|
|
|
|
toolbar.style['background-color'] = theme.colorSamples.toolbar;
|
|
|
|
let nameb = document.createElement('span');
|
|
|
|
nameb.className = "name";
|
|
|
|
nameb.innerHTML = theme['name'];
|
|
|
|
sampler.appendChild(toolbar);
|
|
|
|
btn.appendChild(sampler);
|
|
|
|
btn.appendChild(nameb);
|
|
|
|
btn.setAttribute('id', 'theme-'+name);
|
|
|
|
|
|
|
|
return btn;
|
2016-09-23 14:26:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-26 15:41:48 +00:00
|
|
|
/*****************************\
|
|
|
|
|** **|
|
|
|
|
|** CLIENT COMMANDS **|
|
|
|
|
|** **|
|
|
|
|
\*****************************/
|
|
|
|
|
|
|
|
// commandName: {execute: function(buffer, handler, command, message, listargs) {}, description: ""}
|
|
|
|
let commands = {
|
|
|
|
join: {execute: function(buffer, handler, command, message, listargs) {
|
|
|
|
if (!listargs[1]) {
|
|
|
|
if(!buffer.alive) {
|
|
|
|
irc.socket.emit("userinput", {command: "join", server: buffer.server, message: "", arguments: [buffer.name]});
|
|
|
|
} else {
|
|
|
|
handler.commandError(buffer, listargs[0].toUpperCase()+': Missing parameters!');
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
irc.socket.emit("userinput", {command: "join", server: buffer.server, message: "", arguments: [listargs[1]]});
|
|
|
|
}
|
|
|
|
}, description: "<channel> - Join a channel"},
|
|
|
|
|
|
|
|
part: {execute: function(buffer, handler, command, message, listargs) {
|
|
|
|
if (!listargs[1] && buffer.type == "channel") {
|
|
|
|
irc.socket.emit("userinput", {command: "part", server: buffer.server, message: "", arguments: [buffer.name]});
|
|
|
|
} else if(buffer.type != "channel") {
|
|
|
|
handler.commandError(buffer, listargs[0].toUpperCase()+': Buffer is not a channel.');
|
|
|
|
} else if(listargs[1]) {
|
2016-09-27 15:13:24 +00:00
|
|
|
if(listargs[1].indexOf('#') != -1) {
|
2016-09-26 15:41:48 +00:00
|
|
|
let msg = "";
|
|
|
|
if(listargs[2])
|
|
|
|
msg = listargs.slice(2).join(" ");
|
|
|
|
irc.socket.emit("userinput", {command: "part", server: buffer.server, message: msg, arguments: [listargs[1]]});
|
|
|
|
} else {
|
|
|
|
if(buffer.type == "channel") {
|
|
|
|
irc.socket.emit("userinput", {command: "part", server: buffer.server, message: listargs.slice(1).join(" "), arguments: [buffer.name]});
|
|
|
|
} else {
|
|
|
|
handler.commandError(buffer, listargs[0].toUpperCase()+': Buffer is not a channel.');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, description: "[<#channel>|<message>] [message] - Leave the channel. If no channel specified, leave the current buffer.", aliases: ['leave']},
|
|
|
|
|
2016-09-27 15:13:24 +00:00
|
|
|
topic: {execute: function(buffer, handler, command, message, listargs) {
|
|
|
|
if (!listargs[1] && buffer.type == "channel") {
|
|
|
|
irc.socket.emit("userinput", {command: "topic", server: buffer.server, message: "", arguments: [buffer.name]});
|
|
|
|
} else if(buffer.type != "channel") {
|
|
|
|
handler.commandError(buffer, listargs[0].toUpperCase()+': Buffer is not a channel.');
|
|
|
|
} else if(listargs[1]) {
|
|
|
|
if(listargs[1].indexOf('#') != -1) {
|
|
|
|
let msg = "";
|
|
|
|
if(listargs[2])
|
|
|
|
msg = listargs.slice(2).join(" ");
|
|
|
|
irc.socket.emit("userinput", {command: "topic", server: buffer.server, message: msg, arguments: [listargs[1]]});
|
|
|
|
} else {
|
|
|
|
if(buffer.type == "channel") {
|
|
|
|
irc.socket.emit("userinput", {command: "topic", server: buffer.server, message: listargs.slice(1).join(" "), arguments: [buffer.name]});
|
|
|
|
} else {
|
|
|
|
handler.commandError(buffer, listargs[0].toUpperCase()+': Buffer is not a channel.');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, description: "[<#channel>|<topic>] [topic] - Sets/prints the current topic of the channel.", aliases: ['t']},
|
|
|
|
|
|
|
|
kick: {execute: function(buffer, handler, command, message, listargs) {
|
|
|
|
if(buffer.type != "channel")
|
|
|
|
return handler.commandError(buffer, listargs[0].toUpperCase()+': Buffer is not a channel!');
|
|
|
|
if(!listargs[1])
|
|
|
|
return handler.commandError(buffer, listargs[0].toUpperCase()+': Missing parameter <user>!');
|
|
|
|
irc.socket.emit("userinput", {command: "kick", server: buffer.server, message: listargs.slice(2).join(" "), arguments: [buffer.name, listargs[1]]});
|
|
|
|
}, description: "<user> <message> - Kick the following user from the channel."},
|
|
|
|
|
2016-09-26 15:41:48 +00:00
|
|
|
quit: {execute: function(buffer, handler, command, message, listargs) {
|
|
|
|
irc.socket.emit("userinput", {command: "quit", server: buffer.server, message: listargs.slice(1).join(" "), arguments: []});
|
|
|
|
}, description: "[<message>] - Quit the current server with message.", aliases: ['exit']},
|
|
|
|
|
2016-09-27 15:59:09 +00:00
|
|
|
mode: {execute: function(buffer, handler, command, message, listargs) {
|
|
|
|
irc.socket.emit("userinput", {command: "mode", server: buffer.server, message: listargs.slice(1).join(" "), arguments: []});
|
|
|
|
}, description: "[target] [mode] - Set/remove mode of target."},
|
|
|
|
|
2016-09-27 15:13:24 +00:00
|
|
|
msg: {execute: function(buffer, handler, command, message, listargs) {
|
2016-09-26 15:41:48 +00:00
|
|
|
if(!listargs[1] || !listargs[2])
|
|
|
|
return handler.commandError(buffer, listargs[0].toUpperCase()+': Missing parameters!');
|
|
|
|
if(listargs[1] == '*')
|
|
|
|
listargs[1] = buffer.name;
|
|
|
|
irc.socket.emit("userinput", {command: "privmsg", server: buffer.server, message: listargs.slice(2).join(" "), arguments: [listargs[1]]});
|
2016-09-27 15:13:24 +00:00
|
|
|
}, description: "<target> <message> - Sends a message to target.", aliases: ['privmsg', 'q', 'query', 'say']},
|
2016-09-26 15:41:48 +00:00
|
|
|
|
2016-10-01 19:42:17 +00:00
|
|
|
ctcp: {execute: function(buffer, handler, command, message, listargs) {
|
|
|
|
if(!listargs[1] || !listargs[2])
|
|
|
|
return handler.commandError(buffer, listargs[0].toUpperCase()+': Missing parameters!');
|
|
|
|
if(listargs[1] == '*')
|
|
|
|
listargs[1] = buffer.name;
|
|
|
|
|
|
|
|
listargs[2] = listargs[2].toUpperCase();
|
|
|
|
|
|
|
|
irc.socket.emit("userinput", {command: "ctcp", server: buffer.server, message: listargs.slice(2).join(" "), arguments: listargs.slice(1)});
|
|
|
|
}, description: "<target> <type> [arguments] - Sends a CTCP request to target."},
|
|
|
|
|
2016-09-26 15:41:48 +00:00
|
|
|
notice: {execute: function(buffer, handler, command, message, listargs) {
|
|
|
|
if(!listargs[1] || !listargs[2])
|
|
|
|
return handler.commandError(buffer, listargs[0].toUpperCase()+': Missing parameters!');
|
|
|
|
if(listargs[1] == '*')
|
|
|
|
listargs[1] = buffer.name;
|
|
|
|
irc.socket.emit("userinput", {command: "notice", server: buffer.server, message: listargs.slice(2).join(" "), arguments: [listargs[1]]});
|
|
|
|
}, description: "<target> <message> - Sends a NOTICE to target."},
|
|
|
|
|
|
|
|
action: {execute: function(buffer, handler, command, message, listargs) {
|
|
|
|
irc.socket.emit("userinput", {command: "privmsg", server: buffer.server, message: "\x01ACTION "+message.substring(command.length+2)+"\x01", arguments: [buffer.name]});
|
2016-09-30 15:55:12 +00:00
|
|
|
}, description: "<message> - 'act' as yourself", aliases: ['me']},
|
2016-09-26 15:41:48 +00:00
|
|
|
|
|
|
|
list: {execute: function(buffer, handler, command, message, listargs) {
|
|
|
|
irc.socket.emit("userinput", {command: "list", server: buffer.server, message: "", arguments: listargs.splice(1)});
|
|
|
|
}, description: "- List all channels on the current server."},
|
|
|
|
|
2016-09-27 15:13:24 +00:00
|
|
|
nick: {execute: function(buffer, handler, command, message, listargs) {
|
|
|
|
if(!listargs[1]) {
|
|
|
|
if(buffer.server != '') {
|
|
|
|
let mynick = irc.serverData[buffer.server].my_nick;
|
|
|
|
buffer.addMessage("Your nickname is: <span class='nick'>"+mynick+"</span>", null, "help");
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
irc.socket.emit("userinput", {command: "nick", server: buffer.server, message: "", arguments: listargs.splice(1)});
|
|
|
|
}, description: "- List all channels on the current server.", aliases: ['nickname']},
|
|
|
|
|
|
|
|
names: {execute: function(buffer, handler, command, message, listargs) {
|
|
|
|
let channel = "";
|
|
|
|
if(!listargs[1]) {
|
|
|
|
if(buffer.type == 'channel')
|
|
|
|
channel = buffer.name;
|
|
|
|
else
|
|
|
|
return handler.commandError(buffer, '/'+cmd.toUpperCase()+': Buffer is not a channel!');
|
|
|
|
} else if(listargs[1].indexOf('#') == 0) {
|
|
|
|
channel = listargs[1];
|
|
|
|
} else {
|
|
|
|
return handler.commandError(buffer, '/'+cmd.toUpperCase()+': Invalid channel name!');
|
|
|
|
}
|
|
|
|
irc.socket.emit("userinput", {command: "names", server: buffer.server, message: "", arguments: [channel]});
|
|
|
|
}, description: "- List all users on the current channel.", aliases: ['nicknames']},
|
|
|
|
|
2016-09-26 15:41:48 +00:00
|
|
|
quote: {execute: function(buffer, handler, command, message, listargs) {
|
|
|
|
irc.socket.emit("userinput", {command: listargs[1], server: buffer.server, message: listargs.slice(2).join(" "), arguments: listargs.splice(2)});
|
|
|
|
}, description: "<command> [args] - Send a raw command to the server.", aliases: ['raw']},
|
|
|
|
|
|
|
|
whois: {execute: function(buffer, handler, command, message, listargs) {
|
|
|
|
if(!listargs[1])
|
|
|
|
return handler.commandError(buffer, listargs[0].toUpperCase()+': Missing parameters!');
|
|
|
|
|
|
|
|
irc.socket.emit("userinput", {command: "whois", server: buffer.server, message: "", arguments: [listargs[1]]});
|
|
|
|
}, description: "<nickname> - Display information about a user."},
|
|
|
|
|
|
|
|
connect: {execute: function(buffer, handler, command, message, listargs) {
|
|
|
|
clientdom.connector.frame.style.display = "block";
|
|
|
|
irc.auther.authMessage("Create a new connection", false);
|
|
|
|
irc.auther.canClose = true;
|
|
|
|
}, description: "- Create a new connection."},
|
|
|
|
|
|
|
|
help: {execute: function(buffer, handler, command, message, listargs) {
|
|
|
|
if(!listargs[1])
|
|
|
|
return handler.commandError(buffer, listargs[0].toUpperCase()+': Missing parameters!');
|
|
|
|
|
|
|
|
let cmd = listargs[1].toLowerCase();
|
|
|
|
if(cmd.indexOf('/') === 0)
|
|
|
|
cmd = cmd.substring(1);
|
|
|
|
|
|
|
|
if(cmd in commands) {
|
|
|
|
if("description" in commands[cmd])
|
|
|
|
buffer.addMessage("<span class='command'>/"+cmd.toUpperCase()+"</span> "+
|
|
|
|
validators.escapeHTML(commands[cmd].description), null, "help");
|
|
|
|
else
|
|
|
|
buffer.addMessage("<span class='command'>/"+cmd.toUpperCase()+"</span> - No description provided", null, "help");
|
|
|
|
} else {
|
|
|
|
let foundAliased = null;
|
|
|
|
for(let cmd2 in commands) {
|
|
|
|
if(!commands[cmd2]['aliases']) continue;
|
|
|
|
if(commands[cmd2].aliases.indexOf(cmd) != -1) foundAliased = cmd2;
|
|
|
|
}
|
|
|
|
if(foundAliased) {
|
|
|
|
if("description" in commands[foundAliased])
|
|
|
|
buffer.addMessage("<span class='command'>/"+cmd.toUpperCase()+"</span> "+
|
|
|
|
validators.escapeHTML(commands[foundAliased].description), null, "help");
|
|
|
|
else
|
|
|
|
buffer.addMessage("<span class='command'>/"+cmd.toUpperCase()+"</span> - No description provided", null, "help");
|
|
|
|
} else {
|
|
|
|
handler.commandError(buffer, '/'+cmd.toUpperCase()+': Unknown command!');
|
|
|
|
}
|
|
|
|
}
|
2016-09-27 15:13:24 +00:00
|
|
|
}, description: "<command> - Display help for command"},
|
|
|
|
|
|
|
|
clear: {execute: function(buffer, handler, command, message, listargs) {
|
|
|
|
buffer.clearMessages();
|
|
|
|
}, description: "- Clears the current buffer."}
|
2016-09-26 15:41:48 +00:00
|
|
|
}
|
|
|
|
|
2016-09-23 09:47:12 +00:00
|
|
|
/*********************\
|
|
|
|
|** **|
|
|
|
|
|** CLASSES **|
|
|
|
|
|** **|
|
|
|
|
\*********************/
|
|
|
|
|
2016-09-23 07:38:47 +00:00
|
|
|
class Nicklist {
|
2016-09-23 12:36:56 +00:00
|
|
|
constructor(buffer) {
|
2016-09-23 07:38:47 +00:00
|
|
|
this.buffer = buffer;
|
|
|
|
this.nicks = [];
|
2016-09-26 14:16:05 +00:00
|
|
|
this.simplifiedNicksList = [];
|
2016-09-23 07:38:47 +00:00
|
|
|
}
|
|
|
|
|
2016-09-23 09:47:12 +00:00
|
|
|
sort() {
|
2016-09-23 12:36:56 +00:00
|
|
|
let spfx = irc.serverData[this.buffer.server].supportedPrefixes
|
2016-09-23 09:47:12 +00:00
|
|
|
this.nicks.sort(function (a,b) {
|
2016-09-23 12:36:56 +00:00
|
|
|
let rex = new RegExp('^['+spfx+']');
|
2016-09-23 09:47:12 +00:00
|
|
|
let nicks = [a.prefix.replace(rex,'').toLowerCase(), b.prefix.replace(rex,'').toLowerCase()];
|
|
|
|
let prefix = [];
|
2016-09-23 12:36:56 +00:00
|
|
|
if (rex.test(a.prefix)) prefix.push(spfx.indexOf(a.prefix[0]));
|
|
|
|
else prefix.push(spfx.length+1);
|
|
|
|
if (rex.test(b.prefix)) prefix.push(spfx.indexOf(b.prefix[0]));
|
|
|
|
else prefix.push(spfx.length+1);
|
2016-09-23 09:47:12 +00:00
|
|
|
if (prefix[0] < prefix[1]) return -1;
|
|
|
|
if (prefix[0] > prefix[1]) return 1;
|
|
|
|
if (nicks[0] > nicks[1]) return 1;
|
|
|
|
if (nicks[0] < nicks[1]) return -1;
|
|
|
|
return 0;
|
|
|
|
});
|
|
|
|
return this.nicks;
|
|
|
|
}
|
|
|
|
|
|
|
|
appendToList(nick) {
|
|
|
|
if(!this.buffer.active) return;
|
|
|
|
|
|
|
|
let str = document.createElement("div");
|
|
|
|
str.className = "nick";
|
|
|
|
str.setAttribute('id', 'nick-'+nick.nickname);
|
2016-09-23 12:36:56 +00:00
|
|
|
let construct = "";
|
|
|
|
|
|
|
|
if(nick.prefix != "")
|
|
|
|
construct += "<span class='prefix'>"+nick.prefix+"</span>";
|
|
|
|
else
|
|
|
|
construct += "<span class='no-prefix'> </span>";
|
|
|
|
|
2016-09-25 18:48:35 +00:00
|
|
|
if(irc.config.colorNicklist)
|
|
|
|
construct += "<span class='nickname' style='color: "+colorizer.get_random_color(nick.nickname)+";'>"+nick.nickname+"</span>";
|
|
|
|
else
|
|
|
|
construct += "<span class='nickname'>"+nick.nickname+"</span>";
|
|
|
|
|
2016-09-23 09:47:12 +00:00
|
|
|
str.innerHTML = construct;
|
2016-09-23 12:36:56 +00:00
|
|
|
clientdom.nicklist.appendChild(str);
|
2016-09-23 09:47:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
2016-09-23 14:26:31 +00:00
|
|
|
if(!this.buffer.active) return;
|
2016-09-23 12:36:56 +00:00
|
|
|
clientdom.nicklist.innerHTML = "";
|
2016-09-26 14:16:05 +00:00
|
|
|
this.simplifiedNicksList = [];
|
2016-09-23 12:36:56 +00:00
|
|
|
this.sort();
|
2016-09-26 14:16:05 +00:00
|
|
|
|
2016-09-23 09:47:12 +00:00
|
|
|
for(let n in this.nicks) {
|
|
|
|
let nick = this.nicks[n];
|
2016-09-26 14:16:05 +00:00
|
|
|
this.simplifiedNicksList.push(nick.nickname);
|
2016-09-23 09:47:12 +00:00
|
|
|
this.appendToList(nick);
|
|
|
|
}
|
2016-09-26 14:16:05 +00:00
|
|
|
|
|
|
|
irc.chat.input_handler.searchNicknames = this.simplifiedNicksList;
|
2016-09-23 09:47:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nickAdd(nickname) {
|
|
|
|
let newbie = { nickname: nickname, prefix: "", modes: [] }
|
2016-09-23 14:26:31 +00:00
|
|
|
if(this.getNickIndex(nickname) != null) return;
|
2016-09-23 09:47:12 +00:00
|
|
|
this.nicks.push(newbie);
|
|
|
|
this.render();
|
|
|
|
}
|
|
|
|
|
2016-09-23 12:36:56 +00:00
|
|
|
nickAddObject(obj) {
|
2016-09-23 21:38:09 +00:00
|
|
|
if(this.getNickIndex(obj.nickname) != null) return;
|
2016-09-23 12:36:56 +00:00
|
|
|
this.nicks.push(obj);
|
|
|
|
}
|
|
|
|
|
2016-09-23 09:47:12 +00:00
|
|
|
nickRemove(nickname) {
|
|
|
|
let nickIndex = this.getNickIndex(nickname);
|
|
|
|
|
|
|
|
if(nickIndex != null)
|
|
|
|
this.nicks.splice(nickIndex, 1);
|
|
|
|
else
|
|
|
|
return;
|
|
|
|
|
2016-09-23 14:26:31 +00:00
|
|
|
if(!this.buffer.active) return;
|
|
|
|
let tt = clientdom.nicklist.querySelector('#nick-'+nickname);
|
|
|
|
if(tt) tt.remove();
|
2016-09-26 14:16:05 +00:00
|
|
|
remove_str(this.simplifiedNicksList, nickname);
|
2016-09-23 09:47:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nickChange(oldNickname, newNickname) {
|
|
|
|
let nickIndex = this.getNickIndex(oldNickname);
|
|
|
|
|
|
|
|
if(nickIndex != null)
|
|
|
|
this.nicks[nickIndex].nickname = newNickname;
|
|
|
|
else
|
|
|
|
return;
|
|
|
|
|
|
|
|
this.render();
|
|
|
|
}
|
|
|
|
|
|
|
|
getNickIndex(nickname) {
|
|
|
|
let result = null;
|
|
|
|
|
|
|
|
for(let n in this.nicks)
|
|
|
|
if(this.nicks[n].nickname == nickname) result = n;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
modeAdded(nickname, newMode) {
|
|
|
|
let nickIndex = this.getNickIndex(nickname);
|
|
|
|
let nick = null;
|
|
|
|
|
|
|
|
if(nickIndex != null)
|
|
|
|
nick = this.nicks[nickIndex];
|
|
|
|
else
|
|
|
|
return;
|
|
|
|
|
2016-09-24 12:25:47 +00:00
|
|
|
let modeTranslations = irc.serverData[this.buffer.server].modeTranslation;
|
|
|
|
let prefixes = irc.serverData[this.buffer.server].supportedPrefixes;
|
|
|
|
|
|
|
|
nick.modes.push(newMode);
|
|
|
|
|
|
|
|
for(let mode in modeTranslations) {
|
|
|
|
let prefix = modeTranslations[mode];
|
|
|
|
if(nick.modes.indexOf(mode) == -1) continue;
|
|
|
|
let a = nick.modes.indexOf(mode) - 1;
|
|
|
|
if(a >= 0) {
|
|
|
|
if(prefixes.indexOf(modeTranslations[nick.modes[a]]) < prefixes.indexOf(prefix)) {
|
|
|
|
nick.prefix = modeTranslations[nick.modes[a]];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
nick.prefix = prefix;
|
|
|
|
break;
|
|
|
|
}
|
2016-09-23 09:47:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
this.render();
|
|
|
|
}
|
|
|
|
|
|
|
|
modeRemoved(nickname, oldMode) {
|
|
|
|
let nickIndex = this.getNickIndex(nickname);
|
|
|
|
let nick = null;
|
|
|
|
|
|
|
|
if(nickIndex != null)
|
|
|
|
nick = this.nicks[nickIndex];
|
|
|
|
else
|
|
|
|
return;
|
|
|
|
|
2016-09-24 12:25:47 +00:00
|
|
|
let modeTranslations = irc.serverData[this.buffer.server].modeTranslation;
|
|
|
|
let prefixes = irc.serverData[this.buffer.server].supportedPrefixes;
|
|
|
|
|
|
|
|
remove_str(nick.modes, oldMode);
|
|
|
|
|
|
|
|
let currentLowest = "";
|
|
|
|
|
|
|
|
for(let n in nick.modes) {
|
|
|
|
let mode = nick.modes[n];
|
|
|
|
let nextMode = nick.modes[n+1];
|
|
|
|
if(!nextMode && mode) {
|
|
|
|
currentLowest = modeTranslations[mode];
|
|
|
|
break;
|
|
|
|
} else if(nextMode) {
|
|
|
|
if(prefixes.indexOf(modeTranslations[nextMode]) > prefixes.indexOf(modeTranslations[mode]))
|
|
|
|
currentLowest = modeTranslations[nextMode];
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
2016-09-23 09:47:12 +00:00
|
|
|
}
|
2016-09-23 07:38:47 +00:00
|
|
|
|
2016-09-24 12:25:47 +00:00
|
|
|
nick.prefix = currentLowest;
|
|
|
|
|
2016-09-23 09:47:12 +00:00
|
|
|
this.render();
|
2016-09-23 07:38:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-22 17:15:40 +00:00
|
|
|
class Tab {
|
|
|
|
constructor(buffer) {
|
|
|
|
this.buffer = buffer;
|
2016-09-23 07:38:47 +00:00
|
|
|
this.element = null;
|
2016-09-23 12:36:56 +00:00
|
|
|
this.closeRequested = false;
|
2016-09-23 07:38:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create a tab element
|
2016-09-23 12:36:56 +00:00
|
|
|
renderTab() {
|
|
|
|
let internals = "<span id='title'>"+ this.buffer.title +"</span><span id='unread' class='none'></span>";
|
|
|
|
|
2016-09-23 07:38:47 +00:00
|
|
|
let ttt = document.createElement('div');
|
|
|
|
ttt.innerHTML = internals;
|
|
|
|
ttt.className = "tab";
|
2016-09-24 17:30:39 +00:00
|
|
|
ttt.setAttribute('id', 'tab-'+this.buffer.name);
|
2016-09-23 12:36:56 +00:00
|
|
|
clientdom.tabby.appendChild(ttt);
|
2016-09-23 07:38:47 +00:00
|
|
|
this.element = ttt;
|
|
|
|
|
2016-09-25 09:07:27 +00:00
|
|
|
ttt.innerHTML += "<span id='close'>x</span>"
|
|
|
|
ttt.querySelector('#close').addEventListener('click', () => {
|
|
|
|
this.close();
|
|
|
|
}, false);
|
2016-09-23 12:36:56 +00:00
|
|
|
|
2016-09-23 07:56:34 +00:00
|
|
|
ttt.addEventListener('click', () => {
|
2016-09-23 12:36:56 +00:00
|
|
|
if(this.closeRequested) return;
|
|
|
|
|
2016-09-23 07:56:34 +00:00
|
|
|
if(this.buffer.active)
|
2016-09-23 07:38:47 +00:00
|
|
|
return;
|
2016-09-23 12:36:56 +00:00
|
|
|
|
2016-09-23 07:56:34 +00:00
|
|
|
irc.chat.render(this.buffer);
|
2016-09-23 07:38:47 +00:00
|
|
|
}, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
setActive(active) {
|
|
|
|
if(this.element) {
|
|
|
|
this.element.className = "tab";
|
|
|
|
if(active) {
|
|
|
|
addClass(this.element, "active");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setUnreadCount(count) {
|
|
|
|
if(this.element) {
|
|
|
|
let counter = this.element.querySelector('#unread');
|
2016-09-23 09:47:12 +00:00
|
|
|
if(count == 0) {
|
|
|
|
counter.className = "none";
|
|
|
|
} else {
|
2016-09-23 07:38:47 +00:00
|
|
|
counter.innerHTML = count;
|
2016-09-23 09:47:12 +00:00
|
|
|
counter.className = "";
|
|
|
|
}
|
2016-09-23 07:38:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-24 16:09:03 +00:00
|
|
|
setTitle(title) {
|
|
|
|
let titleEl = this.element.querySelector('#title');
|
2016-09-24 16:14:12 +00:00
|
|
|
if(titleEl)
|
2016-09-24 16:09:03 +00:00
|
|
|
titleEl.innerHTML = title;
|
|
|
|
}
|
|
|
|
|
2016-09-23 07:38:47 +00:00
|
|
|
close() {
|
2016-09-23 12:36:56 +00:00
|
|
|
this.closeRequested = true;
|
|
|
|
this.buffer.closeBuffer();
|
2016-09-22 17:15:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class Buffer {
|
|
|
|
constructor(servername, buffername, tabname, type) {
|
|
|
|
this.messages = [];
|
2016-09-23 09:47:12 +00:00
|
|
|
this.nicklist = null;
|
2016-09-22 17:15:40 +00:00
|
|
|
this.topic = null;
|
|
|
|
this.input = "";
|
|
|
|
this.lastscroll = 0;
|
2016-09-24 17:30:39 +00:00
|
|
|
this.wasAtBottom = false;
|
2016-09-23 07:56:34 +00:00
|
|
|
this.unreadCount = 0;
|
2016-09-22 17:15:40 +00:00
|
|
|
|
|
|
|
this.server = servername;
|
|
|
|
this.name = buffername;
|
|
|
|
this.title = tabname;
|
|
|
|
this.type = type;
|
2016-09-23 07:38:47 +00:00
|
|
|
this.active = false;
|
2016-09-24 16:09:03 +00:00
|
|
|
this.alive = true;
|
2016-09-22 17:15:40 +00:00
|
|
|
|
2016-09-26 14:16:05 +00:00
|
|
|
if(type != "applet") {
|
2016-09-25 18:48:35 +00:00
|
|
|
this.tab = new Tab(this);
|
|
|
|
this.tab.renderTab();
|
|
|
|
}
|
2016-09-22 17:15:40 +00:00
|
|
|
|
2016-09-23 12:36:56 +00:00
|
|
|
if(type == "channel")
|
|
|
|
this.nicklist = new Nicklist(this, clientdom.nicklist);
|
2016-09-23 07:38:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
this.active = true;
|
|
|
|
this.tab.setActive(true);
|
2016-09-23 07:56:34 +00:00
|
|
|
this.unreadCount = 0;
|
|
|
|
this.tab.setUnreadCount(0);
|
2016-09-23 07:38:47 +00:00
|
|
|
|
2016-09-23 12:36:56 +00:00
|
|
|
clientdom.chat.className = "chatarea";
|
|
|
|
clientdom.nicklist.innerHTML = "";
|
|
|
|
clientdom.topicbar.innerHTML = "";
|
2016-09-23 07:38:47 +00:00
|
|
|
|
2016-09-25 18:48:35 +00:00
|
|
|
if(!irc.config.sharedInput)
|
|
|
|
clientdom.input.value = this.input;
|
|
|
|
|
2016-09-23 12:36:56 +00:00
|
|
|
if(this.nicklist) {
|
|
|
|
addClass(clientdom.chat, 'vnicks');
|
|
|
|
this.nicklist.render();
|
2016-09-23 07:38:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(this.topic != null && this.topic != "") {
|
2016-09-23 12:36:56 +00:00
|
|
|
addClass(clientdom.chat, 'vtopic');
|
2016-09-25 18:48:35 +00:00
|
|
|
if(irc.config.colors)
|
|
|
|
clientdom.topicbar.innerHTML = linkify(colorizer.stylize(this.topic));
|
|
|
|
else
|
|
|
|
clientdom.topicbar.innerHTML = linkify(colorizer.strip(this.topic));
|
2016-09-23 07:38:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
this.renderMessages();
|
2016-09-24 17:30:39 +00:00
|
|
|
if(this.wasAtBottom)
|
|
|
|
clientdom.letterbox.scrollTop = clientdom.letterbox.scrollHeight;
|
|
|
|
else
|
|
|
|
clientdom.letterbox.scrollTop = this.lastscroll;
|
2016-09-23 12:36:56 +00:00
|
|
|
|
|
|
|
clientdom.currentNickname.innerHTML = irc.serverData[this.server].my_nick;
|
2016-09-27 18:27:18 +00:00
|
|
|
|
|
|
|
irc.chat.changeTitle("TeemantIRC - "+this.title);
|
2016-09-23 07:38:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
renderMessages() {
|
|
|
|
if(!this.active) return;
|
|
|
|
|
2016-09-23 12:36:56 +00:00
|
|
|
clientdom.letterbox.innerHTML = "";
|
2016-09-23 07:38:47 +00:00
|
|
|
|
|
|
|
for(let t in this.messages) {
|
2016-09-23 07:56:34 +00:00
|
|
|
let mesg = this.messages[t];
|
|
|
|
this.appendMessage({message: mesg.message, sender: mesg.sender, type: mesg.type, time: mesg.time});
|
2016-09-23 07:38:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-27 15:13:24 +00:00
|
|
|
clearMessages() {
|
|
|
|
this.messages = [];
|
|
|
|
|
|
|
|
if(this.active)
|
|
|
|
clientdom.letterbox.innerHTML = "";
|
|
|
|
}
|
|
|
|
|
2016-09-23 07:38:47 +00:00
|
|
|
appendMessage(meta) {
|
2016-09-23 14:26:31 +00:00
|
|
|
let mesgConstr = composer.message[irc.chatType](meta.time, meta.sender, meta.message, meta.type);
|
2016-09-24 17:30:39 +00:00
|
|
|
|
2016-09-25 13:22:20 +00:00
|
|
|
if(irc.serverData[this.server]) {
|
2016-09-27 15:13:24 +00:00
|
|
|
let mynick = irc.serverData[this.server].my_nick;
|
2016-09-25 13:22:20 +00:00
|
|
|
if((meta.type == "privmsg" || meta.type == "notice" || meta.type == "action") &&
|
2016-09-27 15:13:24 +00:00
|
|
|
meta.message.toLowerCase().indexOf(mynick.toLowerCase()) != -1 && meta.sender != mynick)
|
2016-09-25 13:22:20 +00:00
|
|
|
addClass(mesgConstr, "mentioned");
|
|
|
|
}
|
2016-09-24 17:30:39 +00:00
|
|
|
|
2016-09-23 12:36:56 +00:00
|
|
|
clientdom.letterbox.appendChild(mesgConstr);
|
|
|
|
|
|
|
|
let lFactor = clientdom.letterbox.offsetHeight + clientdom.letterbox.scrollTop
|
|
|
|
if(lFactor > clientdom.letterbox.scrollHeight - 100)
|
|
|
|
clientdom.letterbox.scrollTop = clientdom.letterbox.scrollHeight;
|
|
|
|
}
|
2016-09-23 09:47:12 +00:00
|
|
|
|
2016-09-23 12:36:56 +00:00
|
|
|
topicChange(topic) {
|
|
|
|
if(this.active) {
|
2016-09-25 18:48:35 +00:00
|
|
|
if(irc.config.colors)
|
|
|
|
clientdom.topicbar.innerHTML = linkify(colorizer.stylize(topic));
|
|
|
|
else
|
|
|
|
clientdom.topicbar.innerHTML = linkify(colorizer.strip(topic));
|
2016-09-23 12:36:56 +00:00
|
|
|
|
|
|
|
if(this.topic == null)
|
|
|
|
addClass(clientdom.chat, "vtopic");
|
|
|
|
}
|
|
|
|
this.topic = topic;
|
2016-09-23 07:38:47 +00:00
|
|
|
}
|
|
|
|
|
2016-09-23 21:38:09 +00:00
|
|
|
addMessage(message, sender, type, time) {
|
|
|
|
let mesg = {message: message, sender: sender, type: type, time: time || new Date()}
|
2016-09-23 07:38:47 +00:00
|
|
|
this.messages.push(mesg);
|
|
|
|
|
2016-09-24 17:30:39 +00:00
|
|
|
if(this.active) {
|
2016-09-23 07:38:47 +00:00
|
|
|
this.appendMessage(mesg);
|
2016-09-24 17:30:39 +00:00
|
|
|
} else {
|
2016-09-23 07:56:34 +00:00
|
|
|
this.unreadCount += 1;
|
2016-09-25 13:22:20 +00:00
|
|
|
if(irc.serverData[this.server]) {
|
2016-09-27 15:13:24 +00:00
|
|
|
let mynick = irc.serverData[this.server].my_nick;
|
2016-09-25 13:22:20 +00:00
|
|
|
if((type == "privmsg" || type == "notice" || type == "action") &&
|
2016-09-27 15:13:24 +00:00
|
|
|
message.toLowerCase().indexOf(mynick.toLowerCase()) != -1 && sender != mynick)
|
2016-09-25 13:22:20 +00:00
|
|
|
console.log("TODO: notify user of mentioned");
|
|
|
|
}
|
2016-09-24 17:30:39 +00:00
|
|
|
}
|
2016-09-23 07:56:34 +00:00
|
|
|
|
|
|
|
this.tab.setUnreadCount(this.unreadCount);
|
2016-09-23 07:38:47 +00:00
|
|
|
}
|
|
|
|
|
2016-09-23 09:47:12 +00:00
|
|
|
switchOff() {
|
2016-09-26 14:16:05 +00:00
|
|
|
irc.chat.input_handler.searchNicknames = [];
|
|
|
|
|
2016-09-24 17:30:39 +00:00
|
|
|
let lFactor = clientdom.letterbox.offsetHeight + clientdom.letterbox.scrollTop
|
|
|
|
if(lFactor > clientdom.letterbox.scrollHeight - 100)
|
|
|
|
this.wasAtBottom = true;
|
|
|
|
else
|
|
|
|
this.wasAtBottom = false;
|
|
|
|
|
2016-09-25 18:48:35 +00:00
|
|
|
if(!irc.config.sharedInput)
|
|
|
|
this.input = clientdom.input.value;
|
|
|
|
|
2016-09-23 09:47:12 +00:00
|
|
|
this.tab.setActive(false);
|
2016-09-23 12:36:56 +00:00
|
|
|
this.lastscroll = clientdom.letterbox.scrollTop;
|
2016-09-23 09:47:12 +00:00
|
|
|
this.active = false;
|
|
|
|
}
|
|
|
|
|
2016-09-24 16:09:03 +00:00
|
|
|
setAliveStatus(status) {
|
|
|
|
this.alive = status;
|
|
|
|
if(this.alive)
|
|
|
|
this.tab.setTitle(this.title);
|
|
|
|
else
|
|
|
|
this.tab.setTitle('<i>('+this.title+')</i>');
|
|
|
|
}
|
|
|
|
|
2016-09-23 12:36:56 +00:00
|
|
|
closeBuffer() {
|
|
|
|
irc.chat.closeBuffer(this);
|
2016-09-22 17:15:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-01 15:28:53 +00:00
|
|
|
class ThemeSelector {
|
|
|
|
constructor(settings, variable) {
|
|
|
|
this.settings = settings;
|
|
|
|
this.variable = variable;
|
2016-09-28 18:00:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
set_active_selection(name) {
|
|
|
|
let all = clientdom.settings.available_themes.querySelectorAll('.theme_button');
|
|
|
|
if(all.length > 0) {
|
|
|
|
for(let a in all) {
|
|
|
|
if(all[a] && all[a]['className']) {
|
|
|
|
let elem = all[a];
|
|
|
|
if(elem.getAttribute('id') == 'theme-'+name) {
|
|
|
|
addClass(elem, "selected");
|
|
|
|
} else {
|
|
|
|
removeClass(elem, "selected");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-01 15:28:53 +00:00
|
|
|
bindButton(button, theme) {
|
|
|
|
button.onclick = (e) => {
|
|
|
|
this.settings.themeSelection = theme;
|
|
|
|
this.set_active_selection(theme);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
clientdom.settings.available_themes.innerHTML = "";
|
|
|
|
|
2016-09-28 18:00:57 +00:00
|
|
|
for(let n in window.themes.available) {
|
|
|
|
let theme = window.themes.available[n];
|
|
|
|
let button = composer.theme_selection(n, theme);
|
|
|
|
|
|
|
|
clientdom.settings.available_themes.appendChild(button);
|
|
|
|
|
2016-10-01 15:28:53 +00:00
|
|
|
this.bindButton(button, n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class Settings extends Buffer {
|
|
|
|
constructor() {
|
|
|
|
super("", "settings", "Settings", "applet");
|
|
|
|
this.tab = null;
|
|
|
|
this.isOpen = false;
|
|
|
|
this.timeout = null;
|
|
|
|
|
|
|
|
this.themeSelection = "";
|
|
|
|
|
|
|
|
this.themeSelector = new ThemeSelector(this);
|
|
|
|
this.themeSelector.render();
|
|
|
|
|
|
|
|
clientdom.settings.save.onclick = (e) => {
|
|
|
|
this.saveSpecified();
|
|
|
|
}
|
|
|
|
|
|
|
|
clientdom.settings.open.onclick = (e) => {
|
|
|
|
this.open();
|
2016-09-28 18:00:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch_theme() {
|
|
|
|
if(this.themeSelection != '') {
|
|
|
|
window.themes.change_theme(this.themeSelection);
|
|
|
|
irc.config.theme = this.themeSelection;
|
2016-10-01 15:28:53 +00:00
|
|
|
this.themeSelector.set_active_selection(this.themeSelection);
|
2016-09-28 18:00:57 +00:00
|
|
|
}
|
2016-09-25 18:48:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
open() {
|
|
|
|
if(this.isOpen) {
|
|
|
|
irc.chat.render(this);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.tab = new Tab(this);
|
|
|
|
this.tab.renderTab();
|
|
|
|
irc.chat.buffers.push(this);
|
|
|
|
irc.chat.render(this);
|
|
|
|
this.isOpen = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
closeBuffer() {
|
|
|
|
irc.chat.closeBuffer(this);
|
|
|
|
this.tab = null;
|
|
|
|
this.isOpen = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
saveSpecified() {
|
|
|
|
if(this.timeout)
|
|
|
|
clearTimeout(this.timeout);
|
|
|
|
|
2016-09-28 18:00:57 +00:00
|
|
|
this.switch_theme();
|
|
|
|
|
2016-09-25 18:48:35 +00:00
|
|
|
for(let key in irc.config) {
|
|
|
|
let value = irc.config[key];
|
|
|
|
let type = typeof(value);
|
|
|
|
|
2016-09-28 18:00:57 +00:00
|
|
|
if(clientdom.settings[key]) {
|
|
|
|
if(type == "boolean")
|
|
|
|
irc.config[key] = clientdom.settings[key].checked;
|
|
|
|
else
|
|
|
|
irc.config[key] = clientdom.settings[key].value;
|
|
|
|
}
|
2016-09-25 18:48:35 +00:00
|
|
|
}
|
|
|
|
clientdom.settings.saveStatus.innerHTML = "<span class='success'>Settings saved!</span>";
|
|
|
|
|
|
|
|
if("localStorage" in window) {
|
|
|
|
window.localStorage['teemant_settings'] = JSON.stringify(irc.config);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.timeout = setTimeout(function() {
|
|
|
|
clientdom.settings.saveStatus.innerHTML = "";
|
|
|
|
}, 3000);
|
|
|
|
}
|
|
|
|
|
|
|
|
setInitialValues() {
|
|
|
|
if("localStorage" in window) {
|
|
|
|
if(window.localStorage['teemant_settings']) {
|
|
|
|
try {
|
|
|
|
let settings = JSON.parse(window.localStorage.teemant_settings);
|
|
|
|
for(let key in irc.config) {
|
|
|
|
let value = irc.config[key];
|
|
|
|
let type = typeof(value);
|
2016-09-28 18:00:57 +00:00
|
|
|
|
2016-09-25 18:48:35 +00:00
|
|
|
if(settings[key]) {
|
2016-09-28 18:00:57 +00:00
|
|
|
if(key == 'theme') {
|
|
|
|
this.themeSelection = settings[key];
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-09-25 18:48:35 +00:00
|
|
|
if(type == "boolean")
|
|
|
|
clientdom.settings[key].checked = settings[key];
|
|
|
|
else
|
|
|
|
clientdom.settings[key].value = settings[key];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.saveSpecified();
|
|
|
|
return;
|
|
|
|
} catch(e) {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for(let key in irc.config) {
|
|
|
|
let value = irc.config[key];
|
|
|
|
let type = typeof(value);
|
|
|
|
|
2016-09-28 18:00:57 +00:00
|
|
|
if(clientdom.settings[key]) {
|
|
|
|
if(type == "boolean")
|
|
|
|
clientdom.settings[key].checked = value;
|
|
|
|
else
|
|
|
|
clientdom.settings[key].value = value;
|
|
|
|
}
|
2016-09-25 18:48:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-26 16:02:20 +00:00
|
|
|
addMessage(message, sender, type, time) {
|
|
|
|
// Don't send messages to the settings buffer
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-09-25 18:48:35 +00:00
|
|
|
switchOff() {
|
|
|
|
this.active = false;
|
|
|
|
this.tab.setActive(false);
|
|
|
|
clientdom.settings.frame.style.display = "none";
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
this.active = true;
|
|
|
|
this.tab.setActive(true);
|
|
|
|
clientdom.chat.className = "chatarea";
|
|
|
|
clientdom.nicklist.innerHTML = "";
|
|
|
|
clientdom.topicbar.innerHTML = "";
|
|
|
|
clientdom.letterbox.innerHTML = "";
|
|
|
|
clientdom.settings.frame.style.display = "block";
|
2016-09-27 18:27:18 +00:00
|
|
|
irc.chat.changeTitle("TeemantIRC - Settings");
|
2016-09-25 18:48:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-22 17:15:40 +00:00
|
|
|
class IRCConnector {
|
2016-09-23 12:36:56 +00:00
|
|
|
constructor() {
|
2016-09-22 17:15:40 +00:00
|
|
|
this.formLocked = false;
|
2016-09-25 09:07:27 +00:00
|
|
|
this.canClose = false;
|
2016-09-22 17:15:40 +00:00
|
|
|
|
2016-09-23 12:36:56 +00:00
|
|
|
clientdom.connector.form.onsubmit = (e) => {
|
2016-09-23 07:56:34 +00:00
|
|
|
if(this.formLocked) {
|
2016-09-22 17:15:40 +00:00
|
|
|
e.preventDefault();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-09-23 07:56:34 +00:00
|
|
|
this.formLocked = true;
|
2016-09-22 17:15:40 +00:00
|
|
|
|
2016-09-24 12:25:47 +00:00
|
|
|
this.validateForm(e);
|
2016-09-22 17:15:40 +00:00
|
|
|
}
|
2016-09-25 09:07:27 +00:00
|
|
|
|
|
|
|
clientdom.connector.onkeyup = (e) => {
|
|
|
|
let key = evt.keyCode || evt.which || evt.charCode || 0;
|
|
|
|
if(key === 27 && this.canClose)
|
|
|
|
this.authComplete();
|
|
|
|
}
|
2016-09-27 15:59:09 +00:00
|
|
|
|
|
|
|
clientdom.connector.pwtrigger.onclick = (e) => {
|
|
|
|
this.togglePassword();
|
|
|
|
}
|
2016-09-22 17:15:40 +00:00
|
|
|
}
|
|
|
|
|
2016-09-25 15:21:28 +00:00
|
|
|
fillFormFromURI() {
|
|
|
|
for(let param in urlParams) {
|
|
|
|
let value = urlParams[param];
|
|
|
|
|
|
|
|
switch(param) {
|
|
|
|
case "nick":
|
|
|
|
case "nickname":
|
|
|
|
if (window.validators.nickname(value))
|
|
|
|
clientdom.connector.nickname.value = value.replace(/\?/g, rand(10000, 99999));
|
|
|
|
break;
|
|
|
|
case "secure":
|
|
|
|
case "ssl":
|
|
|
|
if(value == "true" || value == "1")
|
|
|
|
clientdom.connector.secure.checked = true;
|
|
|
|
break;
|
2016-09-27 18:27:18 +00:00
|
|
|
case "password":
|
|
|
|
if(value == "true" || value == "1") {
|
|
|
|
clientdom.connector.pwtrigger.checked = true;
|
|
|
|
this.togglePassword();
|
|
|
|
}
|
|
|
|
break;
|
2016-09-25 15:21:28 +00:00
|
|
|
case "server":
|
|
|
|
case "host":
|
|
|
|
if(window.validators.iporhost(value))
|
|
|
|
clientdom.connector.server.value = value;
|
|
|
|
break;
|
|
|
|
case "port":
|
|
|
|
try {
|
|
|
|
let ppp = parseInt(value);
|
|
|
|
clientdom.connector.port.value = ppp;
|
|
|
|
} catch(e) {}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(window.location.hash)
|
|
|
|
clientdom.connector.channel.value = window.location.hash;
|
2016-09-26 16:02:20 +00:00
|
|
|
|
2016-09-25 15:21:28 +00:00
|
|
|
if(window.location.pathname.length > 4) {
|
2016-09-25 15:44:21 +00:00
|
|
|
let t1 = window.location.pathname.substring(1, window.location.pathname.length-1);
|
|
|
|
let proposed = "";
|
|
|
|
|
|
|
|
if(t1.indexOf('/') != -1) {
|
|
|
|
proposed = t1.split('/');
|
|
|
|
proposed = proposed[proposed.length-1]
|
|
|
|
} else {
|
|
|
|
proposed = t1;
|
|
|
|
}
|
|
|
|
|
2016-09-25 15:21:28 +00:00
|
|
|
if(window.validators.iporhost(proposed))
|
|
|
|
clientdom.connector.server.value = proposed;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-22 17:15:40 +00:00
|
|
|
validateForm(event) {
|
|
|
|
event.preventDefault();
|
|
|
|
|
2016-09-23 12:36:56 +00:00
|
|
|
let nickname = clientdom.connector.nickname.value;
|
2016-09-27 15:59:09 +00:00
|
|
|
let password = clientdom.connector.password.value;
|
2016-09-23 12:36:56 +00:00
|
|
|
let channel = clientdom.connector.channel.value;
|
|
|
|
let server = clientdom.connector.server.value;
|
|
|
|
let port = clientdom.connector.port.value;
|
2016-09-22 17:15:40 +00:00
|
|
|
|
|
|
|
if (!window.validators.nickname(nickname)) {
|
2016-09-23 07:38:47 +00:00
|
|
|
this.authMessage("Erroneous nickname!", true);
|
2016-09-22 17:15:40 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (channel.indexOf(",") !== -1) {
|
|
|
|
channel = channel.trim().split(",");
|
|
|
|
|
|
|
|
for (let t in channel) {
|
|
|
|
let chan = channel[t];
|
|
|
|
|
|
|
|
channel[t] = chan.trim();
|
|
|
|
|
|
|
|
if (chan.indexOf("#") != 0) {
|
|
|
|
channel[t] = "#"+chan;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if(channel != "") {
|
|
|
|
channel = channel.trim();
|
|
|
|
if (channel.indexOf("#") != 0) {
|
|
|
|
channel = "#"+channel;
|
|
|
|
}
|
|
|
|
channel = [channel];
|
|
|
|
} else {
|
|
|
|
channel = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!window.validators.iporhost(server)) {
|
2016-09-23 07:38:47 +00:00
|
|
|
this.authMessage("Erroneous server address!", true);
|
2016-09-22 17:15:40 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
port = parseInt(port);
|
|
|
|
} catch(e) {
|
2016-09-23 07:38:47 +00:00
|
|
|
this.authMessage("Erroneous port!", true);
|
2016-09-22 17:15:40 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(port < 10 || port > 65535) {
|
2016-09-23 07:38:47 +00:00
|
|
|
this.authMessage("Erroneous port!", true);
|
2016-09-22 17:15:40 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-09-27 15:59:09 +00:00
|
|
|
if(!clientdom.connector.pwtrigger.checked)
|
|
|
|
password = "";
|
|
|
|
|
2016-09-22 17:15:40 +00:00
|
|
|
irc.socket.emit('irc_create', {nickname: nickname,
|
|
|
|
autojoin: channel,
|
|
|
|
server: server,
|
|
|
|
port: port,
|
2016-09-27 15:59:09 +00:00
|
|
|
password: password,
|
2016-09-25 14:13:14 +00:00
|
|
|
secure: clientdom.connector.secure.checked });
|
2016-09-22 17:15:40 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
authMessage(message, error) {
|
2016-09-23 12:36:56 +00:00
|
|
|
clientdom.connector.messenger.innerHTML = "<span class='msg"+(error?" error":"")+"'>"+message+"</span>";
|
2016-09-24 12:25:47 +00:00
|
|
|
if(error)
|
|
|
|
this.formLocked = false;
|
2016-09-22 17:15:40 +00:00
|
|
|
}
|
|
|
|
|
2016-09-27 15:59:09 +00:00
|
|
|
togglePassword() {
|
|
|
|
if(clientdom.connector.pwtrigger.checked)
|
|
|
|
clientdom.connector.pwbox.style.display = "block";
|
|
|
|
else
|
|
|
|
clientdom.connector.pwbox.style.display = "none";
|
|
|
|
}
|
|
|
|
|
2016-09-22 17:15:40 +00:00
|
|
|
authComplete() {
|
2016-09-23 12:36:56 +00:00
|
|
|
clientdom.connector.frame.style.display = "none";
|
2016-09-22 17:15:40 +00:00
|
|
|
this.formLocked = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-23 14:26:31 +00:00
|
|
|
class InputHandler {
|
|
|
|
constructor() {
|
|
|
|
this.history = [];
|
2016-09-25 19:58:28 +00:00
|
|
|
this.historyCaret = 0;
|
2016-09-26 14:16:05 +00:00
|
|
|
this.searchNicknames = [];
|
|
|
|
|
2016-09-27 15:13:24 +00:00
|
|
|
this.index = -1;
|
2016-09-26 14:16:05 +00:00
|
|
|
this.words = [];
|
|
|
|
this.last = "";
|
2016-09-23 14:26:31 +00:00
|
|
|
|
|
|
|
clientdom.input.onkeyup = (evt) => {
|
|
|
|
let key = evt.keyCode || evt.which || evt.charCode || 0;
|
|
|
|
if (key == 13) {
|
|
|
|
this.handleInput();
|
2016-09-26 14:16:05 +00:00
|
|
|
return;
|
2016-09-23 14:26:31 +00:00
|
|
|
}
|
2016-09-26 14:16:05 +00:00
|
|
|
|
|
|
|
this.keyUpHandle(evt, key);
|
2016-09-23 14:26:31 +00:00
|
|
|
}
|
|
|
|
|
2016-09-26 14:16:05 +00:00
|
|
|
clientdom.input.onkeydown = (e) => {
|
|
|
|
let key = e.keyCode || e.which || e.charCode || 0;
|
|
|
|
if (e.ctrlKey || e.shiftKey || e.altKey) {
|
|
|
|
return;
|
|
|
|
}
|
2016-09-25 19:58:28 +00:00
|
|
|
|
2016-09-26 14:16:05 +00:00
|
|
|
this.keyDownHandle(e, key);
|
|
|
|
}
|
2016-09-25 19:58:28 +00:00
|
|
|
|
2016-09-29 13:47:24 +00:00
|
|
|
clientdom.input.onfocus = (e) => {
|
|
|
|
if(irc.config.scrollOnFocus)
|
|
|
|
clientdom.letterbox.scrollTop = clientdom.letterbox.scrollHeight;
|
|
|
|
}
|
|
|
|
|
2016-09-26 14:16:05 +00:00
|
|
|
clientdom.send.onclick = (e) => {
|
|
|
|
this.handleInput();
|
|
|
|
}
|
|
|
|
}
|
2016-09-25 19:58:28 +00:00
|
|
|
|
2016-09-26 14:16:05 +00:00
|
|
|
keyUpHandle(e, key) {
|
2016-10-01 19:42:17 +00:00
|
|
|
if(key == 38 || key == 40) {
|
|
|
|
clientdom.input.selectionStart = clientdom.input.value.length;
|
|
|
|
clientdom.input.selectionEnd = clientdom.input.value.length;
|
|
|
|
} else if(key == 9) return;
|
2016-09-26 14:16:05 +00:00
|
|
|
let input = clientdom.input.value;
|
|
|
|
let word = input.split(/ |\n/).pop();
|
|
|
|
|
|
|
|
// Reset iteration.
|
|
|
|
this.tabCompleteReset();
|
2016-09-25 19:58:28 +00:00
|
|
|
|
2016-09-26 14:16:05 +00:00
|
|
|
// Check for matches if the current word is the last word.
|
|
|
|
if (clientdom.input.selectionStart == input.length && word.length) {
|
|
|
|
// Call the match() function to filter the words.
|
|
|
|
this.tabWords = match(word, this.searchNicknames);
|
2016-09-27 15:13:24 +00:00
|
|
|
if(input.indexOf(word) == 0)
|
|
|
|
for(let n in this.tabWords)
|
|
|
|
this.tabWords[n] += ": ";
|
2016-09-26 14:16:05 +00:00
|
|
|
}
|
2016-10-01 19:42:17 +00:00
|
|
|
|
2016-09-26 14:16:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
keyDownHandle(e, key) {
|
|
|
|
if(key == 38) {
|
|
|
|
if(this.historyCaret <= 0) {
|
|
|
|
this.historyCaret = 0;
|
|
|
|
} else {
|
|
|
|
this.historyCaret -= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
let selection = this.history[this.historyCaret];
|
|
|
|
|
|
|
|
if(selection) {
|
|
|
|
clientdom.input.value = selection;
|
|
|
|
this.tabCompleteReset();
|
|
|
|
}
|
2016-09-25 19:58:28 +00:00
|
|
|
|
2016-09-26 14:16:05 +00:00
|
|
|
return;
|
|
|
|
} else if(key == 40) {
|
|
|
|
if(this.historyCaret >= this.history.length) {
|
|
|
|
this.historyCaret = this.history.length;
|
|
|
|
} else {
|
|
|
|
this.historyCaret += 1;
|
2016-09-25 19:58:28 +00:00
|
|
|
}
|
2016-09-26 14:16:05 +00:00
|
|
|
|
|
|
|
let selection = this.history[this.historyCaret]
|
|
|
|
|
|
|
|
if(!this.history[this.historyCaret])
|
|
|
|
selection = '';
|
|
|
|
|
|
|
|
clientdom.input.value = selection;
|
|
|
|
this.tabCompleteReset();
|
|
|
|
|
|
|
|
return;
|
2016-09-25 19:58:28 +00:00
|
|
|
}
|
|
|
|
|
2016-09-26 14:16:05 +00:00
|
|
|
if(key == 9) {
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
this.index++;
|
|
|
|
|
|
|
|
// Get next match.
|
|
|
|
let word = this.tabWords[this.index % this.tabWords.length];
|
|
|
|
if (!word) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let value = clientdom.input.value;
|
|
|
|
this.lastWord = this.lastWord || value.split(/ |\n/).pop();
|
|
|
|
|
|
|
|
// Return if the 'minLength' requirement isn't met.
|
|
|
|
if (this.lastWord.length < 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
let text = value.substr(0, clientdom.input.selectionStart - this.lastWord.length) + word;
|
|
|
|
clientdom.input.value = text;
|
|
|
|
|
|
|
|
// Remember the word until next time.
|
|
|
|
this.lastWord = word;
|
|
|
|
|
|
|
|
return;
|
2016-09-23 14:26:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-26 14:16:05 +00:00
|
|
|
tabCompleteReset() {
|
|
|
|
this.index = -1;
|
|
|
|
this.lastWord = "";
|
|
|
|
this.tabWords = [];
|
|
|
|
}
|
|
|
|
|
2016-09-23 14:26:31 +00:00
|
|
|
handleInput() {
|
2016-09-26 15:41:48 +00:00
|
|
|
let message = clientdom.input.value;
|
|
|
|
let buffer = irc.chat.getActiveBuffer();
|
2016-09-23 14:26:31 +00:00
|
|
|
|
2016-09-26 15:41:48 +00:00
|
|
|
if(!buffer) return;
|
|
|
|
if(message.trim() == "") return;
|
2016-09-24 16:09:03 +00:00
|
|
|
|
2016-09-26 15:41:48 +00:00
|
|
|
let listargs = message.split(' ');
|
2016-09-23 22:35:30 +00:00
|
|
|
|
2016-09-24 16:09:03 +00:00
|
|
|
if(listargs[0].indexOf('/') == 0) {
|
2016-09-26 15:41:48 +00:00
|
|
|
let command = listargs[0].substring(1).toLowerCase();
|
|
|
|
if(command.toLowerCase() in commands) {
|
|
|
|
let cmd = commands[command];
|
|
|
|
if("execute" in cmd)
|
|
|
|
cmd.execute(buffer, this, command, message, listargs);
|
|
|
|
} else {
|
|
|
|
let foundAliased = null;
|
|
|
|
for(let cmd in commands) {
|
|
|
|
if(!commands[cmd]['aliases']) continue;
|
|
|
|
if(commands[cmd].aliases.indexOf(command) != -1) foundAliased = commands[cmd];
|
|
|
|
}
|
|
|
|
if(foundAliased)
|
|
|
|
foundAliased.execute(buffer, this, command, message, listargs);
|
|
|
|
else
|
|
|
|
this.commandError(buffer, listargs[0].toUpperCase()+': Unknown command!');
|
2016-09-24 16:09:03 +00:00
|
|
|
}
|
2016-09-26 15:41:48 +00:00
|
|
|
|
2016-09-24 16:09:03 +00:00
|
|
|
} else {
|
2016-09-26 15:41:48 +00:00
|
|
|
irc.socket.emit("userinput", {command: "privmsg", server: buffer.server, message: message, arguments: [buffer.name]});
|
2016-09-24 16:09:03 +00:00
|
|
|
}
|
2016-09-23 14:26:31 +00:00
|
|
|
|
2016-09-26 15:41:48 +00:00
|
|
|
this.history.push(message);
|
2016-09-25 19:58:28 +00:00
|
|
|
this.historyCaret = this.history.length;
|
2016-09-23 14:26:31 +00:00
|
|
|
clientdom.input.value = "";
|
|
|
|
}
|
2016-09-24 16:09:03 +00:00
|
|
|
|
|
|
|
commandError(buffer, message) {
|
|
|
|
buffer.addMessage(message, null, "error");
|
|
|
|
return true;
|
|
|
|
}
|
2016-09-23 14:26:31 +00:00
|
|
|
}
|
|
|
|
|
2016-09-22 17:15:40 +00:00
|
|
|
class IRCChatWindow {
|
2016-09-23 12:36:56 +00:00
|
|
|
constructor() {
|
2016-09-22 17:15:40 +00:00
|
|
|
this.buffers = [];
|
2016-09-23 12:36:56 +00:00
|
|
|
clientdom.frame.style.display = "none";
|
2016-09-22 17:15:40 +00:00
|
|
|
this.firstServer = true;
|
|
|
|
this.currentBuffer = null;
|
2016-09-23 14:26:31 +00:00
|
|
|
this.input_handler = new InputHandler();
|
2016-09-23 15:42:59 +00:00
|
|
|
clientdom.smsctrig.onclick = (e) => {
|
|
|
|
toggleClass(clientdom.chat, "vopentrig");
|
|
|
|
}
|
2016-09-22 17:15:40 +00:00
|
|
|
}
|
|
|
|
|
2016-09-25 09:07:27 +00:00
|
|
|
destroyAllBuffers() {
|
2016-09-25 15:21:28 +00:00
|
|
|
// Wipe all server data
|
2016-09-25 09:07:27 +00:00
|
|
|
irc.serverData = {};
|
2016-09-25 15:21:28 +00:00
|
|
|
irc.serverChatQueue = {};
|
|
|
|
this.buffers = [];
|
|
|
|
|
|
|
|
// Clear tabs
|
|
|
|
clientdom.tabby.innerHTML = "";
|
|
|
|
|
|
|
|
// Reset to the defaults
|
2016-09-25 09:07:27 +00:00
|
|
|
irc.auther.authMessage("Disconnected", true);
|
|
|
|
clientdom.frame.style.display = "none";
|
|
|
|
this.firstServer = true;
|
|
|
|
}
|
|
|
|
|
2016-09-22 17:15:40 +00:00
|
|
|
getBufferByName(buffername) {
|
|
|
|
let result = null;
|
|
|
|
for (let t in this.buffers) {
|
|
|
|
let buf = this.buffers[t];
|
2016-09-26 14:16:05 +00:00
|
|
|
if(buf.name.toLowerCase() == buffername.toLowerCase())
|
2016-09-22 17:15:40 +00:00
|
|
|
result = buf
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-09-23 07:38:47 +00:00
|
|
|
getActiveBuffer() {
|
|
|
|
let result = null;
|
|
|
|
for (let t in this.buffers) {
|
|
|
|
let buf = this.buffers[t];
|
|
|
|
if(buf.active == true)
|
|
|
|
result = buf
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-09-24 12:25:47 +00:00
|
|
|
getServerBuffer(server) {
|
|
|
|
let result = null;
|
|
|
|
for (let t in this.buffers) {
|
|
|
|
let buf = this.buffers[t];
|
|
|
|
if(buf.server == server)
|
|
|
|
result = buf;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-09-22 17:15:40 +00:00
|
|
|
getBuffersByServer(server) {
|
|
|
|
let result = [];
|
|
|
|
for (let t in this.buffers) {
|
|
|
|
let buf = this.buffers[t];
|
|
|
|
if(buf.server == server)
|
|
|
|
result.push(buf);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-09-23 12:36:56 +00:00
|
|
|
getBufferByServerName(server, channel) {
|
2016-09-23 07:38:47 +00:00
|
|
|
let result = null;
|
|
|
|
for (let t in this.buffers) {
|
|
|
|
let buf = this.buffers[t];
|
2016-09-26 14:16:05 +00:00
|
|
|
if(buf.server == server && buf.name.toLowerCase() == channel.toLowerCase())
|
2016-09-23 07:38:47 +00:00
|
|
|
result = buf;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-09-22 17:15:40 +00:00
|
|
|
getBuffersByType(type) {
|
|
|
|
let result = [];
|
|
|
|
for (let t in this.buffers) {
|
|
|
|
let buf = this.buffers[t];
|
|
|
|
if(buf.type == type)
|
|
|
|
result.push(buf);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-09-23 07:38:47 +00:00
|
|
|
newServerBuffer(serverinfo) {
|
|
|
|
if(this.firstServer) {
|
2016-09-23 12:36:56 +00:00
|
|
|
clientdom.frame.style.display = "block";
|
2016-09-25 09:07:27 +00:00
|
|
|
window.onbeforeunload = function(e) {
|
|
|
|
return 'IRC will disconnect.';
|
|
|
|
}
|
2016-09-23 12:36:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let prefixes = "";
|
|
|
|
|
|
|
|
for(let v in serverinfo.supportedModes) {
|
|
|
|
prefixes += serverinfo.supportedModes[v];
|
|
|
|
}
|
|
|
|
|
|
|
|
irc.serverData[serverinfo.address] = {
|
|
|
|
modeTranslation: serverinfo.supportedModes,
|
|
|
|
supportedPrefixes: prefixes,
|
|
|
|
network: serverinfo.network,
|
2016-09-24 16:09:03 +00:00
|
|
|
my_nick: serverinfo.nickname,
|
|
|
|
max_channel_length: serverinfo.max_channel_length
|
2016-09-23 07:38:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let newServer = new Buffer(serverinfo.address, serverinfo.address, serverinfo.network, "server");
|
|
|
|
this.buffers.push(newServer);
|
|
|
|
this.render(newServer);
|
|
|
|
this.firstServer = false;
|
2016-09-23 21:38:09 +00:00
|
|
|
|
|
|
|
if(irc.serverChatQueue[serverinfo.address]) {
|
|
|
|
for(let a in irc.serverChatQueue[serverinfo.address]) {
|
|
|
|
let mesg = irc.serverChatQueue[serverinfo.address][a];
|
|
|
|
newServer.addMessage(mesg.message, mesg.from, mesg.type, mesg.time);
|
|
|
|
}
|
|
|
|
delete irc.serverChatQueue[serverinfo.address];
|
|
|
|
}
|
|
|
|
|
2016-09-23 07:38:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
createBuffer(server, name, type, autoswitch) {
|
2016-09-23 12:36:56 +00:00
|
|
|
let buf = this.getBufferByServerName(server, name);
|
2016-09-23 07:38:47 +00:00
|
|
|
if(buf) {
|
|
|
|
if(autoswitch)
|
|
|
|
this.render(buf);
|
2016-09-23 22:35:30 +00:00
|
|
|
return buf;
|
2016-09-23 07:38:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
buf = new Buffer(server, name, name, type);
|
|
|
|
this.buffers.push(buf);
|
|
|
|
|
|
|
|
if(autoswitch)
|
|
|
|
this.render(buf);
|
2016-09-23 22:35:30 +00:00
|
|
|
|
|
|
|
return buf;
|
2016-09-23 07:38:47 +00:00
|
|
|
}
|
|
|
|
|
2016-09-23 09:47:12 +00:00
|
|
|
closeBuffer(buffer) {
|
2016-09-25 09:07:27 +00:00
|
|
|
if(buffer.type == "server")
|
|
|
|
irc.socket.emit("userinput", {command: "quit", server: buffer.server, message: "Server tab closed", arguments: []});
|
|
|
|
else if(buffer.type == "channel" && buffer.alive)
|
2016-09-24 16:09:03 +00:00
|
|
|
irc.socket.emit("userinput", {command: "part", server: buffer.server, message: "Tab closed", arguments: [buffer.name]});
|
|
|
|
|
2016-09-23 12:36:56 +00:00
|
|
|
let bufIndex = this.buffers.indexOf(buffer);
|
|
|
|
|
|
|
|
if(buffer.active) {
|
|
|
|
if (bufIndex == 0) {
|
|
|
|
if(this.buffers[bufIndex+1]) {
|
|
|
|
this.render(this.buffers[bufIndex+1]);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
this.render(this.buffers[bufIndex-1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
buffer.tab.element.remove();
|
|
|
|
this.buffers.splice(bufIndex, 1);
|
2016-09-25 09:07:27 +00:00
|
|
|
|
2016-09-26 14:16:05 +00:00
|
|
|
if(this.buffers.length == 0 || (this.buffers.length == 1 && this.buffers[0].type == "applet")) {
|
2016-09-25 09:07:27 +00:00
|
|
|
irc.chat.destroyAllBuffers();
|
|
|
|
irc.auther.authMessage("Create a new connection", false);
|
|
|
|
irc.auther.canClose = false;
|
|
|
|
clientdom.connector.frame.style.display = "block";
|
|
|
|
}
|
2016-09-23 09:47:12 +00:00
|
|
|
}
|
|
|
|
|
2016-09-23 07:38:47 +00:00
|
|
|
messageBuffer(name, server, message) {
|
2016-09-23 12:36:56 +00:00
|
|
|
let buf = this.getBufferByServerName(server, name);
|
2016-09-23 09:47:12 +00:00
|
|
|
|
2016-09-23 07:38:47 +00:00
|
|
|
if(buf == null)
|
2016-09-23 09:47:12 +00:00
|
|
|
buf = this.createBuffer(server, name, "message", false);
|
|
|
|
|
2016-09-24 16:09:03 +00:00
|
|
|
if(message.type == "privmsg" && message.message.indexOf('\x01ACTION') == 0) {
|
|
|
|
message.message = message.message.substring(8);
|
|
|
|
message.type = "action";
|
|
|
|
}
|
|
|
|
|
2016-09-23 07:38:47 +00:00
|
|
|
buf.addMessage(message.message, message.from, message.type);
|
|
|
|
}
|
|
|
|
|
2016-09-23 12:36:56 +00:00
|
|
|
buildNicklist(channel, server, nicks) {
|
|
|
|
let buf = this.getBufferByServerName(server, channel);
|
|
|
|
|
|
|
|
if(buf == null)
|
|
|
|
return;
|
|
|
|
|
2016-09-27 15:13:24 +00:00
|
|
|
let channelSendNicks = [];
|
|
|
|
|
2016-09-23 12:36:56 +00:00
|
|
|
for(let n in nicks) {
|
2016-09-24 12:25:47 +00:00
|
|
|
let nick = {nickname: "", prefix: "", modes: []};
|
2016-09-23 12:36:56 +00:00
|
|
|
|
|
|
|
if(irc.serverData[buf.server].supportedPrefixes.split('').indexOf(nicks[n].substring(0, 1)) != -1) {
|
|
|
|
nick.prefix = nicks[n].substring(0, 1);
|
|
|
|
nick.nickname = nicks[n].substring(1);
|
2016-09-24 12:25:47 +00:00
|
|
|
nick.modes = [objectGetKey(irc.serverData[buf.server].modeTranslation, nick.prefix)];
|
2016-09-27 15:13:24 +00:00
|
|
|
channelSendNicks.push("<span class='prefix'>{0}</span><span class='nick'>{1}</span>".format(nick.prefix, nick.nickname));
|
2016-09-23 12:36:56 +00:00
|
|
|
} else {
|
|
|
|
nick.nickname = nicks[n];
|
2016-09-27 15:13:24 +00:00
|
|
|
channelSendNicks.push("<span class='nick'>{1}</span>".format(nick.prefix, nick.nickname));
|
2016-09-23 12:36:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
buf.nicklist.nickAddObject(nick);
|
|
|
|
}
|
|
|
|
|
2016-09-27 15:13:24 +00:00
|
|
|
buf.addMessage("Nicks <span class='channel'>{0}</span>: {1}".format(channel, channelSendNicks.join(', ')), null, "names");
|
|
|
|
|
2016-09-23 12:36:56 +00:00
|
|
|
if(buf.active)
|
|
|
|
buf.nicklist.render();
|
|
|
|
}
|
|
|
|
|
|
|
|
nickChange(server, oldNick, newNick) {
|
|
|
|
let buffers = this.getBuffersByServer(server);
|
|
|
|
|
|
|
|
if(irc.serverData[server].my_nick == oldNick) {
|
|
|
|
irc.serverData[server].my_nick = newNick;
|
|
|
|
|
|
|
|
let activeBuf = this.getActiveBuffer();
|
|
|
|
|
|
|
|
if(activeBuf.server == server) {
|
2016-09-24 17:30:39 +00:00
|
|
|
clientdom.currentNickname.innerHTML = newNick;
|
2016-09-23 12:36:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for(let i in buffers) {
|
|
|
|
let buffer = buffers[i];
|
|
|
|
|
|
|
|
if(buffer.type != "channel") continue;
|
|
|
|
if(buffer.nicklist.getNickIndex(oldNick) == null) continue;
|
|
|
|
|
|
|
|
buffer.nicklist.nickChange(oldNick, newNick);
|
2016-09-27 15:13:24 +00:00
|
|
|
buffer.addMessage("{0} is now known as {1}".format(oldNick, newNick), null, "nick");
|
2016-09-23 12:36:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
topicChange(channel, server, topic, changer) {
|
|
|
|
let buf = this.getBufferByServerName(server, channel);
|
|
|
|
|
|
|
|
if (!buf) return;
|
|
|
|
|
|
|
|
buf.topicChange(topic);
|
|
|
|
if(changer)
|
2016-09-27 15:13:24 +00:00
|
|
|
buf.addMessage("<span class='nick'>{0}</span> has changed the topic of {1} to \"{2}\"".format(changer, channel, topic),
|
|
|
|
null, "topic");
|
2016-09-23 12:36:56 +00:00
|
|
|
else
|
2016-09-27 15:13:24 +00:00
|
|
|
buf.addMessage("Topic of <span class='channel'>{0}</span> is \"{1}\"".format(channel, topic), null, "topic");
|
2016-09-23 12:36:56 +00:00
|
|
|
}
|
|
|
|
|
2016-09-23 14:26:31 +00:00
|
|
|
handleQuit(server, user, reason) {
|
|
|
|
let buffers = this.getBuffersByServer(server);
|
|
|
|
|
|
|
|
for(let i in buffers) {
|
|
|
|
let buffer = buffers[i];
|
|
|
|
|
|
|
|
if(buffer.type != "channel") continue;
|
|
|
|
if(buffer.nicklist.getNickIndex(user.nickname) == null) continue;
|
|
|
|
|
|
|
|
buffer.nicklist.nickRemove(user.nickname);
|
2016-09-27 15:13:24 +00:00
|
|
|
buffer.addMessage("<span class='hostmask'>{0}@{1}</span> has quit <span class='reason'>{2}</span>".format(user.username,
|
|
|
|
user.hostname, reason), user.nickname, "quit");
|
2016-09-23 14:26:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
handleJoin(server, user, channel) {
|
|
|
|
let buffer = this.getBufferByServerName(server, channel);
|
|
|
|
|
|
|
|
if(!buffer) return;
|
|
|
|
|
2016-09-24 16:09:03 +00:00
|
|
|
if(user.nickname == irc.serverData[server].my_nick)
|
|
|
|
buffer.setAliveStatus(true);
|
2016-09-29 17:25:53 +00:00
|
|
|
else
|
|
|
|
buffer.nicklist.nickAdd(user.nickname);
|
2016-09-24 16:09:03 +00:00
|
|
|
|
2016-09-27 15:13:24 +00:00
|
|
|
buffer.addMessage("<span class='hostmask'>{0}@{1}</span> has joined <span class='channel'>{2}</span>".format(user.username,
|
|
|
|
user.hostname, channel), user.nickname, "join");
|
2016-09-23 14:26:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
handleLeave(server, user, channel, reason, kicker) {
|
|
|
|
let buffer = this.getBufferByServerName(server, channel);
|
|
|
|
|
|
|
|
if(!buffer) return;
|
|
|
|
|
2016-09-24 16:09:03 +00:00
|
|
|
if(user['nickname']) {
|
|
|
|
if(user.nickname == irc.serverData[server].my_nick)
|
|
|
|
buffer.setAliveStatus(false);
|
|
|
|
} else {
|
|
|
|
if(user == irc.serverData[server].my_nick)
|
|
|
|
buffer.setAliveStatus(false);
|
|
|
|
}
|
|
|
|
|
2016-09-23 14:26:31 +00:00
|
|
|
if(kicker)
|
2016-09-27 15:13:24 +00:00
|
|
|
buffer.addMessage("has kicked <span class='nick'>{0}</span> <span class='reason'>{1}</span>".format(user, reason), kicker.nickname, "part");
|
2016-09-23 14:26:31 +00:00
|
|
|
else
|
2016-09-27 15:13:24 +00:00
|
|
|
buffer.addMessage("<span class='hostmask'>{0}@{1}</span> has left <span class='channel'>{2}</span>{3}".format(user.username,
|
|
|
|
user.hostname, (reason != null ? " <span class='reason'>"+reason+"</span>" : "")), user.nickname, "part");
|
2016-09-23 14:26:31 +00:00
|
|
|
if(kicker)
|
|
|
|
buffer.nicklist.nickRemove(user);
|
|
|
|
else
|
|
|
|
buffer.nicklist.nickRemove(user.nickname);
|
|
|
|
}
|
|
|
|
|
2016-09-24 12:25:47 +00:00
|
|
|
handleMode(data) {
|
|
|
|
let buf = null;
|
|
|
|
if(data.target == irc.serverData[data.server].my_nick)
|
|
|
|
buf = this.getServerBuffer(data.server);
|
|
|
|
else
|
|
|
|
buf = this.getBufferByServerName(data.server, data.target);
|
|
|
|
|
|
|
|
if(!buf) return;
|
|
|
|
|
|
|
|
if(data.type == "mode_add") {
|
|
|
|
buf.nicklist.modeAdded(data.modeTarget, data.mode);
|
2016-09-27 15:13:24 +00:00
|
|
|
buf.addMessage("set mode <span class='channel'>{0}</span> <span class='mode'>+{1} {2}</span>".format(data.target,
|
|
|
|
data.mode, data.modeTarget), data.user.nickname, "mode");
|
2016-09-24 12:25:47 +00:00
|
|
|
} else if(data.type == "mode_del") {
|
|
|
|
buf.nicklist.modeRemoved(data.modeTarget, data.mode);
|
2016-09-27 15:13:24 +00:00
|
|
|
buf.addMessage("set mode <span class='channel'>{0}</span> <span class='mode'>-{1} {2}</span>".format(data.target,
|
|
|
|
data.mode, data.modeTarget), data.user.nickname, "mode");
|
2016-09-24 12:25:47 +00:00
|
|
|
} else {
|
2016-09-27 15:13:24 +00:00
|
|
|
buf.addMessage("set mode <span class='channel'>{0}</span> <span class='mode'>{1}</span>".format(data.target,
|
|
|
|
data.message), data.user.nickname, "mode");
|
2016-09-24 12:25:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-24 16:09:03 +00:00
|
|
|
joinChannels(server, channel) {
|
|
|
|
if (channel.indexOf(",") !== -1) {
|
|
|
|
channel = channel.trim().split(",");
|
|
|
|
|
|
|
|
for (let t in channel) {
|
|
|
|
let chan = channel[t];
|
|
|
|
|
|
|
|
channel[t] = chan.trim();
|
|
|
|
|
|
|
|
if (chan.indexOf("#") != 0) {
|
|
|
|
channel[t] = "#"+chan;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if(channel != "") {
|
|
|
|
channel = channel.trim();
|
|
|
|
if (channel.indexOf("#") != 0) {
|
|
|
|
channel = "#"+channel;
|
|
|
|
}
|
|
|
|
channel = [channel];
|
|
|
|
} else {
|
|
|
|
channel = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
irc.socket.emit("userinput", {command: "join", server: server, message: "", arguments: channel});
|
|
|
|
}
|
|
|
|
|
2016-09-27 18:27:18 +00:00
|
|
|
changeTitle(title) {
|
|
|
|
// TODO: notify of hot buffers
|
|
|
|
document.title = title;
|
|
|
|
irc.documentTitle = title;
|
|
|
|
}
|
|
|
|
|
2016-09-22 17:15:40 +00:00
|
|
|
render(buffer) {
|
2016-09-23 07:38:47 +00:00
|
|
|
let activeNow = this.getActiveBuffer();
|
2016-09-26 14:16:05 +00:00
|
|
|
this.input_handler.tabCompleteReset();
|
2016-09-23 07:38:47 +00:00
|
|
|
|
2016-09-23 09:47:12 +00:00
|
|
|
if(activeNow)
|
|
|
|
activeNow.switchOff();
|
2016-09-23 07:38:47 +00:00
|
|
|
|
|
|
|
buffer.render();
|
2016-09-22 17:15:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-23 09:47:12 +00:00
|
|
|
/**************************\
|
|
|
|
|** **|
|
|
|
|
|** INITIALIZATION **|
|
|
|
|
|** **|
|
|
|
|
\**************************/
|
|
|
|
|
2016-09-25 15:21:28 +00:00
|
|
|
function parseURL() {
|
|
|
|
let match,
|
|
|
|
pl = /\+/g, // Regex for replacing addition symbol with a space
|
|
|
|
search = /([^&=]+)=?([^&]*)/g,
|
|
|
|
decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
|
|
|
|
query = window.location.search.substring(1);
|
|
|
|
|
|
|
|
urlParams = {};
|
|
|
|
while (match = search.exec(query))
|
|
|
|
urlParams[decode(match[1])] = decode(match[2]);
|
|
|
|
|
|
|
|
irc.auther.fillFormFromURI();
|
|
|
|
}
|
|
|
|
|
|
|
|
window.onpopstate = parseURL;
|
|
|
|
|
2016-09-29 13:47:24 +00:00
|
|
|
window.onresize = function() {
|
|
|
|
if(irc.config.scrollOnResize)
|
|
|
|
clientdom.letterbox.scrollTop = clientdom.letterbox.scrollHeight;
|
|
|
|
}
|
|
|
|
|
2016-09-22 15:41:37 +00:00
|
|
|
window.onload = function() {
|
2016-09-23 12:36:56 +00:00
|
|
|
irc.primaryFrame = document.querySelector('.ircclient');
|
|
|
|
|
2016-09-25 18:48:35 +00:00
|
|
|
clientdom.settings['frame'] = irc.primaryFrame.querySelector('.settings');
|
|
|
|
|
|
|
|
for(let key in irc.config) {
|
|
|
|
clientdom.settings[key] = clientdom.settings.frame.querySelector('#s_'+key);
|
|
|
|
}
|
|
|
|
|
2016-09-28 18:00:57 +00:00
|
|
|
clientdom.settings['available_themes'] = clientdom.settings.frame.querySelector('.available_themes');
|
2016-09-25 18:48:35 +00:00
|
|
|
clientdom.settings['save'] = clientdom.settings.frame.querySelector('#save_settings');
|
|
|
|
clientdom.settings['saveStatus'] = clientdom.settings.frame.querySelector('#settings_status');
|
2016-09-23 12:36:56 +00:00
|
|
|
clientdom.connector['frame'] = irc.primaryFrame.querySelector('#authdialog');
|
|
|
|
clientdom.connector['messenger'] = clientdom.connector.frame.querySelector('#connmsg');
|
|
|
|
clientdom.connector['form'] = clientdom.connector.frame.querySelector('#IRCConnector');
|
|
|
|
clientdom.connector['nickname'] = clientdom.connector.form.querySelector('#nickname');
|
2016-09-27 15:59:09 +00:00
|
|
|
clientdom.connector['password'] = clientdom.connector.form.querySelector('#password');
|
|
|
|
clientdom.connector['pwtrigger'] = clientdom.connector.form.querySelector('#password_trig');
|
|
|
|
clientdom.connector['pwbox'] = clientdom.connector.form.querySelector('.password_box');
|
2016-09-23 12:36:56 +00:00
|
|
|
clientdom.connector['channel'] = clientdom.connector.form.querySelector('#channel');
|
|
|
|
clientdom.connector['server'] = clientdom.connector.form.querySelector('#server');
|
|
|
|
clientdom.connector['port'] = clientdom.connector.form.querySelector('#port');
|
2016-09-25 14:13:14 +00:00
|
|
|
clientdom.connector['secure'] = clientdom.connector.form.querySelector('#secure');
|
2016-09-23 12:36:56 +00:00
|
|
|
clientdom['tabby'] = irc.primaryFrame.querySelector('.tabby')
|
|
|
|
clientdom['frame'] = irc.primaryFrame.querySelector('#chat');
|
|
|
|
clientdom['letterbox'] = clientdom.frame.querySelector('.letterbox');
|
|
|
|
clientdom['nicklist'] = clientdom.frame.querySelector('.nicklist');
|
|
|
|
clientdom['currentNickname'] = clientdom.frame.querySelector('.my_nickname');
|
2016-09-23 14:26:31 +00:00
|
|
|
clientdom['input'] = clientdom.frame.querySelector('.userinput');
|
|
|
|
clientdom['send'] = clientdom.frame.querySelector('.sendbutton');
|
|
|
|
clientdom['chat'] = clientdom.frame.querySelector('.chatarea');
|
2016-09-23 12:36:56 +00:00
|
|
|
clientdom['topicbar'] = clientdom.chat.querySelector('.topicbar');
|
2016-09-23 15:42:59 +00:00
|
|
|
clientdom['smsctrig'] = clientdom.chat.querySelector('.smsc-nicklistbtn');
|
2016-09-25 18:48:35 +00:00
|
|
|
clientdom.settings['open'] = irc.primaryFrame.querySelector('.open_settings');
|
2016-09-23 12:36:56 +00:00
|
|
|
|
2016-09-23 15:42:59 +00:00
|
|
|
irc.socket = io.connect();
|
2016-09-22 17:15:40 +00:00
|
|
|
|
2016-09-25 18:48:35 +00:00
|
|
|
irc.settings = new Settings();
|
2016-09-23 12:36:56 +00:00
|
|
|
irc.auther = new IRCConnector();
|
|
|
|
irc.chat = new IRCChatWindow();
|
2016-09-22 15:41:37 +00:00
|
|
|
|
2016-09-25 15:21:28 +00:00
|
|
|
parseURL();
|
2016-09-25 18:48:35 +00:00
|
|
|
irc.settings.setInitialValues();
|
2016-09-25 15:21:28 +00:00
|
|
|
|
2016-09-22 17:15:40 +00:00
|
|
|
irc.socket.on('connect', function (data) {
|
|
|
|
irc.socketUp = true;
|
|
|
|
});
|
|
|
|
|
|
|
|
irc.socket.on('disconnect', function (data) {
|
|
|
|
irc.socketUp = false;
|
2016-09-25 09:07:27 +00:00
|
|
|
irc.chat.destroyAllBuffers();
|
|
|
|
clientdom.connector.frame.style.display = "block";
|
2016-09-22 17:15:40 +00:00
|
|
|
});
|
2016-09-22 15:41:37 +00:00
|
|
|
|
2016-09-22 17:15:40 +00:00
|
|
|
// Does everything
|
|
|
|
irc.socket.on('act_client', function (data) {
|
2016-09-26 15:41:48 +00:00
|
|
|
if(data['message'])
|
|
|
|
data.message = validators.escapeHTML(data.message);
|
|
|
|
if(data['reason'])
|
|
|
|
data.reason = validators.escapeHTML(data.reason);
|
|
|
|
|
2016-09-22 17:15:40 +00:00
|
|
|
switch(data.type) {
|
|
|
|
case "event_connect":
|
|
|
|
irc.auther.authComplete();
|
|
|
|
irc.chat.newServerBuffer(data);
|
|
|
|
break;
|
2016-09-23 07:38:47 +00:00
|
|
|
case "event_join_channel":
|
2016-09-23 14:26:31 +00:00
|
|
|
if(data.user.nickname == irc.serverData[data.server].my_nick)
|
|
|
|
irc.chat.createBuffer(data.server, data.channel, "channel", true);
|
|
|
|
irc.chat.handleJoin(data.server, data.user, data.channel);
|
|
|
|
break;
|
|
|
|
case "event_kick_channel":
|
|
|
|
irc.chat.handleLeave(data.server, data.kickee, data.channel, data.reason, data.user);
|
|
|
|
break;
|
|
|
|
case "event_part_channel":
|
|
|
|
irc.chat.handleLeave(data.server, data.user, data.channel, data.reason);
|
|
|
|
break;
|
|
|
|
case "event_quit":
|
|
|
|
irc.chat.handleQuit(data.server, data.user, data.reason);
|
2016-09-23 07:38:47 +00:00
|
|
|
break;
|
2016-09-25 09:07:27 +00:00
|
|
|
case "event_server_quit":
|
|
|
|
let serverz = irc.chat.getBuffersByServer(data.server);
|
|
|
|
for(let a in serverz) {
|
|
|
|
let serv = serverz[a];
|
|
|
|
serv.addMessage("You are no longer talking on this server.", null, "error");
|
|
|
|
serv.setAliveStatus(false);
|
|
|
|
}
|
|
|
|
break;
|
2016-09-23 12:36:56 +00:00
|
|
|
case "message":
|
2016-09-24 17:30:39 +00:00
|
|
|
if(data.to == irc.serverData[data.server].my_nick) {
|
2016-09-23 22:35:30 +00:00
|
|
|
irc.chat.messageBuffer(data.user.nickname, data.server, {message: data.message, type: data.messageType, from: data.user.nickname});
|
2016-09-24 17:30:39 +00:00
|
|
|
} else if(data.to == null) {
|
|
|
|
let atest = irc.chat.getActiveBuffer();
|
|
|
|
|
|
|
|
if(atest.server != data.server)
|
|
|
|
atest = irc.chat.getServerBuffer(data.server);
|
|
|
|
|
|
|
|
atest.addMessage(data.message, data.user.nickname, data.messageType);
|
|
|
|
} else {
|
2016-09-23 22:35:30 +00:00
|
|
|
irc.chat.messageBuffer(data.to, data.server, {message: data.message, type: data.messageType, from: data.user.nickname});
|
2016-09-24 17:30:39 +00:00
|
|
|
}
|
2016-09-23 07:38:47 +00:00
|
|
|
break;
|
2016-09-23 12:36:56 +00:00
|
|
|
case "channel_nicks":
|
|
|
|
irc.chat.buildNicklist(data.channel, data.server, data.nicks);
|
|
|
|
break;
|
|
|
|
case "channel_topic":
|
|
|
|
if(data['topic'] && data['set_by'])
|
|
|
|
irc.chat.topicChange(data.channel, data.server, data.topic, data['set_by']);
|
|
|
|
else if(data['topic'])
|
|
|
|
irc.chat.topicChange(data.channel, data.server, data.topic, null);
|
|
|
|
else if(data['set_by'])
|
2016-09-23 21:38:09 +00:00
|
|
|
irc.chat.messageBuffer(data.channel, data.server, {message: "Topic set by "+data.set_by+" on "+new Date(data.time*1000), type: "topic", from: null});
|
2016-09-23 12:36:56 +00:00
|
|
|
break;
|
|
|
|
case "nick_change":
|
|
|
|
irc.chat.nickChange(data.server, data.nick, data.newNick);
|
|
|
|
break;
|
2016-09-24 12:25:47 +00:00
|
|
|
case "mode_add":
|
|
|
|
case "mode_del":
|
|
|
|
case "mode":
|
|
|
|
irc.chat.handleMode(data);
|
|
|
|
break;
|
2016-09-23 12:36:56 +00:00
|
|
|
case "server_message":
|
2016-09-23 22:35:30 +00:00
|
|
|
if(data['error']) data.messageType = "error";
|
2016-09-24 12:25:47 +00:00
|
|
|
if(irc.chat.getServerBuffer(data.server) == null) {
|
2016-09-23 21:38:09 +00:00
|
|
|
if(!irc.serverChatQueue[data.server]) {
|
|
|
|
irc.serverChatQueue[data.server] = [];
|
|
|
|
} else {
|
|
|
|
irc.serverChatQueue[data.server].push({type: data.messageType, message: data.message, from: data.from || null, time: new Date()});
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
irc.chat.messageBuffer(data.server, data.server, {message: data.message, type: data.messageType, from: data.from || null});
|
|
|
|
}
|
2016-09-23 12:36:56 +00:00
|
|
|
break;
|
2016-09-22 17:15:40 +00:00
|
|
|
case "connect_message":
|
2016-09-23 21:38:09 +00:00
|
|
|
irc.auther.authMessage(data.message, data.error);
|
2016-09-22 17:15:40 +00:00
|
|
|
break;
|
2016-09-24 16:09:03 +00:00
|
|
|
case "whoisResponse":
|
|
|
|
irc.whoisMessage(data.whois, irc.chat.getActiveBuffer());
|
|
|
|
break;
|
|
|
|
case "listedchan":
|
|
|
|
irc.chat.messageBuffer(data.server, data.server, {message: "<span class='channel'>"+data.channel+"</span>"+
|
|
|
|
" <span class='usercount'>"+data.users+"</span> <span class='topic'>"+data.topic+"</span>",
|
|
|
|
type: "listentry", from: data.from});
|
|
|
|
break;
|
2016-09-22 17:15:40 +00:00
|
|
|
}
|
2016-09-22 15:41:37 +00:00
|
|
|
});
|
2016-09-25 15:21:28 +00:00
|
|
|
};
|