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