source: sandbox/jabberit_messenger/trophy_expresso/js/trophyim.js @ 2738

Revision 2738, 56.3 KB checked in by alexandrecorreia, 14 years ago (diff)

Ticket #986 - Correcao para alguns erros de carregamento do javascript.

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