Browse Source

Add Skeletor as dependency

JC Brand 5 years ago
parent
commit
a8104d7498

+ 1 - 1
.eslintrc.json

@@ -248,7 +248,7 @@
         "rest-spread-spacing": "error",
         "semi": "off",
         "semi-spacing": "off",
-        "sort-imports": "error",
+        "sort-imports": "off",
         "sort-keys": "off",
         "sort-vars": "off",
         "space-before-blocks": "off",

+ 1 - 0
.nvmrc

@@ -0,0 +1 @@
+v12.13.1

File diff suppressed because it is too large
+ 266 - 190
package-lock.json


+ 2 - 1
package.json

@@ -87,7 +87,7 @@
     "install": "^0.9.5",
     "jasmine-core": "2.99.1",
     "jsdoc": "^3.6.2",
-    "lerna": "^3.19.0",
+    "lerna": "^3.20.2",
     "lodash-template-webpack-loader": "jcbrand/lodash-template-webpack-loader",
     "mini-css-extract-plugin": "^0.7.0",
     "minimist": "^1.2.0",
@@ -106,6 +106,7 @@
     "snabbdom": "^0.7.3",
     "style-loader": "^0.23.1",
     "uglify-es": "^3.3.9",
+    "uglify-js": "^3.7.4",
     "urijs": "^1.19.1",
     "webpack": "^4.35.3",
     "webpack-cli": "^3.3.5",

+ 2 - 2
spec/mam.js

