diff --git a/chrome/content/zotero/collectionTree.jsx b/chrome/content/zotero/collectionTree.jsx index 9dc6b2c114..21de5676ad 100644 --- a/chrome/content/zotero/collectionTree.jsx +++ b/chrome/content/zotero/collectionTree.jsx @@ -1367,6 +1367,7 @@ var CollectionTree = class CollectionTree extends LibraryTree { unregister() { this._uninitialized = true; Zotero.Notifier.unregisterObserver(this._unregisterID); + this.clearEventListeners(); } //////////////////////////////////////////////////////////////////////////////// diff --git a/chrome/content/zotero/itemTree.jsx b/chrome/content/zotero/itemTree.jsx index 192626fa43..748372ace1 100644 --- a/chrome/content/zotero/itemTree.jsx +++ b/chrome/content/zotero/itemTree.jsx @@ -1145,6 +1145,7 @@ var ItemTree = class ItemTree extends LibraryTree { for (let id of this._prefsObserverIDs) { Zotero.Prefs.unregisterObserver(id); } + this.clearEventListeners(); this._writeColumnPrefsToFile(true); } diff --git a/chrome/content/zotero/xpcom/utilities_internal.js b/chrome/content/zotero/xpcom/utilities_internal.js index d6fb48e231..5eda717f7f 100644 --- a/chrome/content/zotero/xpcom/utilities_internal.js +++ b/chrome/content/zotero/xpcom/utilities_internal.js @@ -2374,6 +2374,14 @@ Zotero.Utilities.Internal = { } ev.listeners.delete(listener); }; + + /** + * Remove all listeners from all events, so that an object being torn down doesn't + * keep its listeners' closures alive + */ + cls.prototype.clearEventListeners = function () { + this._events = null; + }; cls.prototype._waitForEvent = async function (event) { return new Zotero.Promise((resolve) => { diff --git a/chrome/content/zotero/zoteroPane.js b/chrome/content/zotero/zoteroPane.js index bb47aed176..0d7ab0b0ef 100644 --- a/chrome/content/zotero/zoteroPane.js +++ b/chrome/content/zotero/zoteroPane.js @@ -38,6 +38,8 @@ var ZoteroPane = new function () { this._listeners = {}; this.__defineGetter__('loaded', function () { return _loaded; }); var _lastSelectedItems = []; + // [element, listener] for the collection tree focus listener added in initCollectionsTree() + var _collectionsTreeFocusListener = null; var lastFocusedElement = null; this.lastKeyPress = null; @@ -779,6 +781,11 @@ var ZoteroPane = new function () { this.serializePersist(); + if (_collectionsTreeFocusListener) { + let [elem, listener] = _collectionsTreeFocusListener; + elem.removeEventListener("focus", listener); + _collectionsTreeFocusListener = null; + } if(this.collectionsView) this.collectionsView.unregister(); if(this.itemsView) this.itemsView.unregister(); if (_syncRemindersObserverID) { @@ -1651,7 +1658,10 @@ var ZoteroPane = new function () { dragAndDrop: true, multiSelect: true }); - collectionsTree.firstChild.addEventListener("focus", ZoteroPane.collectionsView.recordCollectionTreeFocus); + let treeElem = collectionsTree.firstChild; + let focusListener = ZoteroPane.collectionsView.recordCollectionTreeFocus; + treeElem.addEventListener("focus", focusListener); + _collectionsTreeFocusListener = [treeElem, focusListener]; } catch (e) { Zotero.logError(e);