diff -r 6985de83d146 -r 12b42931151a support-chat/js/xmpp_muc.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/support-chat/js/xmpp_muc.js Mon Apr 05 13:15:59 2010 +0100 @@ -0,0 +1,145 @@ +// Wraps a function so that its 'this' is always 'context' when called +var recontext = function (context, f) { return function () { return f.apply(context, arguments); }; }; + +// Returns a child element given a tag name and xmlns +function get_child(stanza, name, xmlns) +{ + var children = stanza.getElementsByTagName(name); + for(var i=0;i<=children.length;i++) + { + if(children[i].getAttribute("xmlns") == xmlns || !xmlns) + return children[i]; + } + return null; +} + + + +var MUC = function (conn, callbacks) +{ + /* Set our properties */ + this.conn = conn; + this.callbacks = callbacks; + + this.occupants = {}; + + /* Initialize stanza handlers */ + conn.addHandler(recontext(this, this.handle_join), null, "presence", null, null, null); + conn.addHandler(recontext(this, this.handle_error), null, "presence", "error", null, null); + conn.addHandler(recontext(this, this.handle_message), null, "message", "groupchat", null, null); + + /* Return newly-created object */ + return this; +} + +MUC.prototype = +{ + /** General methods */ + + join: function (jid, nick, status_text) + { + this.jid = jid; + this.nick = nick; + var pres = $pres({to: jid+'/'+nick}); + if(status) + pres.c("status").t(status); + return this.send_stanza(pres); + }, + + part: function (status_text) + { + var pres = $pres({to: this.jid+'/'+this.nick, type: "unavailable"}); + if(status) + pres.c("status").t(status); + return this.send_stanza(pres); + }, + + send_message: function (message) + { + return this.send_stanza($msg({to: this.jid, type: "groupchat"}) + .c("body").t(message||"")); + }, + + send_private_message: function (nick, message) + { + return this.send_stanza($msg({to: this.jid+"/"+nick, type: "chat"}) + .c("body").t(message||"")); + }, + + send_invite: function (jid, message) + { + return this.send_stanza($msg({to: jid}) + .c("x", { xmlns: "http://jabber.org/protocol/muc#user" }) + .c("invite", { to: jid }) + .c("reason").t(message||"")); + }, + + send_stanza: function (stanza) + { + return this.conn.send(stanza.tree()); + }, + + /** Incoming stanza handlers */ + + handle_join: function (stanza) + { + var nick = Strophe.getResourceFromJid(stanza.getAttribute("from")); + if(stanza.getAttribute("type") != "unavailable" && stanza.getAttribute("type") != "error" + && Strophe.getBareJidFromJid(stanza.getAttribute("from")) == this.jid) + if(!this.occupants[nick]) + { + var text = stanza.getElementsByTagName("status")[0]; + if(text) text = Strophe.getText(text); + this.occupants[nick] = { nick: nick, status: text }; + var item = get_child(stanza, "x", "http://jabber.org/protocol/muc#user"); + if(item) + { + item = item.getElementsByTagName("item")[0]; + this.occupants[nick].affiliation = item.getAttribute("affiliation"); + this.occupants[nick].role = item.getAttribute("role"); + } + if(this.callbacks.joined) + this.callbacks.joined(stanza, this, this.occupants[nick]); + if(this.status_handler) + { + this.status_handler(stanza); + } + } + return true; + }, + + handle_error: function (stanza) + { + if(this.callbacks.error + && Strophe.getBareJidFromJid(stanza.getAttribute("from")) == this.jid) + { + var e = stanza.getElementsByTagName("error"); + if(e.length > 0) + { + var err = null; + Strophe.forEachChild(e[0], null, function (child) + { + if(child.getAttribute("xmlns") == "urn:ietf:params:xml:ns:xmpp-stanzas") + err = child.nodeName; + }); + this.callbacks.error(stanza, this, err); + } + } + return true; + }, + + handle_message: function (stanza) + { + if(!this.callbacks.message) + return true; + + if(stanza.getAttribute("type") == "groupchat" && Strophe.getBareJidFromJid(stanza.getAttribute("from")) == this.jid) + { + var body = stanza.getElementsByTagName("body"); + if(body.length > 0 && stanza.getElementsByTagName("delay").length == 0) + this.callbacks.message(stanza, this, Strophe.getResourceFromJid(stanza.getAttribute("from")), Strophe.getText(body[0])); + } + return true; + } + +};