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

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