/**
* Alias namespace
*/
var Alias = {
/**
* Status constants
*/
Status: {
ONLINE: 2,
AWAY: 1,
OFFLINE: 0
},
/**
* Strophe xmpp connection
*/
connection: null,
/**
* Send a roster request to server
*/
getRoster: function() {
var roster = $iq({type : 'get'}).c('query', {xmlns : Strophe.NS.ROSTER});
Alias.connection.sendIQ(roster, Alias.onRoster);
},
/**
* Return the status of a contact
* @param {jQuery} contact The contact
* @return {Number} The status' number
* @see Alias.Status
*/
getPresence: function(contact) {
if ( contact.hasClass("online") )
return Alias.Status["ONLINE"];
else if ( contact.hasClass("away") )
return Alias.Status["AWAY"];
else
return Alias.Status["OFFLINE"];
},
/**
* Convert a jid to an id string suitable for css id
* @param {String} jid
* @return {String} id
*/
jid_to_id: function(jid) {
return Strophe.getBareJidFromJid(jid).replace(/[@.]/g,'-');
},
/**
* Return the id of a contact
* @param contact jquery object
* @return {String} id
*/
getID: function(contact) {
return contact.find('.roster-jid').text();
},
/**
* Return the name of a contact
*/
getName : function(contact) {
return contact.find('.roster-name').text();
},
/**
* Get the home node of a contact
* @param contact jquery object
*/
getHome: function(contact) {
var name = Base64.encode(Alias.getID(contact)) + '@' + server_component;
var iq = $iq({type : 'get', to : name}).c('query', {xmlns : 'alias:query', type:'content'});
Alias.connection.sendIQ(iq, Alias.onHome);
},
/**
* Called when receiving home node, display in the main div
* @param iq XML object
*/
onHome: function(iq) {
var content = $(iq).find('content').text();
$('#main').html(content);
},
/**
* Insert a contact keeping the sorting of the roster
* The contacts are sorted based on their status and on their names
* @param {jQuery} contact The contact to insert
*/
insertContact: function(contact) {
var presence = Alias.getPresence(contact);
var jid = Alias.getID(contact);
var contacts = $('#roster li');
if (contacts.length > 0) {
var inserted = false;
contacts.each(function () {
var locpres = Alias.getPresence($(this));
var locjid = Alias.getID($(this));
if (presence > locpres)
{
$(this).before(contact);
inserted = true;
return false;
}
else if ( (presence == locpres) && (jid < locjid) )
{
$(this).before(contact);
inserted = true;
return false;
}
});
if (!inserted)
$('#roster ul').append(contact);
}
else
$('#roster ul').append(contact);
// init tooltip
contact.tipTip({
content: "
",
defaultPosition: "right",
keepAlive: true
});
},
/**
* Update the roster when receiving a presence stanza
* @param {XMLElement} presence The presence stanza
* @returns {Boolean}
*/
onPresence: function(presence) {
var who = $(presence).attr('from');
var type = $(presence).attr('type');
if (type !== 'error')
{
var contact = $('#' + Alias.jid_to_id(who));
contact.removeClass('online away offline');
if (type === 'unavailable')
{
contact.addClass('offline');
}
else
{
var show = $(presence).find('show').text();
if (show === '' || show === '')
{
contact.addClass('online');
}
else
{
contact.addClass('away');
}
}
contact.remove();
Alias.insertContact(contact);
}
return true;
},
/**
* Rebuild the contact list when receiving a roster iq
* @param {XMLElement} iq
* @return {Boolean}
*/
onRoster: function(iq) {
$('#roster li').remove();
var elems = iq.getElementsByTagName('query');
var query = elems[0];
Strophe.forEachChild(query, 'item', function(item)
{
var jid = item.getAttribute('jid');
var name = item.getAttribute('name') || jid;
var id = Alias.jid_to_id(jid);
var contact = $("
"
+ "
" + name + "
"
+ "
" + jid + "
");
Alias.insertContact(contact);
});
Alias.connection.addHandler(Alias.onPresence,null,'presence', null, null, null, null);
Alias.connection.send($pres());
return true;
},
/**
* Called when the status of Strophe's connection changes.
* This function is passed to the Strophe's connect function
* @param {Int} status The new status
*/
onStatusChanged: function(status) {
var jid = $('#jid').get(0).value;
if ( status == Strophe.Status.CONNECTING ) {
log('Strophe is connecting.');
} else if ( status == Strophe.Status.CONNFAIL ) {
log('Strophe failed to connect.');
} else if ( status == Strophe.Status.DISCONNECTING ) {
log('Strophe is disconnecting.');
} else if ( status == Strophe.Status.DISCONNECTED ) {
log('Strophe is disconnected.');
} else if ( status == Strophe.Status.CONNECTED ) {
log('Strophe is connected.');
Alias.onConnect();
}
},
/**
* Initialization after connection
*
* Set the interface and the handlers
*/
onConnect: function() {
Alias.getRoster();
// hide the login dialog and load the interface
$('#login').hide();
$('#password').val('');
$('#left').show();
$('#right').show();
$('#status').append($('Disconnect'));
$('#disconnect').click(function(){
Alias.connection.disconnect();
$('#roster ul').empty();
$('#left').hide();
$('#right').hide();
$('#login').hide();
$(this).remove();
});
// handlers must be added only after connection is made
Alias.connection.addHandler(Alias.onMessage, null, "message", "chat");
},
/**
* Add a new chat tab
* @param {String} jid The jid of the contact to chat with
*/
addChatTab: function(jid) {
var jid_id = Alias.jid_to_id(jid);
$('#tabs').tabs('add', jid, 'chat-' + jid_id, true);
$('#chat-' + jid_id).addClass('chat-tab');
$('#chat-' + jid_id).append(""
+ "");
$('#chat-' + jid_id).data({jid: jid});
},
/**
* Add a chat message
* @param {String} chatId The id of the chat tab
* @param {String} authorId The jid of the message's author
* @param {String} body The text of the message
*/
addMessage: function(chatId, authorId, body) {
var author = Strophe.getNodeFromJid( authorId );
var message = $('
'
+ author + ''
+ body + '
');
if ( authorId == Alias.connection.jid ) {
message.find('.chat-name').addClass('me');
}
var chatArea = $('#chat-' + chatId).find('.chat-messages');
chatArea.append(message);
chatArea.scrollTop(chatArea.height());
},
/**
* Callback upon receiving a chat message
* @param {String} message The xml code of the message iq
* @return {Boolean}
*/
onMessage: function (message) {
var full_jid = $(message).attr('from');
var jid = Strophe.getBareJidFromJid(full_jid);
var jid_id = Alias.jid_to_id(jid);
if ( !$('#tabs').tabs('exist','#chat-' + jid_id) ) {
Alias.addChatTab(jid);
}
$('#chat-' + jid_id).data({jid: full_jid});
var body = $(message).find("html > body");
if (body.length === 0) {
body = $(message).find('body');
if (body.length > 0) {
body = body.text();
} else {
body = null;
}
} else {
body = body.contents();
var span = $("");
body.each(function () {
if (document.importNode) {
$(document.importNode(this, true)).appendTo(span);
} else {
// IE workaround
span.append(this.xml);
}
});
body = span;
}
if (body) {
Alias.addMessage( jid_id, jid , body);
}
return true;
}
};
function log(msg, color) {
$('#log').append($('').css('background-color', color).text(msg));
}
function rawInput(data) {
log('RECV: ' + data, '#FBB6B4');
}
function rawOutput(data) {
log('SENT: ' + data, '#B5BBFB');
}
jQuery.expr[':'].Contains = function(a,i,m){
return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0;
};
$(document).ready(function(){
var connection = new Strophe.Connection(BOSH_SERVICE);
connection.rawInput = rawInput;
connection.rawOutput = rawOutput;
Alias.connection = connection;
$('#connect').click(function () {
Alias.connection.connect($('#jid').get(0).value,
$('#pass').get(0).value,
Alias.onStatusChanged);
});
$('#bottomup').click(function(){
$(this).next().slideToggle();
});
$('#tabs').tabs();
$('#rosterfilter').keyup(function() {
var filter = $(this).val();
$('#roster ul li div.roster-name:not(:Contains("' + filter + '"))').parent().hide();
$('#roster ul li div.roster-name:Contains("' + filter + '")').parent().show();
});
$('.roster-contact').live('click', function(){
var jid = Alias.getID($(this));
var name = Alias.getName($(this));
var id = Alias.jid_to_id(jid);
if ( !$('#tabs').tabs('exist','#chat-' + id) ) {
Alias.addChatTab(jid);
}
$('#tabs').tabs('select', '#chat-' + id );
$('#chat-' + id + ' input').focus();
});
$('.chat-input').live('keypress', function (ev) {
var jid = $(this).parent().data('jid');
var id = Alias.jid_to_id(jid);
var me = Alias.connection.jid;
if (ev.which === 13) {
ev.preventDefault();
var body = $(this).val();
var message = $msg({to: jid, "type": "chat"})
.c('body').t(body).up()
.c('active', {xmlns: "http://jabber.org/protocol/chatstates"});
Alias.connection.send(message);
Alias.addMessage(id, me, body);
$(this).val('');
}
});
});