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

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

Ticket #2260 - Sincronismo do branch2.2(versão 2.2.8) do modulo mobile para 2.4

  • 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        var _textarea           = _content.getElementsByTagName( 'textarea' ).item( 0 );
1128        var _send                       = _content.getElementsByTagName( 'input' ).item( 0 );
1129        var _chatStateOnOff     = _content.getElementsByTagName( 'input' ).item( 1 );
1130
1131        var _send_message = function( )
1132        {
1133            if ( ! TrophyIM.sendMessage( barejid, _textarea.value ) )
1134                return false;
1135
1136            // Add Message in chatBox;
1137            TrophyIM.addMessage( _messages, barejid, {
1138                contact : "<font style='font-weight:bold; color:red;'>" + i18n.ME + "</font>",
1139                msg : "<br/>" + _textarea.value
1140            } );
1141
1142            _textarea.value = '';
1143            _textarea.focus( );
1144        };
1145               
1146        var composingTimer_ = 0;
1147        var isComposing_ = 0;
1148        var timeCounter;
1149
1150        var setComposing = function( )
1151        {
1152            var checkComposing = function()
1153            {
1154                if (!isComposing_) {
1155                    // User stopped composing
1156                    composingTimer_ = 0;
1157                    clearInterval(timeCounter);
1158                    TrophyIM.sendContentMessage(barejid, 'paused');
1159                } else {
1160                    TrophyIM.sendContentMessage(barejid, 'composing');
1161                }
1162                isComposing_ = 0; // Reset composing
1163            }
1164
1165            if (!composingTimer_) {
1166                /* User (re)starts composing */
1167                composingTimer_ = 1;
1168                timeCounter = setInterval(checkComposing,4000);
1169            }
1170            isComposing_ = 1;
1171        };
1172
1173        loadscript.configEvents( _send, 'onclick', _send_message );
1174        loadscript.configEvents( _textarea, 'onkeyup', function( e )
1175        {
1176            if ( e.keyCode == 13 ){
1177                _send_message( );
1178                // User stopped composing
1179                composingTimer_ = 0;
1180                clearInterval(timeCounter);
1181            }else{
1182                if (_chatStateOnOff.value == 'on')
1183                    setComposing();
1184            }
1185        } );       
1186
1187        var winChatBox =
1188        {
1189            id_window           : "window_chat_area_" + barejid,
1190            barejid             : barejid,
1191            width               : 387,
1192            height              : 375,
1193            top                 : TrophyIM.posWindow.top,
1194            left                : TrophyIM.posWindow.left,
1195            draggable           : true,
1196            visible             : "display",
1197            resizable           : true,
1198            zindex              : loadscript.getZIndex(),
1199            title               : titleWindow,
1200            closeAction         : "hidden",
1201            content             : _content     
1202        }
1203       
1204        _win = _winBuild(winChatBox);
1205
1206        // Notification New Message
1207        loadscript.notification(barejid);
1208       
1209        // Photo User;
1210        loadscript.getPhotoUser(barejid);
1211               
1212        _textarea.focus( );
1213       
1214        _messages = _win.content( ).firstChild;
1215       
1216        while ( _messages && _messages.nodeType !== 1 )
1217        {
1218            _messages = _messages.nextSibling;
1219        }
1220       
1221        return ( _messages );         
1222    },
1223
1224    /** Function: makeChatRoom
1225    *
1226    *
1227    *
1228    */
1229   
1230    makeChatRoom : function()
1231    {
1232        var jidChatRoom = arguments[0];
1233        var titleWindow = "ChatRoom - " + unescape(arguments[1]);
1234       
1235        var paramsChatRoom =
1236        {
1237            'idChatRoom'        : jidChatRoom + "__roomChat",
1238            'jidTo'                     : jidChatRoom,
1239            'lang_Send'         : i18n.SEND,
1240            'lang_Leave_ChatRoom' : i18n.LEAVE_CHATROOM,
1241            'path_jabberit' : path_jabberit
1242        };
1243
1244        // Position Top
1245        TrophyIM.posWindow.top  = TrophyIM.posWindow.top + 10;
1246        if( TrophyIM.posWindow.top > 200 )
1247            TrophyIM.posWindow.top      = 100;
1248       
1249        // Position Left
1250        TrophyIM.posWindow.left = TrophyIM.posWindow.left + 5;
1251        if( TrophyIM.posWindow.left > 455 )
1252            TrophyIM.posWindow.left     = 400;
1253
1254        var _content = document.createElement( 'div' );
1255        _content.innerHTML = loadscript.parse( "chat_room", "chatRoom.xsl", paramsChatRoom );
1256        _content = _content.firstChild;
1257       
1258        var _messages           = _content.firstChild.firstChild;
1259        var _textarea           = _content.getElementsByTagName( 'textarea' ).item( 0 );
1260        var _send                       = _content.getElementsByTagName( 'input' ).item( 0 );
1261        var _leaveChatRoom      = _content.getElementsByTagName( 'input' ).item( 1 );
1262       
1263        var _send_message = function( )
1264        {
1265            if ( ! TrophyIM.sendMessageChatRoom( jidChatRoom, _textarea.value ) )
1266                return false;
1267               
1268            _textarea.value = '';
1269               
1270            _textarea.focus( );
1271        };
1272       
1273        loadscript.configEvents( _send, 'onclick', _send_message );
1274        loadscript.configEvents( _leaveChatRoom, 'onclick', function( )
1275        {
1276            TrophyIM.leaveChatRoom( jidChatRoom );
1277               
1278            if( TrophyIM.activeChatRoom.name.length > 0 )
1279            {
1280                for( var i = 0;  i < TrophyIM.activeChatRoom.name.length ; i++ )
1281                {
1282                    if( TrophyIM.activeChatRoom.name[i].indexOf( jidChatRoom ) >= 0 )
1283                    {
1284                        TrophyIM.activeChatRoom.name[i] = "";
1285                    }
1286                }
1287            }
1288               
1289            setTimeout( function()
1290            {
1291                _winBuild("window_chat_room_" + jidChatRoom, "remove");
1292                       
1293            }, 650 );
1294               
1295        });
1296       
1297        loadscript.configEvents( _textarea, 'onkeyup', function( e )
1298        {
1299            if ( e.keyCode == 13 )
1300            {
1301                _send_message( );
1302            }
1303        });       
1304       
1305        var winChatRoom =
1306        {
1307            id_window           : "window_chat_room_" + arguments[0],
1308            barejid             : jidChatRoom,
1309            width                       : 500,
1310            height                      : 450,
1311            top                 : TrophyIM.posWindow.top,
1312            left                        : TrophyIM.posWindow.left,
1313            draggable           : true,
1314            visible             : "display",
1315            resizable           : true,
1316            zindex                      : loadscript.getZIndex(),
1317            title                       : titleWindow,
1318            closeAction : "hidden",
1319            content             : _content     
1320        }
1321       
1322        _win = _winBuild(winChatRoom);
1323       
1324        _messages = _win.content( ).firstChild;
1325       
1326        while ( _messages && _messages.nodeType !== 1 )
1327        {
1328            _messages = _messages.nextSibling;
1329        }
1330       
1331        return ( _messages );         
1332
1333       
1334    },
1335   
1336    /** Function addContacts
1337         *
1338         *  Parameters:
1339         *              (string) jidFrom         
1340         *      (string) jidTo
1341         *              (string) name
1342         *              (string) group   
1343         */
1344       
1345    addContact : function( jidTo, name, group )
1346    {
1347        var _flag = true;
1348
1349        if( TrophyIM.removeResult.idResult.length > 0 )
1350        {
1351            for( var i = 0 ; i < TrophyIM.removeResult.idResult.length; i++ )
1352            {
1353                if( TrophyIM.removeResult.idResult[i] == jidTo )
1354                {
1355                    _flag = false;
1356                                       
1357                    TrophyIM.removeResult.idResult.splice(i,1);
1358                                       
1359                    i--;
1360                }
1361            }
1362        }
1363               
1364        if( _flag )
1365        {       
1366            // Add Contact
1367            var _id = TrophyIM.connection.getUniqueId('add');
1368            var newContact = $iq({
1369                type: 'set',
1370                id: _id
1371            });
1372            newContact = newContact.c('query').attrs({
1373                xmlns : 'jabber:iq:roster'
1374            });
1375            newContact = newContact.c('item').attrs({
1376                jid: jidTo,
1377                name:name
1378            });
1379            newContact = newContact.c('group').t(group).tree();
1380       
1381            TrophyIM.connection.send(newContact);
1382        }
1383    },
1384
1385    /** Function: add
1386     *
1387     *  Parameters:
1388     *    (string) msg - the message to add
1389     *    (string) jid - the jid of chat box to add the message to.
1390     */
1391       
1392    addMessage : function( chatBox, jid, msg )
1393    {
1394        // Get Smiles
1395        msg.msg = loadscript.getSmiles( msg.msg );
1396 
1397        var messageDiv  = document.createElement("div");
1398        messageDiv.style.margin = "3px 0px 1em 3px";
1399        messageDiv.innerHTML    = msg.contact + " : " + msg.msg ;
1400               
1401        chatBox.appendChild(messageDiv);
1402        chatBox.scrollTop = chatBox.scrollHeight;
1403    },
1404       
1405    /** Function : renameContact
1406     *
1407     *
1408     */
1409   
1410    renameContact : function( jid )
1411    {
1412        // Name
1413        var name                = TrophyIM.rosterObj.roster[jid].contact.name;
1414
1415        if(( name = prompt(i18n.ASK_NEW_NAME_QUESTION + name + "!", name )))
1416            if(( name = name.replace(/^\s+|\s+$|^\n|\n$/g,"")) == "" )
1417                name = "";
1418
1419        if( name == null || name == "")
1420            name = "";
1421               
1422        var jidTo = jid
1423        var name  = ( name ) ? name : TrophyIM.rosterObj.roster[jid].contact.name;
1424        var group = TrophyIM.rosterObj.roster[jid].contact.groups[0];
1425       
1426        TrophyIM.addContact( jidTo, name, group );
1427       
1428        document.getElementById('itenContact_' + jid ).innerHTML = name;
1429    },
1430   
1431    /** Function : renameGroup
1432     *
1433     *
1434     */
1435
1436    renameGroup : function( jid )
1437    {
1438        var group               = TrophyIM.rosterObj.roster[jid].contact.groups[0];
1439        var presence    = TrophyIM.rosterObj.roster[jid].presence;
1440       
1441        // Group
1442        if(( group = prompt( i18n.ASK_NEW_GROUP_QUESTION, group )))
1443            if(( group = group.replace(/^\s+|\s+$|^\n|\n$/g,"")) == "" )
1444                group = "";
1445
1446        if( group == null || group == "")
1447            group = "";
1448
1449        var jidTo = TrophyIM.rosterObj.roster[jid].contact.jid;
1450        var name  = TrophyIM.rosterObj.roster[jid].contact.name;
1451        var group = ( group ) ? group : TrophyIM.rosterObj.roster[jid].contact.groups[0];
1452
1453        TrophyIM.rosterObj.removeContact( jid );
1454               
1455        TrophyIM.addContact( jidTo, name, group );
1456       
1457        document.getElementById("JabberIMRoster").innerHTML = "";
1458               
1459        TrophyIM.renderRoster();
1460       
1461        setTimeout(function()
1462        {
1463            for( var i in presence )
1464            {
1465                if ( presence[ i ].constructor == Function )
1466                    continue;
1467                               
1468                TrophyIM.rosterObj.setPresence( jid, presence[i].priority, presence[i].show, presence[i].status);
1469            }
1470        },500);
1471    },
1472
1473    /** Function createChatRooms
1474     *
1475     *
1476     */
1477   
1478    createChatRooms : function()
1479    {
1480        var nickName     = document.getElementById('nickName_chatRoom_jabberit').value;
1481        var nameChatRoom = document.getElementById('name_ChatRoom_jabberit').value;
1482       
1483        var _from       = Base64.decode( loadscript.getUserCurrent().jid ) + TROPHYIM_RESOURCE;
1484        var _to         = escape( nameChatRoom ) + "@" + TROPHYIM_CHATROOM + "/" + nickName ;
1485        var new_room    = $pres( {
1486            from: _from,
1487            to: _to
1488        } ).c( "x", {
1489            xmlns: Strophe.NS.MUC
1490            } );
1491
1492        TrophyIM.activeChatRoom.name[ TrophyIM.activeChatRoom.name.length ] = _to;
1493               
1494        TrophyIM.connection.send( new_room.tree() );
1495    },
1496   
1497    /** Function : joinRoom
1498     *
1499     *
1500     */
1501   
1502    joinChatRoom : function( roomName )
1503    {
1504        var presence = $pres( {
1505            from: TrophyIM.connection.jid,
1506            to: roomName
1507        } ).c("x",{
1508            xmlns: Strophe.NS.MUC
1509            });
1510       
1511        TrophyIM.connection.send( presence );
1512    },
1513   
1514    /** Function : Leave Chat Room
1515     *
1516     *
1517     */
1518   
1519    leaveChatRoom : function( roomName )
1520    {
1521        var room_nick   = roomName;
1522       
1523        var presenceid  = TrophyIM.connection.getUniqueId();
1524       
1525        var presence    = $pres( {
1526            type: "unavailable",
1527            id: presenceid,
1528            from: TrophyIM.connection.jid,
1529            to: room_nick
1530        } ).c("x",{
1531            xmlns: Strophe.NS.MUC
1532            });
1533       
1534        TrophyIM.connection.send( presence );       
1535    },
1536   
1537    /** Function : getlistRooms
1538     *
1539     *
1540     */
1541   
1542    getListRooms : function()
1543    {
1544        if( TrophyIM.statusConn.connected )
1545        {
1546            var _error_return = function(element)
1547            {
1548                alert("ERRO : Tente novamente !");
1549            };
1550               
1551            var iq = $iq({
1552                to: TROPHYIM_CHATROOM,
1553                type: "get"
1554            }).c("query",{
1555                xmlns: Strophe.NS.DISCO_ITEMS
1556                });             
1557                       
1558            TrophyIM.connection.sendIQ( iq, loadscript.listRooms, _error_return, 500 );
1559        }
1560        else
1561        {
1562            alert( "ERRO : Sem conexão com o servidor " + TROPHYIM_CHATROOM );
1563        }
1564    },
1565   
1566    /** Function: removeContact
1567     *
1568     *  Parameters:
1569     *          (string) jidTo
1570     */
1571   
1572    removeContact : function( jidTo )
1573    {
1574        var divItenContact       = null;
1575
1576        if( ( divItenContact = document.getElementById('itenContact_' + jidTo )))
1577        {       
1578            // Remove Contact
1579            var _id     = TrophyIM.connection.getUniqueId();   
1580               
1581            // Controller Result
1582            TrophyIM.removeResult.idResult[ TrophyIM.removeResult.idResult.length ] = jidTo;
1583
1584            var delContact      = $iq({
1585                type: 'set',
1586                id: _id
1587            })
1588            delContact  = delContact.c('query').attrs({
1589                xmlns : 'jabber:iq:roster'
1590            });
1591            delContact  = delContact.c('item').attrs({
1592                jid: jidTo,
1593                subscription:'remove'
1594            }).tree();
1595
1596            TrophyIM.connection.send( delContact );
1597               
1598            loadscript.removeElement( document.getElementById('itenContactNotification_' + jidTo ) );
1599               
1600            var spanShow = document.getElementById('span_show_itenContact_' + jidTo )
1601            spanShow.parentNode.removeChild(spanShow);
1602               
1603            loadscript.removeGroup( divItenContact.parentNode );
1604               
1605            divItenContact.parentNode.removeChild(divItenContact);
1606        }
1607    },
1608   
1609    /** Function: renderRoster
1610     *
1611     *  Renders roster, looking only for jids flagged by setPresence as having
1612     *  changed.
1613     */
1614   
1615    renderRoster : function()
1616    {
1617        var roster_div = document.getElementById('JabberIMRoster');
1618               
1619        if( roster_div )
1620        {
1621            var users = new Array();
1622                       
1623            var loading_gif = document.getElementById("JabberIMRosterLoadingGif");
1624                       
1625            if( loading_gif.style.display == "block" )
1626                loading_gif.style.display = "none";
1627                               
1628            for( var user in TrophyIM.rosterObj.roster )
1629            {
1630                if ( TrophyIM.rosterObj.roster[ user ].constructor == Function )
1631                    continue;
1632
1633                users[users.length] = TrophyIM.rosterObj.roster[user].contact.jid;
1634            }
1635
1636            users.sort();
1637                       
1638            var groups          = new Array();
1639            var flagGeral       = false;
1640                       
1641            for (var group in TrophyIM.rosterObj.groups)
1642            {
1643                if ( TrophyIM.rosterObj.groups[ group ].constructor == Function )
1644                    continue;
1645                               
1646                if( group )
1647                    groups[groups.length] = group;
1648                               
1649                if( group == "Geral" )
1650                    flagGeral = true;
1651            }
1652           
1653            if( !flagGeral && users.length > 0 )
1654                groups[groups.length] = "Geral";
1655                               
1656            groups.sort();
1657                       
1658            for ( var i = 0; i < groups.length; i++ )
1659            {
1660                TrophyIM.renderGroups( groups[i] , roster_div );       
1661            }
1662                       
1663            TrophyIM.renderItensGroup( users, roster_div );
1664        }
1665                       
1666        TrophyIM._timeOut.renderRoster = setTimeout("TrophyIM.renderRoster()", 1000 );         
1667    },
1668       
1669    /** Function: renderGroups
1670     *
1671     *
1672     */
1673       
1674    renderGroups: function( nameGroup, element )
1675    {
1676        var _addGroup = function()
1677        {
1678            var _nameGroup      = nameGroup;
1679            var _element        = element;
1680
1681            var paramsGroup =
1682            {
1683                'nameGroup'     : _nameGroup,
1684                'path_jabberit' : path_jabberit
1685            }
1686                       
1687            _element.innerHTML += loadscript.parse("group","groups.xsl", paramsGroup);
1688        }
1689
1690        if( !element.hasChildNodes() )
1691        {
1692            _addGroup();
1693        }
1694        else
1695        {
1696            var _NodeChild      = element.firstChild;
1697            var flagAdd         = false;
1698                       
1699            while( _NodeChild )
1700            {
1701                if( _NodeChild.childNodes[0].nodeName.toLowerCase() === "span" )
1702                {
1703                    if( _NodeChild.childNodes[0].childNodes[0].nodeValue === nameGroup )
1704                    {
1705                        flagAdd = true;
1706                    }
1707                }
1708                               
1709                _NodeChild = _NodeChild.nextSibling;
1710            }
1711
1712            if( !flagAdd )
1713            {
1714                _addGroup();
1715            }
1716        }
1717    },
1718
1719    /** Function: renderItensGroup
1720     *
1721     *
1722     */
1723
1724    renderItensGroup : function( users, element )
1725    {
1726        var addItem = function()
1727        {
1728            if( arguments.length > 0 )
1729            {
1730                // Get Arguments
1731                var objContact  = arguments[0];
1732                var group               = arguments[1];
1733                var element             = arguments[2];
1734                var showOffline = loadscript.getShowContactsOffline();
1735                               
1736                // Presence e Status
1737                var presence            = "unavailable";
1738                var status                      = "";
1739                var statusColor         = "black";
1740                var statusDisplay       = "none";
1741                               
1742                var _resource   = "";
1743                               
1744                // Set Presence
1745                var _presence = function(objContact)
1746                {
1747                    if (objContact.presence)
1748                    {
1749                        for (var resource in objContact.presence)
1750                        {
1751                            if ( objContact.presence[resource].constructor == Function )
1752                                continue;
1753
1754                            if( objContact.presence[resource].show != 'invisible' )
1755                                presence = objContact.presence[resource].show;
1756
1757                            if( objContact.contact.subscription != "both")
1758                                presence = 'subscription';
1759                                                       
1760                            if( objContact.presence[resource].status )
1761                            {
1762                                status = " ( " + objContact.presence[resource].status + " ) ";
1763                                statusDisplay   = "block";
1764                            }
1765                        }
1766                    }
1767                };
1768                               
1769                // Set Subscription
1770                var _subscription = function( objContact )
1771                {
1772                    if( objContact.contact.subscription != "both" )
1773                    {
1774                        switch( objContact.contact.subscription )
1775                        {
1776                            case "none" :
1777                                                               
1778                                status          = " (( " + i18n.ASK_FOR_AUTH  + " )) ";
1779                                statusColor     = "red";
1780                                break;
1781       
1782                            case "to" :
1783                                                               
1784                                status          = " (( " + i18n.CONTACT_ASK_FOR_AUTH  + " )) ";
1785                                statusColor     = "orange";
1786                                break;
1787       
1788                            case "from" :
1789                                                               
1790                                status          = " (( " + i18n.AUTHORIZED + " )) ";
1791                                statusColor = "green";
1792                                break;
1793                                                               
1794                            case "subscribe" :
1795                                                               
1796                                status          = " (( " + i18n.AUTH_SENT  + " )) ";
1797                                statusColor     = "red";       
1798                                break;
1799
1800                            case "not-in-roster" :
1801                                                               
1802                                status          = " (( " + i18n.ASK_FOR_AUTH_QUESTION  + " )) ";
1803                                statusColor     = "orange";     
1804                                break;
1805                                                               
1806                            default :
1807                                                               
1808                                break;
1809                        }
1810
1811                        statusDisplay = "block";
1812                    }
1813                };
1814
1815                if( objContact.contact.subscription != "remove")
1816                {
1817                    var itensJid        = document.getElementById( "itenContact_" + objContact.contact.jid );
1818                                       
1819                    if( itensJid == null )
1820                    {
1821                        // Name
1822                        var nameContact = "";                                   
1823                                               
1824                        if ( objContact.contact.name )
1825                            nameContact = objContact.contact.name;
1826                        else
1827                        {
1828                            nameContact = objContact.contact.jid;
1829                            nameContact = nameContact.substring(0, nameContact.indexOf('@'));
1830                        }
1831                                               
1832                        // Get Presence
1833                        _presence(objContact);
1834                                               
1835                        var paramsContact =
1836                        {
1837                            divDisplay          : "block",
1838                            id                          : 'itenContact_' + objContact.contact.jid ,
1839                            jid                         : objContact.contact.jid,
1840                            nameContact         : nameContact,
1841                            path_jabberit       : path_jabberit,
1842                            presence            : presence,
1843                            spanDisplay         : statusDisplay,
1844                            status                      : status,
1845                            statusColor         : "black",
1846                            subscription        : objContact.contact.subscription,
1847                            resource            : _resource
1848                        }
1849                                               
1850                        // Get Authorization
1851                        _subscription( objContact );
1852                                               
1853                        if( group != "")
1854                        {
1855                            var _NodeChild              = element.firstChild;
1856                                                       
1857                            while( _NodeChild )
1858                            {
1859                                if( _NodeChild.childNodes[0].nodeName.toLowerCase() === "span" )
1860                                {
1861                                    if( _NodeChild.childNodes[0].childNodes[0].nodeValue === group )
1862                                    {
1863                                        _NodeChild.innerHTML += loadscript.parse("itens_group", "itensGroup.xsl", paramsContact);
1864                                    }
1865                                }
1866       
1867                                _NodeChild = _NodeChild.nextSibling;
1868                            }
1869                        }       
1870                    }
1871                    else
1872                    {
1873                        // Get Presence
1874                        _presence(objContact);
1875       
1876                        var is_open = itensJid.parentNode.childNodes[0].style.backgroundImage; 
1877                        is_open = is_open.indexOf("arrow_down.gif");
1878       
1879                        // Get Authorization
1880                        _subscription( objContact );
1881                                               
1882                        // Set subscription
1883                        itensJid.setAttribute('subscription', objContact.contact.subscription );
1884                                               
1885                        with ( document.getElementById('span_show_' + 'itenContact_' + objContact.contact.jid ) )
1886                        {
1887                            if( presence == "unavailable" && !showOffline )
1888                            {
1889                                style.display = "none";
1890                            }
1891                            else
1892                            {
1893                                if( is_open > 0 )
1894                                {
1895                                    style.display       = statusDisplay;
1896                                    style.color         = statusColor;
1897                                    innerHTML           = status;
1898                                }
1899                            }
1900                            }
1901                                               
1902                        if( presence == "unavailable" && !showOffline )
1903                        {
1904                            itensJid.style.display = "none";
1905                        }
1906                        else
1907                        {
1908                            if( is_open > 0 )
1909                            {
1910                                itensJid.style.display = "block";
1911                            }
1912                        }
1913                                               
1914                        itensJid.style.background       = "url('"+path_jabberit+"templates/default/images/" + presence + ".gif') no-repeat center left";
1915                    }
1916       
1917                    // Contact OffLine
1918                    if( !objContact.presence && !showOffline )
1919                    {
1920                        if( objContact.contact.subscription != "remove" )
1921                        {
1922                            with ( document.getElementById('span_show_' + 'itenContact_' + objContact.contact.jid ))
1923                            {
1924                                style.display   = "none";
1925                                }
1926               
1927                            with ( document.getElementById('itenContact_' + objContact.contact.jid ) )
1928                            {
1929                                style.display   = "none";
1930                                }
1931                        }
1932                    }
1933                }
1934            }
1935        };
1936               
1937        var flag = false;
1938               
1939        for( var i = 0 ; i < users.length; i++ )
1940        {
1941            if( TrophyIM.rosterObj.roster[users[i]].contact.jid != Base64.decode( loadscript.getUserCurrent().jid) )
1942            {
1943                var _subscription = TrophyIM.rosterObj.roster[users[i]].contact.subscription;
1944                               
1945                if( _subscription === "to" )
1946                {
1947                    flag = true;
1948                }
1949                               
1950                if(  _subscription === "not-in-roster")
1951                {
1952                    flag = true;
1953                }
1954                               
1955                if( TrophyIM.rosterObj.roster[users[i]].contact.groups )
1956                {
1957                    var groups = TrophyIM.rosterObj.roster[users[i]].contact.groups;
1958                                       
1959                    if( groups.length > 0 )
1960                    {
1961                        for( var j = 0; j < groups.length; j++ )
1962                        {
1963                            addItem( TrophyIM.rosterObj.roster[users[i]], groups[j], element );
1964                        }
1965                    }
1966                    else
1967                    {
1968                        addItem( TrophyIM.rosterObj.roster[users[i]], "Geral", element );
1969                    }
1970                }
1971                else
1972                {
1973                    addItem( TrophyIM.rosterObj.roster[users[i]], "Geral", element );
1974                }
1975            }
1976        }
1977               
1978        if( flag )
1979        {
1980            if ( TrophyIM.controll.notificationNewUsers == 0 )
1981            {
1982                loadscript.enabledNotificationNewUsers();
1983                TrophyIM.controll.notificationNewUsers++;
1984            }
1985        }
1986        else
1987        {
1988            loadscript.disabledNotificationNewUsers();
1989            TrophyIM.controll.notificationNewUsers = 0;
1990        }
1991    },
1992
1993    /** Function: rosterClick
1994     *
1995     *  Handles actions when a roster item is clicked
1996     */
1997   
1998    rosterClick : function(fulljid)
1999    {
2000        TrophyIM.makeChat(fulljid);
2001    },
2002
2003    /** Function SetAutorization
2004         *
2005         */
2006
2007    setAutorization : function( jidTo, jidFrom, _typeSubscription )
2008    {
2009        var _id = TrophyIM.connection.getUniqueId();
2010       
2011        TrophyIM.connection.send($pres( ).attrs({
2012            from: jidFrom,
2013            to: jidTo,
2014            type: _typeSubscription,
2015            id: _id
2016        }).tree());
2017    },
2018
2019    /** Function: setPresence
2020     *
2021     */
2022
2023    setPresence : function( _type )
2024    {
2025        var presence_chatRoom = "";
2026               
2027        if( _type != 'status')
2028        {
2029            if( _type == "unavailable" &&  TrophyIM.statusConn.connected )
2030            {
2031                var loading_gif = document.getElementById("JabberIMRosterLoadingGif");
2032                               
2033                if( TrophyIM._timeOut.renderRoster != null )
2034                    clearTimeout(TrophyIM._timeOut.renderRoster);
2035                               
2036                if( TrophyIM.statusConn.connected )
2037                    TrophyIM.connection.send($pres({
2038                        type : _type
2039                    }).tree());
2040                               
2041                for( var i = 0; i < TrophyIM.connection._requests.length; i++ )
2042                {
2043                    if( TrophyIM.connection._requests[i] )
2044                        TrophyIM.connection._removeRequest(TrophyIM.connection._requests[i]);
2045                }
2046                               
2047                TrophyIM.logout();
2048                               
2049                loadscript.clrAllContacts();
2050                       
2051                delete TrophyIM.rosterObj.roster;
2052                delete TrophyIM.rosterObj.groups;
2053                       
2054                setTimeout(function()
2055                {
2056                    if( loading_gif.style.display == "block" )
2057                        loading_gif.style.display = "none";
2058                }, 1000);
2059            }
2060            else
2061            {
2062                if( !TrophyIM.autoConnection.connect )
2063                {
2064                    TrophyIM.autoConnection.connect = true;
2065                    TrophyIM.load();
2066                }
2067                else
2068                {
2069                    if( TrophyIM.statusConn.connected )
2070                    {
2071                        if( loadscript.getStatusMessage() != "" )
2072                        {
2073                            var _presence = $pres( );
2074                            _presence.node.appendChild( Strophe.xmlElement( 'show' ) ).appendChild( Strophe.xmlTextNode( _type ) );
2075                            _presence.node.appendChild( Strophe.xmlElement( 'status' ) ).appendChild( Strophe.xmlTextNode( loadscript.getStatusMessage() ));
2076                                                       
2077                            TrophyIM.connection.send( _presence.tree() );
2078                                                       
2079                            presence_chatRoom = _type;
2080                        }
2081                        else
2082                        {
2083                            TrophyIM.connection.send($pres( ).c('show').t(_type).tree());
2084                                                       
2085                            presence_chatRoom = _type;
2086                        }
2087                    }
2088                }
2089            }
2090        }
2091        else
2092        {
2093            var _show   = "available";
2094            var _status = "";
2095                       
2096            if( arguments.length < 2 )
2097            {
2098                if( loadscript.getStatusMessage() != "" )
2099                    _status = prompt(i18n.TYPE_YOUR_MSG, loadscript.getStatusMessage());
2100                else
2101                    _status = prompt(i18n.TYPE_YOUR_MSG);
2102                               
2103                var _divStatus = document.getElementById("JabberIMStatusMessage");
2104                               
2105                if( ( _status = _status.replace(/^\s+|\s+$|^\n|\n$/g,"") ) != "")
2106                    _divStatus.firstChild.innerHTML     = "( " + _status + " )";
2107            }
2108            else
2109            {
2110                _status = arguments[1];
2111            }
2112
2113            for( var resource in TrophyIM.rosterObj.roster[Base64.decode(loadscript.getUserCurrent().jid)].presence )
2114            {
2115                if ( TrophyIM.rosterObj.roster[Base64.decode(loadscript.getUserCurrent().jid)].presence[ resource ].constructor == Function )
2116                    continue;
2117                       
2118                if ( TROPHYIM_RESOURCE === ("/" + resource) )
2119                    _show = TrophyIM.rosterObj.roster[Base64.decode(loadscript.getUserCurrent().jid)].presence[resource].show;
2120            }
2121
2122            if ( TrophyIM.statusConn.connected )
2123            {
2124                var _presence = $pres( );
2125                _presence.node.appendChild( Strophe.xmlElement( 'show' ) ).appendChild( Strophe.xmlTextNode( _show ) );
2126                _presence.node.appendChild( Strophe.xmlElement( 'status' ) ).appendChild( Strophe.xmlTextNode( _status ) );
2127                               
2128                TrophyIM.connection.send( _presence.tree() );
2129                               
2130                presence_chatRoom = _show;
2131            }
2132        }
2133               
2134        // Send Presence Chat Room
2135        if( TrophyIM.activeChatRoom.name.length > 0 )
2136        {
2137            for( i = 0; i < TrophyIM.activeChatRoom.name.length; i++ )
2138            {
2139                if( TrophyIM.activeChatRoom.name[i] != "" )
2140                    TrophyIM.connection.send($pres( {
2141                        to : TrophyIM.activeChatRoom.name[i]
2142                        } ).c('show').t( presence_chatRoom ) );
2143            }
2144        }
2145
2146    },
2147       
2148    /** Function: sendMessage
2149     *
2150     *  Send message from chat input to user
2151     */
2152     
2153    sendMessage : function()
2154    {
2155        if (arguments.length > 0)
2156        {
2157            var jidTo = arguments[0];
2158            var message_input = arguments[1];
2159                       
2160                       
2161            message_input = message_input.replace(/^\s+|\s+$|^\n|\n$/g, "");
2162                       
2163            if (message_input != "") {
2164                       
2165                // Send Message
2166                var newMessage = $msg({
2167                    to: jidTo,
2168                    from: TrophyIM.connection.jid,
2169                    type: 'chat'
2170                });
2171                newMessage = newMessage.c('body').t(message_input);
2172                newMessage.up();
2173                newMessage = newMessage.c('active').attrs({
2174                    xmlns: 'http://jabber.org/protocol/chatstates'
2175                });
2176                // Send Message
2177                TrophyIM.connection.send(newMessage.tree());
2178                               
2179                return true;
2180            }
2181        }
2182               
2183        return false;
2184    },
2185
2186    /** Function: sendMessage
2187    *
2188    *  Send message to ChatRoom
2189    */
2190   
2191    sendMessageChatRoom : function( )
2192    {
2193        if( arguments.length > 0 )
2194        {
2195            var room_nick       = arguments[0];
2196            var message         = arguments[1];
2197            var msgid           = TrophyIM.connection.getUniqueId();
2198            var msg                     = $msg({
2199                to: room_nick,
2200                type: "groupchat",
2201                id: msgid
2202            }).c("body",{
2203                xmlns: Strophe.NS.CLIENT
2204                }).t(message);
2205               
2206            msg.up();//.c("x", {xmlns: "jabber:x:event"}).c("composing");
2207               
2208            TrophyIM.connection.send(msg);
2209               
2210            return true;
2211        }
2212    },
2213   
2214    /** Function: sendContentMessage
2215     *
2216     *  Send a content message from chat input to user
2217     */
2218    sendContentMessage : function()
2219    {
2220        if( arguments.length > 0 )
2221        {
2222            var jidTo = arguments[0];
2223            var state = arguments[1];
2224
2225            var newMessage = $msg({
2226                to: jidTo,
2227                from: TrophyIM.connection.jid,
2228                type: 'chat'
2229            });
2230            newMessage = newMessage.c(state).attrs({
2231                xmlns : 'http://jabber.org/protocol/chatstates'
2232            });
2233            // Send content message
2234            TrophyIM.connection.send(newMessage.tree());
2235        }
2236    }
2237};
2238
2239/** Class: TrophyIMRoster
2240 *
2241 *
2242 *  This object stores the roster and presence info for the TrophyIMClient
2243 *
2244 *  roster[jid_lower]['contact']
2245 *  roster[jid_lower]['presence'][resource]
2246 */
2247function TrophyIMRoster()
2248{
2249    /** Constants: internal arrays
2250     *    (Object) roster - the actual roster/presence information
2251     *    (Object) groups - list of current groups in the roster
2252     *    (Array) changes - array of jids with presence changes
2253     */
2254    if (TrophyIM.JSONStore.store_working)
2255    {
2256        var data = TrophyIM.JSONStore.getData(['roster', 'groups']);
2257        this.roster = (data['roster'] != null) ? data['roster'] : {};
2258        this.groups = (data['groups'] != null) ? data['groups'] : {};
2259    }
2260    else
2261    {
2262        this.roster = {};
2263        this.groups = {};
2264    }
2265    this.changes = new Array();
2266   
2267    if (TrophyIM.constants.stale_roster)
2268    {
2269        for (var jid in this.roster)
2270        {
2271            this.changes[this.changes.length] = jid;
2272        }
2273    }
2274
2275    /** Function: addChange
2276         *
2277         *  Adds given jid to this.changes, keeping this.changes sorted and
2278         *  preventing duplicates.
2279         *
2280         *  Parameters
2281         *    (String) jid : jid to add to this.changes
2282         */
2283         
2284    this.addChange = function(jid)
2285    {
2286        for (var c = 0; c < this.changes.length; c++)
2287        {
2288            if (this.changes[c] == jid)
2289            {
2290                return;
2291            }
2292        }
2293               
2294        this.changes[this.changes.length] = jid;
2295               
2296        this.changes.sort();
2297    }
2298       
2299    /** Function: addContact
2300     *
2301     *  Adds given contact to roster
2302     *
2303     *  Parameters:
2304     *    (String) jid - bare jid
2305     *    (String) subscription - subscription attribute for contact
2306     *    (String) name - name attribute for contact
2307     *    (Array)  groups - array of groups contact is member of
2308     */
2309   
2310    this.addContact = function(jid, subscription, name, groups )
2311    {
2312        if( subscription === "remove" )
2313        {
2314            this.removeContact(jid);
2315        }
2316        else
2317        {
2318            var contact         = {
2319                jid:jid,
2320                subscription:subscription,
2321                name:name,
2322                groups:groups
2323            }
2324            var jid_lower       = jid.toLowerCase();
2325       
2326            if ( this.roster[jid_lower] )
2327            {
2328                this.roster[jid_lower]['contact'] = contact;
2329            }
2330            else
2331            {
2332                this.roster[jid_lower] = {
2333                    contact:contact
2334                };
2335            }
2336
2337            groups = groups ? groups : [''];
2338               
2339            for ( var g = 0; g < groups.length; g++ )
2340            {
2341                if ( !this.groups[groups[g]] )
2342                {
2343                    this.groups[groups[g]] = {};
2344                }
2345                   
2346                this.groups[groups[g]][jid_lower] = jid_lower;
2347            }
2348        }
2349    }
2350   
2351    /** Function: getContact
2352     *
2353     *  Returns contact entry for given jid
2354     *
2355     *  Parameter: (String) jid - jid to return
2356     */
2357     
2358    this.getContact = function(jid)
2359    {
2360        if (this.roster[jid.toLowerCase()])
2361        {
2362            return this.roster[jid.toLowerCase()]['contact'];
2363        }
2364    }
2365
2366    /** Function: getPresence
2367        *
2368        *  Returns best presence for given jid as Array(resource, priority, show,
2369        *  status)
2370        *
2371        *  Parameter: (String) fulljid - jid to return best presence for
2372        */
2373         
2374    this.getPresence = function(fulljid)
2375    {
2376        var jid = Strophe.getBareJidFromJid(fulljid);
2377        var current = null;
2378                   
2379        if (this.roster[jid.toLowerCase()] && this.roster[jid.toLowerCase()]['presence'])
2380        {
2381            for (var resource in this.roster[jid.toLowerCase()]['presence'])
2382            {
2383                if ( this.roster[jid.toLowerCase()]['presence'][ resource ].constructor == Function )
2384                    continue;
2385                       
2386                var presence = this.roster[jid.toLowerCase()]['presence'][resource];
2387                if (current == null)
2388                {
2389                    current = presence
2390                }
2391                else
2392                {
2393                    if(presence['priority'] > current['priority'] && ((presence['show'] == "chat"
2394                        || presence['show'] == "available") || (current['show'] != "chat" ||
2395                        current['show'] != "available")))
2396                        {
2397                        current = presence
2398                    }
2399                }
2400            }
2401        }
2402        return current;
2403    }
2404
2405    /** Function: groupHasChanges
2406         *
2407         *  Returns true if current group has members in this.changes
2408         *
2409         *  Parameters:
2410         *    (String) group - name of group to check
2411         */
2412         
2413    this.groupHasChanges = function(group)
2414    {
2415        for (var c = 0; c < this.changes.length; c++)
2416        {
2417            if (this.groups[group][this.changes[c]])
2418            {
2419                return true;
2420            }
2421        }
2422        return false;
2423    }
2424       
2425    /** Function removeContact
2426         *
2427         * Parameters
2428         *       (String) jid           
2429         */
2430         
2431    this.removeContact = function(jid)
2432    {
2433        if( this.roster[ jid ] )
2434        {
2435            var groups = this.roster[ jid ].contact.groups;
2436                       
2437            if( groups )
2438            {
2439                for ( var i = 0; i < groups.length; i++ )
2440                {
2441                    delete this.groups[ groups[ i ] ][ jid ];
2442                }
2443       
2444                for ( var i = 0; i < groups.length; i++ )
2445                {
2446                    var contacts = 0;
2447                    for ( var contact in this.groups[ groups[ i ] ] )
2448                    {
2449                        if ( this.groups[ groups[ i ] ][ contact ].constructor == Function )
2450                            continue;
2451                                       
2452                        contacts++;
2453                    }
2454               
2455                    if ( ! contacts )
2456                        delete this.groups[ groups[ i ] ];
2457                }
2458            }
2459       
2460            // Delete Object roster
2461            if( this.roster[jid] )
2462                delete this.roster[jid];
2463        }
2464    }
2465         
2466    /** Function: setPresence
2467     *
2468     *  Sets presence
2469     *
2470     *  Parameters:
2471     *    (String) fulljid: full jid with presence
2472     *    (Integer) priority: priority attribute from presence
2473     *    (String) show: show attribute from presence
2474     *    (String) status: status attribute from presence
2475     */
2476   
2477    this.setPresence = function(fulljid, priority, show, status)
2478    {
2479        var barejid             = Strophe.getBareJidFromJid(fulljid);
2480        var resource    = Strophe.getResourceFromJid(fulljid);
2481        var jid_lower   = barejid.toLowerCase();
2482       
2483        if( show !== 'unavailable' || show !== 'error' )
2484        {
2485            if (!this.roster[jid_lower])
2486            {
2487                this.addContact( barejid, 'not-in-roster' );
2488            }
2489           
2490            var presence =
2491            {
2492                resource        : resource,
2493                priority        : priority,
2494                show            : show,
2495                status          : status
2496            }
2497           
2498            if (!this.roster[jid_lower]['presence'])
2499            {
2500                this.roster[jid_lower]['presence'] = {};
2501            }
2502           
2503            this.roster[jid_lower]['presence'][resource] = presence;   
2504        }
2505    }
2506
2507    /** Fuction: save
2508         *
2509         *  Saves roster data to JSON store
2510         */
2511       
2512    this.save = function()
2513    {
2514        if (TrophyIM.JSONStore.store_working)
2515        {
2516            TrophyIM.JSONStore.setData({
2517                roster:this.roster,
2518                groups:this.groups,
2519                active_chat:TrophyIM.activeChats['current'],
2520                chat_history:TrophyIM.chatHistory
2521                });
2522        }
2523    }
2524
2525}
2526/** Class: TrophyIMJSONStore
2527 *
2528 *
2529 *  This object is the mechanism by which TrophyIM stores and retrieves its
2530 *  variables from the url provided by TROPHYIM_JSON_STORE
2531 *
2532 */
2533function TrophyIMJSONStore() {
2534    this.store_working = false;
2535    /** Function _newXHR
2536     *
2537     *  Set up new cross-browser xmlhttprequest object
2538     *
2539     *  Parameters:
2540     *    (function) handler = what to set onreadystatechange to
2541     */
2542    this._newXHR = function (handler) {
2543        var xhr = null;
2544        if (window.XMLHttpRequest) {
2545            xhr = new XMLHttpRequest();
2546            if (xhr.overrideMimeType) {
2547                xhr.overrideMimeType("text/xml");
2548            }
2549        } else if (window.ActiveXObject) {
2550            xhr = new ActiveXObject("Microsoft.XMLHTTP");
2551        }
2552        return xhr;
2553    }
2554    /** Function getData
2555     *  Gets data from JSONStore
2556     *
2557     *  Parameters:
2558     *    (Array) vars = Variables to get from JSON store
2559     *
2560     *  Returns:
2561     *    Object with variables indexed by names given in parameter 'vars'
2562     */
2563    this.getData = function(vars) {
2564        if (typeof(TROPHYIM_JSON_STORE) != undefined) {
2565            Strophe.debug("Retrieving JSONStore data");
2566            var xhr = this._newXHR();
2567            var getdata = "get=" + vars.join(",");
2568            try {
2569                xhr.open("POST", TROPHYIM_JSON_STORE, false);
2570            } catch (e) {
2571                Strophe.error("JSONStore open failed.");
2572                return false;
2573            }
2574            xhr.setRequestHeader('Content-type',
2575                'application/x-www-form-urlencoded');
2576            xhr.setRequestHeader('Content-length', getdata.length);
2577            xhr.send(getdata);
2578            if (xhr.readyState == 4 && xhr.status == 200) {
2579                try {
2580                    var dataObj = JSON.parse(xhr.responseText);
2581                    return this.emptyFix(dataObj);
2582                } catch(e) {
2583                    Strophe.error("Could not parse JSONStore response" +
2584                        xhr.responseText);
2585                    return false;
2586                }
2587            } else {
2588                Strophe.error("JSONStore open failed. Status: " + xhr.status);
2589                return false;
2590            }
2591        }
2592    }
2593    /** Function emptyFix
2594     *    Fix for bugs in external JSON implementations such as
2595     *    http://bugs.php.net/bug.php?id=41504.
2596     *    A.K.A. Don't use PHP, people.
2597     */
2598    this.emptyFix = function(obj) {
2599        if (typeof(obj) == "object") {
2600            for (var i in obj) {
2601                if ( obj[i].constructor == Function )
2602                    continue;
2603                       
2604                if (i == '_empty_') {
2605                    obj[""] = this.emptyFix(obj['_empty_']);
2606                    delete obj['_empty_'];
2607                } else {
2608                    obj[i] = this.emptyFix(obj[i]);
2609                }
2610            }
2611        }
2612        return obj
2613    }
2614    /** Function delData
2615     *    Deletes data from JSONStore
2616     *
2617     *  Parameters:
2618     *    (Array) vars  = Variables to delete from JSON store
2619     *
2620     *  Returns:
2621     *    Status of delete attempt.
2622     */
2623    this.delData = function(vars) {
2624        if (typeof(TROPHYIM_JSON_STORE) != undefined) {
2625            Strophe.debug("Retrieving JSONStore data");
2626            var xhr = this._newXHR();
2627            var deldata = "del=" + vars.join(",");
2628            try {
2629                xhr.open("POST", TROPHYIM_JSON_STORE, false);
2630            } catch (e) {
2631                Strophe.error("JSONStore open failed.");
2632                return false;
2633            }
2634            xhr.setRequestHeader('Content-type',
2635                'application/x-www-form-urlencoded');
2636            xhr.setRequestHeader('Content-length', deldata.length);
2637            xhr.send(deldata);
2638            if (xhr.readyState == 4 && xhr.status == 200) {
2639                try {
2640                    var dataObj = JSON.parse(xhr.responseText);
2641                    return dataObj;
2642                } catch(e) {
2643                    Strophe.error("Could not parse JSONStore response");
2644                    return false;
2645                }
2646            } else {
2647                Strophe.error("JSONStore open failed. Status: " + xhr.status);
2648                return false;
2649            }
2650        }
2651    }
2652    /** Function setData
2653     *    Stores data in JSONStore, overwriting values if they exist
2654     *
2655     *  Parameters:
2656     *    (Object) vars : Object containing named vars to store ({name: value,
2657     *    othername: othervalue})
2658     *
2659     *  Returns:
2660     *    Status of storage attempt
2661     */
2662    this.setData = function(vars)
2663    {
2664        if ( typeof(TROPHYIM_JSON_STORE) != undefined )
2665        {
2666            var senddata = "set=" + JSON.stringify(vars);
2667            var xhr = this._newXHR();
2668            try
2669            {
2670                xhr.open("POST", TROPHYIM_JSON_STORE, false);
2671            }
2672            catch (e)
2673            {
2674                Strophe.error("JSONStore open failed.");
2675                return false;
2676            }
2677            xhr.setRequestHeader('Content-type',
2678                'application/x-www-form-urlencoded');
2679            xhr.setRequestHeader('Content-length', senddata.length);
2680            xhr.send(senddata);
2681            if (xhr.readyState == 4 && xhr.status == 200 && xhr.responseText ==
2682                "OK") {
2683                return true;
2684            } else {
2685                Strophe.error("JSONStore open failed. Status: " + xhr.status);
2686                return false;
2687            }
2688        }
2689    }
2690   
2691    var testData = true;
2692   
2693    if (this.setData({
2694        testData:testData
2695    })) {
2696        var testResult = this.getData(['testData']);
2697        if (testResult && testResult['testData'] == true) {
2698            this.store_working = true;
2699        }
2700    }
2701}
2702/** Constants: Node types
2703 *
2704 * Implementations of constants that IE doesn't have, but we need.
2705 */
2706if (document.ELEMENT_NODE == null) {
2707    document.ELEMENT_NODE = 1;
2708    document.ATTRIBUTE_NODE = 2;
2709    document.TEXT_NODE = 3;
2710    document.CDATA_SECTION_NODE = 4;
2711    document.ENTITY_REFERENCE_NODE = 5;
2712    document.ENTITY_NODE = 6;
2713    document.PROCESSING_INSTRUCTION_NODE = 7;
2714    document.COMMENT_NODE = 8;
2715    document.DOCUMENT_NODE = 9;
2716    document.DOCUMENT_TYPE_NODE = 10;
2717    document.DOCUMENT_FRAGMENT_NODE = 11;
2718    document.NOTATION_NODE = 12;
2719}
2720
2721/** Function: importNode
2722 *
2723 *  document.importNode implementation for IE, which doesn't have importNode
2724 *
2725 *  Parameters:
2726 *    (Object) node - dom object
2727 *    (Boolean) allChildren - import node's children too
2728 */
2729if (!document.importNode) {
2730    document.importNode = function(node, allChildren) {
2731        switch (node.nodeType) {
2732            case document.ELEMENT_NODE:
2733                var newNode = document.createElement(node.nodeName);
2734                if (node.attributes && node.attributes.length > 0) {
2735                    for(var i = 0; i < node.attributes.length; i++) {
2736                        newNode.setAttribute(node.attributes[i].nodeName,
2737                            node.getAttribute(node.attributes[i].nodeName));
2738                    }
2739                }
2740                if (allChildren && node.childNodes &&
2741                    node.childNodes.length > 0) {
2742                    for (var i = 0; i < node.childNodes.length; i++) {
2743                        newNode.appendChild(document.importNode(
2744                            node.childNodes[i], allChildren));
2745                    }
2746                }
2747                return newNode;
2748                break;
2749            case document.TEXT_NODE:
2750            case document.CDATA_SECTION_NODE:
2751            case document.COMMENT_NODE:
2752                return document.createTextNode(node.nodeValue);
2753                break;
2754        }
2755    };
2756}
2757
2758/**
2759 *
2760 * Bootstrap self into window.onload and window.onunload
2761 */
2762
2763var oldonunload = window.onunload;
2764
2765window.onunload = function()
2766{
2767    if( oldonunload )
2768    {
2769        oldonunload();
2770    }
2771       
2772    TrophyIM.setPresence('unavailable');
2773}
Note: See TracBrowser for help on using the repository browser.