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

Revision 3059, 61.4 KB checked in by alexandrecorreia, 14 years ago (diff)

Ticket #1091 - Implementado a busca de salas para bate-papo no novo modulo Expresso messenger XEP-0045-MUC.

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