source: trunk/jabberit_messenger/jmessenger/js/trophyim.js @ 5217

Revision 5217, 86.0 KB checked in by alexandrecorreia, 12 years ago (diff)

Ticket #2356 - Erro corrigido, para mostrar o novo contato adicionado.

  • Property svn:executable set to *
Line 
1/** Object: DOMObjects
2 *  This class contains builders for all the DOM objects needed by TrophyIM
3 */
4DOMObjects = {
5    /** Function: xmlParse
6     *  Cross-browser alternative to using innerHTML
7     *  Parses given string, returns valid DOM HTML object
8     *
9     *  Parameters:
10     *    (String) xml - the xml string to parse
11     */
12    xmlParse : function(xmlString) {
13        var xmlObj = this.xmlRender(xmlString);
14        if(xmlObj) {
15            try { //Firefox, Gecko, etc
16                if (this.processor == undefined) {
17                    this.processor = new XSLTProcessor();
18                    this.processor.importStylesheet(this.xmlRender(
19                        '<xsl:stylesheet version="1.0"\
20                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">\
21                    <xsl:output method="html" indent="yes"/><xsl:template\
22                    match="@*|node()"><xsl:copy><xsl:copy-of\
23                    select="@*|node()"/></xsl:copy></xsl:template>\
24                    </xsl:stylesheet>'));
25                }
26                var htmlObj =
27                this.processor.transformToDocument(xmlObj).documentElement;
28                //Safari has a quirk where it wraps dom elements in <html><body>
29                if (htmlObj.tagName.toLowerCase() == 'html') {
30                    htmlObj = htmlObj.firstChild.firstChild;
31                }
32                return document.importNode(htmlObj, true);
33            } catch(e) {
34                try { //IE is so very very special
35                    var htmlObj = document.importNode(xmlObj.documentElement, true);
36                    if (htmlObj.tagName.toLowerCase() == "div") {
37                        var div_wrapper = document.createElement('div');
38                        div_wrapper.appendChild(htmlObj);
39                        if(div_wrapper.innerHTML) {
40                            div_wrapper.innerHTML = div_wrapper.innerHTML;
41                        }
42                        htmlObj = div_wrapper.firstChild;
43                    }
44                    return htmlObj;
45                } catch(e) {
46                    alert("TrophyIM Error: Cannot add html to page " + e.message);
47                }
48            }
49        }
50    },
51    /** Function: xmlRender
52     *  Uses browser-specific methods to turn given string into xml object
53     *
54     *  Parameters:
55     *    (String) xml - the xml string to parse
56     */
57    xmlRender : function(xmlString) {
58        try {//IE
59            var renderObj = new ActiveXObject("Microsoft.XMLDOM");
60            renderObj.async="false";
61            if(xmlString) {
62                renderObj.loadXML(xmlString);
63            }
64        } catch (e) {
65            try { //Firefox, Gecko, etc
66                if (this.parser == undefined) {
67                    this.parser = new DOMParser();
68                }
69                var renderObj = this.parser.parseFromString(xmlString,
70                    "application/xml");
71            } catch(e) {
72                alert("TrophyIM Error: Cannot create new html for page");
73            }
74        }
75
76        return renderObj;
77    },
78    /** Function: getHTML
79     *  Returns named HTML snippet as DOM object
80     *
81     *  Parameters:
82     *    (String) name - name of HTML snippet to retrieve (see HTMLSnippets
83     *    object)
84     */
85    getHTML : function(page)
86    {
87        return this.xmlParse(HTMLSnippets[page]);
88    },
89       
90    /** Function: getScript
91     *  Returns script object with src to given script
92     *
93     *  Parameters:
94     *    (String) script - name of script to put in src attribute of script
95     *    element
96     */
97    getScript : function(script)
98    {
99        var newscript = document.createElement('script');
100        newscript.setAttribute('src', script);
101        newscript.setAttribute('type', 'text/javascript');
102        return newscript;
103    }
104};
105
106/** Object: TrophyIM
107 *
108 *  This is the actual TrophyIM application.  It searches for the
109 *  'trophyimclient' element and inserts itself into that.
110 */
111TrophyIM = {
112               
113
114    controll : {
115        notificationNewUsers : 0
116    }, 
117   
118    /** AutoConnection
119        *
120        */     
121               
122    autoConnection : {
123        connect : true
124    },
125
126    /** Active Chat Room
127         *
128         */
129       
130    activeChatRoom : {
131        name : []
132    },
133       
134    /** Object: chatHistory
135    *
136    *  Stores chat history (last 10 message) and current presence of active
137    *  chat tabs.  Indexed by jid.
138    */
139       
140    chatHistory : {},
141       
142    /** Constants:
143    *
144    *    (Boolean) stale_roster - roster is stale and needs to be rewritten.
145    */
146       
147    constants : {
148        stale_roster: false
149    },
150       
151    /** PosWindow
152         *
153         */     
154    posWindow : {
155        left : 400,
156        top : 100
157    }, 
158               
159    /** StatusConnection
160         *
161         */
162
163    statusConn : {
164        connected : false
165    },
166       
167    /** TimeOut Render Roster
168         *
169         *
170         */
171       
172    _timeOut : {
173        renderRoster : null
174    },
175       
176       
177    /** Remove Contact ( type = set )
178         *
179         *
180         */
181       
182    removeResult : {
183        idResult : []
184    },
185       
186    /** Function: setCookie
187     *
188     *  Sets cookie name/value pair.  Date and path are auto-selected.
189     *
190     *  Parameters:
191     *    (String) name - the name of the cookie variable
192     *    (String) value - the value of the cookie variable
193     */
194   
195    setCookie : function(name, value)
196    {
197        var expire = new Date();
198        expire.setDate(expire.getDate() + 365);
199        document.cookie = name + "=" + value + "; expires=" + expire.toGMTString();
200    },
201   
202    /** Function: delCookie
203     *
204     *  Deletes cookie
205     *
206     *  Parameters:
207     *    (String) name) - the name of the cookie to delete
208     */
209   
210    delCookie : function(name)
211    {
212        var expire = new Date();
213        expire.setDate(expire.getDate() - 365);
214        document.cookie = name + "= ; expires=" + expire.toGMTString();
215        delete TrophyIM.cookies[name];
216    },
217   
218    /** Function: getCookies
219     *
220     *  Retrieves all trophyim cookies into an indexed object.  Inteneded to be
221     *  called once, at which time the app refers to the returned object instead
222     *  of re-parsing the cookie string every time.
223     *
224     *  Each cookie is also re-applied so as to refresh the expiry date.
225     */
226   
227    getCookies : function()
228    {
229        var cObj = {};
230        var cookies = document.cookie.split(';');
231       
232        for(var i = 0 ; i < cookies.length; i++ )
233        {
234            while ( cookies[i].charAt(0) == ' ')
235            {
236                cookies[i] = cookies[i].substring(1,cookies[i].length);
237            }
238               
239            if (cookies[i].substr(0, 8) == "trophyim")
240            {
241                var nvpair = cookies[i].split("=", 2);
242                cObj[nvpair[0]] = nvpair[1];
243                TrophyIM.setCookie(nvpair[0], nvpair[1]);
244            }
245        }
246       
247        return cObj;
248    },
249       
250    /** Function: load
251     *
252     *  This function searches for the trophyimclient div and loads the client
253     *  into it.
254     */
255
256    load : function()
257    {
258        if( loadscript.getUserCurrent() == null )
259        {
260            loadscript.setUserCurrent();         
261        }       
262
263        if ( !TrophyIM.statusConn.connected )
264        {
265            TrophyIM.cookies = TrophyIM.getCookies();
266
267            //Wait a second to give scripts time to load
268            setTimeout( "TrophyIM.showLogin()", 550 );
269        }
270        else
271        {
272            loadscript.rosterDiv();
273        }
274    },
275
276    /** Function: storeData
277     *
278     *  Store all our data in the JSONStore, if it is active
279     */
280     
281    storeData : function()
282    {
283        if ( TrophyIM.connection && TrophyIM.connection.connected )
284        {
285            TrophyIM.setCookie('trophyim_bosh_xid', TrophyIM.connection.jid + "|" +
286                TrophyIM.connection.sid + "|" +  TrophyIM.connection.rid);
287            TrophyIM.rosterObj.save();
288        }
289    },
290   
291    /**  Function: showlogin
292     *
293     *   This function clears out the IM box and either redisplays the login
294     *   page, or re-attaches to Strophe, preserving the logging div if it
295     *   exists, or creating a new one of we are re-attaching.
296     */
297     
298    showLogin : function()
299    {
300        /**
301         *
302         * JSON is the last script to load, so we wait on it
303                 * Added Strophe check too because of bug where it's sometimes missing
304                 *
305                 */
306
307        if ( typeof(JSON) != undefined && typeof(Strophe) != undefined )
308        {
309            TrophyIM.JSONStore = new TrophyIMJSONStore();
310               
311            if ( TrophyIM.JSONStore.store_working && TrophyIM.cookies['trophyim_bosh_xid'] )
312            {
313                var xids = TrophyIM.cookies['trophyim_bosh_xid'].split("|");
314                TrophyIM.delCookie('trophyim_bosh_xid');
315                TrophyIM.constants.stale_roster = true;
316                       
317                TrophyIM.connection                             = new Strophe.Connection(TROPHYIM_BOSH_SERVICE);
318                TrophyIM.connection.rawInput    = TrophyIM.rawInput;
319                TrophyIM.connection.rawOutput   = TrophyIM.rawOutput;
320                //Strophe.log = TrophyIM.log;
321                Strophe.info('Attempting Strophe attach.');
322                TrophyIM.connection.attach(xids[0], xids[1], xids[2], TrophyIM.onConnect);
323                TrophyIM.onConnect(Strophe.Status.CONNECTED);
324            }
325            else
326            {
327                // List Contact
328                loadscript.rosterDiv();
329
330                // Get User Current;
331                var _getUserCurrent = null;
332                _getUserCurrent = loadscript.getUserCurrent();
333                               
334                if( _getUserCurrent == null )
335                {       
336                    setTimeout( "TrophyIM.showLogin()", 500 );
337                }
338                else
339                {
340                    TrophyIM.login( Base64.decode( _getUserCurrent.jid ), Base64.decode( _getUserCurrent.password ));
341                }
342            }
343        }
344        else
345        {
346            setTimeout("TrophyIM.showLogin()", 500);
347        }
348    },
349   
350    /** Function: log
351     *
352     *  This function logs the given message in the trophyimlog div
353     *
354     *  Parameter: (String) msg - the message to log
355     */
356   
357    log : function(level, msg)
358    {
359        if (TrophyIM.logging_div && level >= TROPHYIM_LOGLEVEL)
360        {
361            while(TrophyIM.logging_div.childNodes.length > TROPHYIM_LOG_LINES)
362            {
363                TrophyIM.logging_div.removeChild( TrophyIM.logging_div.firstChild );
364            }
365           
366            var msg_div = document.createElement('div');
367            msg_div.className = 'trophyimlogitem';
368            msg_div.appendChild(document.createTextNode(msg));
369           
370            TrophyIM.logging_div.appendChild(msg_div);
371            TrophyIM.logging_div.scrollTop = TrophyIM.logging_div.scrollHeight;
372        }
373    },
374       
375    /** Function: rawInput
376     *
377     *  This logs the packets actually recieved by strophe at the debug level
378     */
379    rawInput : function (data)
380    {
381        Strophe.debug("RECV: " + data);
382    },
383       
384    /** Function: rawInput
385     *
386     *  This logs the packets actually recieved by strophe at the debug level
387     */
388    rawOutput : function (data)
389    {
390        Strophe.debug("SEND: " + data);
391    },
392       
393    /** Function: login
394     *
395     *  This function logs into server using information given on login page.
396     *  Since the login page is where the logging checkbox is, it makes or
397     *  removes the logging div and cookie accordingly.
398     *
399     */
400    login : function()
401    {
402        if ( TrophyIM.JSONStore.store_working )
403        {
404            //In case they never logged out
405            TrophyIM.JSONStore.delData(['groups','roster', 'active_chat', 'chat_history']);
406        }
407
408        TrophyIM.connection                             = new Strophe.Connection(TROPHYIM_BOSH_SERVICE);
409        TrophyIM.connection.rawInput    = TrophyIM.rawInput;
410        TrophyIM.connection.rawOutput   = TrophyIM.rawOutput;
411        //Strophe.log                                   = TrophyIM.log;
412       
413        if ( arguments.length > 0 )
414        {
415            var barejid = arguments[0];
416            var password = arguments[1];
417                       
418            TrophyIM.connection.connect( barejid + TROPHYIM_RESOURCE, password, TrophyIM.onConnect );
419        }
420        else
421        {
422                       
423            var barejid         = document.getElementById('trophyimjid').value
424            var fulljid         = barejid + TROPHYIM_RESOURCE;
425            var password        = document.getElementById('trophyimpass').value;
426            var button          = document.getElementById('trophyimconnect');
427                       
428            loadscript.setUserCurrent( barejid, password);
429                       
430            if ( button.value == 'connect' )
431            {
432                button.value = 'disconnect';
433                //TrophyIM.connection.connect( fulljid , password, TrophyIM.onConnect );
434                               
435                TrophyIM.login( barejid, password );
436                _winBuild('window_login_page', 'remove');
437            }
438        }
439
440        TrophyIM.setCookie('trophyimjid', barejid);
441    },
442       
443    /** Function: logout
444     *
445     *  Logs into fresh session through Strophe, purging any old data.
446     */
447    logout : function()
448    {
449        TrophyIM.autoConnection.connect = false;
450       
451        TrophyIM.delCookie('trophyim_bosh_xid');
452       
453        delete TrophyIM['cookies']['trophyim_bosh_xid'];
454       
455        TrophyIM.connection.disconnect();
456    },
457       
458    /** Function onConnect
459     *
460     *  Callback given to Strophe upon connection to BOSH proxy.
461     */
462    onConnect : function(status)
463    {
464        var loading_gif = document.getElementById("JabberIMRosterLoadingGif");
465               
466        if( status == Strophe.Status.CONNECTING )
467        {
468            loading_gif.style.display = "block";
469            Strophe.info('Strophe is connecting.');
470        }
471               
472        if( status == Strophe.Status.CONNFAIL )
473        {
474            TrophyIM.delCookie('trophyim_bosh_xid');
475            TrophyIM.statusConn.connected = false;
476            loading_gif.style.display = "block";
477        }
478               
479        if( status == Strophe.Status.DISCONNECTING )
480        {
481            TrophyIM.statusConn.connected = false;
482        }
483               
484        if( status == Strophe.Status.DISCONNECTED )
485        {
486            if( TrophyIM.autoConnection.connect )
487            {
488                loading_gif.style.display = "block";
489                               
490                TrophyIM.delCookie('trophyim_bosh_xid');
491                   
492                TrophyIM.statusConn.connected = false;
493                   
494                setTimeout(function()
495                {
496                    TrophyIM.showLogin();
497                           
498                },10000);
499                               
500                loadscript.clrAllContacts();   
501                   
502                loadscript.setStatusJabber(i18n.STATUS_ANAVAILABLE,"unavailable");
503                   
504                delete TrophyIM.rosterObj.roster;
505                delete TrophyIM.rosterObj.groups;
506            }
507        }
508               
509        if( status == Strophe.Status.CONNECTED )
510        {
511            loadscript.setStatusJabber(i18n.STATUS_AVAILABLE,'available');
512            TrophyIM.statusConn.connected = true;
513            TrophyIM.showClient();
514        }
515    },
516
517    /** Function: showClient
518     *
519     *  This clears out the main div and puts in the main client.  It also
520     *  registers all the handlers for Strophe to call in the client.
521     */
522    showClient : function()
523    {
524        TrophyIM.setCookie('trophyim_bosh_xid', TrophyIM.connection.jid + "|" +
525            TrophyIM.connection.sid + "|" +  TrophyIM.connection.rid);
526               
527        TrophyIM.rosterObj = new TrophyIMRoster();
528        TrophyIM.connection.addHandler(TrophyIM.onVersion, Strophe.NS.VERSION, 'iq', null, null, null);
529        TrophyIM.connection.addHandler(TrophyIM.onRoster, Strophe.NS.ROSTER, 'iq', null, null, null);
530        TrophyIM.connection.addHandler(TrophyIM.onPresence, null, 'presence', null, null, null);
531        TrophyIM.connection.addHandler(TrophyIM.onMessage, null, 'message', null, null,  null);
532       
533        //Get roster then announce presence.
534        TrophyIM.connection.send($iq({
535            type: 'get',
536            xmlns: Strophe.NS.CLIENT
537            }).c('query', {
538            xmlns: Strophe.NS.ROSTER
539            }).tree());
540        TrophyIM.connection.send($pres().tree());
541        setTimeout( TrophyIM.renderRoster, 1000);
542    },
543       
544    /** Function: clearClient
545     *
546     *  Clears out client div, preserving and returning existing logging_div if
547     *  one exists
548     */
549     
550    clearClient : function()
551    {
552        if(TrophyIM.logging_div)
553        {
554            var logging_div = TrophyIM.client_div.removeChild(document.getElementById('trophyimlog'));
555        }
556        else
557        {
558            var logging_div = null;
559        }
560       
561        while(TrophyIM.client_div.childNodes.length > 0)
562        {
563            TrophyIM.client_div.removeChild(TrophyIM.client_div.firstChild);
564        }
565       
566        return logging_div;
567    },
568   
569    /** Function: onVersion
570     *
571     *  jabber:iq:version query handler
572     */
573     
574    onVersion : function(msg)
575    {
576        Strophe.debug("Version handler");
577        if (msg.getAttribute('type') == 'get')
578        {
579            var from = msg.getAttribute('from');
580            var to = msg.getAttribute('to');
581            var id = msg.getAttribute('id');
582            var reply = $iq({
583                type: 'result',
584                to: from,
585                from: to,
586                id: id
587            }).c('query',
588
589            {
590                name: "TrophyIM",
591                version: TROPHYIM_VERSION,
592                os:
593                "Javascript-capable browser"
594            });
595            TrophyIM.connection.send(reply.tree());
596        }
597        return true;
598    },
599   
600    /** Function: onRoster
601     *
602     *  Roster iq handler
603     */
604   
605    onRoster : function(msg)
606    {
607        var roster_items = msg.firstChild.getElementsByTagName('item');
608               
609        for (var i = 0; i < roster_items.length; i++)
610        {
611            with(roster_items[i])
612            {
613                var groups              = getElementsByTagName('group');       
614                var group_array = [];
615                               
616                for( var g = 0 ; g < groups.length; g++ )
617                {
618                    if( groups[g].hasChildNodes() )
619                        group_array[group_array.length] = groups[g].firstChild.nodeValue;
620                }
621
622                if( getAttribute('ask') && getAttribute('ask').toString() === "subscribe" )
623                {
624                    if( getAttribute('subscription').toString() === "remove" )
625                    {
626                        TrophyIM.rosterObj.removeContact( getAttribute('jid').toString() );
627                    }
628                    else
629                    {
630                        TrophyIM.rosterObj.addContact( getAttribute('jid'), getAttribute('ask'), getAttribute('name'), group_array );
631                    }
632                }
633                else
634                {
635                    if( ( getAttribute('ask') == null && getAttribute('subscription').toString() === "remove" ) || getAttribute('subscription').toString() === "remove" )
636                    {
637                        TrophyIM.rosterObj.removeContact( getAttribute('jid').toString() );
638                    }
639                    else
640                    {
641                        TrophyIM.rosterObj.addContact( getAttribute('jid'), getAttribute('subscription'), getAttribute('name'), group_array );
642                    }
643                }
644            }
645        }
646
647        if ( msg.getAttribute('type') == 'set' )
648        {
649            var _iq = $iq({
650                type: 'reply',
651                id: msg.getAttribute('id'),
652                to: msg.getAttribute('from')
653                });
654            TrophyIM.connection.send( _iq.tree());
655        }
656
657        return true;
658    },
659   
660    /** Function: onPresence
661     *
662     *  Presence Handler
663     */
664   
665    onPresence : function(msg)
666    {
667        // Get Presences ChatRoom
668        TrophyIM.onPresenceChatRoom( msg );
669
670        var type                = msg.getAttribute('type') ? msg.getAttribute('type') : 'available';
671        var show                = msg.getElementsByTagName('show').length ? Strophe.getText(msg.getElementsByTagName('show')[0]) : type;
672        var status              = msg.getElementsByTagName('status').length ? Strophe.getText(msg.getElementsByTagName('status')[0]) : '';
673        var priority    = msg.getElementsByTagName('priority').length ? parseInt(Strophe.getText(msg.getElementsByTagName('priority')[0])) : 0;
674
675        if( msg.getAttribute('from').toString().indexOf( TROPHYIM_CHATROOM ) < 0 )
676        {       
677            var _from = Strophe.getBareJidFromJid( msg.getAttribute('from') );
678            var _flag = true;
679
680            if( TrophyIM.removeResult.idResult.length > 0 )
681            {
682                for( var i = 0 ; i < TrophyIM.removeResult.idResult.length; i++ )
683                {
684                    if( TrophyIM.removeResult.idResult[i] == _from )
685                    {
686                        _flag = false;
687                                       
688                        TrophyIM.removeResult.idResult.splice(i,1);
689                                       
690                        i--;
691                                       
692                        if( show.toLowerCase() === 'subscribe' )
693                            _flag = true;
694                    }
695                }
696            }
697               
698            if( _flag )
699                TrophyIM.rosterObj.setPresence( msg.getAttribute('from'), priority, show, status );
700        }
701
702        return true;
703    },
704
705    /** Function : onPresenceChatRoom
706     *
707     * Presence ChatRoom Handler
708     */
709   
710    onPresenceChatRoom : function(msg)
711    {
712        var xquery      = msg.getElementsByTagName("x");
713        var _error      = msg.getElementsByTagName("error");
714       
715       
716        if( _error.length > 0 )
717        {   
718            /* Room creation is denied by service policy;
719             *
720             *  <error code='403' type='auth'>
721             *      <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
722             *      <text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>Room creation is denied by service policy</text>
723             *  </error>       
724             */
725           
726            for ( var i = 0; i < _error.length; i++ )
727            {
728                if ( _error[i].getElementsByTagName("text") )
729                {   
730                    var _errorMsg = Strophe.getText( _error[i].getElementsByTagName("text")[0] );
731                   
732                    if( _errorMsg == "Room creation is denied by service policy" )
733                    {
734                        alert( i18n.ROOM_CREATION_IS_DENIED_BY_SERVICE_POLICY );
735                    }
736                    else
737                    {
738                        alert( " Informe ao seu Administrador ERRO : \n" + _errorMsg );
739                    }   
740                       
741                }
742            }
743        }
744        else
745        {
746            if ( xquery.length > 0 )
747            {
748                for ( var i = 0; i < xquery.length; i++ )
749                {
750                    var xmlns = xquery[i].getAttribute("xmlns");
751
752                    if( xmlns.indexOf("http://jabber.org/protocol/muc#user") == 0 )
753                    {
754                        var _from       = xquery[i].parentNode.getAttribute('from');
755                        var _to         = xquery[i].parentNode.getAttribute('to');
756
757                        // Get NameChatRoom
758                        var nameChatRoom        = Strophe.getBareJidFromJid( _from );
759
760                        // Get nickName
761                        var nickName            = Strophe.getResourceFromJid( _from );
762
763                        // Get Type/Show
764                        var type        = ( xquery[i].parentNode.getAttribute('type') != null ) ? xquery[i].parentNode.getAttribute('type') : 'available' ;
765                        var show        = ( xquery[i].parentNode.firstChild.nodeName == "show" ) ? xquery[i].parentNode.firstChild.firstChild.nodeValue : type;
766
767                        var _idElement = nameChatRoom + "_UserChatRoom__" + nickName;
768
769                        var _UserChatRoom                                       = document.createElement("div");
770                        _UserChatRoom.id                                = _idElement;
771                        _UserChatRoom.style.paddingLeft = '18px';
772                        _UserChatRoom.style.margin              = '3px 0px 0px 2px';
773                        _UserChatRoom.style.background  = 'url("'+path_jabberit+'templates/default/images/' + show + '.gif") no-repeat center left';
774                        _UserChatRoom.appendChild( document.createTextNode( nickName ) );
775
776                        var nodeUser = document.getElementById( _idElement );   
777
778                        if( nodeUser == null )
779                        {
780                            if( document.getElementById( nameChatRoom + '__roomChat__participants' ) != null )
781                            {
782                                nameChatRoom = document.getElementById( nameChatRoom + '__roomChat__participants' );
783                                nameChatRoom.appendChild( _UserChatRoom );
784                            }
785                            else
786                            {
787                                if( type != 'unavailable' )
788                                {
789                                    TrophyIM.makeChatRoom( nameChatRoom, nameChatRoom.substring(0, nameChatRoom.indexOf('@')));
790                                    nameChatRoom = document.getElementById( nameChatRoom + '__roomChat__participants' );
791                                    nameChatRoom.appendChild( _UserChatRoom );
792                                }
793                            }
794                        }
795                        else
796                        {
797                            if( type == 'unavailable' )
798                            {
799                                nodeUser.parentNode.removeChild( nodeUser );
800                            }
801                            else if( show )
802                            {
803                                nodeUser.style.backgroundImage =  'url("'+path_jabberit+'templates/default/images/' + show + '.gif")';
804                            }
805                        }
806                    }
807                }
808            }
809        }
810    },   
811   
812    /** Function: onMessage
813     *
814     *  Message handler
815     */
816   
817    onMessage : function(msg)
818    {
819        var checkTime = function(i)
820        {
821            if ( i < 10 ) i= "0" + i;
822               
823            return i;
824        };
825       
826        var messageDate = function( _date )
827        {
828            var _dt = _date.substr( 0, _date.indexOf( 'T' ) ).split( '-' );
829            var _hr = _date.substr( _date.indexOf( 'T' ) + 1, _date.length - _date.indexOf( 'T' ) - 2 ).split( ':' );
830                       
831            ( _date = new Date ).setTime( Date.UTC( _dt[0], _dt[1] - 1, _dt[2], _hr[0], _hr[1], _hr[2] ) );
832
833            return ( _date.toLocaleDateString( ).replace( /-/g, '/' ) + ' ' + _date.toLocaleTimeString( ) );
834        };
835
836        var data        = new Date();
837        var dtNow       = checkTime(data.getHours()) + ":" + checkTime(data.getMinutes()) + ":" + checkTime(data.getSeconds());
838       
839        var from        = msg.getAttribute('from');
840        var type        = msg.getAttribute('type');
841        var elems       = msg.getElementsByTagName('body');
842        var delay       = ( msg.getElementsByTagName('delay') ) ? msg.getElementsByTagName('delay') : null;
843        var stamp       = ( delay[0] != null ) ? "<font style='color:red;'>" + messageDate(delay[0].getAttribute('stamp')) + "</font>" :  dtNow;
844
845        var barejid             = Strophe.getBareJidFromJid(from);
846        var jidChatRoom = Strophe.getResourceFromJid(from);
847        var jid_lower   = barejid.toLowerCase();
848        var contact             = "";
849        var state               = "";
850
851        var chatBox     = document.getElementById(jid_lower + "__chatState");
852        var chatStateOnOff = null;
853        var active      = msg.getElementsByTagName('active');
854               
855        contact = barejid.toLowerCase();
856        contact = contact.substring(0, contact.indexOf('@'));
857           
858        if( TrophyIM.rosterObj.roster[barejid] )
859        {
860            if( TrophyIM.rosterObj.roster[barejid.toLowerCase()]['contact']['name'] )
861            {
862                contact = TrophyIM.rosterObj.roster[barejid.toLowerCase()]['contact']['name'];
863            }
864        }
865
866        // Message with body are "content message", this means state active
867        if ( elems.length > 0 )
868        {
869            state = "";
870                       
871            // Set notify chat state capability on when sender notify it themself
872            chatStateOnOff = document.getElementById(jid_lower + "__chatStateOnOff");
873                       
874            if (active.length > 0 & chatStateOnOff != null )
875            {
876                chatStateOnOff.value = 'on';
877            }
878
879            // Get Message
880            var _message        = document.createElement("div");
881            var _text           = Strophe.getText( elems[0] );
882                       
883            // Events Javascript
884            _text = _text.replace(/onblur/gi,"EVENT_DENY");
885                       
886            _text = _text.replace(/onchange/gi,"EVENT_DENY");
887                       
888            _text = _text.replace(/onclick/gi,"EVENT_DENY");
889                       
890            _text = _text.replace(/ondblclick/gi,"EVENT_DENY");
891                       
892            _text = _text.replace(/onerror/gi,"EVENT_DENY");
893                       
894            _text = _text.replace(/onfocus/gi,"EVENT_DENY");
895                       
896            _text = _text.replace(/onkeydown/gi,"EVENT_DENY");
897                       
898            _text = _text.replace(/onkeypress/gi,"EVENT_DENY");
899                       
900            _text = _text.replace(/onkeyup/gi,"EVENT_DENY");
901                       
902            _text = _text.replace(/onmousedown/gi,"EVENT_DENY");
903                       
904            _text = _text.replace(/onmousemove/gi,"EVENT_DENY");
905                       
906            _text = _text.replace(/onmouseout/gi,"EVENT_DENY");
907                       
908            _text = _text.replace(/onmouseover/gi,"EVENT_DENY");
909                       
910            _text = _text.replace(/onmouseup/gi,"EVENT_DENY");
911                       
912            _text = _text.replace(/onresize/gi,"EVENT_DENY");
913                       
914            _text = _text.replace(/onselect/gi,"EVENT_DENY");
915                       
916            _text = _text.replace(/onunload/gi,"EVENT_DENY");
917                       
918            // Events CSS
919            _text = _text.replace(/style/gi,"EVENT_DENY");
920
921            // Tags HTML
922            _text = _text.replace(/img /gi,"IMG_DENY ");
923                       
924            _text = _text.replace(/script /gi,"SCRIPT_DENY ");
925                       
926            _text = _text.replace(/div /gi,"DIV_DENY ");
927                       
928            _text = _text.replace(/span /gi,"SPAN_DENY ");
929                       
930            _text = _text.replace(/iframe /gi,"IFRAME_DENY ");
931                       
932            _message.innerHTML = _text;
933                       
934            ////////// BEGIN XSS //////////////////////////////////////////////////
935            // Delete Tags <SCRIPT>
936            var scripts = _message.getElementsByTagName('script_deny');
937            for (var i = 0; i < scripts.length; i++){
938                _message.removeChild(scripts[i--]);
939            }
940            ////////////////////////////////////////////////////
941                       
942            // Delete Tags <IMG>
943            var _imgSrc = _message.getElementsByTagName('img_deny');
944            for (var i = 0; i < _imgSrc.length; i++){
945                _imgSrc[i].parentNode.removeChild( _imgSrc[i--] );
946            }
947            ////////////////////////////////////////////////////
948                       
949            // Delete Tags <DIV>
950            var _Div = _message.getElementsByTagName('div_deny');
951            for (var i = 0; i < _Div.length; i++){
952                _Div[i].parentNode.removeChild( _Div[i--] );
953            }
954            ////////////////////////////////////////////////////
955                       
956            // Delete Tags <SPAN>
957            var _Span = _message.getElementsByTagName('span_deny');
958            for (var i = 0; i < _Span.length; i++){
959                _Span[i].parentNode.removeChild( _Span[i--] );
960            }
961            ////////////////////////////////////////////////////
962
963            // Delete Tags <IFRAME>
964            var _Iframe = _message.getElementsByTagName('iframe_deny');
965            for (var i = 0; i < _Iframe.length; i++){
966                _Iframe[i].parentNode.removeChild( _Iframe[i--] );
967            }
968
969            // Delete Tags <A HREF>
970            var _aHref = _message.getElementsByTagName('a');
971            for (var i = 0; i < _aHref.length; i++){
972                _aHref[i].parentNode.removeChild( _aHref[i--] );
973            }
974                       
975            _message.innerHTML = _message.innerHTML.replace(/^\s+|\s+$|^\n|\n$/g, "");
976            ////////// END XSS //////////////////////////////////////////////////
977                       
978            // Get Smiles
979            _message.innerHTML = loadscript.getSmiles( _message.innerHTML );
980
981            if (type == 'chat' || type == 'normal')
982            {
983                if ( _message.hasChildNodes() )
984                {
985                    var message =
986                    {
987                        contact : "[" + stamp + "] <font style='font-weight:bold; color:black;'>" + contact + "</font>",
988                        msg             : "</br>" + _message.innerHTML
989                    };
990                                       
991                    TrophyIM.addMessage( TrophyIM.makeChat( from ), jid_lower, message );
992                }
993            }
994            else if( type == 'groupchat')
995            {
996                if ( _message.hasChildNodes() )
997                {
998                    var message =
999                    {
1000                        contact : "[" + stamp + "] <font style='font-weight:bold; color:black;'>" + jidChatRoom + "</font>",
1001                        msg     : "</br>" + _message.innerHTML
1002                    };
1003
1004                    TrophyIM.addMessage( TrophyIM.makeChatRoom( barejid ), jid_lower, message );
1005                }
1006            }
1007        }
1008        // Message without body are "content message", this mean state is not active
1009        else
1010        {
1011            if( chatBox != null )
1012                state = TrophyIM.getChatState(msg);                     
1013        }
1014               
1015        // Clean chat status message some time later           
1016        var clearChatState = function()
1017        {
1018            chatBox.innerHTML='';
1019        }
1020               
1021        if (chatBox != null)
1022        {
1023            var clearChatStateTimer;
1024                       
1025            chatBox.innerHTML = "<font style='font-weight:bold; color:grey; float:right;'>" + state + "</font>";
1026                       
1027            var _composing =  msg.getElementsByTagName('composing');
1028                       
1029            if ( _composing.length == 0 )
1030                               
1031                clearChatStateTimer = setTimeout(clearChatState, 2000);
1032            else
1033                clearTimeout(clearChatStateTimer);                     
1034        }
1035
1036        return true;
1037    },
1038
1039    /** Function: getChatState
1040         *
1041         *  Parameters:
1042         *    (string) msg - the message to get chat state
1043         *    (string) jid - the jid of chat box to update the chat state to.
1044         */
1045    getChatState : function(msg)
1046    {
1047        var     state =  msg.getElementsByTagName('inactive');
1048               
1049        if ( state.length > 0 )
1050        {
1051            return i18n.INACTIVE;
1052        }
1053        else
1054        {
1055            state = msg.getElementsByTagName('gone');
1056            if ( state.length > 0 )
1057            {
1058                return i18n.GONE;
1059            }
1060            else
1061            {
1062                state = msg.getElementsByTagName('composing');
1063                if ( state.length > 0 )
1064                {
1065                    return i18n.COMPOSING;
1066                }
1067                else
1068                {
1069                    state =  msg.getElementsByTagName('paused');
1070                    if ( state.length > 0 )
1071                    {
1072                        return i18n.PAUSED;
1073                    }
1074                }
1075            }
1076        }
1077               
1078        return '';
1079    },
1080
1081    /** Function: makeChat
1082     *
1083     *  Make sure chat window to given fulljid exists, switching chat context to
1084     *  given resource.
1085     */
1086     
1087    makeChat : function(fulljid)
1088    {
1089        var barejid             = Strophe.getBareJidFromJid(fulljid);
1090        var titleWindow = "";
1091
1092        var paramsChatBox =
1093        {
1094            'enabledPopUp'      : ( ( loadscript.getBrowserCompatible() ) ? "block" : "none" ),
1095            'idChatBox'         : barejid + "__chatBox",
1096            'jidTo'                     : barejid,
1097            'path_jabberit' : path_jabberit
1098        };
1099
1100        titleWindow = barejid.toLowerCase();
1101        titleWindow = titleWindow.substring(0, titleWindow.indexOf('@'));
1102
1103        if( TrophyIM.rosterObj.roster[barejid] )
1104        {
1105            if( TrophyIM.rosterObj.roster[barejid.toLowerCase()]['contact']['name'] )
1106            {
1107                titleWindow = TrophyIM.rosterObj.roster[barejid.toLowerCase()]['contact']['name'];
1108            }
1109        }
1110
1111        // Position Top
1112        TrophyIM.posWindow.top  = TrophyIM.posWindow.top + 10;
1113        if( TrophyIM.posWindow.top > 200 )
1114            TrophyIM.posWindow.top      = 100;
1115       
1116        // Position Left
1117        TrophyIM.posWindow.left = TrophyIM.posWindow.left + 5;
1118        if( TrophyIM.posWindow.left > 455 )
1119            TrophyIM.posWindow.left     = 400;
1120       
1121        var _content = document.createElement( 'div' );
1122        _content.innerHTML = loadscript.parse( "chat_box", "chatBox.xsl", paramsChatBox);
1123        _content = _content.firstChild;
1124       
1125        var _messages           = _content.firstChild.firstChild;
1126        var _textarea           = _content.getElementsByTagName( 'textarea' ).item( 0 );
1127        var _send                       = _content.getElementsByTagName( 'input' ).item( 0 );
1128        var _chatStateOnOff     = _content.getElementsByTagName( 'input' ).item( 1 );
1129
1130        var _send_message = function( )
1131        {
1132            if ( ! TrophyIM.sendMessage( barejid, _textarea.value ) )
1133                return false;
1134
1135            // Add Message in chatBox;
1136            TrophyIM.addMessage( _messages, barejid, {
1137                contact : "<font style='font-weight:bold; color:red;'>" + i18n.ME + "</font>",
1138                msg : "<br/>" + _textarea.value
1139            } );
1140
1141            _textarea.value = '';
1142            _textarea.focus( );
1143        };
1144               
1145        var composingTimer_ = 0;
1146        var isComposing_ = 0;
1147        var timeCounter;
1148
1149        var setComposing = function( )
1150        {
1151            var checkComposing = function()
1152            {
1153                if (!isComposing_) {
1154                    // User stopped composing
1155                    composingTimer_ = 0;
1156                    clearInterval(timeCounter);
1157                    TrophyIM.sendContentMessage(barejid, 'paused');
1158                } else {
1159                    TrophyIM.sendContentMessage(barejid, 'composing');
1160                }
1161                isComposing_ = 0; // Reset composing
1162            }
1163
1164            if (!composingTimer_) {
1165                /* User (re)starts composing */
1166                composingTimer_ = 1;
1167                timeCounter = setInterval(checkComposing,4000);
1168            }
1169            isComposing_ = 1;
1170        };
1171
1172        loadscript.configEvents( _send, 'onclick', _send_message );
1173        loadscript.configEvents( _textarea, 'onkeyup', function( e )
1174        {
1175            if ( e.keyCode == 13 ){
1176                _send_message( );
1177                // User stopped composing
1178                composingTimer_ = 0;
1179                clearInterval(timeCounter);
1180            }else{
1181                if (_chatStateOnOff.value == 'on')
1182                    setComposing();
1183            }
1184        } );       
1185
1186        var winChatBox =
1187        {
1188            id_window           : "window_chat_area_" + barejid,
1189            barejid             : barejid,
1190            width               : 387,
1191            height              : 375,
1192            top                 : TrophyIM.posWindow.top,
1193            left                : TrophyIM.posWindow.left,
1194            draggable           : true,
1195            visible             : "display",
1196            resizable           : true,
1197            zindex              : loadscript.getZIndex(),
1198            title               : titleWindow,
1199            closeAction         : "hidden",
1200            content             : _content     
1201        }
1202       
1203        _win = _winBuild(winChatBox);
1204
1205        // Notification New Message
1206        loadscript.notification(barejid);
1207       
1208        // Photo User;
1209        loadscript.getPhotoUser(barejid);
1210               
1211        _textarea.focus( );
1212       
1213        _messages = _win.content( ).firstChild;
1214       
1215        while ( _messages && _messages.nodeType !== 1 )
1216        {
1217            _messages = _messages.nextSibling;
1218        }
1219       
1220        return ( _messages );         
1221    },
1222
1223    /** Function: makeChatRoom
1224    *
1225    *
1226    *
1227    */
1228   
1229    makeChatRoom : function()
1230    {
1231        var jidChatRoom = arguments[0];
1232        var titleWindow = "ChatRoom - " + unescape(arguments[1]);
1233       
1234        var paramsChatRoom =
1235        {
1236            'idChatRoom'        : jidChatRoom + "__roomChat",
1237            'jidTo'                     : jidChatRoom,
1238            'lang_Send'         : i18n.SEND,
1239            'lang_Leave_ChatRoom' : i18n.LEAVE_CHATROOM,
1240            'path_jabberit' : path_jabberit
1241        };
1242
1243        // Position Top
1244        TrophyIM.posWindow.top  = TrophyIM.posWindow.top + 10;
1245        if( TrophyIM.posWindow.top > 200 )
1246            TrophyIM.posWindow.top      = 100;
1247       
1248        // Position Left
1249        TrophyIM.posWindow.left = TrophyIM.posWindow.left + 5;
1250        if( TrophyIM.posWindow.left > 455 )
1251            TrophyIM.posWindow.left     = 400;
1252
1253        var _content = document.createElement( 'div' );
1254        _content.innerHTML = loadscript.parse( "chat_room", "chatRoom.xsl", paramsChatRoom );
1255        _content = _content.firstChild;
1256       
1257        var _messages           = _content.firstChild.firstChild;
1258        var _textarea           = _content.getElementsByTagName( 'textarea' ).item( 0 );
1259        var _send                       = _content.getElementsByTagName( 'input' ).item( 0 );
1260        var _leaveChatRoom      = _content.getElementsByTagName( 'input' ).item( 1 );
1261       
1262        var _send_message = function( )
1263        {
1264            if ( ! TrophyIM.sendMessageChatRoom( jidChatRoom, _textarea.value ) )
1265                return false;
1266               
1267            _textarea.value = '';
1268               
1269            _textarea.focus( );
1270        };
1271       
1272        loadscript.configEvents( _send, 'onclick', _send_message );
1273        loadscript.configEvents( _leaveChatRoom, 'onclick', function( )
1274        {
1275            TrophyIM.leaveChatRoom( jidChatRoom );
1276               
1277            if( TrophyIM.activeChatRoom.name.length > 0 )
1278            {
1279                for( var i = 0;  i < TrophyIM.activeChatRoom.name.length ; i++ )
1280                {
1281                    if( TrophyIM.activeChatRoom.name[i].indexOf( jidChatRoom ) >= 0 )
1282                    {
1283                        TrophyIM.activeChatRoom.name[i] = "";
1284                    }
1285                }
1286            }
1287               
1288            setTimeout( function()
1289            {
1290                _winBuild("window_chat_room_" + jidChatRoom, "remove");
1291                       
1292            }, 650 );
1293               
1294        });
1295       
1296        loadscript.configEvents( _textarea, 'onkeyup', function( e )
1297        {
1298            if ( e.keyCode == 13 )
1299            {
1300                _send_message( );
1301            }
1302        });       
1303       
1304        var winChatRoom =
1305        {
1306            id_window           : "window_chat_room_" + arguments[0],
1307            barejid             : jidChatRoom,
1308            width                       : 500,
1309            height                      : 450,
1310            top                 : TrophyIM.posWindow.top,
1311            left                        : TrophyIM.posWindow.left,
1312            draggable           : true,
1313            visible             : "display",
1314            resizable           : true,
1315            zindex                      : loadscript.getZIndex(),
1316            title                       : titleWindow,
1317            closeAction : "hidden",
1318            content             : _content     
1319        }
1320       
1321        _win = _winBuild(winChatRoom);
1322       
1323        _messages = _win.content( ).firstChild;
1324       
1325        while ( _messages && _messages.nodeType !== 1 )
1326        {
1327            _messages = _messages.nextSibling;
1328        }
1329       
1330        return ( _messages );         
1331
1332       
1333    },
1334   
1335    /** Function addContacts
1336         *
1337         *  Parameters:
1338         *              (string) jidFrom         
1339         *      (string) jidTo
1340         *              (string) name
1341         *              (string) group   
1342         */
1343       
1344    addContact : function( jidTo, name, group )
1345    {
1346        var _flag = true;
1347
1348        if( TrophyIM.removeResult.idResult.length > 0 )
1349        {
1350            for( var i = 0 ; i < TrophyIM.removeResult.idResult.length; i++ )
1351            {
1352                if( TrophyIM.removeResult.idResult[i] == jidTo )
1353                {
1354                    _flag = false;
1355                                       
1356                    TrophyIM.removeResult.idResult.splice(i,1);
1357                                       
1358                    i--;
1359                }
1360            }
1361        }
1362               
1363        if( _flag )
1364        {       
1365            // Add Contact
1366            var _id = TrophyIM.connection.getUniqueId('add');
1367            var newContact = $iq({
1368                type: 'set',
1369                id: _id
1370            });
1371            newContact = newContact.c('query').attrs({
1372                xmlns : 'jabber:iq:roster'
1373            });
1374            newContact = newContact.c('item').attrs({
1375                jid: jidTo,
1376                name:name
1377            });
1378            newContact = newContact.c('group').t(group).tree();
1379       
1380            TrophyIM.connection.send(newContact);
1381        }
1382    },
1383
1384    /** Function: add
1385     *
1386     *  Parameters:
1387     *    (string) msg - the message to add
1388     *    (string) jid - the jid of chat box to add the message to.
1389     */
1390       
1391    addMessage : function( chatBox, jid, msg )
1392    {
1393        // Get Smiles
1394        msg.msg = loadscript.getSmiles( msg.msg );
1395 
1396        var messageDiv  = document.createElement("div");
1397        messageDiv.style.margin = "3px 0px 1em 3px";
1398        messageDiv.innerHTML    = msg.contact + " : " + msg.msg ;
1399               
1400        chatBox.appendChild(messageDiv);
1401        chatBox.scrollTop = chatBox.scrollHeight;
1402    },
1403       
1404    /** Function : renameContact
1405     *
1406     *
1407     */
1408   
1409    renameContact : function( jid )
1410    {
1411        // Name
1412        var name                = TrophyIM.rosterObj.roster[jid].contact.name;
1413
1414        if(( name = prompt(i18n.ASK_NEW_NAME_QUESTION + name + "!", name )))
1415            if(( name = name.replace(/^\s+|\s+$|^\n|\n$/g,"")) == "" )
1416                name = "";
1417
1418        if( name == null || name == "")
1419            name = "";
1420               
1421        var jidTo = jid
1422        var name  = ( name ) ? name : TrophyIM.rosterObj.roster[jid].contact.name;
1423        var group = TrophyIM.rosterObj.roster[jid].contact.groups[0];
1424       
1425        TrophyIM.addContact( jidTo, name, group );
1426       
1427        document.getElementById('itenContact_' + jid ).innerHTML = name;
1428    },
1429   
1430    /** Function : renameGroup
1431     *
1432     *
1433     */
1434
1435    renameGroup : function( jid )
1436    {
1437        var group               = TrophyIM.rosterObj.roster[jid].contact.groups[0];
1438        var presence    = TrophyIM.rosterObj.roster[jid].presence;
1439       
1440        // Group
1441        if(( group = prompt( i18n.ASK_NEW_GROUP_QUESTION, group )))
1442            if(( group = group.replace(/^\s+|\s+$|^\n|\n$/g,"")) == "" )
1443                group = "";
1444
1445        if( group == null || group == "")
1446            group = "";
1447
1448        var jidTo = TrophyIM.rosterObj.roster[jid].contact.jid;
1449        var name  = TrophyIM.rosterObj.roster[jid].contact.name;
1450        var group = ( group ) ? group : TrophyIM.rosterObj.roster[jid].contact.groups[0];
1451
1452        TrophyIM.rosterObj.removeContact( jid );
1453               
1454        TrophyIM.addContact( jidTo, name, group );
1455       
1456        document.getElementById("JabberIMRoster").innerHTML = "";
1457               
1458        TrophyIM.renderRoster();
1459       
1460        setTimeout(function()
1461        {
1462            for( var i in presence )
1463            {
1464                if ( presence[ i ].constructor == Function )
1465                    continue;
1466                               
1467                TrophyIM.rosterObj.setPresence( jid, presence[i].priority, presence[i].show, presence[i].status);
1468            }
1469        },500);
1470    },
1471
1472    /** Function createChatRooms
1473     *
1474     *
1475     */
1476   
1477    createChatRooms : function()
1478    {
1479        var nickName     = document.getElementById('nickName_chatRoom_jabberit').value;
1480        var nameChatRoom = document.getElementById('name_ChatRoom_jabberit').value;
1481       
1482        var _from       = Base64.decode( loadscript.getUserCurrent().jid ) + TROPHYIM_RESOURCE;
1483        var _to         = escape( nameChatRoom ) + "@" + TROPHYIM_CHATROOM + "/" + nickName ;
1484        var new_room    = $pres( {
1485            from: _from,
1486            to: _to
1487        } ).c( "x", {
1488            xmlns: Strophe.NS.MUC
1489            } );
1490
1491        TrophyIM.activeChatRoom.name[ TrophyIM.activeChatRoom.name.length ] = _to;
1492               
1493        TrophyIM.connection.send( new_room.tree() );
1494    },
1495   
1496    /** Function : joinRoom
1497     *
1498     *
1499     */
1500   
1501    joinChatRoom : function( roomName )
1502    {
1503        var presence = $pres( {
1504            from: TrophyIM.connection.jid,
1505            to: roomName
1506        } ).c("x",{
1507            xmlns: Strophe.NS.MUC
1508            });
1509       
1510        TrophyIM.connection.send( presence );
1511    },
1512   
1513    /** Function : Leave Chat Room
1514     *
1515     *
1516     */
1517   
1518    leaveChatRoom : function( roomName )
1519    {
1520        var room_nick   = roomName;
1521       
1522        var presenceid  = TrophyIM.connection.getUniqueId();
1523       
1524        var presence    = $pres( {
1525            type: "unavailable",
1526            id: presenceid,
1527            from: TrophyIM.connection.jid,
1528            to: room_nick
1529        } ).c("x",{
1530            xmlns: Strophe.NS.MUC
1531            });
1532       
1533        TrophyIM.connection.send( presence );       
1534    },
1535   
1536    /** Function : getlistRooms
1537     *
1538     *
1539     */
1540   
1541    getListRooms : function()
1542    {
1543        if( TrophyIM.statusConn.connected )
1544        {
1545            var _error_return = function(element)
1546            {
1547                alert("ERRO : Tente novamente !");
1548            };
1549               
1550            var iq = $iq({
1551                to: TROPHYIM_CHATROOM,
1552                type: "get"
1553            }).c("query",{
1554                xmlns: Strophe.NS.DISCO_ITEMS
1555                });             
1556                       
1557            TrophyIM.connection.sendIQ( iq, loadscript.listRooms, _error_return, 500 );
1558        }
1559        else
1560        {
1561            alert( "ERRO : Sem conexão com o servidor " + TROPHYIM_CHATROOM );
1562        }
1563    },
1564   
1565    /** Function: removeContact
1566     *
1567     *  Parameters:
1568     *          (string) jidTo
1569     */
1570   
1571    removeContact : function( jidTo )
1572    {
1573        var divItenContact       = null;
1574
1575        if( ( divItenContact = document.getElementById('itenContact_' + jidTo )))
1576        {       
1577            // Remove Contact
1578            var _id     = TrophyIM.connection.getUniqueId();   
1579               
1580            // Controller Result
1581            TrophyIM.removeResult.idResult[ TrophyIM.removeResult.idResult.length ] = jidTo;
1582
1583            var delContact      = $iq({
1584                type: 'set',
1585                id: _id
1586            })
1587            delContact  = delContact.c('query').attrs({
1588                xmlns : 'jabber:iq:roster'
1589            });
1590            delContact  = delContact.c('item').attrs({
1591                jid: jidTo,
1592                subscription:'remove'
1593            }).tree();
1594
1595            TrophyIM.connection.send( delContact );
1596               
1597            loadscript.removeElement( document.getElementById('itenContactNotification_' + jidTo ) );
1598               
1599            var spanShow = document.getElementById('span_show_itenContact_' + jidTo )
1600            spanShow.parentNode.removeChild(spanShow);
1601               
1602            loadscript.removeGroup( divItenContact.parentNode );
1603               
1604            divItenContact.parentNode.removeChild(divItenContact);
1605        }
1606    },
1607   
1608    /** Function: renderRoster
1609     *
1610     *  Renders roster, looking only for jids flagged by setPresence as having
1611     *  changed.
1612     */
1613   
1614    renderRoster : function()
1615    {
1616        var roster_div = document.getElementById('JabberIMRoster');
1617               
1618        if( roster_div )
1619        {
1620            var users = new Array();
1621                       
1622            var loading_gif = document.getElementById("JabberIMRosterLoadingGif");
1623                       
1624            if( loading_gif.style.display == "block" )
1625                loading_gif.style.display = "none";
1626                               
1627            for( var user in TrophyIM.rosterObj.roster )
1628            {
1629                if ( TrophyIM.rosterObj.roster[ user ].constructor == Function )
1630                    continue;
1631
1632                users[users.length] = TrophyIM.rosterObj.roster[user].contact.jid;
1633            }
1634
1635            users.sort();
1636                       
1637            var groups          = new Array();
1638            var flagGeral       = false;
1639                       
1640            for (var group in TrophyIM.rosterObj.groups)
1641            {
1642                if ( TrophyIM.rosterObj.groups[ group ].constructor == Function )
1643                    continue;
1644                               
1645                if( group )
1646                    groups[groups.length] = group;
1647                               
1648                if( group == "Geral" )
1649                    flagGeral = true;
1650            }
1651           
1652            if( !flagGeral && users.length > 0 )
1653                groups[groups.length] = "Geral";
1654                               
1655            groups.sort();
1656                       
1657            for ( var i = 0; i < groups.length; i++ )
1658            {
1659                TrophyIM.renderGroups( groups[i] , roster_div );       
1660            }
1661                       
1662            TrophyIM.renderItensGroup( users, roster_div );
1663        }
1664                       
1665        TrophyIM._timeOut.renderRoster = setTimeout("TrophyIM.renderRoster()", 1000 );         
1666    },
1667       
1668    /** Function: renderGroups
1669     *
1670     *
1671     */
1672       
1673    renderGroups: function( nameGroup, element )
1674    {
1675        var _addGroup = function()
1676        {
1677            var _nameGroup      = nameGroup;
1678            var _element        = element;
1679
1680            var paramsGroup =
1681            {
1682                'nameGroup'     : _nameGroup,
1683                'path_jabberit' : path_jabberit
1684            }
1685                       
1686            _element.innerHTML += loadscript.parse("group","groups.xsl", paramsGroup);
1687        }
1688
1689        if( !element.hasChildNodes() )
1690        {
1691            _addGroup();
1692        }
1693        else
1694        {
1695            var _NodeChild      = element.firstChild;
1696            var flagAdd         = false;
1697                       
1698            while( _NodeChild )
1699            {
1700                if( _NodeChild.childNodes[0].nodeName.toLowerCase() === "span" )
1701                {
1702                    if( _NodeChild.childNodes[0].childNodes[0].nodeValue === nameGroup )
1703                    {
1704                        flagAdd = true;
1705                    }
1706                }
1707                               
1708                _NodeChild = _NodeChild.nextSibling;
1709            }
1710
1711            if( !flagAdd )
1712            {
1713                _addGroup();
1714            }
1715        }
1716    },
1717
1718    /** Function: renderItensGroup
1719     *
1720     *
1721     */
1722
1723    renderItensGroup : function( users, element )
1724    {
1725        var addItem = function()
1726        {
1727            if( arguments.length > 0 )
1728            {
1729                // Get Arguments
1730                var objContact  = arguments[0];
1731                var group               = arguments[1];
1732                var element             = arguments[2];
1733                var showOffline = loadscript.getShowContactsOffline();
1734                               
1735                // Presence e Status
1736                var presence            = "unavailable";
1737                var status                      = "";
1738                var statusColor         = "black";
1739                var statusDisplay       = "none";
1740                               
1741                var _resource   = "";
1742                               
1743                // Set Presence
1744                var _presence = function(objContact)
1745                {
1746                    if (objContact.presence)
1747                    {
1748                        for (var resource in objContact.presence)
1749                        {
1750                            if ( objContact.presence[resource].constructor == Function )
1751                                continue;
1752
1753                            if( objContact.presence[resource].show != 'invisible' )
1754                                presence = objContact.presence[resource].show;
1755
1756                            if( objContact.contact.subscription != "both")
1757                                presence = 'subscription';
1758                                                       
1759                            if( objContact.presence[resource].status )
1760                            {
1761                                status = " ( " + objContact.presence[resource].status + " ) ";
1762                                statusDisplay   = "block";
1763                            }
1764                        }
1765                    }
1766                };
1767                               
1768                // Set Subscription
1769                var _subscription = function( objContact )
1770                {
1771                    if( objContact.contact.subscription != "both" )
1772                    {
1773                        switch( objContact.contact.subscription )
1774                        {
1775                            case "none" :
1776                                                               
1777                                status          = " (( " + i18n.ASK_FOR_AUTH  + " )) ";
1778                                statusColor     = "red";
1779                                break;
1780       
1781                            case "to" :
1782                                                               
1783                                status          = " (( " + i18n.CONTACT_ASK_FOR_AUTH  + " )) ";
1784                                statusColor     = "orange";
1785                                break;
1786       
1787                            case "from" :
1788                                                               
1789                                status          = " (( " + i18n.AUTHORIZED + " )) ";
1790                                statusColor = "green";
1791                                break;
1792                                                               
1793                            case "subscribe" :
1794                                                               
1795                                status          = " (( " + i18n.AUTH_SENT  + " )) ";
1796                                statusColor     = "red";       
1797                                break;
1798
1799                            case "not-in-roster" :
1800                                                               
1801                                status          = " (( " + i18n.ASK_FOR_AUTH_QUESTION  + " )) ";
1802                                statusColor     = "orange";     
1803                                break;
1804                                                               
1805                            default :
1806                                                               
1807                                break;
1808                        }
1809
1810                        statusDisplay = "block";
1811                    }
1812                };
1813
1814                if( objContact.contact.subscription != "remove")
1815                {
1816                    var itensJid        = document.getElementById( "itenContact_" + objContact.contact.jid );
1817                                       
1818                    if( itensJid == null )
1819                    {
1820                        // Name
1821                        var nameContact = "";                                   
1822                                               
1823                        if ( objContact.contact.name )
1824                            nameContact = objContact.contact.name;
1825                        else
1826                        {
1827                            nameContact = objContact.contact.jid;
1828                            nameContact = nameContact.substring(0, nameContact.indexOf('@'));
1829                        }
1830                                               
1831                        // Get Presence
1832                        _presence(objContact);
1833                                               
1834                        var paramsContact =
1835                        {
1836                            divDisplay          : "block",
1837                            id                          : 'itenContact_' + objContact.contact.jid ,
1838                            jid                         : objContact.contact.jid,
1839                            nameContact         : nameContact,
1840                            path_jabberit       : path_jabberit,
1841                            presence            : presence,
1842                            spanDisplay         : statusDisplay,
1843                            status                      : status,
1844                            statusColor         : "black",
1845                            subscription        : objContact.contact.subscription,
1846                            resource            : _resource
1847                        }
1848                                               
1849                        // Get Authorization
1850                        _subscription( objContact );
1851                                               
1852                        if( group != "")
1853                        {
1854                            var _NodeChild              = element.firstChild;
1855                                                       
1856                            while( _NodeChild )
1857                            {
1858                                if( _NodeChild.childNodes[0].nodeName.toLowerCase() === "span" )
1859                                {
1860                                    if( _NodeChild.childNodes[0].childNodes[0].nodeValue === group )
1861                                    {
1862                                        _NodeChild.innerHTML += loadscript.parse("itens_group", "itensGroup.xsl", paramsContact);
1863                                    }
1864                                }
1865       
1866                                _NodeChild = _NodeChild.nextSibling;
1867                            }
1868                        }       
1869                    }
1870                    else
1871                    {
1872                        // Get Presence
1873                        _presence(objContact);
1874       
1875                        var is_open = itensJid.parentNode.childNodes[0].style.backgroundImage; 
1876                        is_open = is_open.indexOf("arrow_down.gif");
1877       
1878                        // Get Authorization
1879                        _subscription( objContact );
1880                                               
1881                        // Set subscription
1882                        itensJid.setAttribute('subscription', objContact.contact.subscription );
1883                                               
1884                        with ( document.getElementById('span_show_' + 'itenContact_' + objContact.contact.jid ) )
1885                        {
1886                            if( presence == "unavailable" && !showOffline )
1887                            {
1888                                style.display = "none";
1889                            }
1890                            else
1891                            {
1892                                if( is_open > 0 )
1893                                {
1894                                    style.display       = statusDisplay;
1895                                    style.color         = statusColor;
1896                                    innerHTML           = status;
1897                                }
1898                            }
1899                            }
1900                                               
1901                        if( presence == "unavailable" && !showOffline )
1902                        {
1903                            itensJid.style.display = "none";
1904                        }
1905                        else
1906                        {
1907                            if( is_open > 0 )
1908                            {
1909                                itensJid.style.display = "block";
1910                            }
1911                        }
1912                                               
1913                        itensJid.style.background       = "url('"+path_jabberit+"templates/default/images/" + presence + ".gif') no-repeat center left";
1914                    }
1915       
1916                    // Contact OffLine
1917                    if( !objContact.presence && !showOffline )
1918                    {
1919                        if( objContact.contact.subscription != "remove" )
1920                        {
1921                            with ( document.getElementById('span_show_' + 'itenContact_' + objContact.contact.jid ))
1922                            {
1923                                style.display   = "none";
1924                                }
1925               
1926                            with ( document.getElementById('itenContact_' + objContact.contact.jid ) )
1927                            {
1928                                style.display   = "none";
1929                                }
1930                        }
1931                    }
1932                }
1933            }
1934        };
1935               
1936        var flag = false;
1937               
1938        for( var i = 0 ; i < users.length; i++ )
1939        {
1940            if( TrophyIM.rosterObj.roster[users[i]].contact.jid != Base64.decode( loadscript.getUserCurrent().jid) )
1941            {
1942                var _subscription = TrophyIM.rosterObj.roster[users[i]].contact.subscription;
1943                               
1944                if( _subscription === "to" )
1945                {
1946                    flag = true;
1947                }
1948                               
1949                if(  _subscription === "not-in-roster")
1950                {
1951                    flag = true;
1952                }
1953                               
1954                if( TrophyIM.rosterObj.roster[users[i]].contact.groups )
1955                {
1956                    var groups = TrophyIM.rosterObj.roster[users[i]].contact.groups;
1957                                       
1958                    if( groups.length > 0 )
1959                    {
1960                        for( var j = 0; j < groups.length; j++ )
1961                        {
1962                            addItem( TrophyIM.rosterObj.roster[users[i]], groups[j], element );
1963                        }
1964                    }
1965                    else
1966                    {
1967                        addItem( TrophyIM.rosterObj.roster[users[i]], "Geral", element );
1968                    }
1969                }
1970                else
1971                {
1972                    addItem( TrophyIM.rosterObj.roster[users[i]], "Geral", element );
1973                }
1974            }
1975        }
1976               
1977        if( flag )
1978        {
1979            if ( TrophyIM.controll.notificationNewUsers == 0 )
1980            {
1981                loadscript.enabledNotificationNewUsers();
1982                TrophyIM.controll.notificationNewUsers++;
1983            }
1984        }
1985        else
1986        {
1987            loadscript.disabledNotificationNewUsers();
1988            TrophyIM.controll.notificationNewUsers = 0;
1989        }
1990    },
1991
1992    /** Function: rosterClick
1993     *
1994     *  Handles actions when a roster item is clicked
1995     */
1996   
1997    rosterClick : function(fulljid)
1998    {
1999        TrophyIM.makeChat(fulljid);
2000    },
2001
2002    /** Function SetAutorization
2003         *
2004         */
2005
2006    setAutorization : function( jidTo, jidFrom, _typeSubscription )
2007    {
2008        var _id = TrophyIM.connection.getUniqueId();
2009       
2010        TrophyIM.connection.send($pres( ).attrs({
2011            from: jidFrom,
2012            to: jidTo,
2013            type: _typeSubscription,
2014            id: _id
2015        }).tree());
2016    },
2017
2018    /** Function: setPresence
2019     *
2020     */
2021
2022    setPresence : function( _type )
2023    {
2024        var presence_chatRoom = "";
2025               
2026        if( _type != 'status')
2027        {
2028            if( _type == "unavailable" &&  TrophyIM.statusConn.connected )
2029            {
2030                var loading_gif = document.getElementById("JabberIMRosterLoadingGif");
2031                               
2032                if( TrophyIM._timeOut.renderRoster != null )
2033                    clearTimeout(TrophyIM._timeOut.renderRoster);
2034                               
2035                if( TrophyIM.statusConn.connected )
2036                    TrophyIM.connection.send($pres({
2037                        type : _type
2038                    }).tree());
2039                               
2040                for( var i = 0; i < TrophyIM.connection._requests.length; i++ )
2041                {
2042                    if( TrophyIM.connection._requests[i] )
2043                        TrophyIM.connection._removeRequest(TrophyIM.connection._requests[i]);
2044                }
2045                               
2046                TrophyIM.logout();
2047                               
2048                loadscript.clrAllContacts();
2049                       
2050                delete TrophyIM.rosterObj.roster;
2051                delete TrophyIM.rosterObj.groups;
2052                       
2053                setTimeout(function()
2054                {
2055                    if( loading_gif.style.display == "block" )
2056                        loading_gif.style.display = "none";
2057                }, 1000);
2058            }
2059            else
2060            {
2061                if( !TrophyIM.autoConnection.connect )
2062                {
2063                    TrophyIM.autoConnection.connect = true;
2064                    TrophyIM.load();
2065                }
2066                else
2067                {
2068                    if( TrophyIM.statusConn.connected )
2069                    {
2070                        if( loadscript.getStatusMessage() != "" )
2071                        {
2072                            var _presence = $pres( );
2073                            _presence.node.appendChild( Strophe.xmlElement( 'show' ) ).appendChild( Strophe.xmlTextNode( _type ) );
2074                            _presence.node.appendChild( Strophe.xmlElement( 'status' ) ).appendChild( Strophe.xmlTextNode( loadscript.getStatusMessage() ));
2075                                                       
2076                            TrophyIM.connection.send( _presence.tree() );
2077                                                       
2078                            presence_chatRoom = _type;
2079                        }
2080                        else
2081                        {
2082                            TrophyIM.connection.send($pres( ).c('show').t(_type).tree());
2083                                                       
2084                            presence_chatRoom = _type;
2085                        }
2086                    }
2087                }
2088            }
2089        }
2090        else
2091        {
2092            var _show   = "available";
2093            var _status = "";
2094                       
2095            if( arguments.length < 2 )
2096            {
2097                if( loadscript.getStatusMessage() != "" )
2098                    _status = prompt(i18n.TYPE_YOUR_MSG, loadscript.getStatusMessage());
2099                else
2100                    _status = prompt(i18n.TYPE_YOUR_MSG);
2101                               
2102                var _divStatus = document.getElementById("JabberIMStatusMessage");
2103                               
2104                if( ( _status = _status.replace(/^\s+|\s+$|^\n|\n$/g,"") ) != "")
2105                    _divStatus.firstChild.innerHTML     = "( " + _status + " )";
2106            }
2107            else
2108            {
2109                _status = arguments[1];
2110            }
2111
2112            for( var resource in TrophyIM.rosterObj.roster[Base64.decode(loadscript.getUserCurrent().jid)].presence )
2113            {
2114                if ( TrophyIM.rosterObj.roster[Base64.decode(loadscript.getUserCurrent().jid)].presence[ resource ].constructor == Function )
2115                    continue;
2116                       
2117                if ( TROPHYIM_RESOURCE === ("/" + resource) )
2118                    _show = TrophyIM.rosterObj.roster[Base64.decode(loadscript.getUserCurrent().jid)].presence[resource].show;
2119            }
2120
2121            if ( TrophyIM.statusConn.connected )
2122            {
2123                var _presence = $pres( );
2124                _presence.node.appendChild( Strophe.xmlElement( 'show' ) ).appendChild( Strophe.xmlTextNode( _show ) );
2125                _presence.node.appendChild( Strophe.xmlElement( 'status' ) ).appendChild( Strophe.xmlTextNode( _status ) );
2126                               
2127                TrophyIM.connection.send( _presence.tree() );
2128                               
2129                presence_chatRoom = _show;
2130            }
2131        }
2132               
2133        // Send Presence Chat Room
2134        if( TrophyIM.activeChatRoom.name.length > 0 )
2135        {
2136            for( i = 0; i < TrophyIM.activeChatRoom.name.length; i++ )
2137            {
2138                if( TrophyIM.activeChatRoom.name[i] != "" )
2139                    TrophyIM.connection.send($pres( {
2140                        to : TrophyIM.activeChatRoom.name[i]
2141                        } ).c('show').t( presence_chatRoom ) );
2142            }
2143        }
2144
2145    },
2146       
2147    /** Function: sendMessage
2148     *
2149     *  Send message from chat input to user
2150     */
2151     
2152    sendMessage : function()
2153    {
2154        if (arguments.length > 0)
2155        {
2156            var jidTo = arguments[0];
2157            var message_input = arguments[1];
2158                       
2159                       
2160            message_input = message_input.replace(/^\s+|\s+$|^\n|\n$/g, "");
2161                       
2162            if (message_input != "") {
2163                       
2164                // Send Message
2165                var newMessage = $msg({
2166                    to: jidTo,
2167                    from: TrophyIM.connection.jid,
2168                    type: 'chat'
2169                });
2170                newMessage = newMessage.c('body').t(message_input);
2171                newMessage.up();
2172                newMessage = newMessage.c('active').attrs({
2173                    xmlns: 'http://jabber.org/protocol/chatstates'
2174                });
2175                // Send Message
2176                TrophyIM.connection.send(newMessage.tree());
2177                               
2178                return true;
2179            }
2180        }
2181               
2182        return false;
2183    },
2184
2185    /** Function: sendMessage
2186    *
2187    *  Send message to ChatRoom
2188    */
2189   
2190    sendMessageChatRoom : function( )
2191    {
2192        if( arguments.length > 0 )
2193        {
2194            var room_nick       = arguments[0];
2195            var message         = arguments[1];
2196            var msgid           = TrophyIM.connection.getUniqueId();
2197            var msg                     = $msg({
2198                to: room_nick,
2199                type: "groupchat",
2200                id: msgid
2201            }).c("body",{
2202                xmlns: Strophe.NS.CLIENT
2203                }).t(message);
2204               
2205            msg.up();//.c("x", {xmlns: "jabber:x:event"}).c("composing");
2206               
2207            TrophyIM.connection.send(msg);
2208               
2209            return true;
2210        }
2211    },
2212   
2213    /** Function: sendContentMessage
2214     *
2215     *  Send a content message from chat input to user
2216     */
2217    sendContentMessage : function()
2218    {
2219        if( arguments.length > 0 )
2220        {
2221            var jidTo = arguments[0];
2222            var state = arguments[1];
2223
2224            var newMessage = $msg({
2225                to: jidTo,
2226                from: TrophyIM.connection.jid,
2227                type: 'chat'
2228            });
2229            newMessage = newMessage.c(state).attrs({
2230                xmlns : 'http://jabber.org/protocol/chatstates'
2231            });
2232            // Send content message
2233            TrophyIM.connection.send(newMessage.tree());
2234        }
2235    }
2236};
2237
2238/** Class: TrophyIMRoster
2239 *
2240 *
2241 *  This object stores the roster and presence info for the TrophyIMClient
2242 *
2243 *  roster[jid_lower]['contact']
2244 *  roster[jid_lower]['presence'][resource]
2245 */
2246function TrophyIMRoster()
2247{
2248    /** Constants: internal arrays
2249     *    (Object) roster - the actual roster/presence information
2250     *    (Object) groups - list of current groups in the roster
2251     *    (Array) changes - array of jids with presence changes
2252     */
2253    if (TrophyIM.JSONStore.store_working)
2254    {
2255        var data = TrophyIM.JSONStore.getData(['roster', 'groups']);
2256        this.roster = (data['roster'] != null) ? data['roster'] : {};
2257        this.groups = (data['groups'] != null) ? data['groups'] : {};
2258    }
2259    else
2260    {
2261        this.roster = {};
2262        this.groups = {};
2263    }
2264    this.changes = new Array();
2265   
2266    if (TrophyIM.constants.stale_roster)
2267    {
2268        for (var jid in this.roster)
2269        {
2270            this.changes[this.changes.length] = jid;
2271        }
2272    }
2273
2274    /** Function: addChange
2275         *
2276         *  Adds given jid to this.changes, keeping this.changes sorted and
2277         *  preventing duplicates.
2278         *
2279         *  Parameters
2280         *    (String) jid : jid to add to this.changes
2281         */
2282         
2283    this.addChange = function(jid)
2284    {
2285        for (var c = 0; c < this.changes.length; c++)
2286        {
2287            if (this.changes[c] == jid)
2288            {
2289                return;
2290            }
2291        }
2292               
2293        this.changes[this.changes.length] = jid;
2294               
2295        this.changes.sort();
2296    }
2297       
2298    /** Function: addContact
2299     *
2300     *  Adds given contact to roster
2301     *
2302     *  Parameters:
2303     *    (String) jid - bare jid
2304     *    (String) subscription - subscription attribute for contact
2305     *    (String) name - name attribute for contact
2306     *    (Array)  groups - array of groups contact is member of
2307     */
2308   
2309    this.addContact = function(jid, subscription, name, groups )
2310    {
2311        if( subscription === "remove" )
2312        {
2313            this.removeContact(jid);
2314        }
2315        else
2316        {
2317            var contact         = {
2318                jid:jid,
2319                subscription:subscription,
2320                name:name,
2321                groups:groups
2322            }
2323            var jid_lower       = jid.toLowerCase();
2324       
2325            if ( this.roster[jid_lower] )
2326            {
2327                this.roster[jid_lower]['contact'] = contact;
2328            }
2329            else
2330            {
2331                this.roster[jid_lower] = {
2332                    contact:contact
2333                };
2334            }
2335
2336            groups = groups ? groups : [''];
2337               
2338            for ( var g = 0; g < groups.length; g++ )
2339            {
2340                if ( !this.groups[groups[g]] )
2341                {
2342                    this.groups[groups[g]] = {};
2343                }
2344                   
2345                this.groups[groups[g]][jid_lower] = jid_lower;
2346            }
2347        }
2348    }
2349   
2350    /** Function: getContact
2351     *
2352     *  Returns contact entry for given jid
2353     *
2354     *  Parameter: (String) jid - jid to return
2355     */
2356     
2357    this.getContact = function(jid)
2358    {
2359        if (this.roster[jid.toLowerCase()])
2360        {
2361            return this.roster[jid.toLowerCase()]['contact'];
2362        }
2363    }
2364
2365    /** Function: getPresence
2366        *
2367        *  Returns best presence for given jid as Array(resource, priority, show,
2368        *  status)
2369        *
2370        *  Parameter: (String) fulljid - jid to return best presence for
2371        */
2372         
2373    this.getPresence = function(fulljid)
2374    {
2375        var jid = Strophe.getBareJidFromJid(fulljid);
2376        var current = null;
2377                   
2378        if (this.roster[jid.toLowerCase()] && this.roster[jid.toLowerCase()]['presence'])
2379        {
2380            for (var resource in this.roster[jid.toLowerCase()]['presence'])
2381            {
2382                if ( this.roster[jid.toLowerCase()]['presence'][ resource ].constructor == Function )
2383                    continue;
2384                       
2385                var presence = this.roster[jid.toLowerCase()]['presence'][resource];
2386                if (current == null)
2387                {
2388                    current = presence
2389                }
2390                else
2391                {
2392                    if(presence['priority'] > current['priority'] && ((presence['show'] == "chat"
2393                        || presence['show'] == "available") || (current['show'] != "chat" ||
2394                        current['show'] != "available")))
2395                        {
2396                        current = presence
2397                    }
2398                }
2399            }
2400        }
2401        return current;
2402    }
2403
2404    /** Function: groupHasChanges
2405         *
2406         *  Returns true if current group has members in this.changes
2407         *
2408         *  Parameters:
2409         *    (String) group - name of group to check
2410         */
2411         
2412    this.groupHasChanges = function(group)
2413    {
2414        for (var c = 0; c < this.changes.length; c++)
2415        {
2416            if (this.groups[group][this.changes[c]])
2417            {
2418                return true;
2419            }
2420        }
2421        return false;
2422    }
2423       
2424    /** Function removeContact
2425         *
2426         * Parameters
2427         *       (String) jid           
2428         */
2429         
2430    this.removeContact = function(jid)
2431    {
2432        if( this.roster[ jid ] )
2433        {
2434            var groups = this.roster[ jid ].contact.groups;
2435                       
2436            if( groups )
2437            {
2438                for ( var i = 0; i < groups.length; i++ )
2439                {
2440                    delete this.groups[ groups[ i ] ][ jid ];
2441                }
2442       
2443                for ( var i = 0; i < groups.length; i++ )
2444                {
2445                    var contacts = 0;
2446                    for ( var contact in this.groups[ groups[ i ] ] )
2447                    {
2448                        if ( this.groups[ groups[ i ] ][ contact ].constructor == Function )
2449                            continue;
2450                                       
2451                        contacts++;
2452                    }
2453               
2454                    if ( ! contacts )
2455                        delete this.groups[ groups[ i ] ];
2456                }
2457            }
2458       
2459            // Delete Object roster
2460            if( this.roster[jid] )
2461                delete this.roster[jid];
2462        }
2463    }
2464         
2465    /** Function: setPresence
2466     *
2467     *  Sets presence
2468     *
2469     *  Parameters:
2470     *    (String) fulljid: full jid with presence
2471     *    (Integer) priority: priority attribute from presence
2472     *    (String) show: show attribute from presence
2473     *    (String) status: status attribute from presence
2474     */
2475   
2476    this.setPresence = function(fulljid, priority, show, status)
2477    {
2478        var barejid             = Strophe.getBareJidFromJid(fulljid);
2479        var resource    = Strophe.getResourceFromJid(fulljid);
2480        var jid_lower   = barejid.toLowerCase();
2481       
2482        if( show !== 'unavailable' || show !== 'error' )
2483        {
2484            if (!this.roster[jid_lower])
2485            {
2486                this.addContact( barejid, 'not-in-roster' );
2487            }
2488           
2489            var presence =
2490            {
2491                resource        : resource,
2492                priority        : priority,
2493                show            : show,
2494                status          : status
2495            }
2496           
2497            if (!this.roster[jid_lower]['presence'])
2498            {
2499                this.roster[jid_lower]['presence'] = {};
2500            }
2501           
2502            this.roster[jid_lower]['presence'][resource] = presence;   
2503        }
2504    }
2505
2506    /** Fuction: save
2507         *
2508         *  Saves roster data to JSON store
2509         */
2510       
2511    this.save = function()
2512    {
2513        if (TrophyIM.JSONStore.store_working)
2514        {
2515            TrophyIM.JSONStore.setData({
2516                roster:this.roster,
2517                groups:this.groups,
2518                active_chat:TrophyIM.activeChats['current'],
2519                chat_history:TrophyIM.chatHistory
2520                });
2521        }
2522    }
2523
2524}
2525/** Class: TrophyIMJSONStore
2526 *
2527 *
2528 *  This object is the mechanism by which TrophyIM stores and retrieves its
2529 *  variables from the url provided by TROPHYIM_JSON_STORE
2530 *
2531 */
2532function TrophyIMJSONStore() {
2533    this.store_working = false;
2534    /** Function _newXHR
2535     *
2536     *  Set up new cross-browser xmlhttprequest object
2537     *
2538     *  Parameters:
2539     *    (function) handler = what to set onreadystatechange to
2540     */
2541    this._newXHR = function (handler) {
2542        var xhr = null;
2543        if (window.XMLHttpRequest) {
2544            xhr = new XMLHttpRequest();
2545            if (xhr.overrideMimeType) {
2546                xhr.overrideMimeType("text/xml");
2547            }
2548        } else if (window.ActiveXObject) {
2549            xhr = new ActiveXObject("Microsoft.XMLHTTP");
2550        }
2551        return xhr;
2552    }
2553    /** Function getData
2554     *  Gets data from JSONStore
2555     *
2556     *  Parameters:
2557     *    (Array) vars = Variables to get from JSON store
2558     *
2559     *  Returns:
2560     *    Object with variables indexed by names given in parameter 'vars'
2561     */
2562    this.getData = function(vars) {
2563        if (typeof(TROPHYIM_JSON_STORE) != undefined) {
2564            Strophe.debug("Retrieving JSONStore data");
2565            var xhr = this._newXHR();
2566            var getdata = "get=" + vars.join(",");
2567            try {
2568                xhr.open("POST", TROPHYIM_JSON_STORE, false);
2569            } catch (e) {
2570                Strophe.error("JSONStore open failed.");
2571                return false;
2572            }
2573            xhr.setRequestHeader('Content-type',
2574                'application/x-www-form-urlencoded');
2575            xhr.setRequestHeader('Content-length', getdata.length);
2576            xhr.send(getdata);
2577            if (xhr.readyState == 4 && xhr.status == 200) {
2578                try {
2579                    var dataObj = JSON.parse(xhr.responseText);
2580                    return this.emptyFix(dataObj);
2581                } catch(e) {
2582                    Strophe.error("Could not parse JSONStore response" +
2583                        xhr.responseText);
2584                    return false;
2585                }
2586            } else {
2587                Strophe.error("JSONStore open failed. Status: " + xhr.status);
2588                return false;
2589            }
2590        }
2591    }
2592    /** Function emptyFix
2593     *    Fix for bugs in external JSON implementations such as
2594     *    http://bugs.php.net/bug.php?id=41504.
2595     *    A.K.A. Don't use PHP, people.
2596     */
2597    this.emptyFix = function(obj) {
2598        if (typeof(obj) == "object") {
2599            for (var i in obj) {
2600                if ( obj[i].constructor == Function )
2601                    continue;
2602                       
2603                if (i == '_empty_') {
2604                    obj[""] = this.emptyFix(obj['_empty_']);
2605                    delete obj['_empty_'];
2606                } else {
2607                    obj[i] = this.emptyFix(obj[i]);
2608                }
2609            }
2610        }
2611        return obj
2612    }
2613    /** Function delData
2614     *    Deletes data from JSONStore
2615     *
2616     *  Parameters:
2617     *    (Array) vars  = Variables to delete from JSON store
2618     *
2619     *  Returns:
2620     *    Status of delete attempt.
2621     */
2622    this.delData = function(vars) {
2623        if (typeof(TROPHYIM_JSON_STORE) != undefined) {
2624            Strophe.debug("Retrieving JSONStore data");
2625            var xhr = this._newXHR();
2626            var deldata = "del=" + vars.join(",");
2627            try {
2628                xhr.open("POST", TROPHYIM_JSON_STORE, false);
2629            } catch (e) {
2630                Strophe.error("JSONStore open failed.");
2631                return false;
2632            }
2633            xhr.setRequestHeader('Content-type',
2634                'application/x-www-form-urlencoded');
2635            xhr.setRequestHeader('Content-length', deldata.length);
2636            xhr.send(deldata);
2637            if (xhr.readyState == 4 && xhr.status == 200) {
2638                try {
2639                    var dataObj = JSON.parse(xhr.responseText);
2640                    return dataObj;
2641                } catch(e) {
2642                    Strophe.error("Could not parse JSONStore response");
2643                    return false;
2644                }
2645            } else {
2646                Strophe.error("JSONStore open failed. Status: " + xhr.status);
2647                return false;
2648            }
2649        }
2650    }
2651    /** Function setData
2652     *    Stores data in JSONStore, overwriting values if they exist
2653     *
2654     *  Parameters:
2655     *    (Object) vars : Object containing named vars to store ({name: value,
2656     *    othername: othervalue})
2657     *
2658     *  Returns:
2659     *    Status of storage attempt
2660     */
2661    this.setData = function(vars)
2662    {
2663        if ( typeof(TROPHYIM_JSON_STORE) != undefined )
2664        {
2665            var senddata = "set=" + JSON.stringify(vars);
2666            var xhr = this._newXHR();
2667            try
2668            {
2669                xhr.open("POST", TROPHYIM_JSON_STORE, false);
2670            }
2671            catch (e)
2672            {
2673                Strophe.error("JSONStore open failed.");
2674                return false;
2675            }
2676            xhr.setRequestHeader('Content-type',
2677                'application/x-www-form-urlencoded');
2678            xhr.setRequestHeader('Content-length', senddata.length);
2679            xhr.send(senddata);
2680            if (xhr.readyState == 4 && xhr.status == 200 && xhr.responseText ==
2681                "OK") {
2682                return true;
2683            } else {
2684                Strophe.error("JSONStore open failed. Status: " + xhr.status);
2685                return false;
2686            }
2687        }
2688    }
2689   
2690    var testData = true;
2691   
2692    if (this.setData({
2693        testData:testData
2694    })) {
2695        var testResult = this.getData(['testData']);
2696        if (testResult && testResult['testData'] == true) {
2697            this.store_working = true;
2698        }
2699    }
2700}
2701/** Constants: Node types
2702 *
2703 * Implementations of constants that IE doesn't have, but we need.
2704 */
2705if (document.ELEMENT_NODE == null) {
2706    document.ELEMENT_NODE = 1;
2707    document.ATTRIBUTE_NODE = 2;
2708    document.TEXT_NODE = 3;
2709    document.CDATA_SECTION_NODE = 4;
2710    document.ENTITY_REFERENCE_NODE = 5;
2711    document.ENTITY_NODE = 6;
2712    document.PROCESSING_INSTRUCTION_NODE = 7;
2713    document.COMMENT_NODE = 8;
2714    document.DOCUMENT_NODE = 9;
2715    document.DOCUMENT_TYPE_NODE = 10;
2716    document.DOCUMENT_FRAGMENT_NODE = 11;
2717    document.NOTATION_NODE = 12;
2718}
2719
2720/** Function: importNode
2721 *
2722 *  document.importNode implementation for IE, which doesn't have importNode
2723 *
2724 *  Parameters:
2725 *    (Object) node - dom object
2726 *    (Boolean) allChildren - import node's children too
2727 */
2728if (!document.importNode) {
2729    document.importNode = function(node, allChildren) {
2730        switch (node.nodeType) {
2731            case document.ELEMENT_NODE:
2732                var newNode = document.createElement(node.nodeName);
2733                if (node.attributes && node.attributes.length > 0) {
2734                    for(var i = 0; i < node.attributes.length; i++) {
2735                        newNode.setAttribute(node.attributes[i].nodeName,
2736                            node.getAttribute(node.attributes[i].nodeName));
2737                    }
2738                }
2739                if (allChildren && node.childNodes &&
2740                    node.childNodes.length > 0) {
2741                    for (var i = 0; i < node.childNodes.length; i++) {
2742                        newNode.appendChild(document.importNode(
2743                            node.childNodes[i], allChildren));
2744                    }
2745                }
2746                return newNode;
2747                break;
2748            case document.TEXT_NODE:
2749            case document.CDATA_SECTION_NODE:
2750            case document.COMMENT_NODE:
2751                return document.createTextNode(node.nodeValue);
2752                break;
2753        }
2754    };
2755}
2756
2757/**
2758 *
2759 * Bootstrap self into window.onload and window.onunload
2760 */
2761
2762var oldonunload = window.onunload;
2763
2764window.onunload = function()
2765{
2766    if( oldonunload )
2767    {
2768        oldonunload();
2769    }
2770       
2771    TrophyIM.setPresence('unavailable');
2772}
Note: See TracBrowser for help on using the repository browser.