From cd392bb1972d1500437ad71ae283ecfa2cbdf063 Mon Sep 17 00:00:00 2001 From: JC Brand Date: Thu, 1 Aug 2019 10:26:35 +0200 Subject: [PATCH] Fixes #1561 Don't clear localStorage and sessionStorage --- spec/chatbox.js | 24 ++++----- spec/controlbox.js | 6 +-- spec/messages.js | 6 +-- spec/muc.js | 10 ++-- spec/protocol.js | 2 +- src/converse-controlbox.js | 28 ++++------- src/converse-muc-views.js | 2 + src/converse-oauth.js | 2 +- src/converse-omemo.js | 25 ++++++---- src/converse-roomslist.js | 2 +- src/converse-rosterview.js | 5 +- src/headless/converse-bookmarks.js | 2 +- src/headless/converse-bosh.js | 1 + src/headless/converse-chatboxes.js | 4 +- src/headless/converse-core.js | 79 +++++++++++++++++------------- src/headless/converse-disco.js | 35 +++++++------ src/headless/converse-muc.js | 14 +++++- src/headless/converse-roster.js | 28 ++++++++--- src/headless/converse-vcard.js | 9 +++- 19 files changed, 164 insertions(+), 120 deletions(-) diff --git a/spec/chatbox.js b/spec/chatbox.js index 96b7186d5..b83411d49 100644 --- a/spec/chatbox.js +++ b/spec/chatbox.js @@ -263,7 +263,7 @@ const view = await test_utils.openChatBoxFor(_converse, contact_jid); const el = sizzle('a.open-chat:contains("'+view.model.getDisplayName()+'")', _converse.rosterview.el).pop(); const jid = el.textContent.replace(/ /g,'.').toLowerCase() + '@montague.lit'; - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); el.click(); await u.waitUntil(() => _converse.api.trigger.calls.count(), 500); expect(_converse.chatboxes.length).toEqual(2); @@ -280,7 +280,7 @@ await test_utils.waitForRoster(_converse, 'current'); test_utils.openControlBox(); - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); test_utils.openControlBox(); test_utils.openChatBoxes(_converse, 6); @@ -323,7 +323,7 @@ spyOn(chatview, 'close').and.callThrough(); spyOn(controlview, 'close').and.callThrough(); - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); // We need to rebind all events otherwise our spy won't be called controlview.delegateEvents(); @@ -356,7 +356,7 @@ const trimmed_chatboxes = _converse.minimized_chats; const chatview = _converse.chatboxviews.get(contact_jid); spyOn(chatview, 'minimize').and.callThrough(); - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); // We need to rebind all events otherwise our spy won't be called chatview.delegateEvents(); chatview.el.querySelector('.toggle-chatbox-button').click(); @@ -390,7 +390,7 @@ await test_utils.waitForRoster(_converse, 'current'); test_utils.openControlBox(); await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length); - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); _converse.chatboxes.browserStorage._clear(); test_utils.closeControlBox(); @@ -538,7 +538,7 @@ let toolbar, call_button; const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@montague.lit'; - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); // First check that the button doesn't show if it's not enabled // via "visible_toolbar_buttons" _converse.visible_toolbar_buttons.call = false; @@ -603,7 +603,7 @@ await test_utils.waitForRoster(_converse, 'current'); test_utils.openControlBox(); - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@montague.lit'; // state const msg = $msg({ @@ -690,7 +690,7 @@ var view = _converse.chatboxviews.get(contact_jid); expect(view.model.get('chat_state')).toBe('active'); spyOn(_converse.connection, 'send'); - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); view.onKeyDown({ target: view.el.querySelector('textarea.chat-textarea'), keyCode: 1 @@ -724,7 +724,7 @@ test_utils.openControlBox(); // See XEP-0085 https://xmpp.org/extensions/xep-0085.html#definitions - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@montague.lit'; await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length); await test_utils.openChatBoxFor(_converse, sender_jid); @@ -1052,7 +1052,7 @@ test_utils.openControlBox(); const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@montague.lit'; // See XEP-0085 https://xmpp.org/extensions/xep-0085.html#definitions - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); await test_utils.openChatBoxFor(_converse, sender_jid); const view = _converse.chatboxviews.get(sender_jid); expect(view.el.querySelectorAll('.chat-event').length).toBe(0); @@ -1093,7 +1093,7 @@ await test_utils.waitForRoster(_converse, 'current', 3); test_utils.openControlBox(); - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@montague.lit'; // state const msg = $msg({ @@ -1125,7 +1125,7 @@ test_utils.openControlBox(); const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit'; - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); await test_utils.openChatBoxFor(_converse, contact_jid); const view = _converse.chatboxviews.get(contact_jid); let message = 'This message is another sent from this chatbox'; diff --git a/spec/controlbox.js b/spec/controlbox.js index 48da19bbe..96ae06897 100644 --- a/spec/controlbox.js +++ b/spec/controlbox.js @@ -24,7 +24,7 @@ expect(u.isVisible(el)).toBe(false); spyOn(_converse.controlboxtoggle, 'onClick').and.callThrough(); spyOn(_converse.controlboxtoggle, 'showControlBox').and.callThrough(); - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); // Redelegate so that the spies are now registered as the event handlers (specifically for 'onClick') _converse.controlboxtoggle.delegateEvents(); document.querySelector('.toggle-controlbox').click(); @@ -38,12 +38,12 @@ describe("The \"Contacts\" section", function () { - it("can be used to add contact and it checks for case-sensivity", + it("can be used to add contact and it checks for case-sensivity", mock.initConverse( null, ['rosterGroupsFetched'], {}, async function (done, _converse) { - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); spyOn(_converse.rosterview, 'update').and.callThrough(); test_utils.openControlBox(); // Adding two contacts one with Capital initials and one with small initials of same JID (Case sensitive check) diff --git a/spec/messages.js b/spec/messages.js index 473b77889..d4ae25b8d 100644 --- a/spec/messages.js +++ b/spec/messages.js @@ -737,7 +737,7 @@ const include_nick = false; await test_utils.waitForRoster(_converse, 'current', 2, include_nick); test_utils.openControlBox(); - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); const contact_name = mock.cur_names[1]; const contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@montague.lit'; @@ -1382,7 +1382,7 @@ await test_utils.waitForRoster(_converse, 'current'); test_utils.openControlBox(); - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit'; await test_utils.openChatBoxFor(_converse, contact_jid) expect(_converse.api.trigger).toHaveBeenCalledWith('chatBoxFocused', jasmine.any(Object)); @@ -1626,7 +1626,7 @@ _converse.allow_non_roster_messaging = false; _converse.api.trigger('rosterContactsFetched'); - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); const message = 'This is a received message from someone not on the roster'; const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit'; const msg = $msg({ diff --git a/spec/muc.js b/spec/muc.js index 7238e7a90..ca6bfcf1b 100644 --- a/spec/muc.js +++ b/spec/muc.js @@ -1969,7 +1969,7 @@ const text = 'This is a received message'; await test_utils.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); const view = _converse.chatboxviews.get('lounge@montague.lit'); if (!view.el.querySelectorAll('.chat-area').length) { view.renderChatArea(); @@ -2001,7 +2001,7 @@ async function (done, _converse) { await test_utils.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); const view = _converse.chatboxviews.get('lounge@montague.lit'); if (!view.el.querySelectorAll('.chat-area').length) { view.renderChatArea(); @@ -2742,7 +2742,7 @@ spyOn(view, 'onMinimized').and.callThrough(); spyOn(view, 'onMaximized').and.callThrough(); - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); view.delegateEvents(); // We need to rebind all events otherwise our spy won't be called view.el.querySelector('.toggle-chatbox-button').click(); @@ -2770,7 +2770,7 @@ await test_utils.openChatRoom(_converse, 'lounge', 'montague.lit', 'romeo'); const view = _converse.chatboxviews.get('lounge@montague.lit'); spyOn(view, 'close').and.callThrough(); - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); spyOn(view.model, 'leave'); view.delegateEvents(); // We need to rebind all events otherwise our spy won't be called view.el.querySelector('.close-chatbox-button').click(); @@ -3787,7 +3787,7 @@ 'from': view.model.get('jid'), 'to': _converse.connection.jid }); - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); expect(_converse.chatboxes.length).toBe(2); _converse.connection._dataRecv(test_utils.createRequest(result_stanza)); await u.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED)); diff --git a/spec/protocol.js b/spec/protocol.js index 963ceb16d..73daf5ac9 100644 --- a/spec/protocol.js +++ b/spec/protocol.js @@ -516,7 +516,7 @@ null, ['rosterGroupsFetched'], {}, async function (done, _converse) { - spyOn(_converse.api, "trigger"); + spyOn(_converse.api, "trigger").and.callThrough(); test_utils.openControlBox(_converse); // Create some contacts so that we can test positioning test_utils.createContacts(_converse, 'current'); diff --git a/src/converse-controlbox.js b/src/converse-controlbox.js index c7830412c..98967569d 100644 --- a/src/converse-controlbox.js +++ b/src/converse-controlbox.js @@ -586,19 +586,18 @@ converse.plugins.add('converse-controlbox', { }); _converse.api.listen.on('clearSession', () => { - if (_converse.config.get('trusted')) { - const chatboxes = _.get(_converse, 'chatboxes', null); - if (!_.isNil(chatboxes)) { - const controlbox = chatboxes.get('controlbox'); - if (controlbox && - controlbox.collection && - controlbox.collection.browserStorage) { - controlbox.save({'connected': false}); - } - } + const chatboxviews = _.get(_converse, 'chatboxviews', null); + const view = chatboxviews && chatboxviews.get('controlbox'); + if (view) { + u.safeSave(view.model, {'connected': false}); + if (_.get(view, 'controlbox_pane')) { + view.controlbox_pane.remove(); + delete view.controlbox_pane; + } } }); + Promise.all([ _converse.api.waitUntil('connectionInitialized'), _converse.api.waitUntil('chatBoxViewsInitialized') @@ -621,15 +620,6 @@ converse.plugins.add('converse-controlbox', { _converse.api.listen.on('disconnected', () => disconnect().renderLoginPanel()); _converse.api.listen.on('will-reconnect', disconnect); - _converse.api.listen.on('clearSession', () => { - const view = _converse.chatboxviews.get('controlbox'); - if (view && view.controlbox_pane) { - view.controlbox_pane.remove(); - delete view.controlbox_pane; - } - }); - - /************************ API ************************/ Object.assign(_converse.api, { diff --git a/src/converse-muc-views.js b/src/converse-muc-views.js index cac3a35cc..36228a01c 100644 --- a/src/converse-muc-views.js +++ b/src/converse-muc-views.js @@ -1930,6 +1930,8 @@ converse.plugins.add('converse-muc-views', { _converse.api.listen.on('clearSession', () => { const view = _converse.chatboxviews.get('controlbox'); if (view && view.roomspanel) { + view.roomspanel.model.destroy(); + view.roomspanel.model.browserStorage._clear(); view.roomspanel.remove(); delete view.roomspanel; } diff --git a/src/converse-oauth.js b/src/converse-oauth.js index 673e39408..14d3ffdff 100644 --- a/src/converse-oauth.js +++ b/src/converse-oauth.js @@ -77,7 +77,7 @@ converse.plugins.add("converse-oauth", { 'oauth_providers': {}, }); - _converse.OAuthProviders = Backbone.Collection.extend({ + _converse.OAuthProviders = _converse.Collection.extend({ 'sync': __.noop, initialize () { diff --git a/src/converse-omemo.js b/src/converse-omemo.js index 7b04549ee..98a0366ae 100644 --- a/src/converse-omemo.js +++ b/src/converse-omemo.js @@ -977,7 +977,7 @@ converse.plugins.add('converse-omemo', { } }); - _converse.Devices = Backbone.Collection.extend({ + _converse.Devices = _converse.Collection.extend({ model: _converse.Device, }); @@ -1082,7 +1082,7 @@ converse.plugins.add('converse-omemo', { * @namespace _converse.DeviceLists * @memberOf _converse */ - _converse.DeviceLists = Backbone.Collection.extend({ + _converse.DeviceLists = _converse.Collection.extend({ model: _converse.DeviceList, /** * Returns the {@link _converse.DeviceList} for a particular JID. @@ -1240,6 +1240,8 @@ converse.plugins.add('converse-omemo', { } } + /******************** Event Handlers ********************/ + _converse.api.waitUntil('chatBoxesInitialized').then(() => _converse.chatboxes.on('add', chatbox => { checkOMEMOSupported(chatbox); @@ -1250,12 +1252,6 @@ converse.plugins.add('converse-omemo', { }) ); - _converse.api.listen.on('afterTearDown', () => { - if (_converse.devicelists) { - _converse.devicelists.reset(); - } - delete _converse.omemo_store; - }); _converse.api.listen.on('connected', registerPEPPushHandler); _converse.api.listen.on('renderToolbar', view => view.renderOMEMOToolbarButton()); _converse.api.listen.on('statusInitialized', initOMEMO); @@ -1271,7 +1267,18 @@ converse.plugins.add('converse-omemo', { _converse.generateFingerprints(_converse.bare_jid).catch(_.partial(_converse.log, _, Strophe.LogLevel.ERROR)); }); - /************************ BEGIN API ************************/ + _converse.api.listen.on('afterTearDown', () => (delete _converse.omemo_store)); + + _converse.api.listen.on('clearSession', () => { + if (_converse.shouldClearCache() && _converse.devicelists) { + _converse.devicelists.clearSession(); + delete _converse.devicelists; + } + }); + + + /************************ API ************************/ + Object.assign(_converse.api, { /** * The "omemo" namespace groups methods relevant to OMEMO diff --git a/src/converse-roomslist.js b/src/converse-roomslist.js index 83dcc900a..3d9b4bc09 100644 --- a/src/converse-roomslist.js +++ b/src/converse-roomslist.js @@ -47,7 +47,7 @@ converse.plugins.add('converse-roomslist', { _converse.api.promises.add('roomsListInitialized'); - _converse.OpenRooms = Backbone.Collection.extend({ + _converse.OpenRooms = _converse.Collection.extend({ comparator (room) { if (_converse.bookmarks && room.get('bookmarked')) { diff --git a/src/converse-rosterview.js b/src/converse-rosterview.js index fe92e5169..e4aa5b591 100644 --- a/src/converse-rosterview.js +++ b/src/converse-rosterview.js @@ -290,7 +290,7 @@ converse.plugins.add('converse-rosterview', { }, shouldBeVisible () { - return _converse.roster.length >= 5 || this.isActive(); + return _converse.roster && _converse.roster.length >= 5 || this.isActive(); }, showOrHide () { @@ -859,7 +859,6 @@ converse.plugins.add('converse-rosterview', { }, reset () { - _converse.roster.reset(); this.removeAll(); this.render().update(); return this; @@ -943,7 +942,7 @@ converse.plugins.add('converse-rosterview', { /* -------- Event Handlers ----------- */ _converse.api.listen.on('chatBoxesInitialized', () => { function highlightRosterItem (chatbox) { - const contact = _converse.roster.findWhere({'jid': chatbox.get('jid')}); + const contact = _converse.roster && _converse.roster.findWhere({'jid': chatbox.get('jid')}); if (contact !== undefined) { contact.trigger('highlight'); } diff --git a/src/headless/converse-bookmarks.js b/src/headless/converse-bookmarks.js index 37e86a6fa..92867bb74 100644 --- a/src/headless/converse-bookmarks.js +++ b/src/headless/converse-bookmarks.js @@ -93,7 +93,7 @@ converse.plugins.add('converse-bookmarks', { _converse.Bookmark = Backbone.Model; - _converse.Bookmarks = Backbone.Collection.extend({ + _converse.Bookmarks = _converse.Collection.extend({ model: _converse.Bookmark, comparator: (item) => item.get('name').toLowerCase(), diff --git a/src/headless/converse-bosh.js b/src/headless/converse-bosh.js index 253462ff1..af42e9271 100644 --- a/src/headless/converse-bosh.js +++ b/src/headless/converse-bosh.js @@ -107,6 +107,7 @@ converse.plugins.add('converse-bosh', { sessionStorage.removeItem(`${id}-${id}`); } else { _converse.bosh_session.destroy(); + _converse.bosh_session.browserStorage._clear(); delete _converse.bosh_session; } }); diff --git a/src/headless/converse-chatboxes.js b/src/headless/converse-chatboxes.js index 4ff789088..4f4f6e0b7 100644 --- a/src/headless/converse-chatboxes.js +++ b/src/headless/converse-chatboxes.js @@ -238,7 +238,7 @@ converse.plugins.add('converse-chatboxes', { }); - _converse.Messages = Backbone.Collection.extend({ + _converse.Messages = _converse.Collection.extend({ model: _converse.Message, comparator: 'time' }); @@ -977,7 +977,7 @@ converse.plugins.add('converse-chatboxes', { }); - _converse.ChatBoxes = Backbone.Collection.extend({ + _converse.ChatBoxes = _converse.Collection.extend({ comparator: 'time_opened', model (attrs, options) { diff --git a/src/headless/converse-core.js b/src/headless/converse-core.js index 1103f4909..6291ac43e 100644 --- a/src/headless/converse-core.js +++ b/src/headless/converse-core.js @@ -108,6 +108,15 @@ _converse.VERSION_NAME = "v5.0.0dev"; Object.assign(_converse, Backbone.Events); +_converse.Collection = Backbone.Collection.extend({ + clearSession () { + Array.from(this.models).forEach(m => m.destroy()); + this.browserStorage._clear(); + this.reset(); + } +}); + + // Make converse pluggable pluggable.enable(_converse, '_converse', 'pluggable'); @@ -510,18 +519,23 @@ function reconnect () { const debouncedReconnect = _.debounce(reconnect, 2000); +_converse.shouldClearCache = function () { + return !_converse.config.get('trusted') || _converse.isTestEnv(); +} + function clearSession () { if (_converse.session !== undefined) { _converse.session.destroy(); + _converse.session.browserStorage._clear(); delete _converse.session; } - // TODO: Refactor so that we don't clear - if (!_converse.config.get('trusted') || _converse.isTestEnv()) { - window.localStorage.clear(); - window.sessionStorage.clear(); + if (_converse.shouldClearCache()) { + _converse.xmppstatus.destroy(); + _converse.xmppstatus.browserStorage._clear(); + delete _converse.xmppstatus; } /** - * Triggered once the session information has been cleared, + * Triggered once the user session has been cleared, * for example when the user has logged out or when Converse has * disconnected for some other reason. * @event _converse#clearSession @@ -675,6 +689,29 @@ async function finishInitialization () { } } + +/** + * Properly tear down the session so that it's possible to manually connect again. + * @method finishDisconnection + * @emits _converse#disconnected + * @private + */ +function finishDisconnection () { + _converse.log('DISCONNECTED'); + delete _converse.connection.reconnecting; + _converse.connection.reset(); + tearDown(); + clearSession(); + /** + * Triggered after converse.js has disconnected from the XMPP server. + * @event _converse#disconnected + * @memberOf _converse + * @example _converse.api.listen.on('disconnected', () => { ... }); + */ + _converse.api.trigger('disconnected'); +} + + function fetchLoginCredentials (wait=0) { return new Promise( _.debounce((resolve, reject) => { @@ -937,28 +974,6 @@ _converse.initialize = async function (settings, callback) { }; - /** - * Properly tear down the session so that it's possible to manually connect again. - * @method finishDisconnection - * @private - * @memberOf _converse - */ - this.finishDisconnection = function () { - _converse.log('DISCONNECTED'); - delete _converse.connection.reconnecting; - _converse.connection.reset(); - tearDown(); - clearSession(); - /** - * Triggered after converse.js has disconnected from the XMPP server. - * @event _converse#disconnected - * @memberOf _converse - * @example _converse.api.listen.on('disconnected', () => { ... }); - */ - _converse.api.trigger('disconnected'); - }; - - /** * Gets called once strophe's status reaches Strophe.Status.DISCONNECTED. * Will either start a teardown process for converse.js or attempt @@ -981,14 +996,14 @@ _converse.initialize = async function (settings, callback) { */ return _converse.api.connection.reconnect(); } else { - return _converse.finishDisconnection(); + return finishDisconnection(); } } else if (_converse.disconnection_cause === _converse.LOGOUT || (reason !== undefined && reason === _.get(Strophe, 'ErrorCondition.NO_AUTH_MECH')) || reason === "host-unknown" || reason === "remote-connection-failed" || !_converse.auto_reconnect) { - return _converse.finishDisconnection(); + return finishDisconnection(); } _converse.api.connection.reconnect(); }; @@ -1364,9 +1379,6 @@ _converse.api = { disconnect () { if (_converse.connection) { _converse.connection.disconnect(); - } else { - tearDown(); - clearSession(); } }, @@ -1527,12 +1539,9 @@ _converse.api = { * @example _converse.api.user.logout(); */ logout () { - clearSession(); _converse.setDisconnectionCause(_converse.LOGOUT, undefined, true); if (_converse.connection !== undefined) { _converse.connection.disconnect(); - } else { - tearDown(); } // Recreate all the promises Object.keys(_converse.promises).forEach(addPromise); diff --git a/src/headless/converse-disco.js b/src/headless/converse-disco.js index 2fcb7c2a2..fe6ffaf1d 100644 --- a/src/headless/converse-disco.js +++ b/src/headless/converse-disco.js @@ -43,24 +43,24 @@ converse.plugins.add('converse-disco', { initialize (attrs, options) { this.waitUntilFeaturesDiscovered = utils.getResolveablePromise(); - this.dataforms = new Backbone.Collection(); + this.dataforms = new _converse.Collection(); this.dataforms.browserStorage = new BrowserStorage.session( `converse.dataforms-${this.get('jid')}` ); - this.features = new Backbone.Collection(); + this.features = new _converse.Collection(); this.features.browserStorage = new BrowserStorage.session( `converse.features-${this.get('jid')}` ); this.features.on('add', this.onFeatureAdded, this); - this.fields = new Backbone.Collection(); + this.fields = new _converse.Collection(); this.fields.browserStorage = new BrowserStorage.session( `converse.fields-${this.get('jid')}` ); this.fields.on('add', this.onFieldAdded, this); - this.identities = new Backbone.Collection(); + this.identities = new _converse.Collection(); this.identities.browserStorage = new BrowserStorage.session( `converse.identities-${this.get('jid')}` ); @@ -226,7 +226,7 @@ converse.plugins.add('converse-disco', { } }); - _converse.DiscoEntities = Backbone.Collection.extend({ + _converse.DiscoEntities = _converse.Collection.extend({ model: _converse.DiscoEntity, fetchEntities () { @@ -267,7 +267,7 @@ converse.plugins.add('converse-disco', { const bare_jid = Strophe.getBareJidFromJid(_converse.jid); const id = `converse.stream-features-${bare_jid}`; if (!_converse.stream_features || _converse.stream_features.browserStorage.id !== id) { - _converse.stream_features = new Backbone.Collection(); + _converse.stream_features = new _converse.Collection(); _converse.stream_features.browserStorage = new BrowserStorage.session(id); _converse.stream_features.fetch({ success (collection) { @@ -363,17 +363,20 @@ converse.plugins.add('converse-disco', { _converse.api.listen.on('connected', initializeDisco); _converse.api.listen.on('beforeTearDown', () => { - if (_converse.disco_entities) { - _converse.disco_entities.each((entity) => { - entity.features.reset(); - entity.features.browserStorage._clear(); - }); - _converse.disco_entities.reset(); - _converse.disco_entities.browserStorage._clear(); - } if (_converse.stream_features) { - Array.from(_converse.stream_features.models).forEach(f => f.destroy()); - _converse.stream_features.browserStorage._clear(); + _converse.stream_features.clearSession(); + delete _converse.stream_features; + } + }); + + _converse.api.listen.on('clearSession', () => { + if (_converse.shouldClearCache() && _converse.disco_entities) { + Array.from(_converse.disco_entities.models).forEach(e => e.features.clearSession()); + Array.from(_converse.disco_entities.models).forEach(e => e.identities.clearSession()); + Array.from(_converse.disco_entities.models).forEach(e => e.dataforms.clearSession()); + Array.from(_converse.disco_entities.models).forEach(e => e.fields.clearSession()); + _converse.disco_entities.clearSession(); + delete _converse.disco_entities; } }); diff --git a/src/headless/converse-muc.js b/src/headless/converse-muc.js index 36a6c368d..91adbf4fb 100644 --- a/src/headless/converse-muc.js +++ b/src/headless/converse-muc.js @@ -331,7 +331,7 @@ converse.plugins.add('converse-muc', { * @namespace _converse.ChatRoomMessages * @memberOf _converse */ - _converse.ChatRoomMessages = Backbone.Collection.extend({ + _converse.ChatRoomMessages = _converse.Collection.extend({ model: _converse.ChatRoomMessage, comparator: 'time' }); @@ -609,6 +609,16 @@ converse.plugins.add('converse-muc', { this.removeHandlers(); }, + close () { + try { + this.features.destroy(); + this.features.browserStorage._clear(); + } catch (e) { + _converse.log(e, Strophe.LogLevel.ERROR); + } + return _converse.ChatBox.prototype.close.call(this); + }, + sendUnavailablePresence (exit_msg) { const presence = $pres({ type: "unavailable", @@ -1908,7 +1918,7 @@ converse.plugins.add('converse-muc', { }); - _converse.ChatRoomOccupants = Backbone.Collection.extend({ + _converse.ChatRoomOccupants = _converse.Collection.extend({ model: _converse.ChatRoomOccupant, comparator (occupant1, occupant2) { diff --git a/src/headless/converse-roster.js b/src/headless/converse-roster.js index 0ba902cf7..08542bf1d 100644 --- a/src/headless/converse-roster.js +++ b/src/headless/converse-roster.js @@ -141,7 +141,7 @@ converse.plugins.add('converse-roster', { }; const Resource = Backbone.Model.extend({'idAttribute': 'name'}); - const Resources = Backbone.Collection.extend({'model': Resource}); + const Resources = _converse.Collection.extend({'model': Resource}); _converse.Presence = Backbone.Model.extend({ @@ -216,7 +216,7 @@ converse.plugins.add('converse-roster', { }); - _converse.Presences = Backbone.Collection.extend({ + _converse.Presences = _converse.Collection.extend({ model: _converse.Presence, }); @@ -393,7 +393,7 @@ converse.plugins.add('converse-roster', { * @namespace _converse.RosterContacts * @memberOf _converse */ - _converse.RosterContacts = Backbone.Collection.extend({ + _converse.RosterContacts = _converse.Collection.extend({ model: _converse.RosterContact, comparator (contact1, contact2) { @@ -861,7 +861,7 @@ converse.plugins.add('converse-roster', { }); - _converse.RosterGroups = Backbone.Collection.extend({ + _converse.RosterGroups = _converse.Collection.extend({ model: _converse.RosterGroup, comparator (a, b) { @@ -907,9 +907,10 @@ converse.plugins.add('converse-roster', { }; - /********** Event Handlers *************/ + /******************** Event Handlers ********************/ + function updateUnreadCounter (chatbox) { - const contact = _converse.roster.findWhere({'jid': chatbox.get('jid')}); + const contact = _converse.roster && _converse.roster.findWhere({'jid': chatbox.get('jid')}); if (contact !== undefined) { contact.save({'num_unread': chatbox.get('num_unread')}); } @@ -946,12 +947,27 @@ converse.plugins.add('converse-roster', { p.save({'show': 'offline'}, {'silent': true}) }); } + if (_converse.roster) { + _converse.roster.reset(); + } }); _converse.api.listen.on('clearSession', () => { if (_converse.presences) { _converse.presences.browserStorage._clear(); } + if (_converse.shouldClearCache()) { + if (_converse.roster) { + _.invoke(_converse, 'roster.data.destroy'); + _.invoke(_converse, 'roster.data.browserStorage._clear'); + _converse.roster.clearSession(); + delete _converse.roster; + } + if (_converse.rostergroups) { + _converse.rostergroups.clearSession(); + delete _converse.rostergroups; + } + } }); _converse.api.listen.on('statusInitialized', (reconnecting) => { diff --git a/src/headless/converse-vcard.js b/src/headless/converse-vcard.js index 39b84f1fa..fcd8a22bc 100644 --- a/src/headless/converse-vcard.js +++ b/src/headless/converse-vcard.js @@ -53,7 +53,7 @@ converse.plugins.add('converse-vcard', { }); - _converse.VCards = Backbone.Collection.extend({ + _converse.VCards = _converse.Collection.extend({ model: _converse.VCard, initialize () { @@ -138,6 +138,13 @@ converse.plugins.add('converse-vcard', { } }); + _converse.api.listen.on('clearSession', () => { + if (_converse.shouldClearCache() && _converse.vcards) { + _converse.vcards.clearSession(); + delete _converse.vcards; + } + }); + _converse.api.listen.on('addClientFeatures', () => _converse.api.disco.own.features.add(Strophe.NS.VCARD));