Skip to content

Commit

Permalink
fixes #80097
Browse files Browse the repository at this point in the history
  • Loading branch information
joaomoreno committed Aug 30, 2019
1 parent 2c76262 commit defb232
Show file tree
Hide file tree
Showing 49 changed files with 289 additions and 234 deletions.
7 changes: 7 additions & 0 deletions src/vs/base/browser/ui/list/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,10 @@ export interface IListDragAndDrop<T> {
onDragOver(data: IDragAndDropData, targetElement: T | undefined, targetIndex: number | undefined, originalEvent: DragEvent): boolean | IListDragOverReaction;
drop(data: IDragAndDropData, targetElement: T | undefined, targetIndex: number | undefined, originalEvent: DragEvent): void;
}

export class ListError extends Error {

constructor(user: string, message: string) {
super(`ListError [${user}] ${message}`);
}
}
3 changes: 2 additions & 1 deletion src/vs/base/browser/ui/list/listPaging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,14 @@ export class PagedList<T> implements IDisposable {
private _model!: IPagedModel<T>;

constructor(
user: string,
container: HTMLElement,
virtualDelegate: IListVirtualDelegate<number>,
renderers: IPagedRenderer<T, any>[],
options: IListOptions<any> = {}
) {
const pagedRenderers = renderers.map(r => new PagedRenderer<T, ITemplateData<T>>(r, () => this.model));
this.list = new List(container, virtualDelegate, pagedRenderers, options);
this.list = new List(user, container, virtualDelegate, pagedRenderers, options);
}

getHTMLElement(): HTMLElement {
Expand Down
19 changes: 10 additions & 9 deletions src/vs/base/browser/ui/list/listWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { KeyCode } from 'vs/base/common/keyCodes';
import { StandardKeyboardEvent, IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { Event, Emitter, EventBufferer } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { IListVirtualDelegate, IListRenderer, IListEvent, IListContextMenuEvent, IListMouseEvent, IListTouchEvent, IListGestureEvent, IIdentityProvider, IKeyboardNavigationLabelProvider, IListDragAndDrop, IListDragOverReaction, ListAriaRootRole } from './list';
import { IListVirtualDelegate, IListRenderer, IListEvent, IListContextMenuEvent, IListMouseEvent, IListTouchEvent, IListGestureEvent, IIdentityProvider, IKeyboardNavigationLabelProvider, IListDragAndDrop, IListDragOverReaction, ListAriaRootRole, ListError } from './list';
import { ListView, IListViewOptions, IListViewDragAndDrop, IAriaProvider } from './listView';
import { Color } from 'vs/base/common/color';
import { mixin } from 'vs/base/common/objects';
Expand Down Expand Up @@ -1170,6 +1170,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
readonly onDidDispose: Event<void> = this._onDidDispose.event;

constructor(
private user: string,
container: HTMLElement,
virtualDelegate: IListVirtualDelegate<T>,
renderers: IListRenderer<any /* TODO@joao */, any>[],
Expand Down Expand Up @@ -1261,11 +1262,11 @@ export class List<T> implements ISpliceable<T>, IDisposable {

splice(start: number, deleteCount: number, elements: T[] = []): void {
if (start < 0 || start > this.view.length) {
throw new Error(`Invalid start index: ${start}`);
throw new ListError(this.user, `Invalid start index: ${start}`);
}

if (deleteCount < 0) {
throw new Error(`Invalid delete count: ${deleteCount}`);
throw new ListError(this.user, `Invalid delete count: ${deleteCount}`);
}

if (deleteCount === 0 && elements.length === 0) {
Expand Down Expand Up @@ -1348,7 +1349,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
setSelection(indexes: number[], browserEvent?: UIEvent): void {
for (const index of indexes) {
if (index < 0 || index >= this.length) {
throw new Error(`Invalid index ${index}`);
throw new ListError(this.user, `Invalid index ${index}`);
}
}

Expand All @@ -1366,7 +1367,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
setFocus(indexes: number[], browserEvent?: UIEvent): void {
for (const index of indexes) {
if (index < 0 || index >= this.length) {
throw new Error(`Invalid index ${index}`);
throw new ListError(this.user, `Invalid index ${index}`);
}
}

Expand Down Expand Up @@ -1518,7 +1519,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {

reveal(index: number, relativeTop?: number): void {
if (index < 0 || index >= this.length) {
throw new Error(`Invalid index ${index}`);
throw new ListError(this.user, `Invalid index ${index}`);
}

const scrollTop = this.view.getScrollTop();
Expand Down Expand Up @@ -1547,7 +1548,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
*/
getRelativeTop(index: number): number | null {
if (index < 0 || index >= this.length) {
throw new Error(`Invalid index ${index}`);
throw new ListError(this.user, `Invalid index ${index}`);
}

const scrollTop = this.view.getScrollTop();
Expand All @@ -1574,7 +1575,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
open(indexes: number[], browserEvent?: UIEvent): void {
for (const index of indexes) {
if (index < 0 || index >= this.length) {
throw new Error(`Invalid index ${index}`);
throw new ListError(this.user, `Invalid index ${index}`);
}
}

Expand All @@ -1584,7 +1585,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
pin(indexes: number[]): void {
for (const index of indexes) {
if (index < 0 || index >= this.length) {
throw new Error(`Invalid index ${index}`);
throw new ListError(this.user, `Invalid index ${index}`);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/vs/base/browser/ui/selectBox/selectBoxCustom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,7 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi

this.listRenderer = new SelectListRenderer();

this.selectList = new List(this.selectDropDownListContainer, this, [this.listRenderer], {
this.selectList = new List('SelectBoxCustom', this.selectDropDownListContainer, this, [this.listRenderer], {
ariaLabel: this.selectBoxOptions.ariaLabel,
useShadows: false,
verticalScrollMode: ScrollbarVisibility.Visible,
Expand Down
10 changes: 6 additions & 4 deletions src/vs/base/browser/ui/tree/abstractTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1087,14 +1087,15 @@ interface ITreeNodeListOptions<T, TFilterData, TRef> extends IListOptions<ITreeN
class TreeNodeList<T, TFilterData, TRef> extends List<ITreeNode<T, TFilterData>> {

constructor(
user: string,
container: HTMLElement,
virtualDelegate: IListVirtualDelegate<ITreeNode<T, TFilterData>>,
renderers: IListRenderer<any /* TODO@joao */, any>[],
private focusTrait: Trait<T>,
private selectionTrait: Trait<T>,
options: ITreeNodeListOptions<T, TFilterData, TRef>
) {
super(container, virtualDelegate, renderers, options);
super(user, container, virtualDelegate, renderers, options);
}

protected createMouseController(options: ITreeNodeListOptions<T, TFilterData, TRef>): MouseController<ITreeNode<T, TFilterData>> {
Expand Down Expand Up @@ -1195,6 +1196,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
get onDidDispose(): Event<void> { return this.view.onDidDispose; }

constructor(
user: string,
container: HTMLElement,
delegate: IListVirtualDelegate<T>,
renderers: ITreeRenderer<T, TFilterData, any>[],
Expand All @@ -1220,9 +1222,9 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable

this.focus = new Trait(_options.identityProvider);
this.selection = new Trait(_options.identityProvider);
this.view = new TreeNodeList(container, treeDelegate, this.renderers, this.focus, this.selection, { ...asListOptions(() => this.model, _options), tree: this });
this.view = new TreeNodeList(user, container, treeDelegate, this.renderers, this.focus, this.selection, { ...asListOptions(() => this.model, _options), tree: this });

this.model = this.createModel(this.view, _options);
this.model = this.createModel(user, this.view, _options);
onDidChangeCollapseStateRelay.input = this.model.onDidChangeCollapseState;

this.model.onDidSplice(e => {
Expand Down Expand Up @@ -1586,7 +1588,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
this.model.setCollapsed(location, undefined, recursive);
}

protected abstract createModel(view: ISpliceable<ITreeNode<T, TFilterData>>, options: IAbstractTreeOptions<T, TFilterData>): ITreeModel<T, TFilterData, TRef>;
protected abstract createModel(user: string, view: ISpliceable<ITreeNode<T, TFilterData>>, options: IAbstractTreeOptions<T, TFilterData>): ITreeModel<T, TFilterData, TRef>;

navigate(start?: TRef): ITreeNavigator<T> {
return new TreeNavigator(this.view, this.model, start);
Expand Down
13 changes: 7 additions & 6 deletions src/vs/base/browser/ui/tree/asyncDataTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { ComposedTreeDelegate, IAbstractTreeOptions, IAbstractTreeOptionsUpdate } from 'vs/base/browser/ui/tree/abstractTree';
import { ObjectTree, IObjectTreeOptions } from 'vs/base/browser/ui/tree/objectTree';
import { IListVirtualDelegate, IIdentityProvider, IListDragAndDrop, IListDragOverReaction } from 'vs/base/browser/ui/list/list';
import { ITreeElement, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeSorter, ICollapseStateChangeEvent, IAsyncDataSource, ITreeDragAndDrop } from 'vs/base/browser/ui/tree/tree';
import { ITreeElement, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeSorter, ICollapseStateChangeEvent, IAsyncDataSource, ITreeDragAndDrop, TreeError } from 'vs/base/browser/ui/tree/tree';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Emitter, Event } from 'vs/base/common/event';
import { timeout, CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
Expand Down Expand Up @@ -339,6 +339,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
get onDidDispose(): Event<void> { return this.tree.onDidDispose; }

constructor(
private user: string,
container: HTMLElement,
delegate: IListVirtualDelegate<T>,
renderers: ITreeRenderer<T, TFilterData, any>[],
Expand All @@ -354,7 +355,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
const objectTreeRenderers = renderers.map(r => new DataTreeRenderer(r, this._onDidChangeNodeSlowState.event));
const objectTreeOptions = asObjectTreeOptions<TInput, T, TFilterData>(options) || {};

this.tree = new ObjectTree(container, objectTreeDelegate, objectTreeRenderers, objectTreeOptions);
this.tree = new ObjectTree(user, container, objectTreeDelegate, objectTreeRenderers, objectTreeOptions);

this.root = createAsyncDataTreeNode({
element: undefined!,
Expand Down Expand Up @@ -464,7 +465,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable

async updateChildren(element: TInput | T = this.root.element, recursive = true, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): Promise<void> {
if (typeof this.root.element === 'undefined') {
throw new Error('Tree input not set');
throw new TreeError(this.user, 'Tree input not set');
}

if (this.root.loading) {
Expand Down Expand Up @@ -515,7 +516,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable

async expand(element: T, recursive: boolean = false): Promise<boolean> {
if (typeof this.root.element === 'undefined') {
throw new Error('Tree input not set');
throw new TreeError(this.user, 'Tree input not set');
}

if (this.root.loading) {
Expand Down Expand Up @@ -643,7 +644,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
const node: IAsyncDataTreeNode<TInput, T> | undefined = this.nodes.get((element === this.root.element ? null : element) as T);

if (!node) {
throw new Error(`Data tree node not found: ${element}`);
throw new TreeError(this.user, `Data tree node not found: ${element}`);
}

return node;
Expand Down Expand Up @@ -875,7 +876,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable

getViewState(): IAsyncDataTreeViewState {
if (!this.identityProvider) {
throw new Error('Can\'t get tree view state without an identity provider');
throw new TreeError(this.user, 'Can\'t get tree view state without an identity provider');
}

const getId = (element: T) => this.identityProvider!.getId(element).toString();
Expand Down
7 changes: 4 additions & 3 deletions src/vs/base/browser/ui/tree/compressedObjectTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ export class CompressedObjectTree<T extends NonNullable<any>, TFilterData = void
get onDidChangeCollapseState(): Event<ICollapseStateChangeEvent<ICompressedTreeNode<T> | null, TFilterData>> { return this.model.onDidChangeCollapseState; }

constructor(
user: string,
container: HTMLElement,
delegate: IListVirtualDelegate<ICompressedTreeNode<T>>,
renderers: ITreeRenderer<ICompressedTreeNode<T>, TFilterData, any>[],
options: IObjectTreeOptions<ICompressedTreeNode<T>, TFilterData> = {}
) {
super(container, delegate, renderers, options);
super(user, container, delegate, renderers, options);
}

setChildren(
Expand All @@ -50,7 +51,7 @@ export class CompressedObjectTree<T extends NonNullable<any>, TFilterData = void
this.model.resort(element, recursive);
}

protected createModel(view: ISpliceable<ITreeNode<ICompressedTreeNode<T>, TFilterData>>, options: IObjectTreeOptions<ICompressedTreeNode<T>, TFilterData>): ITreeModel<ICompressedTreeNode<T> | null, TFilterData, T | null> {
return new CompressedTreeModel(view, options);
protected createModel(user: string, view: ISpliceable<ITreeNode<ICompressedTreeNode<T>, TFilterData>>, options: IObjectTreeOptions<ICompressedTreeNode<T>, TFilterData>): ITreeModel<ICompressedTreeNode<T> | null, TFilterData, T | null> {
return new CompressedTreeModel(user, view, options);
}
}
17 changes: 11 additions & 6 deletions src/vs/base/browser/ui/tree/compressedObjectTreeModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { ISpliceable } from 'vs/base/common/sequence';
import { Iterator, ISequence } from 'vs/base/common/iterator';
import { Event } from 'vs/base/common/event';
import { ITreeModel, ITreeNode, ITreeElement, ICollapseStateChangeEvent, ITreeModelSpliceEvent } from 'vs/base/browser/ui/tree/tree';
import { ITreeModel, ITreeNode, ITreeElement, ICollapseStateChangeEvent, ITreeModelSpliceEvent, TreeError } from 'vs/base/browser/ui/tree/tree';
import { IObjectTreeModelOptions, ObjectTreeModel, IObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel';

export interface ICompressedTreeElement<T> extends ITreeElement<T> {
Expand Down Expand Up @@ -95,8 +95,12 @@ export class CompressedTreeModel<T extends NonNullable<any>, TFilterData extends

get size(): number { return this.nodes.size; }

constructor(list: ISpliceable<ITreeNode<ICompressedTreeNode<T>, TFilterData>>, options: ICompressedTreeModelOptions<T, TFilterData> = {}) {
this.model = new ObjectTreeModel(list, options);
constructor(
private user: string,
list: ISpliceable<ITreeNode<ICompressedTreeNode<T>, TFilterData>>,
options: ICompressedTreeModelOptions<T, TFilterData> = {}
) {
this.model = new ObjectTreeModel(user, list, options);
}

setChildren(
Expand Down Expand Up @@ -264,7 +268,7 @@ export class CompressedTreeModel<T extends NonNullable<any>, TFilterData extends
const node = this.nodes.get(element);

if (!node) {
throw new Error(`Tree element not found: ${element}`);
throw new TreeError(this.user, `Tree element not found: ${element}`);
}

return node;
Expand Down Expand Up @@ -320,12 +324,13 @@ export class CompressedObjectTreeModel<T extends NonNullable<any>, TFilterData e
private model: CompressedTreeModel<T, TFilterData>;

constructor(
user: string,
list: ISpliceable<ITreeNode<ICompressedTreeNode<T>, TFilterData>>,
options: ICompressedObjectTreeModelOptions<T, TFilterData> = {}
) {
this.mapElement = options.elementMapper || DefaultElementMapper;
this.mapNode = createNodeMapper(this.mapElement);
this.model = new CompressedTreeModel(list, options);
this.model = new CompressedTreeModel(user, list, options);
}

setChildren(
Expand Down Expand Up @@ -415,4 +420,4 @@ export class CompressedObjectTreeModel<T extends NonNullable<any>, TFilterData e
resort(element: T | null = null, recursive = true): void {
return this.model.resort(element, recursive);
}
}
}
15 changes: 8 additions & 7 deletions src/vs/base/browser/ui/tree/dataTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { AbstractTree, IAbstractTreeOptions } from 'vs/base/browser/ui/tree/abstractTree';
import { ISpliceable } from 'vs/base/common/sequence';
import { ITreeNode, ITreeModel, ITreeElement, ITreeRenderer, ITreeSorter, IDataSource } from 'vs/base/browser/ui/tree/tree';
import { ITreeNode, ITreeModel, ITreeElement, ITreeRenderer, ITreeSorter, IDataSource, TreeError } from 'vs/base/browser/ui/tree/tree';
import { ObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel';
import { IListVirtualDelegate, IIdentityProvider } from 'vs/base/browser/ui/list/list';
import { Iterator } from 'vs/base/common/iterator';
Expand All @@ -30,13 +30,14 @@ export class DataTree<TInput, T, TFilterData = void> extends AbstractTree<T | nu
private nodesByIdentity = new Map<string, ITreeNode<T, TFilterData>>();

constructor(
private user: string,
container: HTMLElement,
delegate: IListVirtualDelegate<T>,
renderers: ITreeRenderer<T, TFilterData, any>[],
private dataSource: IDataSource<TInput, T>,
options: IDataTreeOptions<T, TFilterData> = {}
) {
super(container, delegate, renderers, options);
super(user, container, delegate, renderers, options);
this.identityProvider = options.identityProvider;
}

Expand All @@ -48,7 +49,7 @@ export class DataTree<TInput, T, TFilterData = void> extends AbstractTree<T | nu

setInput(input: TInput, viewState?: IDataTreeViewState): void {
if (viewState && !this.identityProvider) {
throw new Error('Can\'t restore tree view state without an identity provider');
throw new TreeError(this.user, 'Can\'t restore tree view state without an identity provider');
}

this.input = input;
Expand Down Expand Up @@ -89,7 +90,7 @@ export class DataTree<TInput, T, TFilterData = void> extends AbstractTree<T | nu

updateChildren(element: TInput | T = this.input!): void {
if (typeof this.input === 'undefined') {
throw new Error('Tree input not set');
throw new TreeError(this.user, 'Tree input not set');
}

let isCollapsed: ((el: T) => boolean | undefined) | undefined;
Expand Down Expand Up @@ -169,15 +170,15 @@ export class DataTree<TInput, T, TFilterData = void> extends AbstractTree<T | nu
return { elements, size: children.length };
}

protected createModel(view: ISpliceable<ITreeNode<T, TFilterData>>, options: IDataTreeOptions<T, TFilterData>): ITreeModel<T | null, TFilterData, T | null> {
return new ObjectTreeModel(view, options);
protected createModel(user: string, view: ISpliceable<ITreeNode<T, TFilterData>>, options: IDataTreeOptions<T, TFilterData>): ITreeModel<T | null, TFilterData, T | null> {
return new ObjectTreeModel(user, view, options);
}

// view state

getViewState(): IDataTreeViewState {
if (!this.identityProvider) {
throw new Error('Can\'t get tree view state without an identity provider');
throw new TreeError(this.user, 'Can\'t get tree view state without an identity provider');
}

const getId = (element: T) => this.identityProvider!.getId(element).toString();
Expand Down
7 changes: 4 additions & 3 deletions src/vs/base/browser/ui/tree/indexTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ export class IndexTree<T, TFilterData = void> extends AbstractTree<T, TFilterDat
protected model!: IndexTreeModel<T, TFilterData>;

constructor(
user: string,
container: HTMLElement,
delegate: IListVirtualDelegate<T>,
renderers: ITreeRenderer<T, TFilterData, any>[],
private rootElement: T,
options: IIndexTreeOptions<T, TFilterData> = {}
) {
super(container, delegate, renderers, options);
super(user, container, delegate, renderers, options);
}

splice(location: number[], deleteCount: number, toInsert: ISequence<ITreeElement<T>> = Iterator.empty()): Iterator<ITreeElement<T>> {
Expand All @@ -40,7 +41,7 @@ export class IndexTree<T, TFilterData = void> extends AbstractTree<T, TFilterDat
this.model.rerender(location);
}

protected createModel(view: ISpliceable<ITreeNode<T, TFilterData>>, options: IIndexTreeOptions<T, TFilterData>): ITreeModel<T, TFilterData, number[]> {
return new IndexTreeModel(view, this.rootElement, options);
protected createModel(user: string, view: ISpliceable<ITreeNode<T, TFilterData>>, options: IIndexTreeOptions<T, TFilterData>): ITreeModel<T, TFilterData, number[]> {
return new IndexTreeModel(user, view, this.rootElement, options);
}
}
Loading

0 comments on commit defb232

Please sign in to comment.