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

Revision 2584, 48.1 KB checked in by alexandrecorreia, 14 years ago (diff)

Ticket #986 - Alterado a parte de autorizacao, informando se o usuario esta permitido ou nao na lista.

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