|
@@ -9,10 +9,10 @@
|
|
|
|
|
|
/*global Backbone, define, window */
|
|
/*global Backbone, define, window */
|
|
(function (root, factory) {
|
|
(function (root, factory) {
|
|
- define(["converse-core", "sizzle", "strophe.disco"], factory);
|
|
|
|
|
|
+ define(["converse-core", "sizzle"], factory);
|
|
}(this, function (converse, sizzle) {
|
|
}(this, function (converse, sizzle) {
|
|
|
|
|
|
- const { Backbone, Promise, Strophe, b64_sha1, utils, _, f } = converse.env;
|
|
|
|
|
|
+ const { Backbone, Promise, Strophe, $iq, b64_sha1, utils, _, f } = converse.env;
|
|
|
|
|
|
converse.plugins.add('converse-disco', {
|
|
converse.plugins.add('converse-disco', {
|
|
|
|
|
|
@@ -127,7 +127,7 @@
|
|
},
|
|
},
|
|
|
|
|
|
queryInfo () {
|
|
queryInfo () {
|
|
- _converse.connection.disco.info(this.get('jid'), null, this.onInfo.bind(this));
|
|
|
|
|
|
+ _converse.api.disco.info(this.get('jid'), null, this.onInfo.bind(this));
|
|
},
|
|
},
|
|
|
|
|
|
onDiscoItems (stanza) {
|
|
onDiscoItems (stanza) {
|
|
@@ -150,7 +150,7 @@
|
|
// server or a conference component.
|
|
// server or a conference component.
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- _converse.connection.disco.items(this.get('jid'), null, this.onDiscoItems.bind(this));
|
|
|
|
|
|
+ _converse.api.disco.items(this.get('jid'), null, this.onDiscoItems.bind(this));
|
|
},
|
|
},
|
|
|
|
|
|
onInfo (stanza) {
|
|
onInfo (stanza) {
|
|
@@ -211,14 +211,14 @@
|
|
*/
|
|
*/
|
|
|
|
|
|
// See http://xmpp.org/registrar/disco-categories.html
|
|
// See http://xmpp.org/registrar/disco-categories.html
|
|
- _converse.connection.disco.addIdentity('client', 'web', 'Converse.js');
|
|
|
|
|
|
+ _converse.api.disco.addIdentity('client', 'web', 'Converse.js');
|
|
|
|
|
|
- _converse.connection.disco.addFeature(Strophe.NS.BOSH);
|
|
|
|
- _converse.connection.disco.addFeature(Strophe.NS.CHATSTATES);
|
|
|
|
- _converse.connection.disco.addFeature(Strophe.NS.DISCO_INFO);
|
|
|
|
- _converse.connection.disco.addFeature(Strophe.NS.ROSTERX); // Limited support
|
|
|
|
|
|
+ _converse.api.disco.addFeature(Strophe.NS.BOSH);
|
|
|
|
+ _converse.api.disco.addFeature(Strophe.NS.CHATSTATES);
|
|
|
|
+ _converse.api.disco.addFeature(Strophe.NS.DISCO_INFO);
|
|
|
|
+ _converse.api.disco.addFeature(Strophe.NS.ROSTERX); // Limited support
|
|
if (_converse.message_carbons) {
|
|
if (_converse.message_carbons) {
|
|
- _converse.connection.disco.addFeature(Strophe.NS.CARBONS);
|
|
|
|
|
|
+ _converse.api.disco.addFeature(Strophe.NS.CARBONS);
|
|
}
|
|
}
|
|
_converse.emit('addClientFeatures');
|
|
_converse.emit('addClientFeatures');
|
|
return this;
|
|
return this;
|
|
@@ -226,6 +226,8 @@
|
|
|
|
|
|
function initializeDisco () {
|
|
function initializeDisco () {
|
|
addClientFeatures();
|
|
addClientFeatures();
|
|
|
|
+ _converse.connection.addHandler(onDiscoInfoRequest, Strophe.NS.DISCO_INFO, 'iq', 'get', null, null);
|
|
|
|
+
|
|
_converse.disco_entities = new _converse.DiscoEntities();
|
|
_converse.disco_entities = new _converse.DiscoEntities();
|
|
_converse.disco_entities.browserStorage = new Backbone.BrowserStorage[_converse.storage](
|
|
_converse.disco_entities.browserStorage = new Backbone.BrowserStorage[_converse.storage](
|
|
b64_sha1(`converse.disco-entities-${_converse.bare_jid}`)
|
|
b64_sha1(`converse.disco-entities-${_converse.bare_jid}`)
|
|
@@ -240,6 +242,7 @@
|
|
_converse.emit('discoInitialized');
|
|
_converse.emit('discoInitialized');
|
|
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
|
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
|
}
|
|
}
|
|
|
|
+
|
|
_converse.api.listen.on('reconnected', initializeDisco);
|
|
_converse.api.listen.on('reconnected', initializeDisco);
|
|
_converse.api.listen.on('connected', initializeDisco);
|
|
_converse.api.listen.on('connected', initializeDisco);
|
|
|
|
|
|
@@ -254,9 +257,69 @@
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
|
|
+ const plugin = this;
|
|
|
|
+ plugin._identities = [];
|
|
|
|
+ plugin._features = [];
|
|
|
|
+
|
|
|
|
+ function onDiscoInfoRequest (stanza) {
|
|
|
|
+ const node = stanza.getElementsByTagName('query')[0].getAttribute('node');
|
|
|
|
+ const attrs = {xmlns: Strophe.NS.DISCO_INFO};
|
|
|
|
+ if (node) { attrs.node = node; }
|
|
|
|
+
|
|
|
|
+ const iqresult = $iq({'type': 'result', 'id': stanza.getAttribute('id')});
|
|
|
|
+ const from = stanza.getAttribute('from');
|
|
|
|
+ if (from !== null) {
|
|
|
|
+ iqresult.attrs({'to': from});
|
|
|
|
+ }
|
|
|
|
+ _.each(plugin._identities, (identity) => {
|
|
|
|
+ const attrs = {
|
|
|
|
+ 'category': identity.category,
|
|
|
|
+ 'type': identity.type
|
|
|
|
+ };
|
|
|
|
+ if (identity.name) {
|
|
|
|
+ attrs.name = identity.name;
|
|
|
|
+ }
|
|
|
|
+ if (identity.lang) {
|
|
|
|
+ attrs['xml:lang'] = identity.lang;
|
|
|
|
+ }
|
|
|
|
+ iqresult.c('identity', attrs).up();
|
|
|
|
+ });
|
|
|
|
+ _.each(plugin._features, (feature) => {
|
|
|
|
+ iqresult.c('feature', {'var': feature}).up();
|
|
|
|
+ });
|
|
|
|
+ _converse.connection.send(iqresult.tree());
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+
|
|
/* We extend the default converse.js API to add methods specific to service discovery */
|
|
/* We extend the default converse.js API to add methods specific to service discovery */
|
|
_.extend(_converse.api, {
|
|
_.extend(_converse.api, {
|
|
'disco': {
|
|
'disco': {
|
|
|
|
+ 'info' (jid, node, callback, errback, timeout) {
|
|
|
|
+ const attrs = {xmlns: Strophe.NS.DISCO_INFO};
|
|
|
|
+ if (node) {
|
|
|
|
+ attrs.node = node;
|
|
|
|
+ }
|
|
|
|
+ const info = $iq({
|
|
|
|
+ 'from': _converse.connection.jid,
|
|
|
|
+ 'to':jid,
|
|
|
|
+ 'type':'get'
|
|
|
|
+ }).c('query', attrs);
|
|
|
|
+ _converse.connection.sendIQ(info, callback, errback, timeout);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ 'items' (jid, node, callback, errback, timeout) {
|
|
|
|
+ const attrs = {'xmlns': Strophe.NS.DISCO_ITEMS};
|
|
|
|
+ if (node) {
|
|
|
|
+ attrs.node = node;
|
|
|
|
+ }
|
|
|
|
+ const items = $iq({
|
|
|
|
+ 'from': _converse.connection.jid,
|
|
|
|
+ 'to':jid,
|
|
|
|
+ 'type':'get'
|
|
|
|
+ }).c('query', attrs);
|
|
|
|
+ _converse.connection.sendIQ(items, callback, errback, timeout);
|
|
|
|
+ },
|
|
|
|
+
|
|
'entities': {
|
|
'entities': {
|
|
'get' (entity_jid, create=false) {
|
|
'get' (entity_jid, create=false) {
|
|
return _converse.api.waitUntil('discoInitialized').then(() => {
|
|
return _converse.api.waitUntil('discoInitialized').then(() => {
|
|
@@ -292,19 +355,39 @@
|
|
return _converse.api.waitUntil('discoInitialized').then(() => {
|
|
return _converse.api.waitUntil('discoInitialized').then(() => {
|
|
return new Promise((resolve, reject) => {
|
|
return new Promise((resolve, reject) => {
|
|
_converse.api.disco.entities.get(entity_jid, true).then((entity) => {
|
|
_converse.api.disco.entities.get(entity_jid, true).then((entity) => {
|
|
- Promise.all(
|
|
|
|
- _.concat(
|
|
|
|
|
|
+ entity.waitUntilFeaturesDiscovered.then(() => {
|
|
|
|
+ const promises = _.concat(
|
|
entity.items.map((item) => item.hasFeature(feature)),
|
|
entity.items.map((item) => item.hasFeature(feature)),
|
|
entity.hasFeature(feature)
|
|
entity.hasFeature(feature)
|
|
- )
|
|
|
|
- ).then((result) => {
|
|
|
|
- resolve(f.filter(f.isObject, result));
|
|
|
|
|
|
+ );
|
|
|
|
+ Promise.all(promises).then((result) => {
|
|
|
|
+ resolve(f.filter(f.isObject, result));
|
|
|
|
+ }).catch(reject);
|
|
}).catch(reject);
|
|
}).catch(reject);
|
|
})
|
|
})
|
|
});
|
|
});
|
|
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
|
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
|
},
|
|
},
|
|
|
|
|
|
|
|
+ 'addIdentity' (category, type, name, lang) {
|
|
|
|
+ for (var i=0; i<plugin._identities.length; i++) {
|
|
|
|
+ if (plugin._identities[i].category == category &&
|
|
|
|
+ plugin._identities[i].type == type &&
|
|
|
|
+ plugin._identities[i].name == name &&
|
|
|
|
+ plugin._identities[i].lang == lang) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ plugin._identities.push({category: category, type: type, name: name, lang: lang});
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ 'addFeature' (name) {
|
|
|
|
+ for (var i=0; i<plugin._features.length; i++) {
|
|
|
|
+ if (plugin._features[i] == name) { return false; }
|
|
|
|
+ }
|
|
|
|
+ plugin._features.push(name);
|
|
|
|
+ },
|
|
|
|
+
|
|
'getIdentity' (category, type, entity_jid) {
|
|
'getIdentity' (category, type, entity_jid) {
|
|
/* Returns a Promise which resolves with a map indicating
|
|
/* Returns a Promise which resolves with a map indicating
|
|
* whether an identity with a given type is provided by
|
|
* whether an identity with a given type is provided by
|