@@ -206,7 +206,7 @@ converse.plugins.add('converse-disco', {
206
206
if ( stanza . querySelector ( `feature[var="${ Strophe . NS . DISCO_ITEMS } "]` ) ) {
207
207
this . queryForItems ( ) ;
208
208
}
209
- _ . forEach ( stanza . querySelectorAll ( 'feature' ) , feature => {
209
+ Array . from ( stanza . querySelectorAll ( 'feature' ) ) . forEach ( feature => {
210
210
this . features . create ( {
211
211
'var' : feature . getAttribute ( 'var' ) ,
212
212
'from' : stanza . getAttribute ( 'from' )
@@ -243,6 +243,7 @@ converse.plugins.add('converse-disco', {
243
243
}
244
244
} ) ;
245
245
246
+
246
247
function addClientFeatures ( ) {
247
248
// See https://xmpp.org/registrar/disco-categories.html
248
249
_converse . api . disco . own . identities . add ( 'client' , 'web' , 'Converse' ) ;
@@ -263,39 +264,52 @@ converse.plugins.add('converse-disco', {
263
264
return this ;
264
265
}
265
266
267
+
266
268
function initStreamFeatures ( ) {
267
- const bare_jid = Strophe . getBareJidFromJid ( _converse . jid ) ;
268
- const id = `converse.stream-features-${ bare_jid } ` ;
269
- if ( ! _converse . stream_features || _converse . stream_features . browserStorage . name !== id ) {
269
+ // Initialize the stream_features collection, and if we're
270
+ // re-attaching to a pre-existing BOSH session, we restore the
271
+ // features from cache.
272
+ // Otherwise the features will be created once we've received them
273
+ // from the server (see populateStreamFeatures).
274
+ if ( ! _converse . stream_features ) {
275
+ const bare_jid = Strophe . getBareJidFromJid ( _converse . jid ) ;
276
+ const id = `converse.stream-features-${ bare_jid } ` ;
277
+ _converse . api . promises . add ( 'streamFeaturesAdded' ) ;
270
278
_converse . stream_features = new _converse . Collection ( ) ;
271
279
_converse . stream_features . browserStorage = _converse . createStore ( id , "session" ) ;
272
- _converse . stream_features . fetch ( {
273
- success ( collection ) {
274
- if ( collection . length === 0 && _converse . connection . features ) {
275
- Array . from ( _converse . connection . features . childNodes )
276
- . forEach ( feature => {
277
- _converse . stream_features . create ( {
278
- 'name' : feature . nodeName ,
279
- 'xmlns' : feature . getAttribute ( 'xmlns' )
280
- } ) ;
281
- } ) ;
282
- }
283
- /**
284
- * Triggered as soon as Converse has processed the stream features as advertised by
285
- * the server. If you want to check whether a stream feature is supported before
286
- * proceeding, then you'll first want to wait for this event.
287
- * @event _converse#streamFeaturesAdded
288
- * @example _converse.api.listen.on('streamFeaturesAdded', () => { ... });
289
- */
290
- _converse . api . trigger ( 'streamFeaturesAdded' ) ;
291
- } ,
292
- error ( m , e ) {
293
- log . error ( e ) ;
294
- }
295
- } ) ;
296
280
}
297
281
}
298
282
283
+
284
+ function populateStreamFeatures ( ) {
285
+ // Strophe.js sets the <stream:features> element on the
286
+ // Strophe.Connection instance (_converse.connection).
287
+ //
288
+ // Once this is done, we populate the _converse.stream_features collection
289
+ // and trigger streamFeaturesAdded.
290
+ initStreamFeatures ( ) ;
291
+ Array . from ( _converse . connection . features . childNodes ) . forEach ( feature => {
292
+ _converse . stream_features . create ( {
293
+ 'name' : feature . nodeName ,
294
+ 'xmlns' : feature . getAttribute ( 'xmlns' )
295
+ } ) ;
296
+ } ) ;
297
+ notifyStreamFeaturesAdded ( ) ;
298
+ }
299
+
300
+
301
+ function notifyStreamFeaturesAdded ( ) {
302
+ /**
303
+ * Triggered as soon as the stream features are known.
304
+ * If you want to check whether a stream feature is supported before proceeding,
305
+ * then you'll first want to wait for this event.
306
+ * @event _converse#streamFeaturesAdded
307
+ * @example _converse.api.listen.on('streamFeaturesAdded', () => { ... });
308
+ */
309
+ _converse . api . trigger ( 'streamFeaturesAdded' ) ;
310
+ }
311
+
312
+
299
313
const plugin = this ;
300
314
plugin . _identities = [ ] ;
301
315
plugin . _features = [ ] ;
@@ -355,9 +369,15 @@ converse.plugins.add('converse-disco', {
355
369
356
370
/******************** Event Handlers ********************/
357
371
358
- // Re-create promise upon reconnection
359
- _converse . api . listen . on ( 'userSessionInitialized' , initStreamFeatures ) ;
360
- _converse . api . listen . on ( 'beforeResourceBinding' , initStreamFeatures ) ;
372
+ _converse . api . listen . on ( 'userSessionInitialized' , async ( ) => {
373
+ initStreamFeatures ( ) ;
374
+ if ( _converse . connfeedback . get ( 'connection_status' ) === Strophe . Status . ATTACHED ) {
375
+ // When re-attaching to a BOSH session, we fetch the stream features from the cache.
376
+ await new Promise ( ( success , error ) => _converse . stream_features . fetch ( { success, error } ) ) ;
377
+ notifyStreamFeaturesAdded ( ) ;
378
+ }
379
+ } ) ;
380
+ _converse . api . listen . on ( 'beforeResourceBinding' , populateStreamFeatures ) ;
361
381
362
382
_converse . api . listen . on ( 'reconnected' , initializeDisco ) ;
363
383
_converse . api . listen . on ( 'connected' , initializeDisco ) ;
0 commit comments