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

Revision 2631, 49.3 KB checked in by alexandrecorreia, 14 years ago (diff)

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

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