source: branches/2.2/jabberit_messenger/jmessenger/js/trophyim.js @ 4475

Revision 4475, 86.0 KB checked in by alexandrecorreia, 13 years ago (diff)

Ticket #1885 - Correção para o funcionamento dentro dos navegadores Chrome11 e Safari.

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