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

Revision 2670, 52.1 KB checked in by alexandrecorreia, 14 years ago (diff)

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

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