mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-02 00:09:30 +01:00
multi select adoption for compressed tree
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IDragAndDropData } from '../../dnd.js';
|
||||
import { IIdentityProvider, IKeyboardNavigationLabelProvider, IListDragAndDrop, IListDragOverReaction, IListMouseEvent, IListTouchEvent, IListVirtualDelegate } from '../list/list.js';
|
||||
import { IIdentityProvider, IKeyboardNavigationLabelProvider, IListDragAndDrop, IListDragOverReaction, IListMouseEvent, IListTouchEvent, IListVirtualDelegate, NotSelectableGroupIdType } from '../list/list.js';
|
||||
import { ElementsDragAndDropData, ListViewTargetSector } from '../list/listView.js';
|
||||
import { IListStyles } from '../list/listWidget.js';
|
||||
import { ComposedTreeDelegate, TreeFindMode, IAbstractTreeOptions, IAbstractTreeOptionsUpdate, TreeFindMatchType, AbstractTreePart, LabelFuzzyScore, FindFilter, FindController, ITreeFindToggleChangeEvent, IFindControllerOptions, IStickyScrollDelegate, AbstractTree } from './abstractTree.js';
|
||||
@@ -1309,7 +1309,10 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
||||
diffIdentityProvider: options.diffIdentityProvider && {
|
||||
getId(node: IAsyncDataTreeNode<TInput, T>): { toString(): string } {
|
||||
return options.diffIdentityProvider!.getId(node.element as T);
|
||||
}
|
||||
},
|
||||
getGroupId: options.diffIdentityProvider!.getGroupId ? (node: IAsyncDataTreeNode<TInput, T>): number | NotSelectableGroupIdType => {
|
||||
return options.diffIdentityProvider!.getGroupId!(node.element as T);
|
||||
} : undefined
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IIdentityProvider } from '../list/list.js';
|
||||
import { IIdentityProvider, NotSelectableGroupIdType } from '../list/list.js';
|
||||
import { getVisibleState, IIndexTreeModelSpliceOptions, isFilterResult } from './indexTreeModel.js';
|
||||
import { IObjectTreeModel, IObjectTreeModelOptions, IObjectTreeModelSetChildrenOptions, ObjectTreeModel } from './objectTreeModel.js';
|
||||
import { ICollapseStateChangeEvent, IObjectTreeElement, ITreeListSpliceData, ITreeModel, ITreeModelSpliceEvent, ITreeNode, TreeError, TreeFilterResult, TreeVisibility, WeakMapper } from './tree.js';
|
||||
@@ -113,7 +113,10 @@ interface ICompressedObjectTreeModelOptions<T, TFilterData> extends IObjectTreeM
|
||||
const wrapIdentityProvider = <T>(base: IIdentityProvider<T>): IIdentityProvider<ICompressedTreeNode<T>> => ({
|
||||
getId(node) {
|
||||
return node.elements.map(e => base.getId(e).toString()).join('\0');
|
||||
}
|
||||
},
|
||||
getGroupId: base.getGroupId ? (node: ICompressedTreeNode<T>): number | NotSelectableGroupIdType => {
|
||||
return base.getGroupId!(node.elements[node.elements.length - 1]);
|
||||
} : undefined
|
||||
});
|
||||
|
||||
// Exported only for test reasons, do not use directly
|
||||
@@ -380,7 +383,10 @@ function mapOptions<T, TFilterData>(compressedNodeUnwrapper: CompressedNodeUnwra
|
||||
identityProvider: options.identityProvider && {
|
||||
getId(node: ICompressedTreeNode<T>): { toString(): string } {
|
||||
return options.identityProvider!.getId(compressedNodeUnwrapper(node));
|
||||
}
|
||||
},
|
||||
getGroupId: options.identityProvider!.getGroupId ? (node: ICompressedTreeNode<T>): number | NotSelectableGroupIdType => {
|
||||
return options.identityProvider!.getGroupId!(compressedNodeUnwrapper(node));
|
||||
} : undefined
|
||||
},
|
||||
sorter: options.sorter && {
|
||||
compare(node: ICompressedTreeNode<T>, otherNode: ICompressedTreeNode<T>): number {
|
||||
|
||||
@@ -8,6 +8,7 @@ import { IIdentityProvider, IListVirtualDelegate } from '../../../../browser/ui/
|
||||
import { ICompressedTreeNode } from '../../../../browser/ui/tree/compressedObjectTreeModel.js';
|
||||
import { CompressibleObjectTree, ICompressibleTreeRenderer, ObjectTree } from '../../../../browser/ui/tree/objectTree.js';
|
||||
import { ITreeNode, ITreeRenderer } from '../../../../browser/ui/tree/tree.js';
|
||||
import { runWithFakedTimers } from '../../../common/timeTravelScheduler.js';
|
||||
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../common/utils.js';
|
||||
|
||||
function getRowsTextContent(container: HTMLElement): string[] {
|
||||
@@ -16,6 +17,17 @@ function getRowsTextContent(container: HTMLElement): string[] {
|
||||
return rows.map(row => row.querySelector('.monaco-tl-contents')!.textContent!);
|
||||
}
|
||||
|
||||
function clickElement(element: HTMLElement, ctrlKey = false): void {
|
||||
element.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, ctrlKey, button: 0 }));
|
||||
element.dispatchEvent(new MouseEvent('click', { bubbles: true, ctrlKey, button: 0 }));
|
||||
}
|
||||
|
||||
function dispatchKeydown(element: HTMLElement, key: string, code: string, keyCode: number): void {
|
||||
const keyboardEvent = new KeyboardEvent('keydown', { bubbles: true, key, code });
|
||||
Object.defineProperty(keyboardEvent, 'keyCode', { get: () => keyCode });
|
||||
element.dispatchEvent(keyboardEvent);
|
||||
}
|
||||
|
||||
suite('ObjectTree', function () {
|
||||
|
||||
suite('TreeNavigator', function () {
|
||||
@@ -231,6 +243,84 @@ suite('ObjectTree', function () {
|
||||
tree.setChildren(null, [{ element: 100 }, { element: 101 }, { element: 102 }, { element: 103 }]);
|
||||
assert.deepStrictEqual(tree.getFocus(), [101]);
|
||||
});
|
||||
|
||||
test('updateOptions preserves wrapped identity provider in view options', function () {
|
||||
const container = document.createElement('div');
|
||||
container.style.width = '200px';
|
||||
container.style.height = '200px';
|
||||
|
||||
const delegate = new Delegate();
|
||||
const renderer = new Renderer();
|
||||
const identityProvider = {
|
||||
getId(element: number): { toString(): string } {
|
||||
return `${element}`;
|
||||
},
|
||||
getGroupId(element: number): number {
|
||||
return element % 2;
|
||||
}
|
||||
};
|
||||
|
||||
const tree = new ObjectTree<number>('test', container, delegate, [renderer], { identityProvider });
|
||||
|
||||
try {
|
||||
tree.layout(200);
|
||||
tree.setChildren(null, [{ element: 0 }, { element: 1 }, { element: 2 }, { element: 3 }]);
|
||||
|
||||
const firstRow = container.querySelector('.monaco-list-row[data-index="0"]') as HTMLElement;
|
||||
const secondRow = container.querySelector('.monaco-list-row[data-index="1"]') as HTMLElement;
|
||||
clickElement(firstRow);
|
||||
assert.deepStrictEqual(tree.getSelection(), [0]);
|
||||
|
||||
tree.updateOptions({ indent: 12 });
|
||||
|
||||
clickElement(secondRow, true);
|
||||
|
||||
assert.deepStrictEqual(tree.getSelection(), [1]);
|
||||
} finally {
|
||||
tree.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
test('updateOptions preserves wrapped accessibility provider for type navigation re-announce', async function () {
|
||||
const container = document.createElement('div');
|
||||
container.style.width = '200px';
|
||||
container.style.height = '200px';
|
||||
|
||||
const delegate = new Delegate();
|
||||
const renderer = new Renderer();
|
||||
const accessibilityProvider = {
|
||||
getAriaLabel(element: number): string {
|
||||
assert.strictEqual(typeof element, 'number');
|
||||
return `aria ${element}`;
|
||||
},
|
||||
getWidgetAriaLabel(): string {
|
||||
return 'tree';
|
||||
}
|
||||
};
|
||||
|
||||
const tree = new ObjectTree<number>('test', container, delegate, [renderer], {
|
||||
accessibilityProvider,
|
||||
keyboardNavigationLabelProvider: {
|
||||
getKeyboardNavigationLabel: () => 'a'
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
await runWithFakedTimers({ useFakeTimers: true }, async () => {
|
||||
tree.layout(200);
|
||||
tree.setChildren(null, [{ element: 0 }]);
|
||||
tree.setFocus([0]);
|
||||
tree.domFocus();
|
||||
|
||||
tree.updateOptions({ indent: 12 });
|
||||
|
||||
dispatchKeydown(tree.getHTMLElement(), 'a', 'KeyA', 65);
|
||||
await Promise.resolve();
|
||||
});
|
||||
} finally {
|
||||
tree.dispose();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
suite('CompressibleObjectTree', function () {
|
||||
|
||||
Reference in New Issue
Block a user