@@ -2,7 +2,7 @@
     define(["jasmine", "mock", "test-utils"], factory);
 } (this, function (jasmine, mock, test_utils) {
     "use strict";
-    const Backbone = converse.env.Backbone;
+    const Model = converse.env.Model;
     const Strophe = converse.env.Strophe;
     const $iq = converse.env.$iq;
     const $msg = converse.env.$msg;
@@ -865,7 +865,7 @@
                 spyOn(_converse, 'onMAMPreferences').and.callThrough();
                 _converse.message_archiving = 'never';
 
-                const feature = new Backbone.Model({
+                const feature = new Model({
                     'var': Strophe.NS.MAM
                 });
                 spyOn(feature, 'save').and.callFake(feature.set); // Save will complain about a url not being set

+ 7 - 7
spec/muc.js

@@ -5,11 +5,11 @@
           $pres = converse.env.$pres,
           $iq = converse.env.$iq,
           $msg = converse.env.$msg,
+          Model = converse.env.Model,
           Strophe = converse.env.Strophe,
           Promise = converse.env.Promise,
           dayjs = converse.env.dayjs,
           sizzle = converse.env.sizzle,
-          Backbone = converse.env.Backbone,
           u = converse.env.utils;
 
     describe("Groupchats", function () {
@@ -115,14 +115,14 @@
 
                 let room = await _converse.api.rooms.open(jid);
                 // Test on groupchat that's not yet open
-                expect(room instanceof Backbone.Model).toBeTruthy();
+                expect(room instanceof Model).toBeTruthy();
                 chatroomview = _converse.chatboxviews.get(jid);
                 expect(chatroomview.is_chatroom).toBeTruthy();
                 await u.waitUntil(() => u.isVisible(chatroomview.el));
 
                 // Test again, now that the room exists.
                 room = await _converse.api.rooms.open(jid);
-                expect(room instanceof Backbone.Model).toBeTruthy();
+                expect(room instanceof Model).toBeTruthy();
                 chatroomview = _converse.chatboxviews.get(jid);
                 expect(chatroomview.is_chatroom).toBeTruthy();
                 expect(u.isVisible(chatroomview.el)).toBeTruthy();
@@ -131,19 +131,19 @@
                 // Test with mixed case in JID
                 jid = 'Leisure@montague.lit';
                 room = await _converse.api.rooms.open(jid);
-                expect(room instanceof Backbone.Model).toBeTruthy();
+                expect(room instanceof Model).toBeTruthy();
                 chatroomview = _converse.chatboxviews.get(jid.toLowerCase());
                 await u.waitUntil(() => u.isVisible(chatroomview.el));
 
                 jid = 'leisure@montague.lit';
                 room = await _converse.api.rooms.open(jid);
-                expect(room instanceof Backbone.Model).toBeTruthy();
+                expect(room instanceof Model).toBeTruthy();
                 chatroomview = _converse.chatboxviews.get(jid.toLowerCase());
                 await u.waitUntil(() => u.isVisible(chatroomview.el));
 
                 jid = 'leiSure@montague.lit';
                 room = await _converse.api.rooms.open(jid);
-                expect(room instanceof Backbone.Model).toBeTruthy();
+                expect(room instanceof Model).toBeTruthy();
                 chatroomview = _converse.chatboxviews.get(jid.toLowerCase());
                 await u.waitUntil(() => u.isVisible(chatroomview.el));
                 chatroomview.close();
@@ -167,7 +167,7 @@
                         'whois': 'anyone'
                     }
                 });
-                expect(room instanceof Backbone.Model).toBeTruthy();
+                expect(room instanceof Model).toBeTruthy();
                 chatroomview = _converse.chatboxviews.get('room@conference.example.org');
 
                 // We pretend this is a new room, so no disco info is returned.

+ 1 - 1
spec/spoilers.js

@@ -74,7 +74,7 @@
             const view = _converse.chatboxviews.get(sender_jid);
             await u.waitUntil(() => u.isVisible(view.el));
             await u.waitUntil(() => view.model.vcard.get('fullname') === 'Mercutio')
-            expect(_.includes(view.el.querySelector('.chat-msg__author').textContent, 'Mercutio')).toBeTruthy();
+            expect(view.el.querySelector('.chat-msg__author').textContent.includes('Mercutio')).toBeTruthy();
             const message_content = view.el.querySelector('.chat-msg__text');
             expect(message_content.textContent).toBe(spoiler);
             const spoiler_hint_el = view.el.querySelector('.spoiler-hint');

+ 7 - 10
src/converse-autocomplete.js

@@ -1,18 +1,15 @@
-// Converse.js
-// https://conversejs.org
-//
-// Copyright (c) 2013-2019, the Converse.js developers
-// Licensed under the Mozilla Public License (MPLv2)
-
 /**
  * @module converse-autocomplete
+ * @copyright Lea Verou and the Converse.js developers
  * @description
- * Converse.js plugin which started as a fork of Lea Verou's Awesomplete
- * https://leaverou.github.io/awesomplete/
+ *  Converse.js plugin which started as a fork of Lea Verou's Awesomplete
+ *  https://leaverou.github.io/awesomplete/
+ * @license Mozilla Public License (MPLv2)
  */
+import { Events } from 'skeletor.js/src/events.js';
 import converse from "@converse/headless/converse-core";
 
-const { _, Backbone } = converse.env,
+const { _ } = converse.env,
       u = converse.env.utils;
 
 converse.plugins.add("converse-autocomplete", {
@@ -375,7 +372,7 @@ converse.plugins.add("converse-autocomplete", {
         }
 
         // Make it an event emitter
-        Object.assign(AutoComplete.prototype, Backbone.Events);
+        Object.assign(AutoComplete.prototype, Events);
 
 
         const helpers = {

+ 2 - 2
src/converse-bookmark-views.js

@@ -9,8 +9,8 @@
  * @description
  * Converse.js plugin which adds views for XEP-0048 bookmarks
  */
-import "backbone.nativeview";
 import "@converse/headless/converse-muc";
+import { Model } from 'skeletor.js/src/model.js';
 import converse from "@converse/headless/converse-core";
 import tpl_bookmarks_list from "templates/bookmarks_list.html"
 import tpl_chatroom_bookmark_form from "templates/chatroom_bookmark_form.html";
@@ -82,7 +82,7 @@ converse.plugins.add('converse-bookmark-views', {
                 const name = ev.target.getAttribute('data-bookmark-name');
                 const jid = ev.target.getAttribute('data-room-jid');
                 if (confirm(__("Are you sure you want to remove the bookmark \"%1$s\"?", name))) {
-                    _.invokeMap(_converse.bookmarks.where({'jid': jid}), Backbone.Model.prototype.destroy);
+                    _.invokeMap(_converse.bookmarks.where({'jid': jid}), Model.prototype.destroy);
                 }
             },
 

+ 3 - 2
src/converse-chatboxviews.js

@@ -9,7 +9,8 @@
  */
 import "@converse/headless/converse-chatboxes";
 import "backbone.nativeview";
-import { Overview } from "backbone.overview";
+import { Overview } from "skeletor.js/src/overview";
+import { View } from "skeletor.js/src/view";
 import converse from "@converse/headless/converse-core";
 import tpl_avatar from "templates/avatar.svg";
 import tpl_background_logo from "templates/background_logo.html";
@@ -63,7 +64,7 @@ converse.plugins.add('converse-chatboxviews', {
             'theme': 'default'
         });
 
-        _converse.ViewWithAvatar = Backbone.NativeView.extend(AvatarMixin);
+        _converse.ViewWithAvatar = View.extend(AvatarMixin);
         _converse.VDOMViewWithAvatar = Backbone.VDOMView.extend(AvatarMixin);
 
 

+ 3 - 3
src/converse-chatview.js

@@ -7,12 +7,12 @@
 /**
  * @module converse-chatview
  */
-import "backbone.nativeview";
 import "converse-chatboxviews";
 import "converse-message-view";
 import "converse-modal";
 import { debounce, get, isString } from "lodash";
-import { Overview } from "backbone.overview";
+import { Overview } from "skeletor.js/src/overview";
+import { View } from "skeletor.js/src/view";
 import converse from "@converse/headless/converse-core";
 import log from "@converse/headless/log";
 import tpl_chatbox from "templates/chatbox.html";
@@ -1173,7 +1173,7 @@ converse.plugins.add('converse-chatview', {
 
             async close (ev) {
                 if (ev && ev.preventDefault) { ev.preventDefault(); }
-                if (Backbone.history.getFragment() === "converse/chat?jid="+this.model.get('jid')) {
+                if (_converse.router.history.getFragment() === "converse/chat?jid="+this.model.get('jid')) {
                     _converse.router.navigate('');
                 }
                 if (_converse.api.connection.connected()) {

+ 6 - 4
src/converse-controlbox.js

@@ -12,6 +12,8 @@ import "formdata-polyfill";
 import bootstrap from "bootstrap.native";
 import converse from "@converse/headless/converse-core";
 import { get } from "lodash";
+import { Model } from 'skeletor.js/src/model.js';
+import { View } from "skeletor.js/src/view";
 import log from "@converse/headless/log";
 import tpl_brand_heading from "templates/converse_brand_heading.html";
 import tpl_controlbox from "templates/controlbox.html";
@@ -355,7 +357,7 @@ converse.plugins.add('converse-controlbox', {
             }
         });
 
-        _converse.LoginPanelModel = Backbone.Model.extend({
+        _converse.LoginPanelModel = Model.extend({
             defaults: {
                 // Passed-by-reference. Fine in this case because there's
                 // only one such model.
@@ -467,7 +469,7 @@ converse.plugins.add('converse-controlbox', {
             },
 
             connect (jid, password) {
-                if (["converse/login", "converse/register"].includes(Backbone.history.getFragment())) {
+                if (["converse/login", "converse/register"].includes(_converse.router.history.getFragment())) {
                     _converse.router.navigate('', {'replace': true});
                 }
                 _converse.connection && _converse.connection.reset();
@@ -476,7 +478,7 @@ converse.plugins.add('converse-controlbox', {
         });
 
 
-        _converse.ControlBoxPane = Backbone.NativeView.extend({
+        _converse.ControlBoxPane = View.extend({
             tagName: 'div',
             className: 'controlbox-pane',
 
@@ -492,7 +494,7 @@ converse.plugins.add('converse-controlbox', {
         });
 
 
-        _converse.ControlBoxToggle = Backbone.NativeView.extend({
+        _converse.ControlBoxToggle = View.extend({
             tagName: 'a',
             className: 'toggle-controlbox hidden',
             id: 'toggle-controlbox',

+ 6 - 4
src/converse-minimize.js

@@ -7,7 +7,9 @@
  * @module converse-minimize
  */
 import "converse-chatview";
-import { Overview } from "backbone.overview";
+import { Model } from 'skeletor.js/src/model.js';
+import { Overview } from "skeletor.js/src/overview";
+import { View } from "skeletor.js/src/view";
 import converse from "@converse/headless/converse-core";
 import tpl_chatbox_minimize from "templates/chatbox_minimize.html";
 import tpl_chats_panel from "templates/chats_panel.html";
@@ -382,7 +384,7 @@ converse.plugins.add('converse-minimize', {
 
         _converse.api.promises.add('minimizedChatsInitialized');
 
-        _converse.MinimizedChatBoxView = Backbone.NativeView.extend({
+        _converse.MinimizedChatBoxView = View.extend({
             tagName: 'div',
             events: {
                 'click .close-chatbox-button': 'close',
@@ -531,7 +533,7 @@ converse.plugins.add('converse-minimize', {
         });
 
 
-        _converse.MinimizedChatsToggle = Backbone.Model.extend({
+        _converse.MinimizedChatsToggle = Model.extend({
             defaults: {
                 'collapsed': false,
                 'num_minimized': 0,
@@ -540,7 +542,7 @@ converse.plugins.add('converse-minimize', {
         });
 
 
-        _converse.MinimizedChatsToggleView = Backbone.NativeView.extend({
+        _converse.MinimizedChatsToggleView = View.extend({
             _setElement (){
                 this.el = _converse.root.querySelector('#toggle-minimized-chats');
             },

+ 4 - 3
src/converse-modal.js

@@ -9,6 +9,7 @@
 import "backbone.vdomview";
 import bootstrap from "bootstrap.native";
 import converse from "@converse/headless/converse-core";
+import { Model } from 'skeletor.js/src/model.js';
 import { isString } from "lodash";
 import tpl_alert from "templates/alert.html";
 import tpl_alert_modal from "templates/alert_modal.html";
@@ -170,7 +171,7 @@ converse.plugins.add('converse-modal', {
                     messages = [messages];
                 }
                 if (confirm === undefined) {
-                    const model = new Backbone.Model({
+                    const model = new Model({
                         'title': title,
                         'messages': messages,
                         'type': 'confirm'
@@ -206,7 +207,7 @@ converse.plugins.add('converse-modal', {
                     messages = [messages];
                 }
                 if (prompt === undefined) {
-                    const model = new Backbone.Model({
+                    const model = new Model({
                         'title': title,
                         'messages': messages,
                         'placeholder': placeholder,
@@ -250,7 +251,7 @@ converse.plugins.add('converse-modal', {
                 }
 
                 if (alert === undefined) {
-                    const model = new Backbone.Model({
+                    const model = new Model({
                         'title': title,
                         'messages': messages,
                         'level': level,

+ 9 - 7
src/converse-muc-views.js

@@ -9,7 +9,9 @@ import "backbone.vdomview";
 import "formdata-polyfill";
 import "@converse/headless/utils/muc";
 import { get, head, isString, isUndefined, pick } from "lodash";
-import { OrderedListView } from "backbone.overview";
+import { Model } from 'skeletor.js/src/model.js';
+import { OrderedListView } from "skeletor.js/src/overview";
+import { View } from "skeletor.js/src/view";
 import converse from "@converse/headless/converse-core";
 import log from "@converse/headless/log";
 import tpl_add_chatroom_modal from "templates/add_chatroom_modal.html";
@@ -638,7 +640,7 @@ converse.plugins.add('converse-muc-views', {
 
 
         /**
-         * Backbone.NativeView which renders a groupchat, based upon
+         * NativeView which renders a groupchat, based upon
          * { @link _converse.ChatBoxView } for normal one-on-one chat boxes.
          * @class
          * @namespace _converse.ChatRoomView
@@ -1032,7 +1034,7 @@ converse.plugins.add('converse-muc-views', {
                     return;
                 }
                 if (isUndefined(this.model.modtools_modal)) {
-                    const model = new Backbone.Model({'affiliation': affiliation});
+                    const model = new Model({'affiliation': affiliation});
                     this.modtools_modal = new _converse.ModeratorToolsModal({'model': model, 'chatroomview': this});
                 } else {
                     this.modtools_modal.set('affiliation', affiliation);
@@ -1188,7 +1190,7 @@ converse.plugins.add('converse-muc-views', {
              */
             async close () {
                 this.hide();
-                if (Backbone.history.getFragment() === "converse/room?jid="+this.model.get('jid')) {
+                if (_converse.router.history.getFragment() === "converse/room?jid="+this.model.get('jid')) {
                     _converse.router.navigate('');
                 }
                 await this.model.leave();
@@ -1642,7 +1644,7 @@ converse.plugins.add('converse-muc-views', {
 
                 if (!this.password_form) {
                     this.password_form = new _converse.MUCPasswordForm({
-                        'model': new Backbone.Model({
+                        'model': new Model({
                             'validation_message': message
                         }),
                         'chatroomview': this,
@@ -2003,12 +2005,12 @@ converse.plugins.add('converse-muc-views', {
 
 
         /**
-         * Backbone.NativeView which renders MUC section of the control box.
+         * View which renders MUC section of the control box.
          * @class
          * @namespace _converse.RoomsPanel
          * @memberOf _converse
          */
-        _converse.RoomsPanel = Backbone.NativeView.extend({
+        _converse.RoomsPanel = View.extend({
             tagName: 'div',
             className: 'controlbox-section',
             id: 'chatrooms',

+ 6 - 4
src/converse-oauth.js

@@ -4,6 +4,8 @@
 // Copyright (c) 2013-2019, the Converse.js developers
 // Licensed under the Mozilla Public License (MPLv2)
 
+import { Collection } from "skeletor.js/src/collection";
+import { Model } from 'skeletor.js/src/model.js';
 import converse from "@converse/headless/converse-core";
 import hello from "hellojs";
 import tpl_oauth_providers from "templates/oauth_providers.html";
@@ -28,8 +30,8 @@ converse.plugins.add("converse-oauth", {
      */
     'optional_dependencies': ['converse-register'],
 
-    /* If you want to override some function or a Backbone model or
-     * view defined elsewhere in converse.js, then you do that under
+    /* If you want to override some function or a Model or
+     * View defined elsewhere in converse.js, then you do that under
      * the "overrides" namespace.
      */
     'overrides': {
@@ -75,12 +77,12 @@ converse.plugins.add("converse-oauth", {
             'oauth_providers': {},
         });
 
-        _converse.OAuthProviders = _converse.Collection.extend({
+        _converse.OAuthProviders = Collection.extend({
             'sync': function sync () {},
 
             initialize () {
                 _converse.user_settings.oauth_providers.forEach(provider => {
-                    const item = new Backbone.Model(Object.assign(provider, {
+                    const item = new Model(Object.assign(provider, {
                         'login_text': __('Log in with %1$s', provider.name)
                     }));
                     this.add(item, {'silent': true});

+ 11 - 13
src/converse-omemo.js

@@ -1,19 +1,17 @@
-// Converse.js
-// https://conversejs.org
-//
-// Copyright (c) 2013-2019, the Converse.js developers
-// Licensed under the Mozilla Public License (MPLv2)
-
 /* global libsignal, ArrayBuffer */
 /**
  * @module converse-omemo
+ * @copyright The Converse.js developers
+ * @license Mozilla Public License (MPLv2)
  */
 import "converse-profile";
+import { Collection } from "skeletor.js/src/collection";
+import { Model } from 'skeletor.js/src/model.js';
 import converse from "@converse/headless/converse-core";
 import log from "@converse/headless/log";
 import tpl_toolbar_omemo from "templates/toolbar_omemo.html";
 
-const { Backbone, Strophe, sizzle, $build, $iq, $msg, _ } = converse.env;
+const { Strophe, sizzle, $build, $iq, $msg, _ } = converse.env;
 const u = converse.env.utils;
 
 Strophe.addNamespace('OMEMO_DEVICELIST', Strophe.NS.OMEMO+".devicelist");
@@ -668,7 +666,7 @@ converse.plugins.add('converse-omemo', {
         }
 
 
-        _converse.OMEMOStore = Backbone.Model.extend({
+        _converse.OMEMOStore = Model.extend({
 
             Direction: {
                 SENDING: 1,
@@ -917,7 +915,7 @@ converse.plugins.add('converse-omemo', {
             }
         });
 
-        _converse.Device = Backbone.Model.extend({
+        _converse.Device = Model.extend({
             defaults: {
                 'trusted': UNDECIDED,
                 'active': true
@@ -965,7 +963,7 @@ converse.plugins.add('converse-omemo', {
             }
         });
 
-        _converse.Devices = _converse.Collection.extend({
+        _converse.Devices = Collection.extend({
             model: _converse.Device,
         });
 
@@ -974,7 +972,7 @@ converse.plugins.add('converse-omemo', {
          * @namespace _converse.DeviceList
          * @memberOf _converse
          */
-        _converse.DeviceList = Backbone.Model.extend({
+        _converse.DeviceList = Model.extend({
             idAttribute: 'jid',
 
             initialize () {
@@ -1073,7 +1071,7 @@ converse.plugins.add('converse-omemo', {
          * @namespace _converse.DeviceLists
          * @memberOf _converse
          */
-        _converse.DeviceLists = _converse.Collection.extend({
+        _converse.DeviceLists = Collection.extend({
             model: _converse.DeviceList,
             /**
              * Returns the {@link _converse.DeviceList} for a particular JID.
@@ -1258,7 +1256,7 @@ converse.plugins.add('converse-omemo', {
 
         _converse.api.listen.on('clearSession', () => {
             if (_converse.shouldClearCache() && _converse.devicelists) {
-                _converse.devicelists.clearSession();
+                _converse.devicelists.clearStore();
                 delete _converse.devicelists;
             }
         });

+ 3 - 2
src/converse-register.js

@@ -11,6 +11,7 @@
  * as specified in XEP-0077.
  */
 import "converse-controlbox";
+import { View } from "skeletor.js/src/view";
 import converse from "@converse/headless/converse-core";
 import log from "@converse/headless/log";
 import tpl_form_input from "templates/form_input.html";
@@ -165,7 +166,7 @@ converse.plugins.add('converse-register', {
          * @namespace _converse.RegisterPanel
          * @memberOf _converse
          */
-        _converse.RegisterPanel = Backbone.NativeView.extend({
+        _converse.RegisterPanel = View.extend({
             tagName: 'div',
             id: "converse-register-panel",
             className: 'controlbox-pane fade-in',
@@ -421,7 +422,7 @@ converse.plugins.add('converse-register', {
                     _converse.connection.reset();
                     this.showSpinner();
 
-                    if (_.includes(["converse/login", "converse/register"], Backbone.history.getFragment())) {
+                    if (["converse/login", "converse/register"].includes(_converse.router.history.getFragment())) {
                         _converse.router.navigate('', {'replace': true});
                     }
 

+ 2 - 1
src/converse-roomslist.js

@@ -10,6 +10,7 @@
  * rooms in the "Rooms Panel" of the ControlBox.
  */
 import "@converse/headless/converse-muc";
+import { Model } from 'skeletor.js/src/model.js';
 import converse from "@converse/headless/converse-core";
 import tpl_rooms_list from "templates/rooms_list.html";
 
@@ -44,7 +45,7 @@ converse.plugins.add('converse-roomslist', {
         _converse.api.promises.add('roomsListInitialized');
 
 
-        _converse.RoomsList = Backbone.Model.extend({
+        _converse.RoomsList = Model.extend({
             defaults: {
                 "toggle-state":  _converse.OPENED
             }

+ 4 - 3
src/converse-rosterview.js

@@ -11,7 +11,8 @@ import "@converse/headless/converse-roster";
 import "converse-modal";
 import "formdata-polyfill";
 import { compact, debounce, has, isString, uniq, without } from "lodash";
-import { OrderedListView } from "backbone.overview";
+import { Model } from 'skeletor.js/src/model.js';
+import { OrderedListView } from "skeletor.js/src/overview";
 import SHA1 from 'strophe.js/src/sha1';
 import converse from "@converse/headless/converse-core";
 import log from "@converse/headless/log";
@@ -196,7 +197,7 @@ converse.plugins.add('converse-rosterview', {
         });
 
 
-        _converse.RosterFilter = Backbone.Model.extend({
+        _converse.RosterFilter = Model.extend({
             initialize () {
                 this.set({
                     'filter_text': '',
@@ -814,7 +815,7 @@ converse.plugins.add('converse-rosterview', {
 
             showAddContactModal (ev) {
                 if (this.add_contact_modal === undefined) {
-                    this.add_contact_modal = new _converse.AddContactModal({'model': new Backbone.Model()});
+                    this.add_contact_modal = new _converse.AddContactModal({'model': new Model()});
                 }
                 this.add_contact_modal.show(ev);
             },

+ 7 - 5
src/headless/converse-bookmarks.js

@@ -11,10 +11,12 @@
  */
 import "@converse/headless/converse-muc";
 import converse from "@converse/headless/converse-core";
+import { Collection } from "skeletor.js/src/collection";
+import { Model } from 'skeletor.js/src/model.js';
 import { get } from "lodash";
 import log from "./log";
 
-const { Backbone, Strophe, $iq, sizzle } = converse.env;
+const { Strophe, $iq, sizzle } = converse.env;
 const u = converse.env.utils;
 
 
@@ -93,13 +95,13 @@ converse.plugins.add('converse-bookmarks', {
             }
         }
 
-        _converse.Bookmark = Backbone.Model.extend({
+        _converse.Bookmark = Model.extend({
             getDisplayName () {
                 return Strophe.xmlunescape(this.get('name'));
             }
         });
 
-        _converse.Bookmarks = _converse.Collection.extend({
+        _converse.Bookmarks = Collection.extend({
             model: _converse.Bookmark,
             comparator: (item) => item.get('name').toLowerCase(),
 
@@ -258,7 +260,7 @@ converse.plugins.add('converse-bookmarks', {
             }
         });
 
-        _converse.BookmarksList = Backbone.Model.extend({
+        _converse.BookmarksList = Model.extend({
             defaults: {
                 "toggle-state":  _converse.OPENED
             }
@@ -292,7 +294,7 @@ converse.plugins.add('converse-bookmarks', {
 
         _converse.api.listen.on('clearSession', () => {
             if (_converse.bookmarks !== undefined) {
-                _converse.bookmarks.clearSession({'silent': true});
+                _converse.bookmarks.clearStore({'silent': true});
                 window.sessionStorage.removeItem(_converse.bookmarks.fetched_flag);
                 delete _converse.bookmarks;
             }

+ 6 - 9
src/headless/converse-bosh.js

@@ -1,18 +1,15 @@
-// Converse.js
-// http://conversejs.org
-//
-// Copyright (c) The Converse.js developers
-// Licensed under the Mozilla Public License (MPLv2)
 /**
  * @module converse-bosh
- * @description
- * Converse.js plugin which add support for XEP-0206: XMPP Over BOSH
+ * @copyright The Converse.js developers
+ * @license Mozilla Public License (MPLv2)
+ * @description Converse.js plugin which add support for XEP-0206: XMPP Over BOSH
  */
 import 'strophe.js/src/bosh';
+import { Model } from 'skeletor.js/src/model.js';
 import converse from "./converse-core";
 import log from "./log";
 
-const { Backbone, Strophe } = converse.env;
+const { Strophe } = converse.env;
 
 const BOSH_SESSION_ID = 'converse.bosh-session';
 
@@ -35,7 +32,7 @@ converse.plugins.add('converse-bosh', {
         async function initBOSHSession () {
             const id = BOSH_SESSION_ID;
             if (!_converse.bosh_session) {
-                _converse.bosh_session = new Backbone.Model({id});
+                _converse.bosh_session = new Model({id});
                 _converse.bosh_session.browserStorage = _converse.createStore(id, "session");
                 await new Promise(resolve => _converse.bosh_session.fetch({'success': resolve, 'error': resolve}));
             }

+ 7 - 5
src/headless/converse-chat.js

@@ -1,10 +1,12 @@
 import { get, isObject, isString, pick } from "lodash";
+import { Collection } from "skeletor.js/src/collection";
+import { Model } from 'skeletor.js/src/model.js';
 import converse from "./converse-core";
 import filesize from "filesize";
 import log from "./log";
 import stanza_utils from "./utils/stanza";
 
-const { $msg, Backbone, Strophe, sizzle, utils } = converse.env;
+const { $msg, Strophe, sizzle, utils } = converse.env;
 const u = converse.env.utils;
 
 
@@ -43,7 +45,7 @@ converse.plugins.add('converse-chat', {
         });
 
 
-        const ModelWithContact = Backbone.Model.extend({
+        const ModelWithContact = Model.extend({
 
             initialize () {
                 this.rosterContactAdded = u.getResolveablePromise();
@@ -257,7 +259,7 @@ converse.plugins.add('converse-chat', {
         });
 
 
-        _converse.Messages = _converse.Collection.extend({
+        _converse.Messages = Collection.extend({
             model: _converse.Message,
             comparator: 'time'
         });
@@ -387,7 +389,7 @@ converse.plugins.add('converse-chat', {
 
             async clearMessages () {
                 try {
-                    await this.messages.clearSession();
+                    await this.messages.clearStore();
                 } catch (e) {
                     this.messages.trigger('reset');
                     log.error(e);
@@ -1253,7 +1255,7 @@ converse.plugins.add('converse-chat', {
 
         _converse.api.listen.on('clearSession', () => {
             if (_converse.shouldClearCache()) {
-                _converse.chatboxes.filter(c => c.messages && c.messages.clearSession({'silent': true}));
+                _converse.chatboxes.filter(c => c.messages && c.messages.clearStore({'silent': true}));
             }
         });
         /************************ END Event Handlers ************************/

+ 5 - 4
src/headless/converse-chatboxes.js

@@ -7,6 +7,7 @@
  * @module converse-chatboxes
  */
 import "./converse-emoji";
+import { Collection } from "skeletor.js/src/collection";
 import converse from "./converse-core";
 import { isString } from "lodash";
 import log from "./log";
@@ -62,7 +63,7 @@ converse.plugins.add('converse-chatboxes', {
         };
 
 
-        _converse.ChatBoxes = _converse.Collection.extend({
+        _converse.ChatBoxes = Collection.extend({
             comparator: 'time_opened',
 
             model (attrs, options) {
@@ -96,12 +97,12 @@ converse.plugins.add('converse-chatboxes', {
         });
 
 
-        async function createChatBox (jid, attrs, model) {
+        async function createChatBox (jid, attrs, Model) {
             jid = Strophe.getBareJidFromJid(jid.toLowerCase());
             Object.assign(attrs, {'jid': jid, 'id': jid});
             let chatbox;
             try {
-                chatbox = new model(attrs, {'collection': _converse.chatboxes});
+                chatbox = new Model(attrs, {'collection': _converse.chatboxes});
             } catch (e) {
                 log.error(e);
                 return null;
@@ -154,7 +155,7 @@ converse.plugins.add('converse-chatboxes', {
                  * @method _converse.api.chats.create
                  * @param { String|String[] } jids - A JID or array of JIDs
                  * @param { Object } [attrs] An object containing configuration attributes
-                 * @param { Backbone.Model } model - The type of chatbox that should be created
+                 * @param { Model } model - The type of chatbox that should be created
                  */
                 async create (jids=[], attrs={}, model) {
                     await _converse.api.waitUntil('chatBoxesFetched');

+ 23 - 39
src/headless/converse-core.js

@@ -1,18 +1,18 @@
-// Converse.js
-// https://conversejs.org
-//
-// Copyright (c) 2013-2019, the Converse.js developers
-// Licensed under the Mozilla Public License (MPLv2)
 /**
  * @module converse-core
+ * @copyright The Converse.js developers
+ * @license Mozilla Public License (MPLv2)
  */
+import { assignIn, debounce, get, invoke, isFunction, isObject, isString, pick } from 'lodash';
+import { Collection } from "skeletor.js/src/collection";
+import { Model } from 'skeletor.js/src/model.js';
+import { Router } from 'skeletor.js/src/router.js';
 import 'strophe.js/src/websocket';
 import './polyfill';
 import * as strophe from 'strophe.js/src/core';
-import { assignIn, debounce, get, invoke, isFunction, isObject, isString, pick } from 'lodash';
-import Backbone from 'backbone';
-import BrowserStorage from 'backbone.browserStorage';
 import _ from './lodash.noconflict';
+import Backbone from 'backbone';
+import Storage from 'skeletor.js/src/storage.js';
 import advancedFormat from 'dayjs/plugin/advancedFormat';
 import dayjs from 'dayjs';
 import i18n from './i18n';
@@ -29,7 +29,6 @@ const $msg = strophe.default.$msg;
 const $pres = strophe.default.$pres;
 
 Backbone = Backbone.noConflict();
-BrowserStorage.patch(Backbone);
 
 dayjs.extend(advancedFormat);
 
@@ -117,22 +116,7 @@ _converse.VERSION_NAME = "v6.0.1dev";
 
 Object.assign(_converse, Backbone.Events);
 
-_converse.Collection = Backbone.Collection.extend({
-    async clearSession (options={}) {
-        await Promise.all(Array.from(this.models).map(m => {
-            return new Promise(
-                resolve => {
-                    m.destroy(Object.assign(options, {
-                        'success': resolve,
-                        'error': (m, e) => { log.error(e); resolve() }
-                    }));
-                }
-            );
-        }));
-        await this.browserStorage.clear();
-        this.reset();
-    }
-});
+_converse.router = new Router();
 
 
 /**
@@ -354,9 +338,9 @@ _converse.isUniView = function () {
 
 
 async function initSessionStorage () {
-    await BrowserStorage.sessionStorageInitialized;
+    await Storage.sessionStorageInitialized;
     _converse.storage = {
-        'session': BrowserStorage.localForage.createInstance({
+        'session': Storage.localForage.createInstance({
             'name': _converse.isTestEnv() ? 'converse-test-session' : 'converse-session',
             'description': 'sessionStorage instance',
             'driver': ['sessionStorageWrapper']
@@ -375,22 +359,21 @@ function initPersistentStorage () {
     }
     if (_converse.persistent_store === 'localStorage') {
         config['description'] = 'localStorage instance';
-        config['driver'] = [BrowserStorage.localForage.LOCALSTORAGE];
+        config['driver'] = [Storage.localForage.LOCALSTORAGE];
     } else if (_converse.persistent_store === 'IndexedDB') {
         config['description'] = 'indexedDB instance';
-        config['driver'] = [BrowserStorage.localForage.INDEXEDDB];
+        config['driver'] = [Storage.localForage.INDEXEDDB];
     }
-    _converse.storage['persistent'] = BrowserStorage.localForage.createInstance(config);
+    _converse.storage['persistent'] = Storage.localForage.createInstance(config);
 }
 
 
 _converse.createStore = function (id, storage) {
     const s = _converse.storage[storage ? storage : _converse.config.get('storage')];
-    return new Backbone.BrowserStorage(id, s);
+    return new Storage(id, s);
 }
 
 
-_converse.router = new Backbone.Router();
 
 function initPlugins () {
     // If initialize gets called a second time (e.g. during tests), then we
@@ -442,7 +425,7 @@ function initClientConfig () {
      * user sessions.
      */
     const id = 'converse.client-config';
-    _converse.config = new Backbone.Model({
+    _converse.config = new Model({
         'id': id,
         'trusted': _converse.trusted && true || false,
         'storage': _converse.trusted ? 'persistent' : 'session'
@@ -670,7 +653,7 @@ async function initSession (jid) {
     const bare_jid = Strophe.getBareJidFromJid(jid).toLowerCase();
     const id = `converse.session-${bare_jid}`;
     if (!_converse.session || _converse.session.get('id') !== id) {
-        _converse.session = new Backbone.Model({id});
+        _converse.session = new Model({id});
         _converse.session.browserStorage = _converse.createStore(id, "session");
         await new Promise(r => _converse.session.fetch({'success': r, 'error': r}));
         if (_converse.session.get('active')) {
@@ -832,8 +815,9 @@ async function finishInitialization () {
     initPlugins();
     registerGlobalEventHandlers();
 
-    if (!Backbone.History.started) {
-        Backbone.history.start();
+
+    if (!History.started) {
+        _converse.router.history.start();
     }
     if (_converse.idle_presence_timeout > 0) {
         _converse.api.listen.on('addClientFeatures', () => {
@@ -980,7 +964,7 @@ function unregisterGlobalEventHandlers () {
 function cleanup () {
     // Make sure everything is reset in case this is a subsequent call to
     // convesre.initialize (happens during tests).
-    Backbone.history.stop();
+    _converse.router.history.stop();
     unregisterGlobalEventHandlers();
     delete _converse.controlboxtoggle;
     if (_converse.chatboxviews) {
@@ -1192,7 +1176,7 @@ _converse.initialize = async function (settings, callback) {
         _converse.connection.bind();
     };
 
-    this.ConnectionFeedback = Backbone.Model.extend({
+    this.ConnectionFeedback = Model.extend({
         defaults: {
             'connection_status': Strophe.Status.DISCONNECTED,
             'message': ''
@@ -1820,7 +1804,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, BrowserStorage, Promise, Strophe, _, dayjs, log, sizzle, stanza_utils, u, 'utils': u }
+    'env': { $build, $iq, $msg, $pres, Backbone, Model, Collection, Promise, Strophe, _, dayjs, log, sizzle, stanza_utils, u, 'utils': u }
 });
 
 /**

+ 20 - 22
src/headless/converse-disco.js

@@ -1,19 +1,17 @@
-// Converse.js
-// https://conversejs.org
-//
-// Copyright (c) 2013-2019, the Converse developers
-// Licensed under the Mozilla Public License (MPLv2)
 /**
  * @module converse-disco
- * @description
- * Converse plugin which add support for XEP-0030: Service Discovery
+ * @copyright The Converse.js developers
+ * @license Mozilla Public License (MPLv2)
+ * @description Converse plugin which add support for XEP-0030: Service Discovery
  */
 import { get, isEmpty, isObject } from "lodash";
+import { Collection } from "skeletor.js/src/collection";
+import { Model } from 'skeletor.js/src/model.js';
 import converse from "./converse-core";
 import log from "./log";
 import sizzle from "sizzle";
 
-const { Backbone, Strophe, $iq, utils } = converse.env;
+const { Strophe, $iq, utils } = converse.env;
 
 converse.plugins.add('converse-disco', {
 
@@ -33,7 +31,7 @@ converse.plugins.add('converse-disco', {
          * @namespace _converse.DiscoEntity
          * @memberOf _converse
          */
-        _converse.DiscoEntity = Backbone.Model.extend({
+        _converse.DiscoEntity = Model.extend({
             /* A Disco Entity is a JID addressable entity that can be queried
              * for features.
              *
@@ -44,21 +42,21 @@ converse.plugins.add('converse-disco', {
             initialize (attrs, options) {
                 this.waitUntilFeaturesDiscovered = utils.getResolveablePromise();
 
-                this.dataforms = new _converse.Collection();
+                this.dataforms = new Collection();
                 let id = `converse.dataforms-${this.get('jid')}`;
                 this.dataforms.browserStorage = _converse.createStore(id, 'session');
 
-                this.features = new _converse.Collection();
+                this.features = new Collection();
                 id = `converse.features-${this.get('jid')}`;
                 this.features.browserStorage = _converse.createStore(id, 'session');
                 this.listenTo(this.features, 'add', this.onFeatureAdded)
 
-                this.fields = new _converse.Collection();
+                this.fields = new Collection();
                 id = `converse.fields-${this.get('jid')}`;
                 this.fields.browserStorage = _converse.createStore(id, 'session');
                 this.listenTo(this.fields, 'add', this.onFieldAdded)
 
-                this.identities = new _converse.Collection();
+                this.identities = new Collection();
                 id = `converse.identities-${this.get('jid')}`;
                 this.identities.browserStorage = _converse.createStore(id, 'session');
                 this.fetchFeatures(options);
@@ -105,7 +103,7 @@ converse.plugins.add('converse-disco', {
                  * Triggered when Converse has learned of a service provided by the XMPP server.
                  * See XEP-0030.
                  * @event _converse#serviceDiscovered
-                 * @type { Backbone.Model }
+                 * @type { Model }
                  * @example _converse.api.listen.on('featuresDiscovered', feature => { ... });
                  */
                 _converse.api.trigger('serviceDiscovered', feature);
@@ -228,7 +226,7 @@ converse.plugins.add('converse-disco', {
             }
         });
 
-        _converse.DiscoEntities = _converse.Collection.extend({
+        _converse.DiscoEntities = Collection.extend({
             model: _converse.DiscoEntity,
 
             fetchEntities () {
@@ -277,7 +275,7 @@ converse.plugins.add('converse-disco', {
                 const bare_jid = Strophe.getBareJidFromJid(_converse.jid);
                 const id = `converse.stream-features-${bare_jid}`;
                 _converse.api.promises.add('streamFeaturesAdded');
-                _converse.stream_features = new _converse.Collection();
+                _converse.stream_features = new Collection();
                 _converse.stream_features.browserStorage = _converse.createStore(id, "session");
             }
         }
@@ -387,18 +385,18 @@ converse.plugins.add('converse-disco', {
         _converse.api.listen.on('beforeTearDown', async () => {
             _converse.api.promises.add('streamFeaturesAdded')
             if (_converse.stream_features) {
-                await _converse.stream_features.clearSession();
+                await _converse.stream_features.clearStore();
                 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();
+                Array.from(_converse.disco_entities.models).forEach(e => e.features.clearStore());
+                Array.from(_converse.disco_entities.models).forEach(e => e.identities.clearStore());
+                Array.from(_converse.disco_entities.models).forEach(e => e.dataforms.clearStore());
+                Array.from(_converse.disco_entities.models).forEach(e => e.fields.clearStore());
+                _converse.disco_entities.clearStore();
                 delete _converse.disco_entities;
             }
         });

+ 2 - 2
src/headless/converse-emoji.js

@@ -6,11 +6,11 @@
 /**
  * @module converse-emoji
  */
+import { Model } from 'skeletor.js/src/model.js';
 import * as twemoji from "twemoji";
 import _ from "./lodash.noconflict";
 import converse from "./converse-core";
 
-const { Backbone } = converse.env;
 const u = converse.env.utils;
 
 const ASCII_LIST = {
@@ -111,7 +111,7 @@ converse.plugins.add('converse-emoji', {
          * @namespace _converse.EmojiPicker
          * @memberOf _converse
          */
-        _converse.EmojiPicker = Backbone.Model.extend({
+        _converse.EmojiPicker = Model.extend({
             defaults: {
                 'current_category': 'smileys',
                 'current_skintone': '',

+ 10 - 12
src/headless/converse-headlines.js

@@ -1,18 +1,16 @@
-// Converse.js (A browser based XMPP chat client)
-// https://conversejs.org
-//
-// Copyright (c) 2019, Jan-Carel Brand <jc@opkode.com>
-// Licensed under the Mozilla Public License (MPLv2)
 /**
  * @module converse-headlines
+ * @copyright 2013-2019, the Converse.js developers
+ * @description XEP-0045 Multi-User Chat Views
  */
 import "converse-chatview";
 import converse from "@converse/headless/converse-core";
+import { View } from "skeletor.js/src/view";
 import { isString } from "lodash";
 import tpl_headline_list from "templates/headline_list.html";
 import tpl_headline_panel from "templates/headline_panel.html";
 
-const { Backbone, utils } = converse.env;
+const u = converse.env.utils;
 
 
 converse.plugins.add('converse-headlines', {
@@ -63,7 +61,7 @@ converse.plugins.add('converse-headlines', {
 
         const viewWithHeadlinePanel = {
             renderHeadlinePanel () {
-                if (this.headlinepanel && utils.isInDOM(this.headlinepanel.el)) {
+                if (this.headlinepanel && u.isInDOM(this.headlinepanel.el)) {
                     return this.headlinepanel;
                 }
                 this.headlinepanel = new _converse.HeadlinePanel();
@@ -74,7 +72,7 @@ converse.plugins.add('converse-headlines', {
             },
 
             getHeadlinePanel () {
-                if (this.headlinepanel && utils.isInDOM(this.headlinepanel.el)) {
+                if (this.headlinepanel && u.isInDOM(this.headlinepanel.el)) {
                     return this.headlinepanel;
                 } else {
                     return this.renderHeadlinePanel();
@@ -140,7 +138,7 @@ converse.plugins.add('converse-headlines', {
 
         async function onHeadlineMessage (message) {
             // Handler method for all incoming messages of type "headline".
-            if (utils.isHeadlineMessage(_converse, message)) {
+            if (u.isHeadlineMessage(_converse, message)) {
                 const from_jid = message.getAttribute('from');
                 if (from_jid.includes('@') &&
                         !_converse.roster.get(from_jid) &&
@@ -170,12 +168,12 @@ converse.plugins.add('converse-headlines', {
         }
 
         /**
-         * Backbone.NativeView which renders headlines section of the control box.
+         * View which renders headlines section of the control box.
          * @class
          * @namespace _converse.HeadlinePanel
          * @memberOf _converse
          */
-        _converse.HeadlinePanel = Backbone.NativeView.extend({
+        _converse.HeadlinePanel = View.extend({
             tagName: 'div',
             className: 'controlbox-section',
             id: 'headline',
@@ -193,7 +191,7 @@ converse.plugins.add('converse-headlines', {
 
             render () {
                 this.el.innerHTML = tpl_headline_panel({
-                    'heading_headline': __('Server Messages')
+                    'heading_headline': __('Announcements')
                 });
                 return this;
             }

+ 14 - 12
src/headless/converse-muc.js

@@ -7,6 +7,8 @@
 import "./converse-chat";
 import "./converse-disco";
 import "./converse-emoji";
+import { Collection } from "skeletor.js/src/collection";
+import { Model } from 'skeletor.js/src/model.js';
 import { clone, get, intersection, invoke, isElement, isObject, isString, pick, uniq, zipObject } from "lodash";
 import converse from "./converse-core";
 import log from "./log";
@@ -21,7 +23,7 @@ const MUC_ROLE_WEIGHTS = {
     'none':         2,
 };
 
-const { Strophe, Backbone, $iq, $build, $msg, $pres, sizzle } = converse.env;
+const { Strophe, $iq, $build, $msg, $pres, sizzle } = converse.env;
 
 // Add Strophe Namespaces
 Strophe.addNamespace('MUC_ADMIN', Strophe.NS.MUC + "#admin");
@@ -293,7 +295,7 @@ converse.plugins.add('converse-muc', {
         });
 
 
-        const MUCSession = Backbone.Model.extend({
+        const MUCSession = Model.extend({
             defaults () {
                 return {
                     'connection_status': converse.ROOMSTATUS.DISCONNECTED
@@ -308,7 +310,7 @@ converse.plugins.add('converse-muc', {
          * @namespace _converse.ChatRoomMessages
          * @memberOf _converse
          */
-        _converse.ChatRoomMessages = _converse.Collection.extend({
+        _converse.ChatRoomMessages = Collection.extend({
             model: _converse.ChatRoomMessage,
             comparator: 'time'
         });
@@ -436,7 +438,7 @@ converse.plugins.add('converse-muc', {
                     this.occupants.filter(o => !o.isMember()).forEach(o => o.destroy());
                 } else {
                     // Looks like we haven't restored occupants from cache, so we clear it.
-                    this.occupants.clearSession();
+                    this.occupants.clearStore();
                 }
                 if (_converse.clear_messages_on_reconnection) {
                     await this.clearMessages();
@@ -489,13 +491,13 @@ converse.plugins.add('converse-muc', {
 
             initDiscoModels () {
                 let id = `converse.muc-features-${_converse.bare_jid}-${this.get('jid')}`;
-                this.features = new Backbone.Model(
+                this.features = new Model(
                     Object.assign({id}, zipObject(converse.ROOM_FEATURES, converse.ROOM_FEATURES.map(() => false)))
                 );
                 this.features.browserStorage = _converse.createStore(id, "session");
 
                 id = `converse.muc-config-{_converse.bare_jid}-${this.get('jid')}`;
-                this.config = new Backbone.Model();
+                this.config = new Model();
                 this.config.browserStorage = _converse.createStore(id, "session");
             },
 
@@ -716,7 +718,7 @@ converse.plugins.add('converse-muc', {
              */
             async leave (exit_msg) {
                 this.features.destroy();
-                this.occupants.clearSession();
+                this.occupants.clearStore();
                 if (_converse.disco_entities) {
                     const disco_entity = _converse.disco_entities.get(this.get('jid'));
                     if (disco_entity) {
@@ -2087,7 +2089,7 @@ converse.plugins.add('converse-muc', {
          * @namespace _converse.ChatRoomOccupant
          * @memberOf _converse
          */
-        _converse.ChatRoomOccupant = Backbone.Model.extend({
+        _converse.ChatRoomOccupant = Model.extend({
 
             defaults: {
                 'show': 'offline',
@@ -2132,7 +2134,7 @@ converse.plugins.add('converse-muc', {
         });
 
 
-        _converse.ChatRoomOccupants = _converse.Collection.extend({
+        _converse.ChatRoomOccupants = Collection.extend({
             model: _converse.ChatRoomOccupant,
 
             comparator (occupant1, occupant2) {
@@ -2204,7 +2206,7 @@ converse.plugins.add('converse-muc', {
         });
 
 
-        _converse.RoomsPanelModel = Backbone.Model.extend({
+        _converse.RoomsPanelModel = Model.extend({
             defaults: function () {
                 return {
                     'muc_domain': _converse.muc_domain,
@@ -2382,7 +2384,7 @@ converse.plugins.add('converse-muc', {
                  * @param {(string[]|string)} jid|jids The JID or array of
                  *     JIDs of the chatroom(s) to create
                  * @param {object} [attrs] attrs The room attributes
-                 * @returns {Promise} Promise which resolves with the Backbone.Model representing the chat.
+                 * @returns {Promise} Promise which resolves with the Model representing the chat.
                  */
                 create (jids, attrs={}) {
                     attrs = isString(attrs) ? {'nick': attrs} : (attrs || {});
@@ -2426,7 +2428,7 @@ converse.plugins.add('converse-muc', {
                  *   another chat already in the foreground.
                  *   Set `force` to `true` if you want to force the room to be
                  *   maximized or shown.
-                 * @returns {Promise} Promise which resolves with the Backbone.Model representing the chat.
+                 * @returns {Promise} Promise which resolves with the Model representing the chat.
                  *
                  * @example
                  * this._converse.api.rooms.open('group@muc.example.com')

+ 2 - 5
src/headless/converse-pubsub.js

@@ -1,10 +1,7 @@
-// Converse.js
-// https://conversejs.org
-//
-// Copyright (c) 2019, the Converse.js developers
-// Licensed under the Mozilla Public License (MPLv2)
 /**
  * @module converse-pubsub
+ * @copyright The Converse.js developers
+ * @license Mozilla Public License (MPLv2)
  */
 import "./converse-disco";
 import converse from "./converse-core";

+ 17 - 18
src/headless/converse-roster.js

@@ -1,17 +1,16 @@
-// Converse.js
-// https://conversejs.org
-//
-// Copyright (c) 2013-2019, the Converse.js developers
-// Licensed under the Mozilla Public License (MPLv2)
 /**
  * @module converse-roster
+ * @copyright The Converse.js developers
+ * @license Mozilla Public License (MPLv2)
  */
 import "@converse/headless/converse-status";
+import { Collection } from "skeletor.js/src/collection";
+import { Model } from 'skeletor.js/src/model.js';
 import { get, invoke, isEmpty, isNaN, isString, propertyOf, sum } from "lodash";
 import converse from "@converse/headless/converse-core";
 import log from "./log";
 
-const { Backbone, Strophe, $iq, $pres, dayjs, sizzle } = converse.env;
+const { Strophe, $iq, $pres, dayjs, sizzle } = converse.env;
 const u = converse.env.utils;
 
 
@@ -118,11 +117,11 @@ converse.plugins.add('converse-roster', {
             }
         };
 
-        const Resource = Backbone.Model.extend({'idAttribute': 'name'});
-        const Resources = _converse.Collection.extend({'model': Resource});
+        const Resource = Model.extend({'idAttribute': 'name'});
+        const Resources = Collection.extend({'model': Resource});
 
 
-        _converse.Presence = Backbone.Model.extend({
+        _converse.Presence = Model.extend({
             defaults: {
                 'show': 'offline'
             },
@@ -194,7 +193,7 @@ converse.plugins.add('converse-roster', {
         });
 
 
-        _converse.Presences = _converse.Collection.extend({
+        _converse.Presences = Collection.extend({
             model: _converse.Presence,
         });
 
@@ -204,7 +203,7 @@ converse.plugins.add('converse-roster', {
          * @namespace _converse.RosterContact
          * @memberOf _converse
          */
-        _converse.RosterContact = Backbone.Model.extend({
+        _converse.RosterContact = Model.extend({
             defaults: {
                 'chat_state': undefined,
                 'image': _converse.DEFAULT_IMAGE,
@@ -359,7 +358,7 @@ converse.plugins.add('converse-roster', {
          * @namespace _converse.RosterContacts
          * @memberOf _converse
          */
-        _converse.RosterContacts = _converse.Collection.extend({
+        _converse.RosterContacts = Collection.extend({
             model: _converse.RosterContact,
 
             comparator (contact1, contact2) {
@@ -813,7 +812,7 @@ converse.plugins.add('converse-roster', {
         });
 
 
-        _converse.RosterGroup = Backbone.Model.extend({
+        _converse.RosterGroup = Model.extend({
 
             initialize (attributes) {
                 this.set(Object.assign({
@@ -831,7 +830,7 @@ converse.plugins.add('converse-roster', {
          * @namespace _converse.RosterGroups
          * @memberOf _converse
          */
-        _converse.RosterGroups = _converse.Collection.extend({
+        _converse.RosterGroups = Collection.extend({
             model: _converse.RosterGroup,
 
             comparator (a, b) {
@@ -919,7 +918,7 @@ converse.plugins.add('converse-roster', {
                 _converse.presences.forEach(p => {
                     p.resources.reject(r => r === undefined).forEach(r => r.destroy({'silent': true}));
                 });
-                _converse.presences.clearSession();
+                _converse.presences.clearStore();
             }
         }
 
@@ -930,11 +929,11 @@ converse.plugins.add('converse-roster', {
             if (_converse.shouldClearCache()) {
                 if (_converse.roster) {
                     invoke(_converse, 'roster.data.destroy');
-                    _converse.roster.clearSession();
+                    _converse.roster.clearStore();
                     delete _converse.roster;
                 }
                 if (_converse.rostergroups) {
-                    _converse.rostergroups.clearSession();
+                    _converse.rostergroups.clearStore();
                     delete _converse.rostergroups;
                 }
             }
@@ -975,7 +974,7 @@ converse.plugins.add('converse-roster', {
             let id = `converse.contacts-${_converse.bare_jid}`;
             _converse.roster.browserStorage = _converse.createStore(id);
 
-            _converse.roster.data = new Backbone.Model();
+            _converse.roster.data = new Model();
             id = `converse-roster-model-${_converse.bare_jid}`;
             _converse.roster.data.id = id;
             _converse.roster.data.browserStorage = _converse.createStore(id);

+ 5 - 11
src/headless/converse-rsm.js

@@ -1,16 +1,10 @@
-// Converse.js (A browser based XMPP chat client)
-// https://conversejs.org
-//
-// Copyright (c) Jan-Carel Brand <jc@opkode.com>
-// Licensed under the Mozilla Public License (MPLv2)
-//
-// Some code taken from the Strophe RSM plugin, licensed under the MIT License
-// Copyright 2006-2017 Strophe (https://github.com/strophe/strophejs)
-//
 /**
  * @module converse-rsm
- * @description
- * XEP-0059 Result Set Management
+ * @copyright The Converse.js developers
+ * @license Mozilla Public License (MPLv2)
+ * @description XEP-0059 Result Set Management
+ *   Some code taken from the Strophe RSM plugin, licensed under the MIT License
+ *   Copyright 2006-2017 Strophe (https://github.com/strophe/strophejs)
  */
 import converse from "./converse-core";
 

+ 3 - 8
src/headless/converse-smacks.js

@@ -1,13 +1,8 @@
-// Converse.js
-// http://conversejs.org
-//
-// Copyright (c) The Converse.js developers
-// Licensed under the Mozilla Public License (MPLv2)
-//
 /**
  * @module converse-smacks
- * @description
- * Converse.js plugin which adds support for XEP-0198: Stream Management
+ * @copyright The Converse.js developers
+ * @license Mozilla Public License (MPLv2)
+ * @description Converse.js plugin which adds support for XEP-0198: Stream Management
  */
 import converse from "./converse-core";
 import log from "./log";

+ 5 - 7
src/headless/converse-status.js

@@ -1,15 +1,13 @@
-// Converse.js
-// https://conversejs.org
-//
-// Copyright (c) 2013-2019, the Converse.js developers
-// Licensed under the Mozilla Public License (MPLv2)
 /**
  * @module converse-status
+ * @copyright The Converse.js developers
+ * @license Mozilla Public License (MPLv2)
  */
 import { get, isNaN, isObject, isString } from "lodash";
+import { Model } from 'skeletor.js/src/model.js';
 import converse from "@converse/headless/converse-core";
 
-const { Backbone, Strophe, $build, $pres } = converse.env;
+const { Strophe, $build, $pres } = converse.env;
 
 
 converse.plugins.add('converse-status', {
@@ -17,7 +15,7 @@ converse.plugins.add('converse-status', {
     initialize () {
         const { _converse } = this;
 
-        _converse.XMPPStatus = Backbone.Model.extend({
+        _converse.XMPPStatus = Model.extend({
             defaults () {
                 return {"status":  _converse.default_state}
             },

+ 16 - 17
src/headless/converse-vcard.js

@@ -1,18 +1,17 @@
-// Converse.js
-// https://conversejs.org
-//
-// Copyright (c) 2013-2019, the Converse.js developers
-// Licensed under the Mozilla Public License (MPLv2)
 /**
  * @module converse-vcard
+ * @copyright The Converse.js developers
+ * @license Mozilla Public License (MPLv2)
  */
 import "./converse-status";
+import { Collection } from "skeletor.js/src/collection";
+import { Model } from 'skeletor.js/src/model.js';
 import { get, has, isString } from "lodash";
 import converse from "./converse-core";
 import log from "@converse/headless/log";
 import tpl_vcard from "./templates/vcard.html";
 
-const { Backbone, Strophe, $iq, dayjs } = converse.env;
+const { Strophe, $iq, dayjs } = converse.env;
 const u = converse.env.utils;
 
 
@@ -70,14 +69,14 @@ converse.plugins.add('converse-vcard', {
         _converse.api.promises.add('VCardsInitialized');
 
 
-        _converse.VCard = Backbone.Model.extend({
+        _converse.VCard = Model.extend({
             defaults: {
                 'image': _converse.DEFAULT_IMAGE,
                 'image_type': _converse.DEFAULT_IMAGE_TYPE
             },
 
             set (key, val, options) {
-                // Override Backbone.Model.prototype.set to make sure that the
+                // Override Model.prototype.set to make sure that the
                 // default `image` and `image_type` values are maintained.
                 let attrs;
                 if (typeof key === 'object') {
@@ -89,9 +88,9 @@ converse.plugins.add('converse-vcard', {
                 if (has(attrs, 'image') && !attrs['image']) {
                     attrs['image'] = _converse.DEFAULT_IMAGE;
                     attrs['image_type'] = _converse.DEFAULT_IMAGE_TYPE;
-                    return Backbone.Model.prototype.set.call(this, attrs, options);
+                    return Model.prototype.set.call(this, attrs, options);
                 } else {
-                    return Backbone.Model.prototype.set.apply(this, arguments);
+                    return Model.prototype.set.apply(this, arguments);
                 }
             },
 
@@ -101,7 +100,7 @@ converse.plugins.add('converse-vcard', {
         });
 
 
-        _converse.VCards = _converse.Collection.extend({
+        _converse.VCards = Collection.extend({
             model: _converse.VCard,
 
             initialize () {
@@ -238,7 +237,7 @@ converse.plugins.add('converse-vcard', {
             if (_converse.shouldClearCache()) {
                 _converse.api.promises.add('VCardsInitialized');
                 if (_converse.vcards) {
-                    _converse.vcards.clearSession();
+                    _converse.vcards.clearStore();
                     delete _converse.vcards;
                 }
             }
@@ -295,13 +294,13 @@ converse.plugins.add('converse-vcard', {
 
                 /**
                  * @method _converse.api.vcard.get
-                 * @param {Backbone.Model|string} model Either a `Backbone.Model` instance, or a string JID.
-                 *     If a `Backbone.Model` instance is passed in, then it must have either a `jid`
+                 * @param {Model|string} model Either a `Model` instance, or a string JID.
+                 *     If a `Model` instance is passed in, then it must have either a `jid`
                  *     attribute or a `muc_jid` attribute.
                  * @param {boolean} [force] A boolean indicating whether the vcard should be
                  *     fetched even if it's been fetched before.
                  * @returns {promise} A Promise which resolves with the VCard data for a particular JID or for
-                 *     a `Backbone.Model` instance which represents an entity with a JID (such as a roster contact,
+                 *     a `Model` instance which represents an entity with a JID (such as a roster contact,
                  *     chat or chatroom occupant).
                  *
                  * @example
@@ -331,12 +330,12 @@ converse.plugins.add('converse-vcard', {
                 },
 
                 /**
-                 * Fetches the VCard associated with a particular `Backbone.Model` instance
+                 * Fetches the VCard associated with a particular `Model` instance
                  * (by using its `jid` or `muc_jid` attribute) and then updates the model with the
                  * returned VCard data.
                  *
                  * @method _converse.api.vcard.update
-                 * @param {Backbone.Model} model A `Backbone.Model` instance
+                 * @param {Model} model A `Model` instance
                  * @param {boolean} [force] A boolean indicating whether the vcard should be
                  *     fetched again even if it's been fetched before.
                  * @returns {promise} A promise which resolves once the update has completed.

+ 1 - 1
src/headless/headless.js

@@ -5,7 +5,7 @@
 import "./converse-bookmarks";   // XEP-0199 XMPP Ping
 import "./converse-bosh";        // XEP-0206 BOSH
 import "./converse-caps";        // XEP-0115 Entity Capabilities
-import "./converse-chatboxes";   // Backbone Collection and Models for chat boxes
+import "./converse-chatboxes";
 import "./converse-chat";        // Support for one-on-one chats
 import "./converse-disco";       // XEP-0030 Service discovery
 import "./converse-mam";         // XEP-0313 Message Archive Management

+ 1 - 0
src/headless/package.json

@@ -26,6 +26,7 @@
   },
   "gitHead": "9641dcdc820e029b05930479c242d2b707bbe8e2",
   "devDependencies": {
+    "skeletor.js": "skeletorjs/skeletor#abc4e9d25d30159e9cffc14bf5f7ffe17b3665eb",
     "backbone": "1.4",
     "backbone.browserStorage": "conversejs/backbone.browserStorage#674ba3aa0e4d0f0b0dcac48fcc7dea531012828f",
     "filesize": "^4.1.2",

+ 5 - 5
src/headless/utils/core.js

@@ -7,7 +7,7 @@
 // Licensed under the Mozilla Public License (MPLv2)
 //
 import * as strophe from 'strophe.js/src/core';
-import Backbone from "backbone";
+import { Model } from 'skeletor.js/src/model.js';
 import _ from "../lodash.noconflict";
 import log from "@converse/headless/log";
 import sizzle from "sizzle";
@@ -120,14 +120,14 @@ u.isNewMessage = function (message) {
             sizzle(`result[xmlns="${Strophe.NS.MAM}"]`, message).length &&
             sizzle(`delay[xmlns="${Strophe.NS.DELAY}"]`, message).length
         );
-    } else if (message instanceof Backbone.Model) {
+    } else if (message instanceof Model) {
         message = message.attributes;
     }
     return !(message['is_delayed'] && message['is_archived']);
 };
 
 u.isEmptyMessage = function (attrs) {
-    if (attrs instanceof Backbone.Model) {
+    if (attrs instanceof Model) {
         attrs = attrs.attributes;
     }
     return !attrs['oob_url'] &&
@@ -146,7 +146,7 @@ u.isOnlyChatStateNotification = function (msg) {
                     (msg.querySelector('paused') !== null) ||
                     (msg.querySelector('gone') !== null));
     }
-    if (msg instanceof Backbone.Model) {
+    if (msg instanceof Model) {
         msg = msg.attributes;
     }
     return msg['chat_state'] && u.isEmptyMessage(msg);
@@ -158,7 +158,7 @@ u.isOnlyMessageDeliveryReceipt = function (msg) {
         return (msg.querySelector('body') === null) &&
                     (msg.querySelector('received') !== null);
     }
-    if (msg instanceof Backbone.Model) {
+    if (msg instanceof Model) {
         msg = msg.attributes;
     }
     return msg['received'] && u.isEmptyMessage(msg);

+ 1 - 1
tests/utils.js

@@ -311,7 +311,7 @@
     utils.clearChatBoxMessages = function (converse, jid) {
         const view = converse.chatboxviews.get(jid);
         view.el.querySelector('.chat-content').innerHTML = '';
-        return view.model.messages.clearSession();
+        return view.model.messages.clearStore();
     };
 
     utils.createContact = async function (_converse, name, ask, requesting, subscription) {

Some files were not shown because too many files changed in this diff