diff --git a/dev.html b/dev.html
index d5d0e59bd..94511dedc 100644
--- a/dev.html
+++ b/dev.html
@@ -41,6 +41,7 @@
'discuss@conference.conversejs.org'
],
enable_smacks: true,
+ persistent_store: 'IndexedDB',
muc_respect_autojoin: true,
message_archiving: 'always',
loglevel: 'debug'
diff --git a/spec/login.js b/spec/login.js
index ca8350700..7cc47fd31 100644
--- a/spec/login.js
+++ b/spec/login.js
@@ -29,9 +29,9 @@
spyOn(cbview.loginpanel, 'connect');
cbview.delegateEvents();
- expect(_converse.config.get('storage')).toBe('local');
+ expect(_converse.config.get('storage')).toBe('persistent');
cbview.el.querySelector('input[type="submit"]').click();
- expect(_converse.config.get('storage')).toBe('local');
+ expect(_converse.config.get('storage')).toBe('persistent');
expect(cbview.loginpanel.connect).toHaveBeenCalled();
checkbox.click();
@@ -72,7 +72,7 @@
checkbox.click();
cbview.el.querySelector('input[type="submit"]').click();
- expect(_converse.config.get('storage')).toBe('local');
+ expect(_converse.config.get('storage')).toBe('persistent');
done();
});
}));
diff --git a/src/converse-controlbox.js b/src/converse-controlbox.js
index 990d3028a..b63c11516 100644
--- a/src/converse-controlbox.js
+++ b/src/converse-controlbox.js
@@ -442,12 +442,12 @@ converse.plugins.add('converse-controlbox', {
if (_converse.trusted === 'on' || _converse.trusted === 'off') {
_converse.config.save({
'trusted': _converse.trusted === 'on',
- 'storage': _converse.trusted === 'on' ? 'local' : 'session'
+ 'storage': _converse.trusted === 'on' ? 'persistent' : 'session'
});
} else {
_converse.config.save({
'trusted': form_data.get('trusted') && true || false,
- 'storage': form_data.get('trusted') ? 'local' : 'session'
+ 'storage': form_data.get('trusted') ? 'persistent' : 'session'
});
}
diff --git a/src/converse-minimize.js b/src/converse-minimize.js
index 215ec4a18..28345798b 100644
--- a/src/converse-minimize.js
+++ b/src/converse-minimize.js
@@ -471,12 +471,11 @@ converse.plugins.add('converse-minimize', {
},
initToggle () {
- const storage = _converse.config.get('storage'),
- id = `converse.minchatstoggle-${_converse.bare_jid}`;
+ const id = `converse.minchatstoggle-${_converse.bare_jid}`;
this.toggleview = new _converse.MinimizedChatsToggleView({
'model': new _converse.MinimizedChatsToggle({'id': id})
});
- this.toggleview.model.browserStorage = _converse.createStore(id, storage);
+ this.toggleview.model.browserStorage = _converse.createStore(id);
this.toggleview.model.fetch();
},
@@ -568,22 +567,22 @@ converse.plugins.add('converse-minimize', {
}
});
- /************************ BEGIN Event Handlers ************************/
- _converse.api.waitUntil('chatBoxViewsInitialized').then(() => {
- _converse.minimized_chats = new _converse.MinimizedChats({
- model: _converse.chatboxes
- });
+ function initMinimizedChats () {
+ _converse.minimized_chats = new _converse.MinimizedChats({model: _converse.chatboxes});
/**
* Triggered once the _converse.MinimizedChats instance has been * initialized
* @event _converse#minimizedChatsInitialized
* @example _converse.api.listen.on('minimizedChatsInitialized', () => { ... });
*/
_converse.api.trigger('minimizedChatsInitialized');
- }).catch(e => log.fatal(e));
+ }
- const debouncedTrimChats = _.debounce(() => _converse.chatboxviews.trimChats(), 250);
+ /************************ BEGIN Event Handlers ************************/
+ _converse.api.listen.on('userSessionInitialized', () => initMinimizedChats());
_converse.api.listen.on('chatBoxInsertedIntoDOM', view => _converse.chatboxviews.trimChats(view));
_converse.api.listen.on('controlBoxOpened', view => _converse.chatboxviews.trimChats(view));
+
+ const debouncedTrimChats = _.debounce(() => _converse.chatboxviews.trimChats(), 250);
_converse.api.listen.on('registeredGlobalEventHandlers', () => window.addEventListener("resize", debouncedTrimChats));
_converse.api.listen.on('unregisteredGlobalEventHandlers', () => window.removeEventListener("resize", debouncedTrimChats));
/************************ END Event Handlers ************************/
diff --git a/src/converse-muc-views.js b/src/converse-muc-views.js
index af000fd3b..3304909ba 100644
--- a/src/converse-muc-views.js
+++ b/src/converse-muc-views.js
@@ -131,7 +131,7 @@ converse.plugins.add('converse-muc-views', {
this.roomspanel = new _converse.RoomsPanel({
'model': new (_converse.RoomsPanelModel.extend({
id,
- 'browserStorage': _converse.createStore(id, _converse.config.get('storage'))
+ 'browserStorage': _converse.createStore(id)
}))()
});
this.roomspanel.model.fetch();
diff --git a/src/headless/converse-bookmarks.js b/src/headless/converse-bookmarks.js
index ba0677550..9d33ec73a 100644
--- a/src/headless/converse-bookmarks.js
+++ b/src/headless/converse-bookmarks.js
@@ -112,10 +112,9 @@ converse.plugins.add('converse-bookmarks', {
this.on('remove', this.markRoomAsUnbookmarked, this);
this.on('remove', this.sendBookmarkStanza, this);
- const storage = _converse.config.get('storage');
const cache_key = `converse.room-bookmarks${_converse.bare_jid}`;
this.fetched_flag = cache_key+'fetched';
- this.browserStorage = _converse.createStore(cache_key, storage);
+ this.browserStorage = _converse.createStore(cache_key);
},
async openBookmarkedRoom (bookmark) {
diff --git a/src/headless/converse-core.js b/src/headless/converse-core.js
index 89131d14f..574f35d11 100644
--- a/src/headless/converse-core.js
+++ b/src/headless/converse-core.js
@@ -359,33 +359,34 @@ _converse.isUniView = function () {
};
-async function initStorage () {
+async function initSessionStorage () {
await BrowserStorage.sessionStorageInitialized;
-
- // Sets up Backbone.BrowserStorage and localForage for the 3 different stores.
- _converse.localStorage = BrowserStorage.localForage.createInstance({
- 'name': 'local',
- 'description': 'localStorage instance',
- 'driver': [BrowserStorage.localForage.LOCALSTORAGE]
- });
-
- _converse.indexedDB = BrowserStorage.localForage.createInstance({
- 'name': 'indexed',
- 'description': 'indexedDB instance',
- 'driver': [BrowserStorage.localForage.INDEXEDDB]
- });
-
- _converse.sessionStorage = BrowserStorage.localForage.createInstance({
- 'name': 'session',
- 'description': 'sessionStorage instance',
- 'driver': ['sessionStorageWrapper']
- });
-
_converse.storage = {
- 'session': _converse.sessionStorage,
- 'local': _converse.localStorage,
- 'indexed': _converse.indexedDB
+ 'session': BrowserStorage.localForage.createInstance({
+ 'name': _converse.isTestEnv() ? 'converse-test-session' : 'converse-session',
+ 'description': 'sessionStorage instance',
+ 'driver': ['sessionStorageWrapper']
+ })
+ };
+}
+
+
+function initPersistentStorage () {
+ if (_converse.config.get('storage') !== 'persistent') {
+ return;
}
+ const config = {
+ 'name': _converse.isTestEnv() ? 'converse-test-persistent' : 'converse-persistent',
+ 'storeName': _converse.bare_jid
+ }
+ if (_converse.persistent_store === 'localStorage') {
+ config['description'] = 'localStorage instance';
+ config['driver'] = [BrowserStorage.localForage.LOCALSTORAGE];
+ } else if (_converse.persistent_store === 'IndexedDB') {
+ config['description'] = 'indexedDB instance';
+ config['driver'] = [BrowserStorage.localForage.INDEXEDDB];
+ }
+ _converse.storage['persistent'] = BrowserStorage.localForage.createInstance(config);
}
@@ -447,11 +448,10 @@ function initClientConfig () {
* user sessions.
*/
const id = 'converse.client-config';
- const store_map = { 'localStorage': 'local', 'IndexedDB': 'indexed' };
_converse.config = new Backbone.Model({
'id': id,
'trusted': _converse.trusted && true || false,
- 'storage': _converse.trusted ? store_map[_converse.persistent_store] : 'session'
+ 'storage': _converse.trusted ? 'persistent' : 'session'
});
_converse.config.browserStorage = _converse.createStore(id, "session");
_converse.config.fetch();
@@ -684,6 +684,7 @@ async function initSession (jid) {
_converse.session.save({id});
}
saveJIDtoSession(jid);
+ initPersistentStorage();
/**
* Triggered once the user's session has been initialized. The session is a
* cache which stores information about the user's current session.
@@ -831,7 +832,7 @@ function setUpXMLLogging () {
async function finishInitialization () {
- await initStorage();
+ await initSessionStorage();
initClientConfig();
initPlugins();
registerGlobalEventHandlers();
@@ -976,15 +977,10 @@ function unregisterGlobalEventHandlers () {
_converse.api.trigger('unregisteredGlobalEventHandlers');
}
-async function cleanup () {
+
+function cleanup () {
// Make sure everything is reset in case this is a subsequent call to
// convesre.initialize (happens during tests).
- if (_converse.localStorage) {
- await Promise.all([
- BrowserStorage.localForage.dropInstance({'name': 'local'}),
- BrowserStorage.localForage.dropInstance({'name': 'indexed'}),
- BrowserStorage.localForage.dropInstance({'name': 'session'})]);
- }
Backbone.history.stop();
unregisterGlobalEventHandlers();
delete _converse.controlboxtoggle;
@@ -1000,7 +996,7 @@ async function cleanup () {
_converse.initialize = async function (settings, callback) {
- await cleanup();
+ cleanup();
settings = settings !== undefined ? settings : {};
PROMISES.forEach(addPromise);
@@ -1802,7 +1798,7 @@ Object.assign(window.converse, {
* @property {function} converse.env.sizzle - [Sizzle](https://sizzlejs.com) CSS selector engine.
* @property {object} converse.env.utils - Module containing common utility methods used by Converse.
*/
- 'env': { $build, $iq, $msg, $pres, Backbone, Promise, Strophe, _, dayjs, log, sizzle, stanza_utils, u, 'utils': u }
+ 'env': { $build, $iq, $msg, $pres, Backbone, BrowserStorage, Promise, Strophe, _, dayjs, log, sizzle, stanza_utils, u, 'utils': u }
});
/**
diff --git a/src/headless/converse-disco.js b/src/headless/converse-disco.js
index 8057acee7..c5cb8f7f6 100644
--- a/src/headless/converse-disco.js
+++ b/src/headless/converse-disco.js
@@ -236,7 +236,8 @@ converse.plugins.add('converse-disco', {
this.fetch({
add: true,
success: resolve,
- error () {
+ error (m, e) {
+ log.error(e);
reject (new Error("Could not fetch disco entities"));
}
});
diff --git a/src/headless/converse-roster.js b/src/headless/converse-roster.js
index d3dca0562..87f061b3b 100644
--- a/src/headless/converse-roster.js
+++ b/src/headless/converse-roster.js
@@ -970,20 +970,19 @@ converse.plugins.add('converse-roster', {
// Initialize the Bakcbone collections that represent the contats
// roster and the roster groups.
await _converse.api.waitUntil('VCardsInitialized');
- const storage = _converse.config.get('storage');
_converse.roster = new _converse.RosterContacts();
let id = `converse.contacts-${_converse.bare_jid}`;
- _converse.roster.browserStorage = _converse.createStore(id, storage);
+ _converse.roster.browserStorage = _converse.createStore(id);
_converse.roster.data = new Backbone.Model();
id = `converse-roster-model-${_converse.bare_jid}`;
_converse.roster.data.id = id;
- _converse.roster.data.browserStorage = _converse.createStore(id, storage);
+ _converse.roster.data.browserStorage = _converse.createStore(id);
_converse.roster.data.fetch();
id = `converse.roster.groups${_converse.bare_jid}`;
_converse.rostergroups = new _converse.RosterGroups();
- _converse.rostergroups.browserStorage = _converse.createStore(id, storage);
+ _converse.rostergroups.browserStorage = _converse.createStore(id);
/**
* Triggered once the `_converse.RosterContacts` and `_converse.RosterGroups` have
* been created, but not yet populated with data.
diff --git a/tests/mock.js b/tests/mock.js
index 47328961a..b9bd1af56 100644
--- a/tests/mock.js
+++ b/tests/mock.js
@@ -5,6 +5,7 @@
converse.load();
const _ = converse.env._;
+ const u = converse.env.utils;
const Promise = converse.env.Promise;
const Strophe = converse.env.Strophe;
const dayjs = converse.env.dayjs;
@@ -220,9 +221,30 @@
Strophe.Connection = MockConnection;
+ function clearIndexedDB () {
+ const promise = u.getResolveablePromise();
+ const DBOpenRequest = window.indexedDB.open("converse-test-persistent");
+ DBOpenRequest.onsuccess = function () {
+ const db = DBOpenRequest.result;
+ const bare_jid = "romeo@montague.lit";
+ const objectStore = db.transaction([bare_jid], "readwrite").objectStore(bare_jid);
+ const objectStoreRequest = objectStore.clear();
+ objectStoreRequest.onsuccess = promise.resolve();
+ objectStoreRequest.onerror = promise.resolve();
+ };
+ return promise;
+ }
+
+ function clearStores () {
+ [localStorage, sessionStorage].forEach(
+ s => Object.keys(s).forEach(k => k.match(/^converse-test-/) && s.removeItem(k))
+ );
+ }
+
+
async function initConverse (settings) {
- window.localStorage.clear();
- window.sessionStorage.clear();
+ clearStores();
+ await clearIndexedDB();
const _converse = await converse.initialize(Object.assign({
'animate': false,
@@ -230,6 +252,7 @@
'bosh_service_url': 'montague.lit/http-bind',
'enable_smacks': false,
'i18n': 'en',
+ // 'persistent_store': 'IndexedDB',
'loglevel': 'warn',
'no_trimming': true,
'play_sounds': false,
@@ -282,6 +305,7 @@
promise_names = []
settings = null;
}
+
return async done => {
const _converse = await initConverse(settings);
async function _done () {
@@ -301,7 +325,7 @@
} catch(e) {
console.error(e);
fail(e);
- _done();
+ await _done();
}
}
};