Don't make an unloaded tab reopenable with Undo Close Tab

unload() closes and re-adds the tab, and the close recorded an undo-close
history entry, so Undo Close Tab could open a duplicate of a tab that was
still open.
This commit is contained in:
Dan Stillman 2026-09-04 15:17:34 -04:00
parent e88b7ee10f
commit 92dfac8c64
2 changed files with 26 additions and 3 deletions

View file

@ -722,8 +722,10 @@ var Zotero_Tabs = new function () {
* Close tabs
*
* @param {String|Array<String>|undefined} ids One or more ids, or empty for the current tab
* @param {Object} [options]
* @param {Boolean} [options.skipHistory=false] - Don't make the tabs reopenable with undoClose()
*/
this.close = function (ids) {
this.close = function (ids, { skipHistory = false } = {}) {
if (!ids) {
ids = [this._selectedID];
}
@ -779,7 +781,9 @@ var Zotero_Tabs = new function () {
}
});
}
this._history.push(historyEntry);
if (!skipHistory) {
this._history.push(historyEntry);
}
Zotero.Notifier.trigger('close', 'tab', [closedIDs], true);
this._update();
};
@ -990,7 +994,8 @@ var Zotero_Tabs = new function () {
return;
}
var { tab, tabIndex } = this._getTab(id);
this.close(tab.id);
// The tab stays open, so it isn't reopenable
this.close(tab.id, { skipHistory: true });
this.add({
id: tab.id,
type: `${tab.type}-unloaded`,

View file

@ -41,6 +41,24 @@ describe("Zotero_Tabs", function() {
});
});
describe("#unload()", function () {
it("should not make an unloaded tab reopenable", async function () {
let item = await createDataObject('item');
let attachment = await importPDFAttachment(item);
let reader = await Zotero.Reader.open(attachment.id);
let tabs = win.Zotero_Tabs;
tabs.select('zotero-pane');
let historyLength = tabs._history.length;
tabs.unload(reader.tabID);
let { tab } = tabs._getTab(reader.tabID);
assert.equal(tab.type, 'reader-unloaded');
assert.lengthOf(tabs._history, historyLength);
tabs.close(reader.tabID);
});
});
describe("Window teardown", function () {
it("should not leave observers registered after a window is closed", async function () {
this.timeout(60000);