|
1 // Wraps a function so that its 'this' is always 'context' when called |
|
2 var recontext = function (context, f) { return function () { return f.apply(context, arguments); }; }; |
|
3 |
|
4 var MUC = function (conn, callbacks) |
|
5 { |
|
6 /* Set our properties */ |
|
7 this.conn = conn; |
|
8 this.callbacks = callbacks; |
|
9 |
|
10 this.occupants = {}; |
|
11 |
|
12 /* Initialize stanza handlers */ |
|
13 conn.addHandler(recontext(this, this.handle_join), null, "presence", null, null, null); |
|
14 conn.addHandler(recontext(this, this.handle_error), null, "presence", "error", null, null); |
|
15 conn.addHandler(recontext(this, this.handle_message), null, "message", "groupchat", null, null); |
|
16 |
|
17 /* Return newly-created object */ |
|
18 return this; |
|
19 } |
|
20 |
|
21 MUC.prototype = |
|
22 { |
|
23 /** General methods */ |
|
24 |
|
25 join: function (jid, nick, status_text) |
|
26 { |
|
27 this.jid = jid; |
|
28 this.nick = nick; |
|
29 var pres = $pres({to: jid+'/'+nick}); |
|
30 if(status) |
|
31 pres.c("status").t(status); |
|
32 return this.send_stanza(pres); |
|
33 }, |
|
34 |
|
35 part: function (status_text) |
|
36 { |
|
37 var pres = $pres({to: this.jid+'/'+this.nick, type: "unavailable"}); |
|
38 if(status) |
|
39 pres.c("status").t(status); |
|
40 return this.send_stanza(pres); |
|
41 }, |
|
42 |
|
43 send_message: function (message) |
|
44 { |
|
45 return this.send_stanza($msg({to: this.jid, type: "groupchat"}) |
|
46 .c("body").t(message||"")); |
|
47 }, |
|
48 |
|
49 send_private_message: function (nick, message) |
|
50 { |
|
51 return this.send_stanza($msg({to: this.jid+"/"+nick, type: "chat"}) |
|
52 .c("body").t(message||"")); |
|
53 }, |
|
54 |
|
55 send_invite: function (jid, message) |
|
56 { |
|
57 return this.send_stanza($msg({to: jid}) |
|
58 .c("x", { xmlns: "http://jabber.org/protocol/muc#user" }) |
|
59 .c("invite", { to: jid }) |
|
60 .c("reason").t(message||"")); |
|
61 }, |
|
62 |
|
63 send_stanza: function (stanza) |
|
64 { |
|
65 return this.conn.send(stanza.tree()); |
|
66 }, |
|
67 |
|
68 /** Incoming stanza handlers */ |
|
69 |
|
70 handle_join: function (stanza) |
|
71 { |
|
72 var nick = Strophe.getResourceFromJid(stanza.getAttribute("from")); |
|
73 if(stanza.getAttribute("type") != "unavailable" && stanza.getAttribute("type") != "error" |
|
74 && Strophe.getBareJidFromJid(stanza.getAttribute("from")) == this.jid) |
|
75 if(!this.occupants[nick]) |
|
76 { |
|
77 var text = stanza.getElementsByTagName("status")[0]; |
|
78 if(text) text = Strophe.getText(text); |
|
79 this.occupants[nick] = {}; |
|
80 if(this.callbacks.joined) |
|
81 this.callbacks.joined(stanza, this, nick, text); |
|
82 if(this.status_handler) |
|
83 { |
|
84 this.status_handler(stanza); |
|
85 } |
|
86 } |
|
87 return true; |
|
88 }, |
|
89 |
|
90 handle_error: function (stanza) |
|
91 { |
|
92 if(this.callbacks.error |
|
93 && Strophe.getBareJidFromJid(stanza.getAttribute("from")) == this.jid) |
|
94 { |
|
95 var e = stanza.getElementsByTagName("error"); |
|
96 if(e.length > 0) |
|
97 { |
|
98 var err = null; |
|
99 Strophe.forEachChild(e[0], null, function (child) |
|
100 { |
|
101 if(child.getAttribute("xmlns") == "urn:ietf:params:xml:ns:xmpp-stanzas") |
|
102 err = child.nodeName; |
|
103 }); |
|
104 this.callbacks.error(stanza, this, err); |
|
105 } |
|
106 } |
|
107 return true; |
|
108 }, |
|
109 |
|
110 handle_message: function (stanza) |
|
111 { |
|
112 if(!this.callbacks.message) |
|
113 return true; |
|
114 |
|
115 if(stanza.getAttribute("type") == "groupchat" && Strophe.getBareJidFromJid(stanza.getAttribute("from")) == this.jid) |
|
116 { |
|
117 var body = stanza.getElementsByTagName("body"); |
|
118 if(body.length > 0 && stanza.getElementsByTagName("delay").length == 0) |
|
119 this.callbacks.message(stanza, this, Strophe.getResourceFromJid(stanza.getAttribute("from")), Strophe.getText(body[0])); |
|
120 } |
|
121 return true; |
|
122 } |
|
123 |
|
124 }; |