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

Revision 2437, 42.4 KB checked in by alexandrecorreia, 14 years ago (diff)

Ticket #986 - Adicao de contatos com resultados da busca do ldap e exclusao de contatos da lista.

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