diff --git a/CHANGELOG.md b/CHANGELOG.md index c0fed8c2bda41f087ed55b6505a877b2dd7fc17f..414b948e2c41b314d74173fb2ee1c22c0f28c001 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ This file contains the changes applied to the sources of converse<br> The current build version of converse is: `v7.0.3dev`<br> If the converse sources have to be updated, apply these changes again, or fix them using plugins +### 2021-06-25 +* Fix memory leaks caused by events not properly disconnected. + ### 2021-05-19 * Avoid clearing the textarea when pressing the ESC key and not editing any messages diff --git a/src/conversejs/converse.js b/src/conversejs/converse.js index e86a471bf1938ebfae7fbd0c0e79f54dade00400..6be0ec3447865efd93a53e6ebbae8a70a2324a20 100644 --- a/src/conversejs/converse.js +++ b/src/conversejs/converse.js @@ -91104,13 +91104,29 @@ function dropdown_taggedTemplateLiteral(strings, raw) { if (!raw) { raw = string const dropdown_u = converse.env.utils; class dropdown_BaseDropdown extends element_CustomElement { + + connectedCallback() { + super.connectedCallback(); + this.registerEvents(); + } + + registerEvents() { + this.clickOutside = this._clickOutside.bind(this); + document.addEventListener('click', this.clickOutside); + } + firstUpdated() { this.menu = this.querySelector('.dropdown-menu'); this.dropdown = this.firstElementChild; this.button = this.dropdown.querySelector('button'); this.dropdown.addEventListener('click', ev => this.toggleMenu(ev)); this.dropdown.addEventListener('keyup', ev => this.handleKeyUp(ev)); - document.addEventListener('click', ev => !this.contains(ev.composedPath()[0]) && this.hideMenu(ev)); + } + + _clickOutside(ev) { + if (!this.contains(ev.composedPath()[0])) { + this.hideMenu(ev); + } } hideMenu() { @@ -91144,6 +91160,10 @@ class dropdown_BaseDropdown extends element_CustomElement { } } + disconnectedCallback() { + document.removeEventListener('click', this.clickOutside); + super.disconnectedCallback(); + } } class dropdown_DropdownList extends dropdown_BaseDropdown { static get properties() { @@ -94071,7 +94091,6 @@ class emoji_picker_EmojiPicker extends element_CustomElement { this.debouncedFilter = lodash_es_debounce(input => this.model.set({ 'query': input.value }), 250); - this.registerEvents(); } get search_results() { @@ -110777,4 +110796,4 @@ converse.initialize = function (settings, callback) { /***/ }) /******/ ]); -//# sourceMappingURL=converse.js.map \ No newline at end of file +//# sourceMappingURL=converse.js.map diff --git a/src/plugins/sib-history-improved.js b/src/plugins/sib-history-improved.js index a9c93c21659b36a54380ff9cf90972a366e00583..2abd12d0446578052577d2be17cfcf544d1c3460 100644 --- a/src/plugins/sib-history-improved.js +++ b/src/plugins/sib-history-improved.js @@ -76,17 +76,21 @@ converse.plugins.add('sib-history-improved', { if (oldest_message) { const by_jid = is_groupchat ? data.chatbox.get('jid') : _converse.bare_jid; const stanza_id = oldest_message && oldest_message['stanza_id '.concat(by_jid)]; + const time = oldest_message['time']; if (stanza_id) { log.info(`Loading messages before stanza: ${stanza_id}`); await data.chatbox.fetchArchivedMessages({ 'before': stanza_id, }); - } else { - log.info(`Loading messages before time: ${oldest_message['time']}`); + } else if (''.concat(time).length) { + log.info(`Loading messages before time: ${time}`); await data.chatbox.fetchArchivedMessages({ - 'end': oldest_message['time'], + 'end': time, }); + } else { + log.info(`Couldn't load more messages before the oldest (stanza_id: "${stanza_id}", time: "${time}")`); + console.warn(oldest_message); } } }); diff --git a/src/plugins/sib-reactions.js b/src/plugins/sib-reactions.js index 61d54da65c249b7dc0cf1f206782e8dbfb903a23..3a18a64bf9aad98ce0891e70a7da0ddd1980eec0 100644 --- a/src/plugins/sib-reactions.js +++ b/src/plugins/sib-reactions.js @@ -61,6 +61,12 @@ converse.plugins.add('sib-reactions', { Strophe.addNamespace('REACTIONS', 'urn:xmpp:reactions:0'); + /** + * Document callback (when clicking outside of the picker) + * TODO: This is a quick and dirty implementation, needs update + */ + let documentCallback; + /** * Send a reaction stanza for this user with the given emojis. * @param message @@ -225,6 +231,11 @@ converse.plugins.add('sib-reactions', { const picker = new Picker(); picker.classList.add('light', 'emoji-reaction-select'); + function closePicker() { + picker.remove(); + document.removeEventListener('click', documentCallback); + } + picker.addEventListener('emoji-click', e => { const emoji = e.detail.unicode; const emojis = getUserReactionEmojis(this.model); @@ -232,12 +243,12 @@ converse.plugins.add('sib-reactions', { // TODO: If it has the reaction from this user already, remove it? (config) if (emojis?.includes(emoji)) { log.warn(`The emoji "${emoji}" is already in the list of this user reactions`); - picker.remove(); + closePicker(); return; } emojis.push(emoji); - picker.remove(); + closePicker(); sendReactionStanza(this.model, emojis); }); @@ -245,18 +256,18 @@ converse.plugins.add('sib-reactions', { // Close the picker if the ESC key is pressed picker.addEventListener('keydown', ev => { if (ev.key === 'Escape') { - picker.remove(); + closePicker(); } }); // Close the picker if clicked outside of it - // TODO: Remove this listener when the picker is removed from the dom setTimeout(() => { - document.addEventListener('click', ev => { + documentCallback = ev => { if (!picker.shadowRoot.contains(ev.composedPath()[0])) { - picker.remove(); + closePicker(); } - }); + }; + document.addEventListener('click', documentCallback); }); // Append picker to the document