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

Revision 2641, 49.8 KB checked in by alexandrecorreia, 14 years ago (diff)

Ticket #986 - Correcao para compatibilizar o carregamento do script para o IE.

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