source: branches/2.2.0.1/jabberir_messenger/jmessenger/js/trophyim.js @ 4453

Revision 4453, 73.3 KB checked in by rafaelraymundo, 13 years ago (diff)

Ticket #1726 - Adicionando jabberit_messenger da comunidade.

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