From e06a2d86e43ebe86b90f9a318900f70127460ec6 Mon Sep 17 00:00:00 2001 From: Zaran Date: Wed, 20 Apr 2011 10:42:45 +0200 Subject: Remove the jQuery-ui dependency. * add a simple jQuery tab plugin * add tabs styling in the CSS * some code factorisation * code formatting in the js and the css --- webclient/lib/alias.js | 342 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 248 insertions(+), 94 deletions(-) (limited to 'webclient/lib/alias.js') diff --git a/webclient/lib/alias.js b/webclient/lib/alias.js index 882d2d3..9b43abf 100644 --- a/webclient/lib/alias.js +++ b/webclient/lib/alias.js @@ -1,11 +1,11 @@ -var BOSH_SERVICE = 'http://alias.im/http-bind'; -var server_component = 'social.alias.im'; +var BOSH_SERVICE = 'http://localhost/http-bind'; +var server_component = 'object.localhost'; /** * Alias namespace */ var Alias = { - + /** * Status constants */ @@ -14,12 +14,12 @@ var Alias = { AWAY: 1, OFFLINE: 0 }, - + /** * Strophe xmpp connection */ connection: null, - + /** * Send a roster request to server */ @@ -30,8 +30,8 @@ var Alias = { /** * Return the status of a contact - * @param contact a jquery object - * @returns {Number} the status number + * @param {jQuery} contact The contact + * @return {Int} The status' number * @see Alias.Status */ getPresence: function(contact) { @@ -42,11 +42,11 @@ var Alias = { else return Alias.Status["OFFLINE"]; }, - + /** * Convert a jid to an id string suitable for css id * @param {String} jid - * @returns {String} id + * @return {String} id */ jid_to_id: function(jid) { return Strophe.getBareJidFromJid(jid).replace(/[@.]/g,'-'); @@ -55,19 +55,19 @@ var Alias = { /** * Return the id of a contact * @param contact jquery object - * @returns {String} id + * @return {String} id */ getID: function(contact) { return contact.find('.roster-jid').text(); }, - + /** - * Return the name of a contact + * 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 @@ -86,11 +86,11 @@ var Alias = { 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 contact jQuery object + * @param {jQuery} contact The contact to insert */ insertContact: function(contact) { var presence = Alias.getPresence(contact); @@ -115,7 +115,7 @@ var Alias = { } }); - if (!inserted) + if (!inserted) $('#roster ul').append(contact); } else @@ -151,6 +151,11 @@ var Alias = { return true; }, + /** + * Rebuild the contact list when receiving a roster iq + * @param iq + * @return {Boolean} + */ onRoster: function(iq) { $('#roster li').remove(); var elems = iq.getElementsByTagName('query'); @@ -170,91 +175,262 @@ var Alias = { return true; }, - onConnect: function(status) { + /** + * 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 ) - { + if ( status == Strophe.Status.CONNECTING ) { log('Strophe is connecting.'); - } else if ( status == Strophe.Status.CONNFAIL ) - { + } else if ( status == Strophe.Status.CONNFAIL ) { log('Strophe failed to connect.'); - } else if ( status == Strophe.Status.DISCONNECTING ) - { + } else if ( status == Strophe.Status.DISCONNECTING ) { log('Strophe is disconnecting.'); - } else if ( status == Strophe.Status.DISCONNECTED ) - { + } else if ( status == Strophe.Status.DISCONNECTED ) { log('Strophe is disconnected.'); - } else if ( status == Strophe.Status.CONNECTED ) - { + } else if ( status == Strophe.Status.CONNECTED ) { log('Strophe is connected.'); - Alias.getRoster(); - $('#password').val(''); - $('#login').dialog('close'); - $('#status').append($('Disconnect')); - $('#connect').click(function(){ - Alias.connection.disconnect(); - $('#roster ul').empty(); - $('#login').dialog('open'); - $(this).remove(); - }); + Alias.onConnect(); } }, - + + /** + * Alias initialization after connection + */ + 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 ($('#chat-' + jid_id).length === 0) { - $('#tabs').tabs('add', '#chat-' + jid_id, jid); - $('#chat-' + jid_id).append( - "
" + - ""); + 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) { - // add the new message - $('#chat-' + jid_id + ' .chat-messages').append( - "

" + - Strophe.getNodeFromJid(jid) + - "

"); - - $('#chat-' + jid_id + ' .chat-message:last .chat-text') - .append(body); - + Alias.addMessage( jid_id, jid , body); } return true; } - + }; +/** + * Light jQuery tab plugin + * + * the html structure is: + * + *
+ * + *
+ * Content 1 + *
+ *
+ */ +(function( $ ){ + + var methods = { + + /** + * Initialise the general tab area + * @return this (to preserve chainability) + */ + init: function() { + var tabs = this; + this.find('ul.tabbar li').bind('click.tabs', function(event){ + event.preventDefault(); + tabs.tabs('select',$(this).find('a').attr('href')); + }); + this.data('tabs',{}); + return this; + }, + + /** + * Select a tab + * @param {String} id The tab id with # + * @return this + */ + select: function(id) { + var selectedId = this.data('tabs').selected; + + if ( selectedId == id) { + return this; + } + + this.find('ul.tabbar li a[href="' + selectedId + '"]').parent().removeClass('selected'); + this.find('ul.tabbar li a[href="' + id + '"]').parent().addClass('selected'); + $(selectedId).hide(); + $(id).show(); + this.data('tabs').selected = id; + return this; + }, + + /** + * Add a tab + * @param {String} name The tab Title + * @param {String} id The tab id without # + * @pram {Bool} remove Wether the tab should be closable + * return this + */ + add: function(name, id, remove) { + var tabs = this; + var li = $('
  • ' + name +'
  • '); + + if ( remove ) { + li.append(''); + li.find('.tab-close').bind('click', function() { + tabs.tabs('remove', '#'+id); + }); + } + + li.bind('click.tabs',function(event){ + event.preventDefault(); + tabs.tabs('select',$(this).find('a').attr('href')); + }); + $(this).find('ul.tabbar').append(li); + $(this).append('
    '); + return this; + }, + + /** + * Test if a tab exists + * @param {String} id The tab id with # + * @return {Bool} + */ + exist: function(id) { + return (this.find('ul.tabbar li a[href="' + id + '"]').length != 0); + }, + + /** + * Remove a tab + * @param {String} id The tab id with # + * @return this + */ + remove: function(id) { + this.find('ul.tabbar li a[href="' + id + '"]').parent().remove(); + $(id).remove(); + + if (this.data('tabs').selected == id) { + var first = this.find('ul.tabbar li:first a').attr('href'); + this.tabs('select', first); + } + } + }; + + /* + * Register the 'tabs' method to the jQuery objects + * the first argument of this method is the submethod + * you want to call + */ + $.fn.tabs = function(method) { + if ( methods[method] ) { + return methods[method].apply(this, Array.prototype.slice + .call(arguments, 1)); + } else if ( typeof method === 'object' || !method ) { + return methods.init.apply(this, arguments); + } else { + $.error('Method ' + method + ' does not exist on jQuery.tabs'); + } + }; + +})(jQuery); + + function log(msg, color) { $('#log').append($('
    ').css('background-color', color).text(msg)); } @@ -276,76 +452,54 @@ $(document).ready(function(){ connection.rawInput = rawInput; connection.rawOutput = rawOutput; Alias.connection = connection; - Alias.connection.addHandler(Alias.onMessage, null, "message", "chat"); - - $('#login').dialog({ - autoOpen: true, - modal: true, - title: 'Connect', - buttons: { - 'Connect' : function () { - Alias.connection.connect($('#jid').get(0).value, - $('#pass').get(0).value, - Alias.onConnect);} - } + + $('#connect').click(function () { + Alias.connection.connect($('#jid').get(0).value, + $('#pass').get(0).value, + Alias.onStatusChanged); }); - + $('#bottomup').click(function(){ $(this).next().slideToggle(); }); - + $('#tabs').tabs(); - $('#tabs').bind('tabsshow',function(event,ui){ - $(ui.panel).find('input').focus(); - $(ui.tab).parent().removeClass('ui-state-focus'); - }); - $('#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(){ - log('test'); var jid = Alias.getID($(this)); var name = Alias.getName($(this)); var id = Alias.jid_to_id(jid); - if ($('#chat-' + id).length === 0) { - $('#tabs').tabs('add', '#chat-' + id, name); - $('#chat-' + id).append( - "
    " + - ""); - $('#chat-' + id).data('jid', jid); + if ( !$('#tabs').tabs('exist','#chat-' + id) ) { + Alias.addChatTab(jid); } - $('#tabs').tabs('select', '#chat-' + id); + $('#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); - - $(this).parent().find('.chat-messages').append( - "

    " + - Strophe.getNodeFromJid(Alias.connection.jid) + - "" + body + - "

    "); - + Alias.addMessage(id, me, body); $(this).val(''); - } + } }); }); -- cgit v1.2.3-70-g09d2