social_stream 0.22.0 → 0.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. data/base/app/assets/javascripts/social_stream.search.js.erb +27 -0
  2. data/base/app/assets/stylesheets/activities.css.scss +2 -0
  3. data/base/app/controllers/search_controller.rb +5 -2
  4. data/base/app/helpers/activities_helper.rb +19 -0
  5. data/base/app/helpers/search_helper.rb +37 -7
  6. data/base/app/models/actor.rb +2 -1
  7. data/base/app/models/group.rb +2 -0
  8. data/base/app/views/activities/_likes.html.erb +5 -0
  9. data/base/app/views/activities/_root.html.erb +3 -0
  10. data/base/app/views/cheesecake/_cheesecake.html.erb +1 -1
  11. data/base/app/views/search/_form.html.erb +27 -48
  12. data/base/config/locales/en.yml +21 -3
  13. data/base/config/locales/es.yml +14 -3
  14. data/base/lib/social_stream/base/version.rb +1 -1
  15. data/documents/config/locales/en.yml +12 -3
  16. data/documents/config/locales/es.yml +12 -4
  17. data/documents/lib/social_stream/documents/version.rb +1 -1
  18. data/documents/lib/social_stream/toolbar_config/documents.rb +2 -2
  19. data/documents/social_stream-documents.gemspec +1 -1
  20. data/events/app/views/events/index.html.erb +2 -2
  21. data/events/config/locales/en.yml +4 -1
  22. data/events/config/locales/es.yml +4 -1
  23. data/events/lib/social_stream/events/version.rb +1 -1
  24. data/events/social_stream-events.gemspec +1 -1
  25. data/lib/social_stream/version.rb +1 -1
  26. data/presence/app/assets/javascripts/social_stream-presence.js +1 -0
  27. data/presence/app/assets/javascripts/xmpp_client_management.js.erb +14 -2
  28. data/presence/lib/social_stream/presence/engine.rb +6 -0
  29. data/presence/lib/social_stream/presence/models/group_manager.rb +41 -0
  30. data/presence/lib/social_stream/presence/version.rb +1 -1
  31. data/presence/lib/social_stream/presence/xmpp_server_order.rb +84 -10
  32. data/presence/lib/social_stream-presence.rb +1 -1
  33. data/presence/lib/tasks/presence/synchronize.rake +15 -0
  34. data/presence/social_stream-presence.gemspec +4 -4
  35. data/presence/vendor/assets/javascripts/strophe.muc.js +934 -0
  36. data/social_stream.gemspec +3 -3
  37. metadata +33 -29
