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

Revision 2620, 48.7 KB checked in by alexandrecorreia, 14 years ago (diff)

Ticket #986 - Correcao para evitar o excesso de requisicoes, quando o servidor aceita apenas uma.

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