Fri, 16 Apr 2010 18:51:44 +0100
Add documentation to README for assistants
// 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_leave), null, "presence", "unavailable", 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_leave: function (stanza) { var nick = Strophe.getResourceFromJid(stanza.getAttribute("from")); if(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].status = text; } if(this.callbacks.left) this.callbacks.left(stanza, this, this.occupants[nick]); if(this.status_handler) { this.status_handler(stanza); } delete this.occupants[nick]; } 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; } };