@@ -0,0 +1,934 @@
1
+ /*
2
+ *Plugin to implement the MUC extension.
3
+ http://xmpp.org/extensions/xep-0045.html
4
+ *Previous Author:
5
+ Nathan Zorn <nathan.zorn@gmail.com>
6
+ *Complete CoffeeScript rewrite:
7
+ Andreas Guth <guth@dbis.rwth-aachen.de>
8
+ */
9
+ var Occupant, RoomConfig, XmppRoom,
10
+ __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
11
+
12
+ Strophe.addConnectionPlugin('muc', {
13
+ _connection: null,
14
+ rooms: [],
15
+ /*Function
16
+ Initialize the MUC plugin. Sets the correct connection object and
17
+ extends the namesace.
18
+ */
19
+ init: function(conn) {
20
+ this._connection = conn;
21
+ this._muc_handler = null;
22
+ Strophe.addNamespace('MUC_OWNER', Strophe.NS.MUC + "#owner");
23
+ Strophe.addNamespace('MUC_ADMIN', Strophe.NS.MUC + "#admin");
24
+ Strophe.addNamespace('MUC_USER', Strophe.NS.MUC + "#user");
25
+ return Strophe.addNamespace('MUC_ROOMCONF', Strophe.NS.MUC + "#roomconfig");
26
+ },
27
+ /*Function
28
+ Join a multi-user chat room
29
+ Parameters:
30
+ (String) room - The multi-user chat room to join.
31
+ (String) nick - The nickname to use in the chat room. Optional
32
+ (Function) msg_handler_cb - The function call to handle messages from the
33
+ specified chat room.
34
+ (Function) pres_handler_cb - The function call back to handle presence
35
+ in the chat room.
36
+ (String) password - The optional password to use. (password protected
37
+ rooms only)
38
+ */
39
+ join: function(room, nick, msg_handler_cb, pres_handler_cb, roster_cb, password) {
40
+ var msg, room_nick, _base,
41
+ _this = this;
42
+ room_nick = this.test_append_nick(room, nick);
43
+ msg = $pres({
44
+ from: this._connection.jid,
45
+ to: room_nick
46
+ }).c("x", {
47
+ xmlns: Strophe.NS.MUC
48
+ });
49
+ if (password != null) msg.cnode(Strophe.xmlElement("password", [], password));
50
+ if (this._muc_handler == null) {
51
+ this._muc_handler = conn.addHandler(function(stanza) {
52
+ var from, handler, handlers, id, roomname, x, xmlns, xquery, _i, _len;
53
+ from = stanza.getAttribute('from');
54
+ roomname = from.split("/")[0];
55
+ if (!_this.rooms[roomname]) return true;
56
+ room = _this.rooms[roomname];
57
+ handlers = {};
58
+ if (stanza.nodeName === "message") {
59
+ handlers = room._message_handlers;
60
+ } else if (stanza.nodeName === "presence") {
61
+ xquery = stanza.getElementsByTagName("x");
62
+ if (xquery.length > 0) {
63
+ for (_i = 0, _len = xquery.length; _i < _len; _i++) {
64
+ x = xquery[_i];
65
+ xmlns = x.getAttribute("xmlns");
66
+ if (xmlns && xmlns.match(Strophe.NS.MUC)) {
67
+ handlers = room._presence_handlers;
68
+ break;
69
+ }
70
+ }
71
+ }
72
+ }
73
+ for (id in handlers) {
74
+ handler = handlers[id];
75
+ if (!handler(stanza, room)) delete handlers[id];
76
+ }
77
+ return true;
78
+ });
79
+ }
80
+ if ((_base = this.rooms)[room] == null) {
81
+ _base[room] = new XmppRoom(this, room, nick, password);
82
+ }
83
+ if (pres_handler_cb) this.rooms[room].addHandler('presence', pres_handler_cb);
84
+ if (msg_handler_cb) this.rooms[room].addHandler('message', msg_handler_cb);
85
+ if (roster_cb) this.rooms[room].addHandler('roster', roster_cb);
86
+ return this._connection.send(msg);
87
+ },
88
+ /*Function
89
+ Leave a multi-user chat room
90
+ Parameters:
91
+ (String) room - The multi-user chat room to leave.
92
+ (String) nick - The nick name used in the room.
93
+ (Function) handler_cb - Optional function to handle the successful leave.
94
+ (String) exit_msg - optional exit message.
95
+ Returns:
96
+ iqid - The unique id for the room leave.
97
+ */
98
+ leave: function(room, nick, handler_cb, exit_msg) {
99
+ var presence, presenceid, room_nick;
100
+ delete this.rooms[room];
101
+ if (this.rooms.length === 0) {
102
+ this._connection.deleteHandler(this._muc_handler);
103
+ this._muc_handler = null;
104
+ }
105
+ room_nick = this.test_append_nick(room, nick);
106
+ presenceid = this._connection.getUniqueId();
107
+ presence = $pres({
108
+ type: "unavailable",
109
+ id: presenceid,
110
+ from: this._connection.jid,
111
+ to: room_nick
112
+ });
113
+ if (exit_msg != null) presence.c("status", exit_msg);
114
+ if (handler_cb != null) {
115
+ this._connection.addHandler(handler_cb, null, "presence", null, presenceid);
116
+ }
117
+ this._connection.send(presence);
118
+ return presenceid;
119
+ },
120
+ /*Function
121
+ Parameters:
122
+ (String) room - The multi-user chat room name.
123
+ (String) nick - The nick name used in the chat room.
124
+ (String) message - The plaintext message to send to the room.
125
+ (String) html_message - The message to send to the room with html markup.
126
+ (String) type - "groupchat" for group chat messages o
127
+ "chat" for private chat messages
128
+ Returns:
129
+ msgiq - the unique id used to send the message
130
+ */
131
+ message: function(room, nick, message, html_message, type) {
132
+ var msg, msgid, parent, room_nick;
133
+ room_nick = this.test_append_nick(room, nick);
134
+ type = type || (nick != null ? "chat" : "groupchat");
135
+ msgid = this._connection.getUniqueId();
136
+ msg = $msg({
137
+ to: room_nick,
138
+ from: this._connection.jid,
139
+ type: type,
140
+ id: msgid
141
+ }).c("body", {
142
+ xmlns: Strophe.NS.CLIENT
143
+ }).t(message);
144
+ msg.up();
145
+ if (html_message != null) {
146
+ msg.c("html", {
147
+ xmlns: Strophe.NS.XHTML_IM
148
+ }).c("body", {
149
+ xmlns: Strophe.NS.XHTML
150
+ }).h(html_message);
151
+ if (msg.node.childNodes.length === 0) {
152
+ parent = msg.node.parentNode;
153
+ msg.up().up();
154
+ msg.node.removeChild(parent);
155
+ } else {
156
+ msg.up().up();
157
+ }
158
+ }
159
+ msg.c("x", {
160
+ xmlns: "jabber:x:event"
161
+ }).c("composing");
162
+ this._connection.send(msg);
163
+ return msgid;
164
+ },
165
+ /*Function
166
+ Convenience Function to send a Message to all Occupants
167
+ Parameters:
168
+ (String) room - The multi-user chat room name.
169
+ (String) message - The plaintext message to send to the room.
170
+ (String) html_message - The message to send to the room with html markup.
171
+ Returns:
172
+ msgiq - the unique id used to send the message
173
+ */
174
+ groupchat: function(room, message, html_message) {
175
+ return this.message(room, null, message, html_message);
176
+ },
177
+ /*Function
178
+ Send a mediated invitation.
179
+ Parameters:
180
+ (String) room - The multi-user chat room name.
181
+ (String) receiver - The invitation's receiver.
182
+ (String) reason - Optional reason for joining the room.
183
+ Returns:
184
+ msgiq - the unique id used to send the invitation
185
+ */
186
+ invite: function(room, receiver, reason) {
187
+ var invitation, msgid;
188
+ msgid = this._connection.getUniqueId();
189
+ invitation = $msg({
190
+ from: this._connection.jid,
191
+ to: room,
192
+ id: msgid
193
+ }).c('x', {
194
+ xmlns: Strophe.NS.MUC_USER
195
+ }).c('invite', {
196
+ to: receiver
197
+ });
198
+ if (reason != null) invitation.c('reason', reason);
199
+ this._connection.send(invitation);
200
+ return msgid;
201
+ },
202
+ /*Function
203
+ Send a direct invitation.
204
+ Parameters:
205
+ (String) room - The multi-user chat room name.
206
+ (String) receiver - The invitation's receiver.
207
+ (String) reason - Optional reason for joining the room.
208
+ (String) password - Optional password for the room.
209
+ Returns:
210
+ msgiq - the unique id used to send the invitation
211
+ */
212
+ directInvite: function(room, receiver, reason, password) {
213
+ var attrs, invitation, msgid;
214
+ msgid = this._connection.getUniqueId();
215
+ attrs = {
216
+ xmlns: 'jabber:x:conference',
217
+ jid: room
218
+ };
219
+ if (reason != null) attrs.reason = reason;
220
+ if (password != null) attrs.password = password;
221
+ invitation = $msg({
222
+ from: this._connection.jid,
223
+ to: receiver,
224
+ id: msgid
225
+ }).c('x', attrs);
226
+ this._connection.send(invitation);
227
+ return msgid;
228
+ },
229
+ /*Function
230
+ Queries a room for a list of occupants
231
+ (String) room - The multi-user chat room name.
232
+ (Function) success_cb - Optional function to handle the info.
233
+ (Function) error_cb - Optional function to handle an error.
234
+ Returns:
235
+ id - the unique id used to send the info request
236
+ */
237
+ queryOccupants: function(room, success_cb, error_cb) {
238
+ var attrs, info;
239
+ attrs = {
240
+ xmlns: Strophe.NS.DISCO_ITEMS
241
+ };
242
+ info = $iq({
243
+ from: this._connection.jid,
244
+ to: room,
245
+ type: 'get'
246
+ }).c('query', attrs);
247
+ return this._connection.sendIQ(info, success_cb, error_cb);
248
+ },
249
+ /*Function
250
+ Start a room configuration.
251
+ Parameters:
252
+ (String) room - The multi-user chat room name.
253
+ (Function) handler_cb - Optional function to handle the config form.
254
+ Returns:
255
+ id - the unique id used to send the configuration request
256
+ */
257
+ configure: function(room, handler_cb) {
258
+ var config, id, stanza;
259
+ config = $iq({
260
+ to: room,
261
+ type: "get"
262
+ }).c("query", {
263
+ xmlns: Strophe.NS.MUC_OWNER
264
+ });
265
+ stanza = config.tree();
266
+ id = this._connection.sendIQ(stanza);
267
+ if (handler_cb != null) {
268
+ this._connection.addHandler(function(stanza) {
269
+ handler_cb(stanza);
270
+ return false;
271
+ }, Strophe.NS.MUC_OWNER, "iq", null, id);
272
+ }
273
+ return id;
274
+ },
275
+ /*Function
276
+ Cancel the room configuration
277
+ Parameters:
278
+ (String) room - The multi-user chat room name.
279
+ Returns:
280
+ id - the unique id used to cancel the configuration.
281
+ */
282
+ cancelConfigure: function(room) {
283
+ var config, stanza;
284
+ config = $iq({
285
+ to: room,
286
+ type: "set"
287
+ }).c("query", {
288
+ xmlns: Strophe.NS.MUC_OWNER
289
+ }).c("x", {
290
+ xmlns: "jabber:x:data",
291
+ type: "cancel"
292
+ });
293
+ stanza = config.tree();
294
+ return this._connection.sendIQ(stanza);
295
+ },
296
+ /*Function
297
+ Save a room configuration.
298
+ Parameters:
299
+ (String) room - The multi-user chat room name.
300
+ (Array) configarray - an array of form elements used to configure the room.
301
+ Returns:
302
+ id - the unique id used to save the configuration.
303
+ */
304
+ saveConfiguration: function(room, configarray) {
305
+ var conf, config, stanza, _i, _len;
306
+ config = $iq({
307
+ to: room,
308
+ type: "set"
309
+ }).c("query", {
310
+ xmlns: Strophe.NS.MUC_OWNER
311
+ }).c("x", {
312
+ xmlns: "jabber:x:data",
313
+ type: "submit"
314
+ });
315
+ for (_i = 0, _len = configarray.length; _i < _len; _i++) {
316
+ conf = configarray[_i];
317
+ config.cnode(conf).up();
318
+ }
319
+ stanza = config.tree();
320
+ return this._connection.sendIQ(stanza);
321
+ },
322
+ /*Function
323
+ Parameters:
324
+ (String) room - The multi-user chat room name.
325
+ Returns:
326
+ id - the unique id used to create the chat room.
327
+ */
328
+ createInstantRoom: function(room) {
329
+ var roomiq;
330
+ roomiq = $iq({
331
+ to: room,
332
+ type: "set"
333
+ }).c("query", {
334
+ xmlns: Strophe.NS.MUC_OWNER
335
+ }).c("x", {
336
+ xmlns: "jabber:x:data",
337
+ type: "submit"
338
+ });
339
+ return this._connection.sendIQ(roomiq.tree());
340
+ },
341
+ /*Function
342
+ Set the topic of the chat room.
343
+ Parameters:
344
+ (String) room - The multi-user chat room name.
345
+ (String) topic - Topic message.
346
+ */
347
+ setTopic: function(room, topic) {
348
+ var msg;
349
+ msg = $msg({
350
+ to: room,
351
+ from: this._connection.jid,
352
+ type: "groupchat"
353
+ }).c("subject", {
354
+ xmlns: "jabber:client"
355
+ }).t(topic);
356
+ return this._connection.send(msg.tree());
357
+ },
358
+ /*Function
359
+ Internal Function that Changes the role or affiliation of a member
360
+ of a MUC room. This function is used by modifyRole and modifyAffiliation.
361
+ The modification can only be done by a room moderator. An error will be
362
+ returned if the user doesn't have permission.
363
+ Parameters:
364
+ (String) room - The multi-user chat room name.
365
+ (Object) item - Object with nick and role or jid and affiliation attribute
366
+ (String) reason - Optional reason for the change.
367
+ (Function) handler_cb - Optional callback for success
368
+ (Function) errer_cb - Optional callback for error
369
+ Returns:
370
+ iq - the id of the mode change request.
371
+ */
372
+ _modifyPrivilege: function(room, item, reason, handler_cb, error_cb) {
373
+ var iq;
374
+ iq = $iq({
375
+ to: room,
376
+ type: "set"
377
+ }).c("query", {
378
+ xmlns: Strophe.NS.MUC_ADMIN
379
+ }).cnode(item.node);
380
+ if (reason != null) iq.c("reason", reason);
381
+ return this._connection.sendIQ(iq.tree(), handler_cb, error_cb);
382
+ },
383
+ /*Function
384
+ Changes the role of a member of a MUC room.
385
+ The modification can only be done by a room moderator. An error will be
386
+ returned if the user doesn't have permission.
387
+ Parameters:
388
+ (String) room - The multi-user chat room name.
389
+ (String) nick - The nick name of the user to modify.
390
+ (String) role - The new role of the user.
391
+ (String) affiliation - The new affiliation of the user.
392
+ (String) reason - Optional reason for the change.
393
+ (Function) handler_cb - Optional callback for success
394
+ (Function) errer_cb - Optional callback for error
395
+ Returns:
396
+ iq - the id of the mode change request.
397
+ */
398
+ modifyRole: function(room, nick, role, reason, handler_cb, error_cb) {
399
+ var item;
400
+ item = $build("item", {
401
+ nick: nick,
402
+ role: role
403
+ });
404
+ return this._modifyPrivilege(room, item, reason, handler_cb, error_cb);
405
+ },
406
+ kick: function(room, nick, reason, handler_cb, error_cb) {
407
+ return this.modifyRole(room, nick, 'none', reason, handler_cb, error_cb);
408
+ },
409
+ voice: function(room, nick, reason, handler_cb, error_cb) {
410
+ return this.modifyRole(room, nick, 'participant', reason, handler_cb, error_cb);
411
+ },
412
+ mute: function(room, nick, reason, handler_cb, error_cb) {
413
+ return this.modifyRole(room, nick, 'visitor', reason, handler_cb, error_cb);
414
+ },
415
+ op: function(room, nick, reason, handler_cb, error_cb) {
416
+ return this.modifyRole(room, nick, 'moderator', reason, handler_cb, error_cb);
417
+ },
418
+ deop: function(room, nick, reason, handler_cb, error_cb) {
419
+ return this.modifyRole(room, nick, 'participant', reason, handler_cb, error_cb);
420
+ },
421
+ /*Function
422
+ Changes the affiliation of a member of a MUC room.
423
+ The modification can only be done by a room moderator. An error will be
424
+ returned if the user doesn't have permission.
425
+ Parameters:
426
+ (String) room - The multi-user chat room name.
427
+ (String) jid - The jid of the user to modify.
428
+ (String) affiliation - The new affiliation of the user.
429
+ (String) reason - Optional reason for the change.
430
+ (Function) handler_cb - Optional callback for success
431
+ (Function) errer_cb - Optional callback for error
432
+ Returns:
433
+ iq - the id of the mode change request.
434
+ */
435
+ modifyAffiliation: function(room, jid, affiliation, reason, handler_cb, error_cb) {
436
+ var item;
437
+ item = $build("item", {
438
+ jid: jid,
439
+ affiliation: affiliation
440
+ });
441
+ return this._modifyPrivilege(room, item, reason, handler_cb, error_cb);
442
+ },
443
+ ban: function(room, jid, reason, handler_cb, error_cb) {
444
+ return this.modifyAffiliation(room, jid, 'outcast', reason, handler_cb, error_cb);
445
+ },
446
+ member: function(room, jid, reason, handler_cb, error_cb) {
447
+ return this.modifyAffiliation(room, jid, 'member', reason, handler_cb, error_cb);
448
+ },
449
+ revoke: function(room, jid, reason, handler_cb, error_cb) {
450
+ return this.modifyAffiliation(room, jid, 'none', reason, handler_cb, error_cb);
451
+ },
452
+ owner: function(room, jid, reason, handler_cb, error_cb) {
453
+ return this.modifyAffiliation(room, jid, 'owner', reason, handler_cb, error_cb);
454
+ },
455
+ admin: function(room, jid, reason, handler_cb, error_cb) {
456
+ return this.modifyAffiliation(room, jid, 'admin', reason, handler_cb, error_cb);
457
+ },
458
+ /*Function
459
+ Change the current users nick name.
460
+ Parameters:
461
+ (String) room - The multi-user chat room name.
462
+ (String) user - The new nick name.
463
+ */
464
+ changeNick: function(room, user) {
465
+ var presence, room_nick;
466
+ room_nick = this.test_append_nick(room, user);
467
+ presence = $pres({
468
+ from: this._connection.jid,
469
+ to: room_nick,
470
+ id: this._connection.getUniqueId()
471
+ });
472
+ return this._connection.send(presence.tree());
473
+ },
474
+ /*Function
475
+ Change the current users status.
476
+ Parameters:
477
+ (String) room - The multi-user chat room name.
478
+ (String) user - The current nick.
479
+ (String) show - The new show-text.
480
+ (String) status - The new status-text.
481
+ */
482
+ setStatus: function(room, user, show, status) {
483
+ var presence, room_nick;
484
+ room_nick = this.test_append_nick(room, user);
485
+ presence = $pres({
486
+ from: this._connection.jid,
487
+ to: room_nick
488
+ });
489
+ if (show != null) presence.c('show', show).up();
490
+ if (status != null) presence.c('status', status);
491
+ return this._connection.send(presence.tree());
492
+ },
493
+ /*Function
494
+ List all chat room available on a server.
495
+ Parameters:
496
+ (String) server - name of chat server.
497
+ (String) handle_cb - Function to call for room list return.
498
+ */
499
+ listRooms: function(server, handle_cb) {
500
+ var iq;
501
+ iq = $iq({
502
+ to: server,
503
+ from: this._connection.jid,
504
+ type: "get"
505
+ }).c("query", {
506
+ xmlns: Strophe.NS.DISCO_ITEMS
507
+ });
508
+ return this._connection.sendIQ(iq, handle_cb);
509
+ },
510
+ test_append_nick: function(room, nick) {
511
+ return room + (nick != null ? "/" + (Strophe.escapeNode(nick)) : "");
512
+ }
513
+ });
514
+
515
+ XmppRoom = (function() {
516
+
517
+ XmppRoom.prototype.roster = {};
518
+
519
+ XmppRoom.prototype._message_handlers = {};
520
+
521
+ XmppRoom.prototype._presence_handlers = {};
522
+
523
+ XmppRoom.prototype._roster_handlers = {};
524
+
525
+ XmppRoom.prototype._handler_ids = 0;
526
+
527
+ function XmppRoom(client, name, nick, password) {
528
+ this.client = client;
529
+ this.name = name;
530
+ this.nick = nick;
531
+ this.password = password;
532
+ this._roomRosterHandler = __bind(this._roomRosterHandler, this);
533
+ this._addOccupant = __bind(this._addOccupant, this);
534
+ if (client.muc) this.client = client.muc;
535
+ this.name = Strophe.getBareJidFromJid(name);
536
+ this.client.rooms[this.name] = this;
537
+ this.addHandler('presence', this._roomRosterHandler);
538
+ }
539
+
540
+ XmppRoom.prototype.join = function(msg_handler_cb, pres_handler_cb) {
541
+ if (!this.client.rooms[this.name]) {
542
+ return this.client.join(this.name, this.nick, msg_handler_cb, pres_handler_cb, this.password);
543
+ }
544
+ };
545
+
546
+ XmppRoom.prototype.leave = function(handler_cb, message) {
547
+ this.client.leave(this.name, this.nick, handler_cb, message);
548
+ return delete this.client.rooms[this.name];
549
+ };
550
+
551
+ XmppRoom.prototype.message = function(nick, message, html_message, type) {
552
+ return this.client.message(this.name, nick, message, html_message, type);
553
+ };
554
+
555
+ XmppRoom.prototype.groupchat = function(message, html_message) {
556
+ return this.client.groupchat(this.name, message, html_message);
557
+ };
558
+
559
+ XmppRoom.prototype.invite = function(receiver, reason) {
560
+ return this.client.invite(this.name, receiver, reason);
561
+ };
562
+
563
+ XmppRoom.prototype.directInvite = function(receiver, reason) {
564
+ return this.client.directInvite(this.name, receiver, reason, this.password);
565
+ };
566
+
567
+ XmppRoom.prototype.configure = function(handler_cb) {
568
+ return this.client.configure(this.name, handler_cb);
569
+ };
570
+
571
+ XmppRoom.prototype.cancelConfigure = function() {
572
+ return this.client.cancelConfigure(this.name);
573
+ };
574
+
575
+ XmppRoom.prototype.saveConfiguration = function(configarray) {
576
+ return this.client.saveConfiguration(this.name, configarray);
577
+ };
578
+
579
+ XmppRoom.prototype.queryOccupants = function(success_cb, error_cb) {
580
+ return this.client.queryOccupants(this.name, success_cb, error_cb);
581
+ };
582
+
583
+ XmppRoom.prototype.setTopic = function(topic) {
584
+ return this.client.setTopic(this.name, topic);
585
+ };
586
+
587
+ XmppRoom.prototype.modifyRole = function(nick, role, reason, success_cb, error_cb) {
588
+ return this.client.modifyRole(this.name, nick, role, reason, success_cb, error_cb);
589
+ };
590
+
591
+ XmppRoom.prototype.kick = function(nick, reason, handler_cb, error_cb) {
592
+ return this.client.kick(this.name, nick, reason, handler_cb, error_cb);
593
+ };
594
+
595
+ XmppRoom.prototype.voice = function(nick, reason, handler_cb, error_cb) {
596
+ return this.client.voice(this.name, nick, reason, handler_cb, error_cb);
597
+ };
598
+
599
+ XmppRoom.prototype.mute = function(nick, reason, handler_cb, error_cb) {
600
+ return this.client.mute(this.name, nick, reason, handler_cb, error_cb);
601
+ };
602
+
603
+ XmppRoom.prototype.op = function(nick, reason, handler_cb, error_cb) {
604
+ return this.client.op(this.name, nick, reason, handler_cb, error_cb);
605
+ };
606
+
607
+ XmppRoom.prototype.deop = function(nick, reason, handler_cb, error_cb) {
608
+ return this.client.deop(this.name, nick, reason, handler_cb, error_cb);
609
+ };
610
+
611
+ XmppRoom.prototype.modifyAffiliation = function(jid, affiliation, reason, success_cb, error_cb) {
612
+ return this.client.modifyAffiliation(this.name, jid, affiliation, reason, success_cb, error_cb);
613
+ };
614
+
615
+ XmppRoom.prototype.ban = function(jid, reason, handler_cb, error_cb) {
616
+ return this.client.ban(this.name, jid, reason, handler_cb, error_cb);
617
+ };
618
+
619
+ XmppRoom.prototype.member = function(jid, reason, handler_cb, error_cb) {
620
+ return this.client.member(this.name, jid, reason, handler_cb, error_cb);
621
+ };
622
+
623
+ XmppRoom.prototype.revoke = function(jid, reason, handler_cb, error_cb) {
624
+ return this.client.revoke(this.name, jid, reason, handler_cb, error_cb);
625
+ };
626
+
627
+ XmppRoom.prototype.owner = function(jid, reason, handler_cb, error_cb) {
628
+ return this.client.owner(this.name, jid, reason, handler_cb, error_cb);
629
+ };
630
+
631
+ XmppRoom.prototype.admin = function(jid, reason, handler_cb, error_cb) {
632
+ return this.client.admin(this.name, jid, reason, handler_cb, error_cb);
633
+ };
634
+
635
+ XmppRoom.prototype.changeNick = function(nick) {
636
+ this.nick = nick;
637
+ return this.client.changeNick(this.name, nick);
638
+ };
639
+
640
+ XmppRoom.prototype.setStatus = function(show, status) {
641
+ return this.client.setStatus(this.name, this.nick, show, status);
642
+ };
643
+
644
+ /*Function
645
+ Adds a handler to the MUC room.
646
+ Parameters:
647
+ (String) handler_type - 'message', 'presence' or 'roster'.
648
+ (Function) handler - The handler function.
649
+ Returns:
650
+ id - the id of handler.
651
+ */
652
+
653
+ XmppRoom.prototype.addHandler = function(handler_type, handler) {
654
+ var id;
655
+ id = this._handler_ids++;
656
+ switch (handler_type) {
657
+ case 'presence':
658
+ this._presence_handlers[id] = handler;
659
+ break;
660
+ case 'message':
661
+ this._message_handlers[id] = handler;
662
+ break;
663
+ case 'roster':
664
+ this._roster_handlers[id] = handler;
665
+ break;
666
+ default:
667
+ this._handler_ids--;
668
+ return null;
669
+ }
670
+ return id;
671
+ };
672
+
673
+ /*Function
674
+ Removes a handler from the MUC room.
675
+ This function takes ONLY ids returned by the addHandler function
676
+ of this room. passing handler ids returned by connection.addHandler
677
+ may brake things!
678
+ Parameters:
679
+ (number) id - the id of the handler
680
+ */
681
+
682
+ XmppRoom.prototype.removeHandler = function(id) {
683
+ delete this._presence_handlers[id];
684
+ delete this._message_handlers[id];
685
+ return delete this._roster_handlers[id];
686
+ };
687
+
688
+ /*Function
689
+ Creates and adds an Occupant to the Room Roster.
690
+ Parameters:
691
+ (Object) data - the data the Occupant is filled with
692
+ Returns:
693
+ occ - the created Occupant.
694
+ */
695
+
696
+ XmppRoom.prototype._addOccupant = function(data) {
697
+ var occ;
698
+ occ = new Occupant(data, this);
699
+ this.roster[occ.nick] = occ;
700
+ return occ;
701
+ };
702
+
703
+ /*Function
704
+ The standard handler that managed the Room Roster.
705
+ Parameters:
706
+ (Object) pres - the presence stanza containing user information
707
+ */
708
+
709
+ XmppRoom.prototype._roomRosterHandler = function(pres) {
710
+ var data, handler, id, newnick, nick, _ref;
711
+ data = XmppRoom._parsePresence(pres);
712
+ nick = data.nick;
713
+ newnick = data.newnick || null;
714
+ switch (data.type) {
715
+ case 'error':
716
+ return;
717
+ case 'unavailable':
718
+ if (newnick) {
719
+ data.nick = newnick;
720
+ if (this.roster[nick] && this.roster[newnick]) {
721
+ this.roster[nick].update(this.roster[newnick]);
722
+ this.roster[newnick] = this.roster[nick];
723
+ }
724
+ if (this.roster[nick] && !this.roster[newnick]) {
725
+ this.roster[newnick] = this.roster[nick].update(data);
726
+ }
727
+ }
728
+ delete this.roster[nick];
729
+ break;
730
+ default:
731
+ if (this.roster[nick]) {
732
+ this.roster[nick].update(data);
733
+ } else {
734
+ this._addOccupant(data);
735
+ }
736
+ }
737
+ _ref = this._roster_handlers;
738
+ for (id in _ref) {
739
+ handler = _ref[id];
740
+ if (!handler(this.roster, this)) delete this._roster_handlers[id];
741
+ }
742
+ return true;
743
+ };
744
+
745
+ /*Function
746
+ Parses a presence stanza
747
+ Parameters:
748
+ (Object) data - the data extracted from the presence stanza
749
+ */
750
+
751
+ XmppRoom._parsePresence = function(pres) {
752
+ var a, c, c2, data, _i, _j, _len, _len2, _ref, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8;
753
+ data = {};
754
+ a = pres.attributes;
755
+ data.nick = Strophe.getResourceFromJid(a.from.textContent);
756
+ data.type = ((_ref = a.type) != null ? _ref.textContent : void 0) || null;
757
+ data.states = [];
758
+ _ref2 = pres.children;
759
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
760
+ c = _ref2[_i];
761
+ switch (c.nodeName) {
762
+ case "status":
763
+ data.status = c.textContent || null;
764
+ break;
765
+ case "show":
766
+ data.show = c.textContent || null;
767
+ break;
768
+ case "x":
769
+ a = c.attributes;
770
+ if (((_ref3 = a.xmlns) != null ? _ref3.textContent : void 0) === Strophe.NS.MUC_USER) {
771
+ _ref4 = c.children;
772
+ for (_j = 0, _len2 = _ref4.length; _j < _len2; _j++) {
773
+ c2 = _ref4[_j];
774
+ switch (c2.nodeName) {
775
+ case "item":
776
+ a = c2.attributes;
777
+ data.affiliation = ((_ref5 = a.affiliation) != null ? _ref5.textContent : void 0) || null;
778
+ data.role = ((_ref6 = a.role) != null ? _ref6.textContent : void 0) || null;
779
+ data.jid = ((_ref7 = a.jid) != null ? _ref7.textContent : void 0) || null;
780
+ data.newnick = ((_ref8 = a.nick) != null ? _ref8.textContent : void 0) || null;
781
+ break;
782
+ case "status":
783
+ if (c2.attributes.code) {
784
+ data.states.push(c2.attributes.code.textContent);
785
+ }
786
+ }
787
+ }
788
+ }
789
+ }
790
+ }
791
+ return data;
792
+ };
793
+
794
+ return XmppRoom;
795
+
796
+ })();
797
+
798
+ RoomConfig = (function() {
799
+
800
+ function RoomConfig(info) {
801
+ this.parse = __bind(this.parse, this); if (info != null) this.parse(info);
802
+ }
803
+
804
+ RoomConfig.prototype.parse = function(result) {
805
+ var attr, attrs, child, field, identity, query, _i, _j, _k, _len, _len2, _len3, _ref;
806
+ query = result.getElementsByTagName("query")[0].children;
807
+ this.identities = [];
808
+ this.features = [];
809
+ this.x = [];
810
+ for (_i = 0, _len = query.length; _i < _len; _i++) {
811
+ child = query[_i];
812
+ attrs = child.attributes;
813
+ switch (child.nodeName) {
814
+ case "identity":
815
+ identity = {};
816
+ for (_j = 0, _len2 = attrs.length; _j < _len2; _j++) {
817
+ attr = attrs[_j];
818
+ identity[attr.name] = attr.textContent;
819
+ }
820
+ this.identities.push(identity);
821
+ break;
822
+ case "feature":
823
+ this.features.push(attrs["var"].textContent);
824
+ break;
825
+ case "x":
826
+ attrs = child.children[0].attributes;
827
+ if ((!attrs["var"].textContent === 'FORM_TYPE') || (!attrs.type.textContent === 'hidden')) {
828
+ break;
829
+ }
830
+ _ref = child.children;
831
+ for (_k = 0, _len3 = _ref.length; _k < _len3; _k++) {
832
+ field = _ref[_k];
833
+ if (!(!field.attributes.type)) continue;
834
+ attrs = field.attributes;
835
+ this.x.push({
836
+ "var": attrs["var"].textContent,
837
+ label: attrs.label.textContent || "",
838
+ value: field.firstChild.textContent || ""
839
+ });
840
+ }
841
+ }
842
+ }
843
+ return {
844
+ "identities": this.identities,
845
+ "features": this.features,
846
+ "x": this.x
847
+ };
848
+ };
849
+
850
+ return RoomConfig;
851
+
852
+ })();
853
+
854
+ Occupant = (function() {
855
+
856
+ function Occupant(data, room) {
857
+ this.room = room;
858
+ this.update = __bind(this.update, this);
859
+ this.admin = __bind(this.admin, this);
860
+ this.owner = __bind(this.owner, this);
861
+ this.revoke = __bind(this.revoke, this);
862
+ this.member = __bind(this.member, this);
863
+ this.ban = __bind(this.ban, this);
864
+ this.modifyAffiliation = __bind(this.modifyAffiliation, this);
865
+ this.deop = __bind(this.deop, this);
866
+ this.op = __bind(this.op, this);
867
+ this.mute = __bind(this.mute, this);
868
+ this.voice = __bind(this.voice, this);
869
+ this.kick = __bind(this.kick, this);
870
+ this.modifyRole = __bind(this.modifyRole, this);
871
+ this.update(data);
872
+ }
873
+
874
+ Occupant.prototype.modifyRole = function(role, reason, success_cb, error_cb) {
875
+ return this.room.modifyRole(this.nick, role, reason, success_cb, error_cb);
876
+ };
877
+
878
+ Occupant.prototype.kick = function(reason, handler_cb, error_cb) {
879
+ return this.room.kick(this.nick, reason, handler_cb, error_cb);
880
+ };
881
+
882
+ Occupant.prototype.voice = function(reason, handler_cb, error_cb) {
883
+ return this.room.voice(this.nick, reason, handler_cb, error_cb);
884
+ };
885
+
886
+ Occupant.prototype.mute = function(reason, handler_cb, error_cb) {
887
+ return this.room.mute(this.nick, reason, handler_cb, error_cb);
888
+ };
889
+
890
+ Occupant.prototype.op = function(reason, handler_cb, error_cb) {
891
+ return this.room.op(this.nick, reason, handler_cb, error_cb);
892
+ };
893
+
894
+ Occupant.prototype.deop = function(reason, handler_cb, error_cb) {
895
+ return this.room.deop(this.nick, reason, handler_cb, error_cb);
896
+ };
897
+
898
+ Occupant.prototype.modifyAffiliation = function(affiliation, reason, success_cb, error_cb) {
899
+ return this.room.modifyAffiliation(this.jid, affiliation, reason, success_cb, error_cb);
900
+ };
901
+
902
+ Occupant.prototype.ban = function(reason, handler_cb, error_cb) {
903
+ return this.room.ban(this.jid, reason, handler_cb, error_cb);
904
+ };
905
+
906
+ Occupant.prototype.member = function(reason, handler_cb, error_cb) {
907
+ return this.room.member(this.jid, reason, handler_cb, error_cb);
908
+ };
909
+
910
+ Occupant.prototype.revoke = function(reason, handler_cb, error_cb) {
911
+ return this.room.revoke(this.jid, reason, handler_cb, error_cb);
912
+ };
913
+
914
+ Occupant.prototype.owner = function(reason, handler_cb, error_cb) {
915
+ return this.room.owner(this.jid, reason, handler_cb, error_cb);
916
+ };
917
+
918
+ Occupant.prototype.admin = function(reason, handler_cb, error_cb) {
919
+ return this.room.admin(this.jid, reason, handler_cb, error_cb);
920
+ };
921
+
922
+ Occupant.prototype.update = function(data) {
923
+ this.nick = data.nick || null;
924
+ this.affiliation = data.affiliation || null;
925
+ this.role = data.role || null;
926
+ this.jid = data.jid || null;
927
+ this.status = data.status || null;
928
+ this.show = data.show || null;
929
+ return this;
930
+ };
931
+
932
+ return Occupant;
933
+
934
+ })();