Skip to content

Commit

Permalink
fixes #199441 (#199591)
Browse files Browse the repository at this point in the history
  • Loading branch information
joaomoreno authored Nov 29, 2023
1 parent 0947a05 commit 0dd6491
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 5 deletions.
4 changes: 2 additions & 2 deletions src/vs/base/browser/ui/tree/asyncDataTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable

asyncDataTreeNode.element = element;
asyncDataTreeNode.hasChildren = hasChildren;
asyncDataTreeNode.collapsedByDefault = this.collapseByDefault?.(element);

if (recursive) {
if (result.collapsed) {
Expand All @@ -963,8 +964,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
} else {
childrenToRefresh.push(asyncDataTreeNode);
}
} else if (hasChildren && this.collapseByDefault && !this.collapseByDefault(element)) {
asyncDataTreeNode.collapsedByDefault = false;
} else if (hasChildren && !asyncDataTreeNode.collapsedByDefault) {
childrenToRefresh.push(asyncDataTreeNode);
}

Expand Down
62 changes: 59 additions & 3 deletions src/vs/base/test/browser/ui/tree/asyncDataTree.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@

import * as assert from 'assert';
import { IIdentityProvider, IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { AsyncDataTree } from 'vs/base/browser/ui/tree/asyncDataTree';
import { IAsyncDataSource, ITreeNode, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
import { AsyncDataTree, CompressibleAsyncDataTree, ITreeCompressionDelegate } from 'vs/base/browser/ui/tree/asyncDataTree';
import { ICompressedTreeNode } from 'vs/base/browser/ui/tree/compressedObjectTreeModel';
import { ICompressibleTreeRenderer } from 'vs/base/browser/ui/tree/objectTree';
import { IAsyncDataSource, ITreeNode } from 'vs/base/browser/ui/tree/tree';
import { timeout } from 'vs/base/common/async';
import { Iterable } from 'vs/base/common/iterator';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
Expand Down Expand Up @@ -37,7 +39,7 @@ function find(element: Element, id: string): Element | undefined {
return undefined;
}

class Renderer implements ITreeRenderer<Element, void, HTMLElement> {
class Renderer implements ICompressibleTreeRenderer<Element, void, HTMLElement> {
readonly templateId = 'default';
renderTemplate(container: HTMLElement): HTMLElement {
return container;
Expand All @@ -48,6 +50,15 @@ class Renderer implements ITreeRenderer<Element, void, HTMLElement> {
disposeTemplate(templateData: HTMLElement): void {
// noop
}
renderCompressedElements(node: ITreeNode<ICompressedTreeNode<Element>, void>, index: number, templateData: HTMLElement, height: number | undefined): void {
const result: string[] = [];

for (const element of node.element.elements) {
result.push(element.id + (element.suffix || ''));
}

templateData.textContent = result.join('/');
}
}

class IdentityProvider implements IIdentityProvider<Element> {
Expand Down Expand Up @@ -495,4 +506,49 @@ suite('AsyncDataTree', function () {
assert(tree.isCollapsible(a), 'a is still collapsible');
assert(!tree.isCollapsed(a), 'a is expanded');
});

test('issue #199441', async () => {
const container = document.createElement('div');

const dataSource = new class implements IAsyncDataSource<Element, Element> {
hasChildren(element: Element): boolean {
return !!element.children && element.children.length > 0;
}
async getChildren(element: Element) {
return element.children ?? Iterable.empty();
}
};

const compressionDelegate = new class implements ITreeCompressionDelegate<Element> {
isIncompressible(element: Element): boolean {
return !dataSource.hasChildren(element);
}
};

const model = new Model({
id: 'root',
children: [{
id: 'a', children: [{
id: 'b',
children: [{ id: 'b.txt' }]
}]
}]
});

const collapseByDefault = (element: Element) => false;

const tree = store.add(new CompressibleAsyncDataTree<Element, Element>('test', container, new VirtualDelegate(), compressionDelegate, [new Renderer()], dataSource, { identityProvider: new IdentityProvider(), collapseByDefault }));
tree.layout(200);

await tree.setInput(model.root);
assert.deepStrictEqual(Array.from(container.querySelectorAll('.monaco-list-row')).map(e => e.textContent), ['a/b', 'b.txt']);

model.get('a').children!.push({
id: 'c',
children: [{ id: 'c.txt' }]
});

await tree.updateChildren(model.root, true);
assert.deepStrictEqual(Array.from(container.querySelectorAll('.monaco-list-row')).map(e => e.textContent), ['a', 'b', 'b.txt', 'c', 'c.txt']);
});
});

0 comments on commit 0dd6491

Please sign in to comment.