提交 d00ae9bd 编写于 作者: S Sandeep Somavarapu

#55879 Collapse all action for custom views

上级 51a83e46
...@@ -1196,7 +1196,30 @@ declare module 'vscode' { ...@@ -1196,7 +1196,30 @@ declare module 'vscode' {
} }
//#endregion //#endregion
//#region Tree Item Label Highlights //#region Tree View
/**
* Options for creating a [TreeView](#TreeView]
*/
export interface TreeViewOptions<T> {
/**
* A data provider that provides tree data.
*/
treeDataProvider: TreeDataProvider<T>;
/**
* Whether to show collapse all action or not.
*/
showCollapseAll?: boolean;
}
namespace window {
export function createTreeView<T>(viewId: string, options: TreeViewOptions<T>): TreeView<T>;
}
/** /**
* Label describing the [Tree item](#TreeItem) * Label describing the [Tree item](#TreeItem)
*/ */
......
...@@ -26,12 +26,13 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie ...@@ -26,12 +26,13 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTreeViews); this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTreeViews);
} }
$registerTreeViewDataProvider(treeViewId: string): void { $registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean }): void {
const dataProvider = new TreeViewDataProvider(treeViewId, this._proxy, this.notificationService); const dataProvider = new TreeViewDataProvider(treeViewId, this._proxy, this.notificationService);
this._dataProviders.set(treeViewId, dataProvider); this._dataProviders.set(treeViewId, dataProvider);
const viewer = this.getTreeViewer(treeViewId); const viewer = this.getTreeViewer(treeViewId);
if (viewer) { if (viewer) {
viewer.dataProvider = dataProvider; viewer.dataProvider = dataProvider;
viewer.showCollapseAllAction = !!options.showCollapseAll;
this.registerListeners(treeViewId, viewer); this.registerListeners(treeViewId, viewer);
this._proxy.$setVisible(treeViewId, viewer.visible); this._proxy.$setVisible(treeViewId, viewer.visible);
} else { } else {
......
...@@ -59,7 +59,7 @@ import { ExtHostUrls } from 'vs/workbench/api/node/extHostUrls'; ...@@ -59,7 +59,7 @@ import { ExtHostUrls } from 'vs/workbench/api/node/extHostUrls';
import { ExtHostWebviews } from 'vs/workbench/api/node/extHostWebview'; import { ExtHostWebviews } from 'vs/workbench/api/node/extHostWebview';
import { ExtHostWindow } from 'vs/workbench/api/node/extHostWindow'; import { ExtHostWindow } from 'vs/workbench/api/node/extHostWindow';
import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; import { IExtensionDescription, throwProposedApiError, checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
import { ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier'; import { ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
...@@ -67,16 +67,6 @@ export interface IExtensionApiFactory { ...@@ -67,16 +67,6 @@ export interface IExtensionApiFactory {
(extension: IExtensionDescription): typeof vscode; (extension: IExtensionDescription): typeof vscode;
} }
export function checkProposedApiEnabled(extension: IExtensionDescription): void {
if (!extension.enableProposedApi) {
throwProposedApiError(extension);
}
}
function throwProposedApiError(extension: IExtensionDescription): never {
throw new Error(`[${extension.id}]: Proposed API is only available when running out of dev or with the following command line switch: --enable-proposed-api ${extension.id}`);
}
function proposedApiFunction<T>(extension: IExtensionDescription, fn: T): T { function proposedApiFunction<T>(extension: IExtensionDescription, fn: T): T {
if (extension.enableProposedApi) { if (extension.enableProposedApi) {
return fn; return fn;
...@@ -461,10 +451,10 @@ export function createApiFactory( ...@@ -461,10 +451,10 @@ export function createApiFactory(
return extHostTerminalService.createTerminalRenderer(name); return extHostTerminalService.createTerminalRenderer(name);
}), }),
registerTreeDataProvider(viewId: string, treeDataProvider: vscode.TreeDataProvider<any>): vscode.Disposable { registerTreeDataProvider(viewId: string, treeDataProvider: vscode.TreeDataProvider<any>): vscode.Disposable {
return extHostTreeViews.registerTreeDataProvider(viewId, treeDataProvider); return extHostTreeViews.registerTreeDataProvider(viewId, treeDataProvider, extension);
}, },
createTreeView(viewId: string, options: { treeDataProvider: vscode.TreeDataProvider<any> }): vscode.TreeView<any> { createTreeView(viewId: string, options: { treeDataProvider: vscode.TreeDataProvider<any> }): vscode.TreeView<any> {
return extHostTreeViews.createTreeView(viewId, options); return extHostTreeViews.createTreeView(viewId, options, extension);
}, },
registerWebviewPanelSerializer: (viewType: string, serializer: vscode.WebviewPanelSerializer) => { registerWebviewPanelSerializer: (viewType: string, serializer: vscode.WebviewPanelSerializer) => {
return extHostWebviews.registerWebviewPanelSerializer(viewType, serializer); return extHostWebviews.registerWebviewPanelSerializer(viewType, serializer);
......
...@@ -210,7 +210,7 @@ export interface MainThreadTextEditorsShape extends IDisposable { ...@@ -210,7 +210,7 @@ export interface MainThreadTextEditorsShape extends IDisposable {
} }
export interface MainThreadTreeViewsShape extends IDisposable { export interface MainThreadTreeViewsShape extends IDisposable {
$registerTreeViewDataProvider(treeViewId: string): void; $registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean }): void;
$refresh(treeViewId: string, itemsToRefresh?: { [treeItemHandle: string]: ITreeItem }): Thenable<void>; $refresh(treeViewId: string, itemsToRefresh?: { [treeItemHandle: string]: ITreeItem }): Thenable<void>;
$reveal(treeViewId: string, treeItem: ITreeItem, parentChain: ITreeItem[], options: { select: boolean, focus: boolean }): Thenable<void>; $reveal(treeViewId: string, treeItem: ITreeItem, parentChain: ITreeItem[], options: { select: boolean, focus: boolean }): Thenable<void>;
} }
......
...@@ -17,6 +17,7 @@ import { TreeItemCollapsibleState, ThemeIcon } from 'vs/workbench/api/node/extHo ...@@ -17,6 +17,7 @@ import { TreeItemCollapsibleState, ThemeIcon } from 'vs/workbench/api/node/extHo
import { isUndefinedOrNull, isString } from 'vs/base/common/types'; import { isUndefinedOrNull, isString } from 'vs/base/common/types';
import { equals } from 'vs/base/common/arrays'; import { equals } from 'vs/base/common/arrays';
import { ILogService } from 'vs/platform/log/common/log'; import { ILogService } from 'vs/platform/log/common/log';
import { IExtensionDescription, checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
type TreeItemHandle = string; type TreeItemHandle = string;
...@@ -59,16 +60,20 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape { ...@@ -59,16 +60,20 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape {
}); });
} }
registerTreeDataProvider<T>(id: string, treeDataProvider: vscode.TreeDataProvider<T>): vscode.Disposable { registerTreeDataProvider<T>(id: string, treeDataProvider: vscode.TreeDataProvider<T>, extension: IExtensionDescription): vscode.Disposable {
const treeView = this.createTreeView(id, { treeDataProvider }); const treeView = this.createTreeView(id, { treeDataProvider }, extension);
return { dispose: () => treeView.dispose() }; return { dispose: () => treeView.dispose() };
} }
createTreeView<T>(viewId: string, options: { treeDataProvider: vscode.TreeDataProvider<T> }): vscode.TreeView<T> { createTreeView<T>(viewId: string, options: vscode.TreeViewOptions<T>, extension: IExtensionDescription): vscode.TreeView<T> {
if (!options || !options.treeDataProvider) { if (!options || !options.treeDataProvider) {
throw new Error('Options with treeDataProvider is mandatory'); throw new Error('Options with treeDataProvider is mandatory');
} }
const treeView = this.createExtHostTreeViewer(viewId, options.treeDataProvider); if (options.showCollapseAll) {
checkProposedApiEnabled(extension);
}
const treeView = this.createExtHostTreeViewer(viewId, options);
return { return {
get onDidCollapseElement() { return treeView.onDidCollapseElement; }, get onDidCollapseElement() { return treeView.onDidCollapseElement; },
get onDidExpandElement() { return treeView.onDidExpandElement; }, get onDidExpandElement() { return treeView.onDidExpandElement; },
...@@ -118,8 +123,8 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape { ...@@ -118,8 +123,8 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape {
treeView.setVisible(isVisible); treeView.setVisible(isVisible);
} }
private createExtHostTreeViewer<T>(id: string, dataProvider: vscode.TreeDataProvider<T>): ExtHostTreeView<T> { private createExtHostTreeViewer<T>(id: string, options: vscode.TreeViewOptions<T>): ExtHostTreeView<T> {
const treeView = new ExtHostTreeView<T>(id, dataProvider, this._proxy, this.commands.converter, this.logService); const treeView = new ExtHostTreeView<T>(id, options, this._proxy, this.commands.converter, this.logService);
this.treeViews.set(id, treeView); this.treeViews.set(id, treeView);
return treeView; return treeView;
} }
...@@ -141,6 +146,8 @@ class ExtHostTreeView<T> extends Disposable { ...@@ -141,6 +146,8 @@ class ExtHostTreeView<T> extends Disposable {
private static LABEL_HANDLE_PREFIX = '0'; private static LABEL_HANDLE_PREFIX = '0';
private static ID_HANDLE_PREFIX = '1'; private static ID_HANDLE_PREFIX = '1';
private readonly dataProvider: vscode.TreeDataProvider<T>;
private roots: TreeNode[] | null = null; private roots: TreeNode[] | null = null;
private elements: Map<TreeItemHandle, T> = new Map<TreeItemHandle, T>(); private elements: Map<TreeItemHandle, T> = new Map<TreeItemHandle, T>();
private nodes: Map<T, TreeNode> = new Map<T, TreeNode>(); private nodes: Map<T, TreeNode> = new Map<T, TreeNode>();
...@@ -165,9 +172,10 @@ class ExtHostTreeView<T> extends Disposable { ...@@ -165,9 +172,10 @@ class ExtHostTreeView<T> extends Disposable {
private refreshPromise: Promise<void> = Promise.resolve(null); private refreshPromise: Promise<void> = Promise.resolve(null);
constructor(private viewId: string, private dataProvider: vscode.TreeDataProvider<T>, private proxy: MainThreadTreeViewsShape, private commands: CommandsConverter, private logService: ILogService) { constructor(private viewId: string, options: vscode.TreeViewOptions<T>, private proxy: MainThreadTreeViewsShape, private commands: CommandsConverter, private logService: ILogService) {
super(); super();
this.proxy.$registerTreeViewDataProvider(viewId); this.dataProvider = options.treeDataProvider;
this.proxy.$registerTreeViewDataProvider(viewId, { showCollapseAll: !!options.showCollapseAll });
if (this.dataProvider.onDidChangeTreeData) { if (this.dataProvider.onDidChangeTreeData) {
let refreshingPromise, promiseCallback; let refreshingPromise, promiseCallback;
this._register(debounceEvent<T, T[]>(this.dataProvider.onDidChangeTreeData, (last, current) => { this._register(debounceEvent<T, T[]>(this.dataProvider.onDidChangeTreeData, (last, current) => {
......
...@@ -8,7 +8,7 @@ import { Event, Emitter } from 'vs/base/common/event'; ...@@ -8,7 +8,7 @@ import { Event, Emitter } from 'vs/base/common/event';
import { IDisposable, dispose, Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { IDisposable, dispose, Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import { IAction, IActionItem, ActionRunner } from 'vs/base/common/actions'; import { IAction, IActionItem, ActionRunner, Action } from 'vs/base/common/actions';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions'; import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
...@@ -36,10 +36,10 @@ import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/v ...@@ -36,10 +36,10 @@ import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/v
import { IMouseEvent } from 'vs/base/browser/mouseEvent'; import { IMouseEvent } from 'vs/base/browser/mouseEvent';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
import { timeout } from 'vs/base/common/async'; import { timeout } from 'vs/base/common/async';
import { CollapseAllAction } from 'vs/base/parts/tree/browser/treeDefaults';
export class CustomTreeViewPanel extends ViewletPanel { export class CustomTreeViewPanel extends ViewletPanel {
private menus: TitleMenus;
private treeViewer: ITreeViewer; private treeViewer: ITreeViewer;
constructor( constructor(
...@@ -47,15 +47,14 @@ export class CustomTreeViewPanel extends ViewletPanel { ...@@ -47,15 +47,14 @@ export class CustomTreeViewPanel extends ViewletPanel {
@INotificationService private notificationService: INotificationService, @INotificationService private notificationService: INotificationService,
@IKeybindingService keybindingService: IKeybindingService, @IKeybindingService keybindingService: IKeybindingService,
@IContextMenuService contextMenuService: IContextMenuService, @IContextMenuService contextMenuService: IContextMenuService,
@IInstantiationService private instantiationService: IInstantiationService,
@IConfigurationService configurationService: IConfigurationService, @IConfigurationService configurationService: IConfigurationService,
@IViewsService viewsService: IViewsService, @IViewsService viewsService: IViewsService,
) { ) {
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService); super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService);
this.treeViewer = (<ICustomViewDescriptor>ViewsRegistry.getView(options.id)).treeViewer; const { treeViewer } = (<ICustomViewDescriptor>ViewsRegistry.getView(options.id));
this.treeViewer = treeViewer;
this.treeViewer.onDidChangeActions(() => this.updateActions(), this, this.disposables);
this.disposables.push(toDisposable(() => this.treeViewer.setVisibility(false))); this.disposables.push(toDisposable(() => this.treeViewer.setVisibility(false)));
this.menus = this.instantiationService.createInstance(TitleMenus, this.id);
this.menus.onDidChangeTitle(() => this.updateActions(), this, this.disposables);
this.updateTreeVisibility(); this.updateTreeVisibility();
} }
...@@ -83,11 +82,11 @@ export class CustomTreeViewPanel extends ViewletPanel { ...@@ -83,11 +82,11 @@ export class CustomTreeViewPanel extends ViewletPanel {
} }
getActions(): IAction[] { getActions(): IAction[] {
return [...this.menus.getTitleActions()]; return [...this.treeViewer.getPrimaryActions()];
} }
getSecondaryActions(): IAction[] { getSecondaryActions(): IAction[] {
return this.menus.getTitleSecondaryActions(); return [...this.treeViewer.getSecondaryActions()];
} }
getActionItem(action: IAction): IActionItem { getActionItem(action: IAction): IActionItem {
...@@ -180,6 +179,7 @@ export class CustomTreeViewer extends Disposable implements ITreeViewer { ...@@ -180,6 +179,7 @@ export class CustomTreeViewer extends Disposable implements ITreeViewer {
private activated: boolean = false; private activated: boolean = false;
private _hasIconForParentNode = false; private _hasIconForParentNode = false;
private _hasIconForLeafNode = false; private _hasIconForLeafNode = false;
private _showCollapseAllAction = false;
private domNode: HTMLElement; private domNode: HTMLElement;
private treeContainer: HTMLElement; private treeContainer: HTMLElement;
...@@ -187,6 +187,7 @@ export class CustomTreeViewer extends Disposable implements ITreeViewer { ...@@ -187,6 +187,7 @@ export class CustomTreeViewer extends Disposable implements ITreeViewer {
private tree: FileIconThemableWorkbenchTree; private tree: FileIconThemableWorkbenchTree;
private root: ITreeItem; private root: ITreeItem;
private elementsToRefresh: ITreeItem[] = []; private elementsToRefresh: ITreeItem[] = [];
private menus: TitleMenus;
private _dataProvider: ITreeViewDataProvider; private _dataProvider: ITreeViewDataProvider;
...@@ -202,6 +203,9 @@ export class CustomTreeViewer extends Disposable implements ITreeViewer { ...@@ -202,6 +203,9 @@ export class CustomTreeViewer extends Disposable implements ITreeViewer {
private _onDidChangeVisibility: Emitter<boolean> = this._register(new Emitter<boolean>()); private _onDidChangeVisibility: Emitter<boolean> = this._register(new Emitter<boolean>());
readonly onDidChangeVisibility: Event<boolean> = this._onDidChangeVisibility.event; readonly onDidChangeVisibility: Event<boolean> = this._onDidChangeVisibility.event;
private _onDidChangeActions: Emitter<void> = this._register(new Emitter<void>());
readonly onDidChangeActions: Event<void> = this._onDidChangeActions.event;
constructor( constructor(
private id: string, private id: string,
private container: ViewContainer, private container: ViewContainer,
...@@ -214,6 +218,8 @@ export class CustomTreeViewer extends Disposable implements ITreeViewer { ...@@ -214,6 +218,8 @@ export class CustomTreeViewer extends Disposable implements ITreeViewer {
) { ) {
super(); super();
this.root = new Root(); this.root = new Root();
this.menus = this._register(this.instantiationService.createInstance(TitleMenus, this.id));
this._register(this.menus.onDidChangeTitle(() => this._onDidChangeActions.fire()));
this._register(this.themeService.onDidFileIconThemeChange(() => this.doRefresh([this.root]) /** soft refresh **/)); this._register(this.themeService.onDidFileIconThemeChange(() => this.doRefresh([this.root]) /** soft refresh **/));
this._register(this.themeService.onThemeChange(() => this.doRefresh([this.root]) /** soft refresh **/)); this._register(this.themeService.onThemeChange(() => this.doRefresh([this.root]) /** soft refresh **/));
this._register(this.configurationService.onDidChangeConfiguration(e => { this._register(this.configurationService.onDidChangeConfiguration(e => {
...@@ -263,6 +269,30 @@ export class CustomTreeViewer extends Disposable implements ITreeViewer { ...@@ -263,6 +269,30 @@ export class CustomTreeViewer extends Disposable implements ITreeViewer {
return this.isVisible; return this.isVisible;
} }
get showCollapseAllAction(): boolean {
return this._showCollapseAllAction;
}
set showCollapseAllAction(showCollapseAllAction: boolean) {
if (this._showCollapseAllAction !== !!showCollapseAllAction) {
this._showCollapseAllAction = !!showCollapseAllAction;
this._onDidChangeActions.fire();
}
}
getPrimaryActions(): IAction[] {
if (this.showCollapseAllAction) {
const collapseAllAction = new Action('vs.tree.collapse', localize('collapse', "Collapse"), 'monaco-tree-action collapse-all', true, () => this.tree ? new CollapseAllAction(this.tree, true).run() : Promise.resolve());
return [...this.menus.getTitleActions(), collapseAllAction];
} else {
return this.menus.getTitleActions();
}
}
getSecondaryActions(): IAction[] {
return this.menus.getTitleSecondaryActions();
}
setVisibility(isVisible: boolean): void { setVisibility(isVisible: boolean): void {
isVisible = !!isVisible; isVisible = !!isVisible;
if (this.isVisible === isVisible) { if (this.isVisible === isVisible) {
......
...@@ -17,6 +17,7 @@ import { ThemeIcon } from 'vs/platform/theme/common/themeService'; ...@@ -17,6 +17,7 @@ import { ThemeIcon } from 'vs/platform/theme/common/themeService';
import { values } from 'vs/base/common/map'; import { values } from 'vs/base/common/map';
import { Registry } from 'vs/platform/registry/common/platform'; import { Registry } from 'vs/platform/registry/common/platform';
import { IKeybindings } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { IKeybindings } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { IAction } from 'vs/base/common/actions';
export const TEST_VIEW_CONTAINER_ID = 'workbench.view.extension.test'; export const TEST_VIEW_CONTAINER_ID = 'workbench.view.extension.test';
...@@ -238,6 +239,10 @@ export interface ITreeViewer extends IDisposable { ...@@ -238,6 +239,10 @@ export interface ITreeViewer extends IDisposable {
dataProvider: ITreeViewDataProvider; dataProvider: ITreeViewDataProvider;
showCollapseAllAction: boolean;
readonly visible: boolean;
readonly onDidExpandItem: Event<ITreeItem>; readonly onDidExpandItem: Event<ITreeItem>;
readonly onDidCollapseItem: Event<ITreeItem>; readonly onDidCollapseItem: Event<ITreeItem>;
...@@ -246,7 +251,7 @@ export interface ITreeViewer extends IDisposable { ...@@ -246,7 +251,7 @@ export interface ITreeViewer extends IDisposable {
readonly onDidChangeVisibility: Event<boolean>; readonly onDidChangeVisibility: Event<boolean>;
readonly visible: boolean; readonly onDidChangeActions: Event<void>;
refresh(treeItems?: ITreeItem[]): TPromise<void>; refresh(treeItems?: ITreeItem[]): TPromise<void>;
...@@ -261,6 +266,10 @@ export interface ITreeViewer extends IDisposable { ...@@ -261,6 +266,10 @@ export interface ITreeViewer extends IDisposable {
getOptimalWidth(): number; getOptimalWidth(): number;
reveal(item: ITreeItem, parentChain: ITreeItem[], options: { select?: boolean }): TPromise<void>; reveal(item: ITreeItem, parentChain: ITreeItem[], options: { select?: boolean }): TPromise<void>;
getPrimaryActions(): IAction[];
getSecondaryActions(): IAction[];
} }
export interface ICustomViewDescriptor extends IViewDescriptor { export interface ICustomViewDescriptor extends IViewDescriptor {
......
...@@ -206,3 +206,13 @@ export interface IExtensionService { ...@@ -206,3 +206,13 @@ export interface IExtensionService {
export interface ProfileSession { export interface ProfileSession {
stop(): TPromise<IExtensionHostProfile>; stop(): TPromise<IExtensionHostProfile>;
} }
export function checkProposedApiEnabled(extension: IExtensionDescription): void {
if (!extension.enableProposedApi) {
throwProposedApiError(extension);
}
}
export function throwProposedApiError(extension: IExtensionDescription): never {
throw new Error(`[${extension.id}]: Proposed API is only available when running out of dev or with the following command line switch: --enable-proposed-api ${extension.id}`);
}
...@@ -72,9 +72,9 @@ suite('ExtHostTreeView', function () { ...@@ -72,9 +72,9 @@ suite('ExtHostTreeView', function () {
testObject = new ExtHostTreeViews(target, new ExtHostCommands(rpcProtocol, new ExtHostHeapService(), new NullLogService()), new NullLogService()); testObject = new ExtHostTreeViews(target, new ExtHostCommands(rpcProtocol, new ExtHostHeapService(), new NullLogService()), new NullLogService());
onDidChangeTreeNode = new Emitter<{ key: string }>(); onDidChangeTreeNode = new Emitter<{ key: string }>();
onDidChangeTreeNodeWithId = new Emitter<{ key: string }>(); onDidChangeTreeNodeWithId = new Emitter<{ key: string }>();
testObject.createTreeView('testNodeTreeProvider', { treeDataProvider: aNodeTreeDataProvider() }); testObject.createTreeView('testNodeTreeProvider', { treeDataProvider: aNodeTreeDataProvider() }, null);
testObject.createTreeView('testNodeWithIdTreeProvider', { treeDataProvider: aNodeWithIdTreeDataProvider() }); testObject.createTreeView('testNodeWithIdTreeProvider', { treeDataProvider: aNodeWithIdTreeDataProvider() }, null);
testObject.createTreeView('testNodeWithHighlightsTreeProvider', { treeDataProvider: aNodeWithHighlightedLabelTreeDataProvider() }); testObject.createTreeView('testNodeWithHighlightsTreeProvider', { treeDataProvider: aNodeWithHighlightedLabelTreeDataProvider() }, null);
return loadCompleteTree('testNodeTreeProvider'); return loadCompleteTree('testNodeTreeProvider');
}); });
...@@ -445,14 +445,14 @@ suite('ExtHostTreeView', function () { ...@@ -445,14 +445,14 @@ suite('ExtHostTreeView', function () {
}); });
test('reveal will throw an error if getParent is not implemented', () => { test('reveal will throw an error if getParent is not implemented', () => {
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aNodeTreeDataProvider() }); const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aNodeTreeDataProvider() }, null);
return treeView.reveal({ key: 'a' }) return treeView.reveal({ key: 'a' })
.then(() => assert.fail('Reveal should throw an error as getParent is not implemented'), () => null); .then(() => assert.fail('Reveal should throw an error as getParent is not implemented'), () => null);
}); });
test('reveal will return empty array for root element', () => { test('reveal will return empty array for root element', () => {
const revealTarget = sinon.spy(target, '$reveal'); const revealTarget = sinon.spy(target, '$reveal');
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }); const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }, null);
return treeView.reveal({ key: 'a' }) return treeView.reveal({ key: 'a' })
.then(() => { .then(() => {
assert.ok(revealTarget.calledOnce); assert.ok(revealTarget.calledOnce);
...@@ -465,7 +465,7 @@ suite('ExtHostTreeView', function () { ...@@ -465,7 +465,7 @@ suite('ExtHostTreeView', function () {
test('reveal will return parents array for an element when hierarchy is not loaded', () => { test('reveal will return parents array for an element when hierarchy is not loaded', () => {
const revealTarget = sinon.spy(target, '$reveal'); const revealTarget = sinon.spy(target, '$reveal');
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }); const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }, null);
return treeView.reveal({ key: 'aa' }) return treeView.reveal({ key: 'aa' })
.then(() => { .then(() => {
assert.ok(revealTarget.calledOnce); assert.ok(revealTarget.calledOnce);
...@@ -478,7 +478,7 @@ suite('ExtHostTreeView', function () { ...@@ -478,7 +478,7 @@ suite('ExtHostTreeView', function () {
test('reveal will return parents array for an element when hierarchy is loaded', () => { test('reveal will return parents array for an element when hierarchy is loaded', () => {
const revealTarget = sinon.spy(target, '$reveal'); const revealTarget = sinon.spy(target, '$reveal');
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }); const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }, null);
return testObject.$getChildren('treeDataProvider') return testObject.$getChildren('treeDataProvider')
.then(() => testObject.$getChildren('treeDataProvider', '0/0:a')) .then(() => testObject.$getChildren('treeDataProvider', '0/0:a'))
.then(() => treeView.reveal({ key: 'aa' }) .then(() => treeView.reveal({ key: 'aa' })
...@@ -500,7 +500,7 @@ suite('ExtHostTreeView', function () { ...@@ -500,7 +500,7 @@ suite('ExtHostTreeView', function () {
} }
}; };
const revealTarget = sinon.spy(target, '$reveal'); const revealTarget = sinon.spy(target, '$reveal');
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }); const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }, null);
return treeView.reveal({ key: 'bac' }, { select: false, focus: false }) return treeView.reveal({ key: 'bac' }, { select: false, focus: false })
.then(() => { .then(() => {
assert.ok(revealTarget.calledOnce); assert.ok(revealTarget.calledOnce);
...@@ -516,7 +516,7 @@ suite('ExtHostTreeView', function () { ...@@ -516,7 +516,7 @@ suite('ExtHostTreeView', function () {
test('reveal after first udpate', () => { test('reveal after first udpate', () => {
const revealTarget = sinon.spy(target, '$reveal'); const revealTarget = sinon.spy(target, '$reveal');
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }); const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }, null);
return loadCompleteTree('treeDataProvider') return loadCompleteTree('treeDataProvider')
.then(() => { .then(() => {
tree = { tree = {
...@@ -544,7 +544,7 @@ suite('ExtHostTreeView', function () { ...@@ -544,7 +544,7 @@ suite('ExtHostTreeView', function () {
test('reveal after second udpate', () => { test('reveal after second udpate', () => {
const revealTarget = sinon.spy(target, '$reveal'); const revealTarget = sinon.spy(target, '$reveal');
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }); const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }, null);
return loadCompleteTree('treeDataProvider') return loadCompleteTree('treeDataProvider')
.then(() => { .then(() => {
tree = { tree = {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册