-
Notifications
You must be signed in to change notification settings - Fork 0
/
disco.js
102 lines (85 loc) · 3.04 KB
/
disco.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/**
* @file disco.js
* Implements XEP-0030 (Service Discovery)
* @see http://xmpp.org/extensions/xep-0030.html
*/
define(['strophe.js'], ({Strophe, $iq}) => {
Strophe.addConnectionPlugin('disco', {
identities: new Map(),
features: new Set(),
items: new Map(),
handlers: {},
init(conn) {
this._c = conn;
// Add default info/items handlers.
this.addInfoHandler();
this.addItemHandler();
},
addIdentity(category, type, name = '', lang = '') {
this.identities.set(String([category, type, name, lang]), {category, type, name, lang});
},
removeIdentity(category, type, name = '', lang = '') {
this.identities.remove(String([category, type, name, lang]))
},
addFeature(...namespaces) {
this.features = new Set([...this.features, ...namespaces]);
},
removeFeature(...namespaces) {
const remove = new Set(namespaces);
this.features = new Set([...this.features].filter(x => !remove.has(x)));
},
addItem({jid, node, attributes}) {
attributes.jid = jid;
attributes.node = node;
this.items.set(String([jid, node]), attributes);
},
removeItem({jid, node}) {
this.items.remove(String([jid, node]));
},
queryInfo(to, timeout) {
const id = this._c.getUniqueId('disco#info');
const iq = $iq({id, to, type: 'get'});
iq.c('query', {xmlns: Strophe.NS.DISCO_INFO});
return new Promise((resolve, reject) => this._c.sendIQ(iq, resolve, reject, timeout));
},
queryItems(to, node, timeout) {
const id = this._c.getUniqueId('disco#items');
const iq = $iq({id, to, type: 'get'});
iq.c('query', {xmlns: Strophe.NS.DISCO_ITEMS});
if (node) iq.attr({node});
return new Promise((resolve, reject) => this._c.sendIQ(iq, resolve, reject, timeout));
},
respond(request) {
const iq = $iq({
id: request.getAttribute('id'),
to: request.getAttribute('from'),
type: 'result'
});
const query = request.querySelector('query');
const xmlns = query.getAttribute('xmlns');
iq.c('query', {xmlns});
if (xmlns === Strophe.NS.DISCO_INFO) {
this.identities.forEach(identity => iq.c('identity', identity, ''));
this.features.forEach(feature => iq.c('feature', {'var': feature}, ''));
}
else this.items.forEach(item => iq.c('item', item, ''));
return this._c.sendIQ(iq);
},
addInfoHandler(handler) {
if (this.handlers.info) {
this._c.deleteHandler(this.handlers.info);
}
handler = handler || (request => this.respond(request));
this.handlers.info = this._c.addHandler(handler, Strophe.NS.DISCO_INFO, 'iq', 'get');
return this.handlers.info;
},
addItemHandler(handler) {
if (this.handlers.items) {
this._c.deleteHandler(this.handlers.items);
}
handler = handler || (request => this.respond(request));
this.handlers.items = this._c.addHandler(handler, Strophe.NS.DISCO_ITEMS, 'iq', 'get');
return this.handlers.items;
}
});
});