浏览代码

Add `listenTo` instead of `on` to avoid memory leaks

JC Brand 6 年之前
父节点
当前提交
cc91f3751e

+ 1 - 0
CHANGES.md

@@ -11,6 +11,7 @@
   This means that all your assets need to be served at `/dist`. If you need to set a
   different path, you'll need to set `publicPath` in `webpack.config.js` to
   your preferred path and then rebuild all assets (e.g. `make dist`).
+- Use `listenTo` to avoid memory leaks when views get removed.
 
 ## 5.0.1 (2019-08-14)
 

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

@@ -246,11 +246,11 @@ converse.plugins.add('converse-bookmark-views', {
             initialize () {
                 OrderedListView.prototype.initialize.apply(this, arguments);
 
-                this.model.on('add', this.showOrHide, this);
-                this.model.on('remove', this.showOrHide, this);
+                this.listenTo(this.model, 'add', this.showOrHide);
+                this.listenTo(this.model, 'remove', this.showOrHide);
 
-                _converse.chatboxes.on('add', this.renderBookmarkListElement, this);
-                _converse.chatboxes.on('remove', this.renderBookmarkListElement, this);
+                this.listenTo(_converse.chatboxes, 'add', this.renderBookmarkListElement);
+                this.listenTo(_converse.chatboxes, 'remove', this.renderBookmarkListElement);
 
                 const storage = _converse.config.get('storage'),
                       id = `converse.room-bookmarks${_converse.bare_jid}-list-model`;

+ 1 - 1
src/converse-chatboxviews.js

@@ -111,7 +111,7 @@ converse.plugins.add('converse-chatboxviews', {
             },
 
             initialize () {
-                this.model.on("destroy", this.removeChat, this);
+                this.listenTo(this.model, "destroy", this.removeChat)
                 const bg = document.getElementById('conversejs-bg');
                 if (bg && !bg.innerHTML.trim()) {
                     bg.innerHTML = tpl_background_logo();

+ 12 - 12
src/converse-chatview.js

@@ -85,15 +85,15 @@ converse.plugins.add('converse-chatview', {
 
         _converse.ChatBoxHeading = _converse.ViewWithAvatar.extend({
             initialize () {
-                this.model.on('change:status', this.onStatusMessageChanged, this);
+                this.listenTo(this.model, 'change:status', this.onStatusMessageChanged);
 
                 this.debouncedRender = _.debounce(this.render, 50);
                 if (this.model.vcard) {
-                    this.model.vcard.on('change', this.debouncedRender, this);
+                    this.listenTo(this.model.vcard, 'change', this.debouncedRender);
                 }
                 if (this.model.rosterContactAdded) {
                     this.model.rosterContactAdded.then(() => {
-                        this.model.contact.on('change:nickname', this.debouncedRender, this);
+                        this.listenTo(this.model.contact, 'change:nickname', this.debouncedRender);
                         this.debouncedRender();
                     });
                 }
@@ -145,7 +145,7 @@ converse.plugins.add('converse-chatview', {
             initialize () {
                 _converse.BootstrapModal.prototype.initialize.apply(this, arguments);
                 this.model.rosterContactAdded.then(() => this.registerContactEventHandlers());
-                this.model.on('change', this.render, this);
+                this.listenTo(this.model, 'change', this.render);
                 this.registerContactEventHandlers();
                 /**
                  * Triggered once the _converse.UserDetailsModal has been initialized
@@ -175,8 +175,8 @@ converse.plugins.add('converse-chatview', {
 
             registerContactEventHandlers () {
                 if (this.model.contact !== undefined) {
-                    this.model.contact.on('change', this.render, this);
-                    this.model.contact.vcard.on('change', this.render, this);
+                    this.listenTo(this.model.contact, 'change', this.render);
+                    this.listenTo(this.model.contact.vcard, 'change', this.render);
                     this.model.contact.on('destroy', () => {
                         delete this.model.contact;
                         this.render();
@@ -257,17 +257,17 @@ converse.plugins.add('converse-chatview', {
 
             async initialize () {
                 this.initDebounced();
-                this.model.messages.on('add', this.onMessageAdded, this);
-                this.model.messages.on('rendered', this.scrollDown, this);
+                this.listenTo(this.model.messages, 'add', this.onMessageAdded);
+                this.listenTo(this.model.messages, 'rendered', this.scrollDown);
                 this.model.messages.on('reset', () => {
                     this.content.innerHTML = '';
                     this.removeAll();
                 });
 
-                this.model.on('show', this.show, this);
-                this.model.on('destroy', this.remove, this);
+                this.listenTo(this.model, 'show', this.show);
+                this.listenTo(this.model, 'destroy', this.remove);
 
-                this.model.presence.on('change:show', this.onPresenceChanged, this);
+                this.listenTo(this.model.presence, 'change:show', this.onPresenceChanged);
                 this.render();
                 await this.updateAfterMessagesFetched();
 
@@ -429,7 +429,7 @@ converse.plugins.add('converse-chatview', {
                 this.heading.chatview = this;
 
                 if (this.model.contact !== undefined) {
-                    this.model.contact.on('destroy', this.heading.render, this);
+                    this.listenTo(this.model.contact, 'destroy', this.heading.render);
                 }
                 const flyout = this.el.querySelector('.flyout');
                 flyout.insertBefore(this.heading.el, flyout.querySelector('.chat-body'));

+ 6 - 6
src/converse-controlbox.js

@@ -189,11 +189,11 @@ converse.plugins.add('converse-controlbox', {
                 }
                 _converse.controlboxtoggle.el.insertAdjacentElement('afterend', this.el);
 
-                this.model.on('change:connected', this.onConnected, this);
-                this.model.on('destroy', this.hide, this);
-                this.model.on('hide', this.hide, this);
-                this.model.on('show', this.show, this);
-                this.model.on('change:closed', this.ensureClosedState, this);
+                this.listenTo(this.model, 'change:connected', this.onConnected)
+                this.listenTo(this.model, 'destroy', this.hide)
+                this.listenTo(this.model, 'hide', this.hide)
+                this.listenTo(this.model, 'show', this.show)
+                this.listenTo(this.model, 'change:closed', this.ensureClosedState)
                 this.render();
                 /**
                  * Triggered when the _converse.ControlBoxView has been initialized and therefore
@@ -366,7 +366,7 @@ converse.plugins.add('converse-controlbox', {
             },
 
             initialize (cfg) {
-                this.model.on('change', this.render, this);
+                this.listenTo(this.model, 'change', this.render)
                 this.listenTo(_converse.connfeedback, 'change', this.render);
                 this.render();
             },

+ 1 - 1
src/converse-dragresize.js

@@ -150,7 +150,7 @@ converse.plugins.add('converse-dragresize', {
                 const view = this;
                 const debouncedSetDimensions = _.debounce(() => view.setDimensions());
                 window.addEventListener('resize', view.debouncedSetDimensions)
-                this.model.on('destroy', () => window.removeEventListener('resize', debouncedSetDimensions));
+                this.listenTo(this.model, 'destroy', () => window.removeEventListener('resize', debouncedSetDimensions));
 
                 // Determine and store the default box size.
                 // We need this information for the drag-resizing feature.

+ 3 - 3
src/converse-emoji-views.js

@@ -149,9 +149,9 @@ converse.plugins.add('converse-emoji-views', {
             async initialize () {
                 this.search_results = [];
                 this.debouncedFilter = debounce(input => this.filter(input.value), 150);
-                this.model.on('change:query', this.render, this);
-                this.model.on('change:current_skintone', this.render, this);
-                this.model.on('change:current_category', this.render, this);
+                this.listenTo(this.model, 'change:query', this.render)
+                this.listenTo(this.model, 'change:current_skintone', this.render)
+                this.listenTo(this.model, 'change:current_category', this.render)
                 await _converse.api.waitUntil('emojisInitialized');
                 this.render();
                 _converse.api.trigger('emojiPickerViewInitialized');

+ 4 - 4
src/converse-headline.js

@@ -85,10 +85,10 @@ converse.plugins.add('converse-headline', {
                 this.initDebounced();
 
                 this.model.disable_mam = true; // Don't do MAM queries for this box
-                this.model.messages.on('add', this.onMessageAdded, this);
-                this.model.on('show', this.show, this);
-                this.model.on('destroy', this.hide, this);
-                this.model.on('change:minimized', this.onMinimizedChanged, this);
+                this.listenTo(this.model.messages, 'add', this.onMessageAdded);
+                this.listenTo(this.model, 'show', this.show);
+                this.listenTo(this.model, 'destroy', this.hide);
+                this.listenTo(this.model, 'change:minimized', this.onMinimizedChanged);
 
                 this.render().insertHeading()
                 this.updateAfterMessagesFetched();

+ 6 - 6
src/converse-message-view.js

@@ -102,24 +102,24 @@ converse.plugins.add('converse-message-view', {
                 }, 50);
 
                 if (this.model.vcard) {
-                    this.model.vcard.on('change', this.debouncedRender, this);
+                    this.listenTo(this.model.vcard, 'change', this.debouncedRender);
                 }
 
                 if (this.model.rosterContactAdded) {
                     this.model.rosterContactAdded.then(() => {
-                        this.model.contact.on('change:nickname', this.debouncedRender, this);
+                        this.listenTo(this.model.contact, 'change:nickname', this.debouncedRender);
                         this.debouncedRender();
                     });
                 }
 
                 if (this.model.occupant) {
-                    this.model.occupant.on('change:role', this.debouncedRender, this);
-                    this.model.occupant.on('change:affiliation', this.debouncedRender, this);
+                    this.listenTo(this.model.occupant, 'change:role', this.debouncedRender);
+                    this.listenTo(this.model.occupant, 'change:affiliation', this.debouncedRender);
                     this.debouncedRender();
                 }
 
-                this.model.on('change', this.onChanged, this);
-                this.model.on('destroy', this.fadeOut, this);
+                this.listenTo(this.model, 'change', this.onChanged);
+                this.listenTo(this.model, 'destroy', this.fadeOut);
             },
 
             async render () {

+ 13 - 13
src/converse-minimize.js

@@ -74,7 +74,7 @@ converse.plugins.add('converse-minimize', {
             },
 
             initialize () {
-                this.model.on('change:minimized', this.onMinimizedChanged, this);
+                this.listenTo(this.model, 'change:minimized', this.onMinimizedChanged)
                 return this.__super__.initialize.apply(this, arguments);
             },
 
@@ -135,7 +135,7 @@ converse.plugins.add('converse-minimize', {
             },
 
             initialize () {
-                this.model.on('change:minimized', this.onMinimizedChanged, this);
+                this.listenTo(this.model, 'change:minimized', this.onMinimizedChanged)
                 const result = this.__super__.initialize.apply(this, arguments);
                 if (this.model.get('minimized')) {
                     this.hide();
@@ -384,11 +384,11 @@ converse.plugins.add('converse-minimize', {
             },
 
             initialize () {
-                this.model.on('change:num_unread', this.render, this);
-                this.model.on('change:name', this.render, this);
-                this.model.on('change:fullname', this.render, this);
-                this.model.on('change:jid', this.render, this);
-                this.model.on('destroy', this.remove, this);
+                this.listenTo(this.model, 'change:num_unread', this.render)
+                this.listenTo(this.model, 'change:name', this.render)
+                this.listenTo(this.model, 'change:fullname', this.render)
+                this.listenTo(this.model, 'change:jid', this.render)
+                this.listenTo(this.model, 'destroy', this.remove)
             },
 
             render () {
@@ -438,10 +438,10 @@ converse.plugins.add('converse-minimize', {
                 this.render();
                 this.initToggle();
                 this.addMultipleChats(this.model.where({'minimized': true}));
-                this.model.on("add", this.onChanged, this);
-                this.model.on("destroy", this.removeChat, this);
-                this.model.on("change:minimized", this.onChanged, this);
-                this.model.on('change:num_unread', this.updateUnreadMessagesCounter, this);
+                this.listenTo(this.model, "add", this.onChanged)
+                this.listenTo(this.model, "destroy", this.removeChat)
+                this.listenTo(this.model, "change:minimized", this.onChanged)
+                this.listenTo(this.model, 'change:num_unread', this.updateUnreadMessagesCounter)
             },
 
             render () {
@@ -535,8 +535,8 @@ converse.plugins.add('converse-minimize', {
             },
 
             initialize () {
-                this.model.on('change:num_minimized', this.render, this);
-                this.model.on('change:num_unread', this.render, this);
+                this.listenTo(this.model, 'change:num_minimized', this.render)
+                this.listenTo(this.model, 'change:num_unread', this.render)
                 this.flyout = this.el.parentElement.querySelector('.minimized-chats-flyout');
             },
 

+ 1 - 1
src/converse-modal.js

@@ -82,7 +82,7 @@ converse.plugins.add('converse-modal', {
 
             initialize () {
                 _converse.BootstrapModal.prototype.initialize.apply(this, arguments);
-                this.model.on('change', this.render, this);
+                this.listenTo(this.model, 'change', this.render)
             },
 
             toHTML () {

+ 32 - 32
src/converse-muc-views.js

@@ -223,11 +223,11 @@ converse.plugins.add('converse-muc-views', {
                 this.chatroomview = attrs.chatroomview;
                 _converse.BootstrapModal.prototype.initialize.apply(this, arguments);
 
-                this.model.on('change:role', () => {
+                this.listenTo(this.model, 'change:role', () => {
                     this.users_with_role = this.getUsersWithRole();
                     this.render();
                 });
-                this.model.on('change:affiliation', async () => {
+                this.listenTo(this.model, 'change:affiliation', async () => {
                     this.loading_users_with_affiliation = true;
                     this.users_with_affiliation = null;
                     this.render();
@@ -384,7 +384,7 @@ converse.plugins.add('converse-muc-views', {
                 if (_converse.muc_domain && !this.model.get('muc_domain')) {
                     this.model.save('muc_domain', _converse.muc_domain);
                 }
-                this.model.on('change:muc_domain', this.onDomainChange, this);
+                this.listenTo(this.model, 'change:muc_domain', this.onDomainChange);
             },
 
             toHTML () {
@@ -511,7 +511,7 @@ converse.plugins.add('converse-muc-views', {
 
             initialize () {
                 _converse.BootstrapModal.prototype.initialize.apply(this, arguments);
-                this.model.on('change:muc_domain', this.render, this);
+                this.listenTo(this.model, 'change:muc_domain', this.render);
             },
 
             toHTML () {
@@ -577,9 +577,9 @@ converse.plugins.add('converse-muc-views', {
 
             initialize () {
                 _converse.BootstrapModal.prototype.initialize.apply(this, arguments);
-                this.model.on('change', this.render, this);
-                this.model.occupants.on('add', this.render, this);
-                this.model.occupants.on('change', this.render, this);
+                this.listenTo(this.model, 'change', this.render);
+                this.listenTo(this.model.occupants, 'add', this.render);
+                this.listenTo(this.model.occupants, 'change', this.render);
             },
 
             toHTML () {
@@ -636,28 +636,28 @@ converse.plugins.add('converse-muc-views', {
             initialize () {
                 this.initDebounced();
 
-                this.model.messages.on('add', this.onMessageAdded, this);
-                this.model.messages.on('rendered', this.scrollDown, this);
+                this.listenTo(this.model.messages, 'add', this.onMessageAdded);
+                this.listenTo(this.model.messages, 'rendered', this.scrollDown);
                 this.model.messages.on('reset', () => {
                     this.content.innerHTML = '';
                     this.removeAll();
                 });
 
-                this.model.on('change', this.renderHeading, this);
-                this.model.on('change:connection_status', this.onConnectionStatusChanged, this);
-                this.model.on('change:hidden_occupants', this.updateOccupantsToggle, this);
-                this.model.on('change:subject', this.setChatRoomSubject, this);
-                this.model.on('configurationNeeded', this.getAndRenderConfigurationForm, this);
-                this.model.on('destroy', this.hide, this);
-                this.model.on('show', this.show, this);
+                this.listenTo(this.model, 'change', this.renderHeading);
+                this.listenTo(this.model, 'change:connection_status', this.onConnectionStatusChanged);
+                this.listenTo(this.model, 'change:hidden_occupants', this.updateOccupantsToggle);
+                this.listenTo(this.model, 'change:subject', this.setChatRoomSubject);
+                this.listenTo(this.model, 'configurationNeeded', this.getAndRenderConfigurationForm);
+                this.listenTo(this.model, 'destroy', this.hide);
+                this.listenTo(this.model, 'show', this.show);
 
-                this.model.features.on('change:moderated', this.renderBottomPanel, this);
+                this.listenTo(this.model.features, 'change:moderated', this.renderBottomPanel);
 
-                this.model.occupants.on('add', this.onOccupantAdded, this);
-                this.model.occupants.on('remove', this.onOccupantRemoved, this);
-                this.model.occupants.on('change:show', this.showJoinOrLeaveNotification, this);
-                this.model.occupants.on('change:role', this.onOccupantRoleChanged, this);
-                this.model.occupants.on('change:affiliation', this.onOccupantAffiliationChanged, this);
+                this.listenTo(this.model.occupants, 'add', this.onOccupantAdded);
+                this.listenTo(this.model.occupants, 'remove', this.onOccupantRemoved);
+                this.listenTo(this.model.occupants, 'change:show', this.showJoinOrLeaveNotification);
+                this.listenTo(this.model.occupants, 'change:role', this.onOccupantRoleChanged);
+                this.listenTo(this.model.occupants, 'change:affiliation', this.onOccupantAffiliationChanged);
 
                 this.render();
                 this.updateAfterMessagesFetched();
@@ -1734,8 +1734,8 @@ converse.plugins.add('converse-muc-views', {
 
             initialize (attrs) {
                 this.chatroomview = attrs.chatroomview;
-                this.chatroomview.model.features.on('change:passwordprotected', this.render, this);
-                this.chatroomview.model.features.on('change:config_stanza', this.render, this);
+                this.listenTo(this.chatroomview.model.features, 'change:passwordprotected', this.render);
+                this.listenTo(this.chatroomview.model.features, 'change:config_stanza', this.render);
                 this.render();
             },
 
@@ -1780,7 +1780,7 @@ converse.plugins.add('converse-muc-views', {
 
             initialize (attrs) {
                 this.chatroomview = attrs.chatroomview;
-                this.model.on('change:validation_message', this.render, this);
+                this.listenTo(this.model, 'change:validation_message', this.render);
                 this.render();
             },
 
@@ -1813,7 +1813,7 @@ converse.plugins.add('converse-muc-views', {
 
             initialize (attrs) {
                 this.chatroomview = attrs.chatroomview;
-                this.model.on('change:validation_message', this.render, this);
+                this.listenTo(this.model, 'change:validation_message', this.render);
                 this.render();
             },
 
@@ -1853,7 +1853,7 @@ converse.plugins.add('converse-muc-views', {
         _converse.ChatRoomOccupantView = Backbone.VDOMView.extend({
             tagName: 'li',
             initialize () {
-                this.model.on('change', this.render, this);
+                this.listenTo(this.model, 'change', this.render);
             },
 
             toHTML () {
@@ -1895,13 +1895,13 @@ converse.plugins.add('converse-muc-views', {
             async initialize () {
                 OrderedListView.prototype.initialize.apply(this, arguments);
 
-                this.model.on('add', this.maybeRenderInviteWidget, this);
-                this.model.on('change:affiliation', this.maybeRenderInviteWidget, this);
+                this.listenTo(this.model, 'add', this.maybeRenderInviteWidget);
+                this.listenTo(this.model, 'change:affiliation', this.maybeRenderInviteWidget);
 
                 this.chatroomview = this.model.chatroomview;
-                this.chatroomview.model.features.on('change', this.renderRoomFeatures, this);
-                this.chatroomview.model.features.on('change:open', this.renderInviteWidget, this);
-                this.chatroomview.model.on('change:hidden_occupants', this.setVisibility, this);
+                this.listenTo(this.chatroomview.model.features, 'change', this.renderRoomFeatures);
+                this.listenTo(this.chatroomview.model.features, 'change:open', this.renderInviteWidget);
+                this.listenTo(this.chatroomview.model, 'change:hidden_occupants', this.setVisibility);
                 this.render();
                 await this.model.fetched;
                 this.sortAndPositionAllItems();

+ 14 - 14
src/converse-omemo.js

@@ -89,11 +89,11 @@ converse.plugins.add('converse-omemo', {
                 const { _converse } = this.__super__;
                 this.debouncedRender = _.debounce(this.render, 50);
                 this.devicelist = _converse.devicelists.get(_converse.bare_jid);
-                this.devicelist.devices.on('change:bundle', this.debouncedRender, this);
-                this.devicelist.devices.on('reset', this.debouncedRender, this);
-                this.devicelist.devices.on('reset', this.debouncedRender, this);
-                this.devicelist.devices.on('remove', this.debouncedRender, this);
-                this.devicelist.devices.on('add', this.debouncedRender, this);
+                this.listenTo(this.devicelist.devices, 'change:bundle', this.debouncedRender);
+                this.listenTo(this.devicelist.devices, 'reset', this.debouncedRender);
+                this.listenTo(this.devicelist.devices, 'reset', this.debouncedRender);
+                this.listenTo(this.devicelist.devices, 'remove', this.debouncedRender);
+                this.listenTo(this.devicelist.devices, 'add', this.debouncedRender);
                 return this.__super__.initialize.apply(this, arguments);
             },
 
@@ -159,11 +159,11 @@ converse.plugins.add('converse-omemo', {
                 const { _converse } = this.__super__;
                 const jid = this.model.get('jid');
                 this.devicelist = _converse.devicelists.getDeviceList(jid);
-                this.devicelist.devices.on('change:bundle', this.render, this);
-                this.devicelist.devices.on('change:trusted', this.render, this);
-                this.devicelist.devices.on('remove', this.render, this);
-                this.devicelist.devices.on('add', this.render, this);
-                this.devicelist.devices.on('reset', this.render, this);
+                this.listenTo(this.devicelist.devices, 'change:bundle', this.render);
+                this.listenTo(this.devicelist.devices, 'change:trusted', this.render);
+                this.listenTo(this.devicelist.devices, 'remove', this.render);
+                this.listenTo(this.devicelist.devices, 'add', this.render);
+                this.listenTo(this.devicelist.devices, 'reset', this.render);
                 return this.__super__.initialize.apply(this, arguments);
             },
 
@@ -217,8 +217,8 @@ converse.plugins.add('converse-omemo', {
 
             initialize () {
                 this.__super__.initialize.apply(this, arguments);
-                this.model.on('change:omemo_active', this.renderOMEMOToolbarButton, this);
-                this.model.on('change:omemo_supported', this.onOMEMOSupportedDetermined, this);
+                this.listenTo(this.model, 'change:omemo_active', this.renderOMEMOToolbarButton);
+                this.listenTo(this.model, 'change:omemo_supported', this.onOMEMOSupportedDetermined);
             },
 
             showMessage (message) {
@@ -236,8 +236,8 @@ converse.plugins.add('converse-omemo', {
 
             initialize () {
                 this.__super__.initialize.apply(this, arguments);
-                this.model.on('change:omemo_active', this.renderOMEMOToolbarButton, this);
-                this.model.on('change:omemo_supported', this.onOMEMOSupportedDetermined, this);
+                this.listenTo(this.model, 'change:omemo_active', this.renderOMEMOToolbarButton);
+                this.listenTo(this.model, 'change:omemo_supported', this.onOMEMOSupportedDetermined);
             }
         }
     },

+ 3 - 3
src/converse-profile.js

@@ -46,7 +46,7 @@ converse.plugins.add('converse-profile', {
             },
 
             initialize () {
-                this.model.on('change', this.render, this);
+                this.listenTo(this.model, 'change', this.render);
                 _converse.BootstrapModal.prototype.initialize.apply(this, arguments);
                 /**
                  * Triggered when the _converse.ProfileModal has been created and initialized.
@@ -234,8 +234,8 @@ converse.plugins.add('converse-profile', {
             },
 
             initialize () {
-                this.model.on("change", this.render, this);
-                this.model.vcard.on("change", this.render, this);
+                this.listenTo(this.model, "change", this.render);
+                this.listenTo(this.model.vcard, "change", this.render);
             },
 
             toHTML () {

+ 9 - 9
src/converse-roomslist.js

@@ -103,13 +103,13 @@ converse.plugins.add('converse-roomslist', {
             },
 
             initialize () {
-                this.model.on('destroy', this.remove, this);
-                this.model.on('remove', this.remove, this);
-                this.model.on('change:bookmarked', this.render, this);
-                this.model.on('change:hidden', this.render, this);
-                this.model.on('change:name', this.render, this);
-                this.model.on('change:num_unread', this.render, this);
-                this.model.on('change:num_unread_general', this.render, this);
+                this.listenTo(this.model, 'destroy', this.remove)
+                this.listenTo(this.model, 'remove', this.remove)
+                this.listenTo(this.model, 'change:bookmarked', this.render)
+                this.listenTo(this.model, 'change:hidden', this.render)
+                this.listenTo(this.model, 'change:name', this.render)
+                this.listenTo(this.model, 'change:num_unread', this.render)
+                this.listenTo(this.model, 'change:num_unread_general', this.render)
             },
 
             toHTML () {
@@ -168,8 +168,8 @@ converse.plugins.add('converse-roomslist', {
             initialize () {
                 OrderedListView.prototype.initialize.apply(this, arguments);
 
-                this.model.on('add', this.showOrHide, this);
-                this.model.on('remove', this.showOrHide, this);
+                this.listenTo(this.model, 'add', this.showOrHide)
+                this.listenTo(this.model, 'remove', this.showOrHide)
 
                 const storage = _converse.config.get('storage'),
                       id = `converse.roomslist${_converse.bare_jid}`;

+ 21 - 21
src/converse-rosterview.js

@@ -68,7 +68,7 @@ converse.plugins.add('converse-rosterview', {
 
             initialize () {
                 _converse.BootstrapModal.prototype.initialize.apply(this, arguments);
-                this.model.on('change', this.render, this);
+                this.listenTo(this.model, 'change', this.render);
             },
 
             toHTML () {
@@ -220,8 +220,8 @@ converse.plugins.add('converse-rosterview', {
             },
 
             initialize () {
-                this.model.on('change:filter_type', this.render, this);
-                this.model.on('change:filter_text', this.render, this);
+                this.listenTo(this.model, 'change:filter_type', this.render);
+                this.listenTo(this.model, 'change:filter_text', this.render);
             },
 
             toHTML () {
@@ -341,14 +341,14 @@ converse.plugins.add('converse-rosterview', {
             },
 
             initialize () {
-                this.model.on("change", this.render, this);
-                this.model.on("highlight", this.highlight, this);
-                this.model.on("destroy", this.remove, this);
-                this.model.on("open", this.openChat, this);
-                this.model.on("remove", this.remove, this);
+                this.listenTo(this.model, "change", this.render);
+                this.listenTo(this.model, "highlight", this.highlight);
+                this.listenTo(this.model, "destroy", this.remove);
+                this.listenTo(this.model, "open", this.openChat);
+                this.listenTo(this.model, "remove", this.remove);
 
-                this.model.presence.on("change:show", this.render, this);
-                this.model.vcard.on('change:fullname', this.render, this);
+                this.listenTo(this.model.presence, "change:show", this.render);
+                this.listenTo(this.model.vcard, 'change:fullname', this.render);
             },
 
             render () {
@@ -551,10 +551,10 @@ converse.plugins.add('converse-rosterview', {
 
             initialize () {
                 OrderedListView.prototype.initialize.apply(this, arguments);
-                this.model.contacts.on("change:subscription", this.onContactSubscriptionChange, this);
-                this.model.contacts.on("change:requesting", this.onContactRequestChange, this);
-                this.model.contacts.on("remove", this.onRemove, this);
-                _converse.roster.on('change:groups', this.onContactGroupChange, this);
+                this.listenTo(this.model.contacts, "change:subscription", this.onContactSubscriptionChange);
+                this.listenTo(this.model.contacts, "change:requesting", this.onContactRequestChange);
+                this.listenTo(this.model.contacts, "remove", this.onRemove);
+                this.listenTo(_converse.roster, 'change:groups', this.onContactGroupChange);
 
                 // This event gets triggered once *all* contacts (i.e. not
                 // just this group's) have been fetched from browser
@@ -748,17 +748,17 @@ converse.plugins.add('converse-rosterview', {
             initialize () {
                 OrderedListView.prototype.initialize.apply(this, arguments);
 
-                _converse.roster.on("add", this.onContactAdded, this);
-                _converse.roster.on('change:groups', this.onContactAdded, this);
-                _converse.roster.on('change', this.onContactChange, this);
-                _converse.roster.on("destroy", this.update, this);
-                _converse.roster.on("remove", this.update, this);
+                this.listenTo(_converse.roster, "add", this.onContactAdded);
+                this.listenTo(_converse.roster, 'change:groups', this.onContactAdded);
+                this.listenTo(_converse.roster, 'change', this.onContactChange);
+                this.listenTo(_converse.roster, "destroy", this.update);
+                this.listenTo(_converse.roster, "remove", this.update);
                 _converse.presences.on('change:show', () => {
                     this.update();
                     this.updateFilter();
                 });
 
-                this.model.on("reset", this.reset, this);
+                this.listenTo(this.model, "reset", this.reset);
 
                 // This event gets triggered once *all* contacts (i.e. not
                 // just this group's) have been fetched from browser
@@ -801,7 +801,7 @@ converse.plugins.add('converse-rosterview', {
                 model.id = `_converse.rosterfilter${_converse.bare_jid}`;
                 model.browserStorage = new BrowserStorage.local(this.filter.id);
                 this.filter_view = new _converse.RosterFilterView({'model': model});
-                this.filter_view.model.on('change', this.updateFilter, this);
+                this.listenTo(this.filter_view.model, 'change', this.updateFilter);
                 this.filter_view.model.fetch();
             },
 

+ 1 - 1
src/headless/converse-chatboxes.js

@@ -326,7 +326,7 @@ converse.plugins.add('converse-chatboxes', {
                 const storage = _converse.config.get('storage');
                 this.messages.browserStorage = new BrowserStorage[storage](this.getMessagesCacheKey());
                 this.messages.chatbox = this;
-                this.messages.on('change:upload', (message) => {
+                this.listenTo(this.messages, 'change:upload', message => {
                     if (message.get('upload') === _converse.SUCCESS) {
                         _converse.api.send(this.createMessageStanza(message));
                     }

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

@@ -52,13 +52,13 @@ converse.plugins.add('converse-disco', {
                 this.features.browserStorage = new BrowserStorage.session(
                     `converse.features-${this.get('jid')}`
                 );
-                this.features.on('add', this.onFeatureAdded, this);
+                this.listenTo(this.features, 'add', this.onFeatureAdded)
 
                 this.fields = new _converse.Collection();
                 this.fields.browserStorage = new BrowserStorage.session(
                     `converse.fields-${this.get('jid')}`
                 );
-                this.fields.on('add', this.onFieldAdded, this);
+                this.listenTo(this.fields, 'add', this.onFieldAdded)
 
                 this.identities = new _converse.Collection();
                 this.identities.browserStorage = new BrowserStorage.session(

+ 0 - 2
src/headless/converse-muc.js

@@ -2304,5 +2304,3 @@ converse.plugins.add('converse-muc', {
         /************************ END API ************************/
     }
 });
-
-

+ 4 - 4
src/headless/converse-roster.js

@@ -153,8 +153,8 @@ converse.plugins.add('converse-roster', {
                 this.resources = new Resources();
                 const id = `converse.identities-${this.get('jid')}`;
                 this.resources.browserStorage = new BrowserStorage.session(id);
-                this.resources.on('update', this.onResourcesChanged, this);
-                this.resources.on('change', this.onResourcesChanged, this);
+                this.listenTo(this.resources, 'update', this.onResourcesChanged);
+                this.listenTo(this.resources, 'change', this.onResourcesChanged);
             },
 
             onResourcesChanged () {
@@ -253,8 +253,8 @@ converse.plugins.add('converse-roster', {
                  * @type { _converse.RosterContact }
                  * @example _converse.api.listen.on('contactPresenceChanged', contact => { ... });
                  */
-                this.presence.on('change:show', () => _converse.api.trigger('contactPresenceChanged', this));
-                this.presence.on('change:show', () => this.trigger('presenceChanged'));
+                this.listenTo(this.presence, 'change:show', () => _converse.api.trigger('contactPresenceChanged', this));
+                this.listenTo(this.presence, 'change:show', () => this.trigger('presenceChanged'));
                 /**
                  * Synchronous event which provides a hook for further initializing a RosterContact
                  * @event _converse#rosterContactInitialized

+ 2 - 2
tests/runner.js

@@ -61,10 +61,10 @@ var specs = [
     "spec/autocomplete",
     "spec/minchats",
     "spec/notification",
-    "spec/emojis",
     "spec/login",
     "spec/register",
-    "spec/http-file-upload"
+    "spec/http-file-upload",
+    "spec/emojis"
 ];
 
 require(['console-reporter', 'mock', 'sinon'], (ConsoleReporter, mock, sinon) => {