This commit is contained in:
abaevbog 2026-06-06 13:56:11 +08:00 • committed by GitHub
commit 81c8bba9e7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 40 additions and 17 deletions

View file

@ -2685,34 +2685,39 @@ var CollectionTree = class CollectionTree extends LibraryTree {
}
}
}
// If the filter has been cleared and the selection has not changed, restore the initial scroll position
if (shouldRestoreScrollPosition) {
// For the initial scroll position to make sense, collapse rows that were initially collapsed
// Filter has been cleared: restore collapsed state of collections and scroll position
if (willBeEmpty && !isEmpty) {
let selectedCollectionID = this.getSelectedCollection(true);
for (let rowID of this._filterInitialCollapsedRows) {
let index = this.getRowIndexByID(rowID);
if (index && this._rows[index].isOpen) {
let row = this._rows[index];
if (!row || !row.isCollection()) continue;
// Do not collapse ancestory of selected collection
let descendents = new Set(Zotero.Collections.getByParent(row.ref.id, true, false).map(col => col.id));
if (row.isOpen && !descendents.has(selectedCollectionID)) {
this.toggleOpenState(index);
}
}
this._filterInitialCollapsedRows = [];
collectionTable.scrollTop = this._filterInitialScrollPosition;
this._filterInitialScrollPosition = null;
// If collection tree was focused, scroll the selected row to the middle
if (this._treeWasFocused) {
let selectedRow = collectionTable.querySelector(".row.selected");
let rowRect = selectedRow.getBoundingClientRect();
let tableRect = collectionTable.getBoundingClientRect();
let rowMiddle = rowRect.top + rowRect.height / 2;
let tableMiddle = tableRect.top + tableRect.height / 2;
collectionTable.scrollTop = collectionTable.scrollTop + rowMiddle - tableMiddle;
}
// Otherwise, restore the initial scroll position
else {
collectionTable.scrollTop = this._filterInitialScrollPosition;
this._filterInitialScrollPosition = null;
}
}
// During filtering, scroll to the very top
else if (!willBeEmpty) {
collectionTable.scrollTop = 0;
}
// If the filtering is cleared and the selection has changed, scroll to have the
// newly selected row in the middle
else if (willBeEmpty && !isEmpty) {
let selectedRow = collectionTable.querySelector(".row.selected");
let rowRect = selectedRow.getBoundingClientRect();
let tableRect = collectionTable.getBoundingClientRect();
let rowMiddle = rowRect.top + rowRect.height / 2;
let tableMiddle = tableRect.top + tableRect.height / 2;
let scrollPosition = collectionTable.scrollTop + rowMiddle - tableMiddle;
collectionTable.scrollTop = scrollPosition;
}
// Focus the collection tree
if (focusTree) {
collectionTable.parentNode.focus();

View file

@ -1616,6 +1616,8 @@ describe("Zotero.CollectionTree", function () {
});
it('should collapse collections collapsed before filtering', async function () {
// Select collection 1
await cv.selectByID(`C${collection1.id}`);
// Collapse top level collections 1 and 6
for (let c of [collection1, collection6]) {
let index = cv.getRowIndexByID("C" + c.id);
@ -1644,6 +1646,22 @@ describe("Zotero.CollectionTree", function () {
assert.isFalse(colOneRow.isOpen);
let colSixRow = cv.getRow(cv.getRowIndexByID("C" + collection6.id));
assert.isFalse(colSixRow.isOpen);
// Filter by 'collection' - this will expand all collections
await cv.setFilter('collection');
assert.isTrue(cv.getRow(cv.getRowIndexByID("C" + collection1.id)).isOpen);
assert.isTrue(cv.getRow(cv.getRowIndexByID("C" + collection2.id)).isOpen);
assert.isTrue(cv.getRow(cv.getRowIndexByID("C" + collection6.id)).isOpen);
// Select collection 8 and clear filter
await cv.selectByID(`C${collection8.id}`);
await cv.setFilter("");
// Collection 1 should be collapsed because it was collapsed before filtering
assert.isFalse(cv.getRow(cv.getRowIndexByID("C" + collection1.id)).isOpen);
// Collection 6 should be expanded because it's child (collection 8) is selected
assert.isTrue(cv.getRow(cv.getRowIndexByID("C" + collection6.id)).isOpen);
});
for (let type of ['collection', 'search']) {