Remove dependency on the strophe disco plugin

And instead implement it ourselves.

This solves a bug with that plugin whereby the connection handlers are
added to early and are therefore never fired.

Also fixed a problem whereby entity items are queried for features
before the features have been fetched.
This commit is contained in:
JC Brand 2018-05-07 17:08:31 +02:00
parent 5136b0c1dd
commit b3619077f9
10 changed files with 109 additions and 28 deletions

View File

@ -68,7 +68,6 @@
"snabbdom": "0.7.1", "snabbdom": "0.7.1",
"snyk": "^1.21.2", "snyk": "^1.21.2",
"strophe.js": "1.2.14", "strophe.js": "1.2.14",
"strophejs-plugin-disco": "0.0.1",
"strophejs-plugin-ping": "0.0.1", "strophejs-plugin-ping": "0.0.1",
"strophejs-plugin-register": "0.0.1", "strophejs-plugin-register": "0.0.1",
"strophejs-plugin-rsm": "0.0.1", "strophejs-plugin-rsm": "0.0.1",

View File

@ -54,7 +54,6 @@ require.config({
"snabbdom-props": "node_modules/snabbdom/dist/snabbdom-props", "snabbdom-props": "node_modules/snabbdom/dist/snabbdom-props",
"snabbdom-style": "node_modules/snabbdom/dist/snabbdom-style", "snabbdom-style": "node_modules/snabbdom/dist/snabbdom-style",
"strophe": "node_modules/strophe.js/strophe", "strophe": "node_modules/strophe.js/strophe",
"strophe.disco": "node_modules/strophejs-plugin-disco/strophe.disco",
"strophe.ping": "node_modules/strophejs-plugin-ping/strophe.ping", "strophe.ping": "node_modules/strophejs-plugin-ping/strophe.ping",
"strophe.rsm": "node_modules/strophejs-plugin-rsm/strophe.rsm", "strophe.rsm": "node_modules/strophejs-plugin-rsm/strophe.rsm",
"strophe.vcard": "node_modules/strophejs-plugin-vcard/strophe.vcard", "strophe.vcard": "node_modules/strophejs-plugin-vcard/strophe.vcard",

View File

@ -765,8 +765,8 @@
_converse.on('chatBoxesFetched', autoJoinChats); _converse.on('chatBoxesFetched', autoJoinChats);
_converse.on('addClientFeatures', () => { _converse.on('addClientFeatures', () => {
_converse.connection.disco.addFeature(Strophe.NS.HTTPUPLOAD); _converse.api.disco.addFeature(Strophe.NS.HTTPUPLOAD);
_converse.connection.disco.addFeature(Strophe.NS.OUTOFBAND); _converse.api.disco.addFeature(Strophe.NS.OUTOFBAND);
}); });
_converse.api.listen.on('pluginsInitialized', () => { _converse.api.listen.on('pluginsInitialized', () => {

View File

@ -1064,7 +1064,7 @@
_converse.on('connected', () => { _converse.on('connected', () => {
// Advertise that we support XEP-0382 Message Spoilers // Advertise that we support XEP-0382 Message Spoilers
_converse.connection.disco.addFeature(Strophe.NS.SPOILER); _converse.api.disco.addFeature(Strophe.NS.SPOILER);
}); });
/************************ BEGIN API ************************/ /************************ BEGIN API ************************/

View File

@ -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.api.disco.addFeature(Strophe.NS.BOSH);
_converse.connection.disco.addFeature(Strophe.NS.CHATSTATES); _converse.api.disco.addFeature(Strophe.NS.CHATSTATES);
_converse.connection.disco.addFeature(Strophe.NS.DISCO_INFO); _converse.api.disco.addFeature(Strophe.NS.DISCO_INFO);
_converse.connection.disco.addFeature(Strophe.NS.ROSTERX); // Limited support _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( entity.waitUntilFeaturesDiscovered.then(() => {
_.concat( 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) => { Promise.all(promises).then((result) => {
resolve(f.filter(f.isObject, 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

View File

@ -384,7 +384,7 @@
}); });
_converse.on('addClientFeatures', () => { _converse.on('addClientFeatures', () => {
_converse.connection.disco.addFeature(Strophe.NS.MAM); _converse.api.disco.addFeature(Strophe.NS.MAM);
}); });
_converse.on('afterMessagesFetched', (chatboxview) => { _converse.on('afterMessagesFetched', (chatboxview) => {

View File

@ -295,7 +295,7 @@
parent_el.querySelector('a.room-info').classList.remove('selected'); parent_el.querySelector('a.room-info').classList.remove('selected');
} else { } else {
parent_el.insertAdjacentHTML('beforeend', tpl_spinner()); parent_el.insertAdjacentHTML('beforeend', tpl_spinner());
_converse.connection.disco.info( _converse.api.disco.info(
ev.target.getAttribute('data-room-jid'), ev.target.getAttribute('data-room-jid'),
null, null,
_.partial(insertRoomInfo, parent_el) _.partial(insertRoomInfo, parent_el)

View File

@ -67,7 +67,7 @@
* *
* NB: These plugins need to have already been loaded via require.js. * NB: These plugins need to have already been loaded via require.js.
*/ */
dependencies: ["converse-chatboxes", "converse-controlbox"], dependencies: ["converse-chatboxes", "converse-disco", "converse-controlbox"],
overrides: { overrides: {
// Overrides mentioned here will be picked up by converse.js's // Overrides mentioned here will be picked up by converse.js's
@ -319,7 +319,7 @@
/* Fetch the room disco info, parse it and then save it. /* Fetch the room disco info, parse it and then save it.
*/ */
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
_converse.connection.disco.info( _converse.api.disco.info(
this.get('jid'), this.get('jid'),
null, null,
_.flow(this.parseRoomFeatures.bind(this), resolve), _.flow(this.parseRoomFeatures.bind(this), resolve),
@ -1134,10 +1134,10 @@
/************************ BEGIN Event Handlers ************************/ /************************ BEGIN Event Handlers ************************/
_converse.on('addClientFeatures', () => { _converse.on('addClientFeatures', () => {
if (_converse.allow_muc) { if (_converse.allow_muc) {
_converse.connection.disco.addFeature(Strophe.NS.MUC); _converse.api.disco.addFeature(Strophe.NS.MUC);
} }
if (_converse.allow_muc_invitations) { if (_converse.allow_muc_invitations) {
_converse.connection.disco.addFeature('jabber:x:conference'); // Invites _converse.api.disco.addFeature('jabber:x:conference'); // Invites
} }
}); });
_converse.on('chatBoxesFetched', autoJoinRooms); _converse.on('chatBoxesFetched', autoJoinRooms);

View File

@ -57,7 +57,7 @@
_converse.registerPongHandler = function () { _converse.registerPongHandler = function () {
if (!_.isUndefined(_converse.connection.disco)) { if (!_.isUndefined(_converse.connection.disco)) {
_converse.connection.disco.addFeature(Strophe.NS.PING); _converse.api.disco.addFeature(Strophe.NS.PING);
} }
_converse.connection.ping.addPingHandler(_converse.pong); _converse.connection.ping.addPingHandler(_converse.pong);
}; };

View File

@ -84,7 +84,7 @@
_converse.on('addClientFeatures', () => { _converse.on('addClientFeatures', () => {
_converse.connection.disco.addFeature(Strophe.NS.VCARD); _converse.api.disco.addFeature(Strophe.NS.VCARD);
}); });
_converse.on('statusInitialized', function fetchOwnVCard () { _converse.on('statusInitialized', function fetchOwnVCard () {