Merge VS Code 1.31.1 (#4283)

This commit is contained in:
Matt Irvine
2019-03-15 13:09:45 -07:00
committed by GitHub
parent 7d31575149
commit 86bac90001
1716 changed files with 53308 additions and 48375 deletions

View File

@@ -12,9 +12,9 @@ export function registerContextMenuListener(): void {
menu.popup({
window: BrowserWindow.fromWebContents(event.sender),
x: options ? options.x : void 0,
y: options ? options.y : void 0,
positioningItem: options ? options.positioningItem : void 0,
x: options ? options.x : undefined,
y: options ? options.y : undefined,
positioningItem: options ? options.positioningItem : undefined,
callback: () => {
event.sender.send(CONTEXT_MENU_CLOSE_CHANNEL, contextMenuId);
}

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { fromNodeEventEmitter } from 'vs/base/common/event';
import { Event } from 'vs/base/common/event';
import { IPCClient } from 'vs/base/parts/ipc/node/ipc';
import { Protocol } from 'vs/base/parts/ipc/node/ipc.electron';
import { ipcRenderer } from 'electron';
@@ -14,7 +14,7 @@ export class Client extends IPCClient implements IDisposable {
private protocol: Protocol;
private static createProtocol(): Protocol {
const onMessage = fromNodeEventEmitter<string>(ipcRenderer, 'ipc:message', (_, message: string) => message);
const onMessage = Event.fromNodeEventEmitter<string>(ipcRenderer, 'ipc:message', (_, message: string) => message);
ipcRenderer.send('ipc:hello');
return new Protocol(ipcRenderer, onMessage);
}

View File

@@ -3,10 +3,11 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Event, filterEvent, mapEvent, fromNodeEventEmitter, signalEvent } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
import { IPCServer, ClientConnectionEvent } from 'vs/base/parts/ipc/node/ipc';
import { Protocol } from 'vs/base/parts/ipc/node/ipc.electron';
import { ipcMain } from 'electron';
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
interface IIPCEvent {
event: { sender: Electron.WebContents; };
@@ -14,19 +15,31 @@ interface IIPCEvent {
}
function createScopedOnMessageEvent(senderId: number, eventName: string): Event<string> {
const onMessage = fromNodeEventEmitter<IIPCEvent>(ipcMain, eventName, (event, message: string) => ({ event, message }));
const onMessageFromSender = filterEvent(onMessage, ({ event }) => event.sender.id === senderId);
return mapEvent(onMessageFromSender, ({ message }) => message);
const onMessage = Event.fromNodeEventEmitter<IIPCEvent>(ipcMain, eventName, (event, message: string) => ({ event, message }));
const onMessageFromSender = Event.filter(onMessage, ({ event }) => event.sender.id === senderId);
return Event.map(onMessageFromSender, ({ message }) => message);
}
export class Server extends IPCServer {
private static getOnDidClientConnect(): Event<ClientConnectionEvent> {
const onHello = fromNodeEventEmitter<Electron.WebContents>(ipcMain, 'ipc:hello', ({ sender }) => sender);
private static Clients = new Map<number, IDisposable>();
return mapEvent(onHello, webContents => {
const onMessage = createScopedOnMessageEvent(webContents.id, 'ipc:message');
const onDidClientDisconnect = signalEvent(createScopedOnMessageEvent(webContents.id, 'ipc:disconnect'));
private static getOnDidClientConnect(): Event<ClientConnectionEvent> {
const onHello = Event.fromNodeEventEmitter<Electron.WebContents>(ipcMain, 'ipc:hello', ({ sender }) => sender);
return Event.map(onHello, webContents => {
const id = webContents.id;
const client = Server.Clients.get(id);
if (client) {
client.dispose();
}
const onDidClientReconnect = new Emitter<void>();
Server.Clients.set(id, toDisposable(() => onDidClientReconnect.fire()));
const onMessage = createScopedOnMessageEvent(id, 'ipc:message');
const onDidClientDisconnect = Event.any(Event.signal(createScopedOnMessageEvent(id, 'ipc:disconnect')), onDidClientReconnect.event);
const protocol = new Protocol(webContents, onMessage);
return { protocol, onDidClientDisconnect };

View File

@@ -7,7 +7,7 @@ import { ChildProcess, fork, ForkOptions } from 'child_process';
import { IDisposable, toDisposable, dispose } from 'vs/base/common/lifecycle';
import { Delayer, always, createCancelablePromise } from 'vs/base/common/async';
import { deepClone, assign } from 'vs/base/common/objects';
import { Emitter, fromNodeEventEmitter, Event } from 'vs/base/common/event';
import { Emitter, Event } from 'vs/base/common/event';
import { createQueuedSender } from 'vs/base/node/processes';
import { ChannelServer as IPCServer, ChannelClient as IPCClient, IChannelClient, IChannel } from 'vs/base/parts/ipc/node/ipc';
import { isRemoteConsoleLog, log } from 'vs/base/node/console';
@@ -29,7 +29,7 @@ export class Server<TContext extends string> extends IPCServer<TContext> {
}
} catch (e) { /* not much to do */ }
},
onMessage: fromNodeEventEmitter(process, 'message', msg => Buffer.from(msg, 'base64'))
onMessage: Event.fromNodeEventEmitter(process, 'message', msg => Buffer.from(msg, 'base64'))
}, ctx);
process.once('disconnect', () => this.dispose());
@@ -105,7 +105,7 @@ export class Client implements IChannelClient, IDisposable {
const that = this;
return {
call<T>(command: string, arg?: any, cancellationToken?: CancellationToken): Thenable<T> {
call<T>(command: string, arg?: any, cancellationToken?: CancellationToken): Promise<T> {
return that.requestPromise<T>(channelName, command, arg, cancellationToken);
},
listen(event: string, arg?: any) {
@@ -114,7 +114,7 @@ export class Client implements IChannelClient, IDisposable {
} as T;
}
protected requestPromise<T>(channelName: string, name: string, arg?: any, cancellationToken = CancellationToken.None): Thenable<T> {
protected requestPromise<T>(channelName: string, name: string, arg?: any, cancellationToken = CancellationToken.None): Promise<T> {
if (!this.disposeDelayer) {
return Promise.reject(new Error('disposed'));
}
@@ -199,7 +199,7 @@ export class Client implements IChannelClient, IDisposable {
this.child = fork(this.modulePath, args, forkOpts);
const onMessageEmitter = new Emitter<Buffer>();
const onRawMessage = fromNodeEventEmitter(this.child, 'message', msg => msg);
const onRawMessage = Event.fromNodeEventEmitter(this.child, 'message', msg => msg);
onRawMessage(msg => {

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { Socket, Server as NetServer, createConnection, createServer } from 'net';
import { Event, Emitter, once, mapEvent, fromNodeEventEmitter } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
import { IMessagePassingProtocol, ClientConnectionEvent, IPCServer, IPCClient } from 'vs/base/parts/ipc/node/ipc';
import { join } from 'path';
import { tmpdir } from 'os';
@@ -207,11 +207,11 @@ export class Protocol implements IDisposable, IMessagePassingProtocol {
export class Server extends IPCServer {
private static toClientConnectionEvent(server: NetServer): Event<ClientConnectionEvent> {
const onConnection = fromNodeEventEmitter<Socket>(server, 'connection');
const onConnection = Event.fromNodeEventEmitter<Socket>(server, 'connection');
return mapEvent(onConnection, socket => ({
return Event.map(onConnection, socket => ({
protocol: new Protocol(socket),
onDidClientDisconnect: once(fromNodeEventEmitter<void>(socket, 'close'))
onDidClientDisconnect: Event.once(Event.fromNodeEventEmitter<void>(socket, 'close'))
}));
}
@@ -239,7 +239,7 @@ export class Client<TContext = string> extends IPCClient<TContext> {
get onClose(): Event<void> { return this.protocol.onClose; }
constructor(private protocol: Protocol, id: TContext) {
constructor(private protocol: Protocol | BufferedProtocol, id: TContext) {
super(protocol, id);
}
@@ -249,9 +249,9 @@ export class Client<TContext = string> extends IPCClient<TContext> {
}
}
export function serve(port: number): Thenable<Server>;
export function serve(namedPipe: string): Thenable<Server>;
export function serve(hook: any): Thenable<Server> {
export function serve(port: number): Promise<Server>;
export function serve(namedPipe: string): Promise<Server>;
export function serve(hook: any): Promise<Server> {
return new Promise<Server>((c, e) => {
const server = createServer();
@@ -263,10 +263,10 @@ export function serve(hook: any): Thenable<Server> {
});
}
export function connect(options: { host: string, port: number }, clientId: string): Thenable<Client>;
export function connect(port: number, clientId: string): Thenable<Client>;
export function connect(namedPipe: string, clientId: string): Thenable<Client>;
export function connect(hook: any, clientId: string): Thenable<Client> {
export function connect(options: { host: string, port: number }, clientId: string): Promise<Client>;
export function connect(port: number, clientId: string): Promise<Client>;
export function connect(namedPipe: string, clientId: string): Promise<Client>;
export function connect(hook: any, clientId: string): Promise<Client> {
return new Promise<Client>((c, e) => {
const socket = createConnection(hook, () => {
socket.removeListener('error', e);
@@ -276,3 +276,68 @@ export function connect(hook: any, clientId: string): Thenable<Client> {
socket.once('error', e);
});
}
/**
* Will ensure no messages are lost if there are no event listeners.
*/
function createBufferedEvent<T>(source: Event<T>): Event<T> {
let emitter: Emitter<T>;
let hasListeners = false;
let isDeliveringMessages = false;
let bufferedMessages: T[] = [];
const deliverMessages = () => {
if (isDeliveringMessages) {
return;
}
isDeliveringMessages = true;
while (hasListeners && bufferedMessages.length > 0) {
emitter.fire(bufferedMessages.shift()!);
}
isDeliveringMessages = false;
};
source((e: T) => {
bufferedMessages.push(e);
deliverMessages();
});
emitter = new Emitter<T>({
onFirstListenerAdd: () => {
hasListeners = true;
// it is important to deliver these messages after this call, but before
// other messages have a chance to be received (to guarantee in order delivery)
// that's why we're using here nextTick and not other types of timeouts
process.nextTick(deliverMessages);
},
onLastListenerRemove: () => {
hasListeners = false;
}
});
return emitter.event;
}
/**
* Will ensure no messages are lost if there are no event listeners.
*/
export class BufferedProtocol implements IMessagePassingProtocol {
private readonly _actual: Protocol;
public readonly onMessage: Event<Buffer>;
public readonly onClose: Event<void>;
constructor(actual: Protocol) {
this._actual = actual;
this.onMessage = createBufferedEvent(this._actual.onMessage);
this.onClose = createBufferedEvent(this._actual.onClose);
}
public send(buffer: Buffer): void {
this._actual.send(buffer);
}
public end(): void {
this._actual.end();
}
}

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { IDisposable, toDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
import { Event, Emitter, once, toPromise, Relay } from 'vs/base/common/event';
import { Event, Emitter, Relay } from 'vs/base/common/event';
import { always, CancelablePromise, createCancelablePromise, timeout } from 'vs/base/common/async';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import * as errors from 'vs/base/common/errors';
@@ -58,7 +58,7 @@ enum State {
* with at most one single return value.
*/
export interface IChannel {
call<T>(command: string, arg?: any, cancellationToken?: CancellationToken): Thenable<T>;
call<T>(command: string, arg?: any, cancellationToken?: CancellationToken): Promise<T>;
listen<T>(event: string, arg?: any): Event<T>;
}
@@ -68,7 +68,7 @@ export interface IChannel {
* if you'd like to handle remote promises or events.
*/
export interface IServerChannel<TContext = string> {
call<T>(ctx: TContext, command: string, arg?: any, cancellationToken?: CancellationToken): Thenable<T>;
call<T>(ctx: TContext, command: string, arg?: any, cancellationToken?: CancellationToken): Promise<T>;
listen<T>(ctx: TContext, event: string, arg?: any): Event<T>;
}
@@ -103,8 +103,8 @@ export interface IConnectionHub<TContext> {
* channels (each from a separate client) to pick from.
*/
export interface IClientRouter<TContext = string> {
routeCall(hub: IConnectionHub<TContext>, command: string, arg?: any, cancellationToken?: CancellationToken): Thenable<Client<TContext>>;
routeEvent(hub: IConnectionHub<TContext>, event: string, arg?: any): Thenable<Client<TContext>>;
routeCall(hub: IConnectionHub<TContext>, command: string, arg?: any, cancellationToken?: CancellationToken): Promise<Client<TContext>>;
routeEvent(hub: IConnectionHub<TContext>, event: string, arg?: any): Promise<Client<TContext>>;
}
/**
@@ -289,8 +289,11 @@ export class ChannelServer<TContext = string> implements IChannelServer<TContext
private onPromise(request: IRawPromiseRequest): void {
const channel = this.channels.get(request.channelName);
if (!channel) {
throw new Error('Unknown channel');
}
const cancellationTokenSource = new CancellationTokenSource();
let promise: Thenable<any>;
let promise: Promise<any>;
try {
promise = channel.call(this.ctx, request.name, request.arg, cancellationTokenSource.token);
@@ -309,7 +312,7 @@ export class ChannelServer<TContext = string> implements IChannelServer<TContext
id, data: {
message: err.message,
name: err.name,
stack: err.stack ? (err.stack.split ? err.stack.split('\n') : err.stack) : void 0
stack: err.stack ? (err.stack.split ? err.stack.split('\n') : err.stack) : undefined
}, type: ResponseType.PromiseError
});
} else {
@@ -325,6 +328,9 @@ export class ChannelServer<TContext = string> implements IChannelServer<TContext
private onEventListen(request: IRawEventListenRequest): void {
const channel = this.channels.get(request.channelName);
if (!channel) {
throw new Error('Unknown channel');
}
const id = request.id;
const event = channel.listen(this.ctx, request.name, request.arg);
@@ -380,7 +386,7 @@ export class ChannelClient implements IChannelClient, IDisposable {
} as T;
}
private requestPromise(channelName: string, name: string, arg?: any, cancellationToken = CancellationToken.None): Thenable<any> {
private requestPromise(channelName: string, name: string, arg?: any, cancellationToken = CancellationToken.None): Promise<any> {
const id = this.lastRequestId++;
const type = RequestType.Promise;
const request: IRawRequest = { id, type, channelName, name, arg };
@@ -539,11 +545,11 @@ export class ChannelClient implements IChannelClient, IDisposable {
}
}
private whenInitialized(): Thenable<void> {
private whenInitialized(): Promise<void> {
if (this.state === State.Idle) {
return Promise.resolve();
} else {
return toPromise(this.onDidInitialize);
return Event.toPromise(this.onDidInitialize);
}
}
@@ -590,7 +596,7 @@ export class IPCServer<TContext = string> implements IChannelServer<TContext>, I
constructor(onDidClientConnect: Event<ClientConnectionEvent>) {
onDidClientConnect(({ protocol, onDidClientDisconnect }) => {
const onFirstMessage = once(protocol.onMessage);
const onFirstMessage = Event.once(protocol.onMessage);
onFirstMessage(msg => {
const reader = new BufferReader(msg);
@@ -681,9 +687,9 @@ export class IPCClient<TContext = string> implements IChannelClient, IChannelSer
}
}
export function getDelayedChannel<T extends IChannel>(promise: Thenable<T>): T {
export function getDelayedChannel<T extends IChannel>(promise: Promise<T>): T {
return {
call(command: string, arg?: any, cancellationToken?: CancellationToken): Thenable<T> {
call(command: string, arg?: any, cancellationToken?: CancellationToken): Promise<T> {
return promise.then(c => c.call(command, arg, cancellationToken));
},
@@ -699,7 +705,7 @@ export function getNextTickChannel<T extends IChannel>(channel: T): T {
let didTick = false;
return {
call<T>(command: string, arg?: any, cancellationToken?: CancellationToken): Thenable<T> {
call<T>(command: string, arg?: any, cancellationToken?: CancellationToken): Promise<T> {
if (didTick) {
return channel.call(command, arg, cancellationToken);
}
@@ -726,13 +732,13 @@ export function getNextTickChannel<T extends IChannel>(channel: T): T {
export class StaticRouter<TContext = string> implements IClientRouter<TContext> {
constructor(private fn: (ctx: TContext) => boolean | Thenable<boolean>) { }
constructor(private fn: (ctx: TContext) => boolean | Promise<boolean>) { }
routeCall(hub: IConnectionHub<TContext>): Thenable<Client<TContext>> {
routeCall(hub: IConnectionHub<TContext>): Promise<Client<TContext>> {
return this.route(hub);
}
routeEvent(hub: IConnectionHub<TContext>): Thenable<Client<TContext>> {
routeEvent(hub: IConnectionHub<TContext>): Promise<Client<TContext>> {
return this.route(hub);
}
@@ -743,7 +749,7 @@ export class StaticRouter<TContext = string> implements IClientRouter<TContext>
}
}
await toPromise(hub.onDidChangeConnections);
await Event.toPromise(hub.onDidChangeConnections);
return await this.route(hub);
}
}

View File

@@ -39,7 +39,7 @@ suite('IPC, Child Process', () => {
service.onMarco(({ answer }) => {
try {
assert.equal(answer, 'polo');
c(null);
c(undefined);
} catch (err) {
e(err);
}

View File

@@ -47,7 +47,7 @@ suite('IPC, Socket Protocol', () => {
const sub = b.onMessage(data => {
sub.dispose();
assert.equal(data.toString(), 'foobarfarboo');
resolve(null);
resolve(undefined);
});
a.send(Buffer.from('foobarfarboo'));
});
@@ -55,7 +55,7 @@ suite('IPC, Socket Protocol', () => {
const sub_1 = b.onMessage(data => {
sub_1.dispose();
assert.equal(data.readInt8(0), 123);
resolve(null);
resolve(undefined);
});
const buffer = Buffer.allocUnsafe(1);
buffer.writeInt8(123, 0);
@@ -81,7 +81,7 @@ suite('IPC, Socket Protocol', () => {
return new Promise(resolve => {
b.onMessage(msg => {
assert.deepEqual(JSON.parse(msg.toString()), data);
resolve(null);
resolve(undefined);
});
});
});
@@ -109,7 +109,7 @@ suite('IPC, Socket Protocol', () => {
const receiver2 = new Protocol(stream, buffer);
receiver2.onMessage((msg) => {
assert.equal(JSON.parse(msg.toString()).value, 2);
resolve(void 0);
resolve(undefined);
});
});

View File

@@ -5,7 +5,7 @@
import * as assert from 'assert';
import { IMessagePassingProtocol, IPCServer, ClientConnectionEvent, IPCClient, IChannel, IServerChannel } from 'vs/base/parts/ipc/node/ipc';
import { Emitter, toPromise, Event } from 'vs/base/common/event';
import { Emitter, Event } from 'vs/base/common/event';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import { canceled } from 'vs/base/common/errors';
import { timeout } from 'vs/base/common/async';
@@ -95,11 +95,11 @@ class TestIPCServer extends IPCServer<string> {
const TestChannelId = 'testchannel';
interface ITestService {
marco(): Thenable<string>;
error(message: string): Thenable<void>;
neverComplete(): Thenable<void>;
neverCompleteCT(cancellationToken: CancellationToken): Thenable<void>;
buffersLength(buffers: Buffer[]): Thenable<number>;
marco(): Promise<string>;
error(message: string): Promise<void>;
neverComplete(): Promise<void>;
neverCompleteCT(cancellationToken: CancellationToken): Promise<void>;
buffersLength(buffers: Buffer[]): Promise<number>;
pong: Event<string>;
}
@@ -109,19 +109,19 @@ class TestService implements ITestService {
private _pong = new Emitter<string>();
readonly pong = this._pong.event;
marco(): Thenable<string> {
marco(): Promise<string> {
return Promise.resolve('polo');
}
error(message: string): Thenable<void> {
error(message: string): Promise<void> {
return Promise.reject(new Error(message));
}
neverComplete(): Thenable<void> {
neverComplete(): Promise<void> {
return new Promise(_ => { });
}
neverCompleteCT(cancellationToken: CancellationToken): Thenable<void> {
neverCompleteCT(cancellationToken: CancellationToken): Promise<void> {
if (cancellationToken.isCancellationRequested) {
return Promise.reject(canceled());
}
@@ -129,7 +129,7 @@ class TestService implements ITestService {
return new Promise((_, e) => cancellationToken.onCancellationRequested(() => e(canceled())));
}
buffersLength(buffers: Buffer[]): Thenable<number> {
buffersLength(buffers: Buffer[]): Promise<number> {
return Promise.resolve(buffers.reduce((r, b) => r + b.length, 0));
}
@@ -142,7 +142,7 @@ class TestChannel implements IServerChannel {
constructor(private service: ITestService) { }
call(_, command: string, arg?: any, cancellationToken?: CancellationToken): Thenable<any> {
call(_, command: string, arg: any, cancellationToken: CancellationToken): Promise<any> {
switch (command) {
case 'marco': return this.service.marco();
case 'error': return this.service.error(arg);
@@ -169,23 +169,23 @@ class TestChannelClient implements ITestService {
constructor(private channel: IChannel) { }
marco(): Thenable<string> {
marco(): Promise<string> {
return this.channel.call('marco');
}
error(message: string): Thenable<void> {
error(message: string): Promise<void> {
return this.channel.call('error', message);
}
neverComplete(): Thenable<void> {
neverComplete(): Promise<void> {
return this.channel.call('neverComplete');
}
neverCompleteCT(cancellationToken: CancellationToken): Thenable<void> {
neverCompleteCT(cancellationToken: CancellationToken): Promise<void> {
return this.channel.call('neverCompleteCT', undefined, cancellationToken);
}
buffersLength(buffers: Buffer[]): Thenable<number> {
buffersLength(buffers: Buffer[]): Promise<number> {
return this.channel.call('buffersLength', buffers);
}
}
@@ -201,8 +201,8 @@ suite('Base IPC', function () {
const b3 = Buffer.alloc(0);
serverProtocol.send(b3);
const b2 = await toPromise(serverProtocol.onMessage);
const b4 = await toPromise(clientProtocol.onMessage);
const b2 = await Event.toPromise(serverProtocol.onMessage);
const b4 = await Event.toPromise(clientProtocol.onMessage);
assert.strictEqual(b1, b2);
assert.strictEqual(b3, b4);

View File

@@ -13,9 +13,9 @@ export interface IMarcoPoloEvent {
export interface ITestService {
onMarco: Event<IMarcoPoloEvent>;
marco(): Thenable<string>;
pong(ping: string): Thenable<{ incoming: string, outgoing: string }>;
cancelMe(): Thenable<boolean>;
marco(): Promise<string>;
pong(ping: string): Promise<{ incoming: string, outgoing: string }>;
cancelMe(): Promise<boolean>;
}
export class TestService implements ITestService {
@@ -23,16 +23,16 @@ export class TestService implements ITestService {
private _onMarco = new Emitter<IMarcoPoloEvent>();
onMarco: Event<IMarcoPoloEvent> = this._onMarco.event;
marco(): Thenable<string> {
marco(): Promise<string> {
this._onMarco.fire({ answer: 'polo' });
return Promise.resolve('polo');
}
pong(ping: string): Thenable<{ incoming: string, outgoing: string }> {
pong(ping: string): Promise<{ incoming: string, outgoing: string }> {
return Promise.resolve({ incoming: ping, outgoing: 'pong' });
}
cancelMe(): Thenable<boolean> {
cancelMe(): Promise<boolean> {
return Promise.resolve(timeout(100)).then(() => true);
}
}
@@ -49,7 +49,7 @@ export class TestChannel implements IServerChannel {
throw new Error('Event not found');
}
call(_, command: string, ...args: any[]): Thenable<any> {
call(_, command: string, ...args: any[]): Promise<any> {
switch (command) {
case 'pong': return this.testService.pong(args[0]);
case 'cancelMe': return this.testService.cancelMe();
@@ -65,15 +65,15 @@ export class TestServiceClient implements ITestService {
constructor(private channel: IChannel) { }
marco(): Thenable<string> {
marco(): Promise<string> {
return this.channel.call('marco');
}
pong(ping: string): Thenable<{ incoming: string, outgoing: string }> {
pong(ping: string): Promise<{ incoming: string, outgoing: string }> {
return this.channel.call('pong', ping);
}
cancelMe(): Thenable<boolean> {
cancelMe(): Promise<boolean> {
return this.channel.call('cancelMe');
}
}

View File

@@ -19,6 +19,7 @@ import { KeybindingLabel } from 'vs/base/browser/ui/keybindingLabel/keybindingLa
import { OS } from 'vs/base/common/platform';
import { ResolvedKeybinding } from 'vs/base/common/keyCodes';
import { IItemAccessor } from 'vs/base/parts/quickopen/common/quickOpenScorer';
import { coalesce } from 'vs/base/common/arrays';
export interface IContext {
event: any;
@@ -45,7 +46,7 @@ export class QuickOpenItemAccessorClass implements IItemAccessor<QuickOpenEntry>
getItemPath(entry: QuickOpenEntry): string {
const resource = entry.getResource();
return resource ? resource.fsPath : void 0;
return resource ? resource.fsPath : undefined;
}
}
@@ -89,8 +90,7 @@ export class QuickOpenEntry {
* The label of the entry to use when a screen reader wants to read about the entry
*/
getAriaLabel(): string {
return [this.getLabel(), this.getDescription(), this.getDetail()]
.filter(s => !!s)
return coalesce([this.getLabel(), this.getDescription(), this.getDetail()])
.join(', ');
}
@@ -468,13 +468,13 @@ class Renderer implements IRenderer<QuickOpenEntry> {
options.title = entry.getTooltip();
options.descriptionTitle = entry.getDescriptionTooltip() || entry.getDescription(); // tooltip over description because it could overflow
options.descriptionMatches = descriptionHighlights || [];
data.label.setValue(entry.getLabel(), entry.getDescription(), options);
data.label.setLabel(entry.getLabel(), entry.getDescription(), options);
// Meta
data.detail.set(entry.getDetail(), detailHighlights);
// Keybinding
data.keybinding.set(entry.getKeybinding(), null);
data.keybinding.set(entry.getKeybinding());
}
}
@@ -484,9 +484,7 @@ class Renderer implements IRenderer<QuickOpenEntry> {
data.actionBar = null;
data.container = null;
data.entry = null;
data.keybinding.dispose();
data.keybinding = null;
data.detail.dispose();
data.detail = null;
data.group = null;
data.icon = null;

View File

@@ -3,7 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { TPromise } from 'vs/base/common/winjs.base';
import { isFunction } from 'vs/base/common/types';
import { ITree, IRenderer, IFilter, IDataSource, IAccessibilityProvider } from 'vs/base/parts/tree/browser/tree';
import { IModel } from 'vs/base/parts/quickopen/common/quickOpen';
@@ -37,13 +36,13 @@ export class DataSource implements IDataSource {
return model && model === element && model.entries.length > 0;
}
getChildren(tree: ITree, element: any): TPromise<any[]> {
getChildren(tree: ITree, element: any): Promise<any[]> {
const model = this.modelProvider.getModel();
return TPromise.as(model === element ? model.entries : []);
return Promise.resolve(model === element ? model.entries : []);
}
getParent(tree: ITree, element: any): TPromise<any> {
return TPromise.as(null);
getParent(tree: ITree, element: any): Promise<any> {
return Promise.resolve(null);
}
}
@@ -140,4 +139,4 @@ export class Renderer implements IRenderer {
const model = this.modelProvider.getModel();
model.renderer.disposeTemplate(templateId, templateData);
}
}
}

View File

@@ -277,7 +277,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider {
this._register(this.tree.onDidChangeSelection(event => {
if (event.selection && event.selection.length > 0) {
const mouseEvent: StandardMouseEvent = event.payload && event.payload.originalEvent instanceof StandardMouseEvent ? event.payload.originalEvent : void 0;
const mouseEvent: StandardMouseEvent = event.payload && event.payload.originalEvent instanceof StandardMouseEvent ? event.payload.originalEvent : undefined;
const shouldOpenInBackground = mouseEvent ? this.shouldOpenInBackground(mouseEvent) : false;
this.elementSelected(event.selection[0], event, shouldOpenInBackground ? Mode.OPEN_IN_BACKGROUND : Mode.OPEN);
@@ -574,7 +574,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider {
show(param: any, options?: IShowOptions): void {
this.visible = true;
this.isLoosingFocus = false;
this.quickNavigateConfiguration = options ? options.quickNavigateConfiguration : void 0;
this.quickNavigateConfiguration = options ? options.quickNavigateConfiguration : undefined;
// Adjust UI for quick navigate mode
if (this.quickNavigateConfiguration) {
@@ -675,8 +675,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider {
let caseInsensitiveMatch: any;
const prefix = autoFocus.autoFocusPrefixMatch;
const lowerCasePrefix = prefix.toLowerCase();
for (let i = 0; i < entries.length; i++) {
const entry = entries[i];
for (const entry of entries) {
const label = input.dataSource.getLabel(entry);
if (!caseSensitiveMatch && label.indexOf(prefix) === 0) {
@@ -773,7 +772,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider {
let preferredItemsHeight: number;
if (this.layoutDimensions && this.layoutDimensions.height) {
preferredItemsHeight = (this.layoutDimensions.height - 50 /* subtract height of input field (30px) and some spacing (drop shadow) to fit */) * 0.40 /* max 40% of screen */;
preferredItemsHeight = (this.layoutDimensions.height - 50 /* subtract height of input field (30px) and some spacing (drop shadow) to fit */) * 0.4 /* max 40% of screen */;
}
if (!preferredItemsHeight || preferredItemsHeight > QuickOpenWidget.MAX_ITEMS_HEIGHT) {

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { compareAnything } from 'vs/base/common/comparers';
import { matchesPrefix, IMatch, createMatches, matchesCamelCase, isUpper } from 'vs/base/common/filters';
import { matchesPrefix, IMatch, matchesCamelCase, isUpper } from 'vs/base/common/filters';
import { nativeSep } from 'vs/base/common/paths';
import { isWindows, isLinux } from 'vs/base/common/platform';
import { stripWildcards, equalsIgnoreCase } from 'vs/base/common/strings';
@@ -60,7 +60,7 @@ export function score(target: string, query: string, queryLower: string, fuzzy:
return res;
}
function doScore(query: string, queryLower: string, queryLength: number, target: string, targetLower: string, targetLength: number): [number, number[]] {
function doScore(query: string, queryLower: string, queryLength: number, target: string, targetLower: string, targetLength: number): Score {
const scores: number[] = [];
const matches: number[] = [];
@@ -80,15 +80,25 @@ function doScore(query: string, queryLower: string, queryLength: number, target:
// y
//
for (let queryIndex = 0; queryIndex < queryLength; queryIndex++) {
const queryIndexOffset = queryIndex * targetLength;
const queryIndexPreviousOffset = queryIndexOffset - targetLength;
const queryIndexGtNull = queryIndex > 0;
const queryCharAtIndex = query[queryIndex];
const queryLowerCharAtIndex = queryLower[queryIndex];
for (let targetIndex = 0; targetIndex < targetLength; targetIndex++) {
const currentIndex = queryIndex * targetLength + targetIndex;
const targetIndexGtNull = targetIndex > 0;
const currentIndex = queryIndexOffset + targetIndex;
const leftIndex = currentIndex - 1;
const diagIndex = (queryIndex - 1) * targetLength + targetIndex - 1;
const diagIndex = queryIndexPreviousOffset + targetIndex - 1;
const leftScore: number = targetIndex > 0 ? scores[leftIndex] : 0;
const diagScore: number = queryIndex > 0 && targetIndex > 0 ? scores[diagIndex] : 0;
const leftScore = targetIndexGtNull ? scores[leftIndex] : 0;
const diagScore = queryIndexGtNull && targetIndexGtNull ? scores[diagIndex] : 0;
const matchesSequenceLength: number = queryIndex > 0 && targetIndex > 0 ? matches[diagIndex] : 0;
const matchesSequenceLength = queryIndexGtNull && targetIndexGtNull ? matches[diagIndex] : 0;
// If we are not matching on the first query character any more, we only produce a
// score if we had a score previously for the last query index (by looking at the diagScore).
@@ -96,10 +106,10 @@ function doScore(query: string, queryLower: string, queryLength: number, target:
// given a target of "ede" and a query of "de", we would otherwise produce a wrong high score
// for query[1] ("e") matching on target[0] ("e") because of the "beginning of word" boost.
let score: number;
if (!diagScore && queryIndex > 0) {
if (!diagScore && queryIndexGtNull) {
score = 0;
} else {
score = computeCharScore(query, queryLower, queryIndex, target, targetLower, targetIndex, matchesSequenceLength);
score = computeCharScore(queryCharAtIndex, queryLowerCharAtIndex, target, targetLower, targetIndex, matchesSequenceLength);
}
// We have a score and its equal or larger than the left score
@@ -146,10 +156,10 @@ function doScore(query: string, queryLower: string, queryLength: number, target:
return [scores[queryLength * targetLength - 1], positions.reverse()];
}
function computeCharScore(query: string, queryLower: string, queryIndex: number, target: string, targetLower: string, targetIndex: number, matchesSequenceLength: number): number {
function computeCharScore(queryCharAtIndex, queryLowerCharAtIndex, target: string, targetLower: string, targetIndex: number, matchesSequenceLength: number): number {
let score = 0;
if (queryLower[queryIndex] !== targetLower[targetIndex]) {
if (queryLowerCharAtIndex !== targetLower[targetIndex]) {
return score; // no match of characters
}
@@ -170,7 +180,7 @@ function computeCharScore(query: string, queryLower: string, queryIndex: number,
}
// Same case bonus
if (query[queryIndex] === target[targetIndex]) {
if (queryCharAtIndex === target[targetIndex]) {
score += 1;
// if (DEBUG) {
@@ -349,11 +359,28 @@ export function scoreItem<T>(item: T, query: IPreparedQuery, fuzzy: boolean, acc
return itemScore;
}
function createMatches(offsets: undefined | number[]): IMatch[] {
let ret: IMatch[] = [];
if (!offsets) {
return ret;
}
let last: IMatch | undefined;
for (const pos of offsets) {
if (last && last.end === pos) {
last.end += 1;
} else {
last = { start: pos, end: pos + 1 };
ret.push(last);
}
}
return ret;
}
function doScoreItem(label: string, description: string, path: string, query: IPreparedQuery, fuzzy: boolean): IItemScore {
// 1.) treat identity matches on full path highest
if (path && isLinux ? query.original === path : equalsIgnoreCase(query.original, path)) {
return { score: PATH_IDENTITY_SCORE, labelMatch: [{ start: 0, end: label.length }], descriptionMatch: description ? [{ start: 0, end: description.length }] : void 0 };
return { score: PATH_IDENTITY_SCORE, labelMatch: [{ start: 0, end: label.length }], descriptionMatch: description ? [{ start: 0, end: description.length }] : undefined };
}
// We only consider label matches if the query is not including file path separators
@@ -605,4 +632,4 @@ export function fallbackCompare<T>(itemA: T, itemB: T, query: IPreparedQuery, ac
// equal
return 0;
}
}

View File

@@ -38,11 +38,11 @@ suite('QuickOpen', () => {
model.addEntries([entry1, entry2, entry3]);
const ds = new DataSource(model);
assert.equal(entry1.getId(), ds.getId(null, entry1));
assert.equal(true, ds.hasChildren(null, model));
assert.equal(false, ds.hasChildren(null, entry1));
assert.equal(entry1.getId(), ds.getId(null!, entry1));
assert.equal(true, ds.hasChildren(null!, model));
assert.equal(false, ds.hasChildren(null!, entry1));
ds.getChildren(null, model).then((children: any[]) => {
ds.getChildren(null!, model).then((children: any[]) => {
assert.equal(3, children.length);
});
});

View File

@@ -29,15 +29,15 @@ const ResourceAccessor = new ResourceAccessorClass();
class NullAccessorClass implements scorer.IItemAccessor<URI> {
getItemLabel(resource: URI): string {
return void 0;
return undefined!;
}
getItemDescription(resource: URI): string {
return void 0;
return undefined!;
}
getItemPath(resource: URI): string {
return void 0;
return undefined!;
}
}
@@ -120,52 +120,52 @@ suite('Quick Open Scorer', () => {
// Path Identity
const identityRes = scoreItem(resource, ResourceAccessor.getItemPath(resource), true, ResourceAccessor, cache);
assert.ok(identityRes.score);
assert.equal(identityRes.descriptionMatch.length, 1);
assert.equal(identityRes.labelMatch.length, 1);
assert.equal(identityRes.descriptionMatch[0].start, 0);
assert.equal(identityRes.descriptionMatch[0].end, ResourceAccessor.getItemDescription(resource).length);
assert.equal(identityRes.labelMatch[0].start, 0);
assert.equal(identityRes.labelMatch[0].end, ResourceAccessor.getItemLabel(resource).length);
assert.equal(identityRes.descriptionMatch!.length, 1);
assert.equal(identityRes.labelMatch!.length, 1);
assert.equal(identityRes.descriptionMatch![0].start, 0);
assert.equal(identityRes.descriptionMatch![0].end, ResourceAccessor.getItemDescription(resource).length);
assert.equal(identityRes.labelMatch![0].start, 0);
assert.equal(identityRes.labelMatch![0].end, ResourceAccessor.getItemLabel(resource).length);
// Basename Prefix
const basenamePrefixRes = scoreItem(resource, 'som', true, ResourceAccessor, cache);
assert.ok(basenamePrefixRes.score);
assert.ok(!basenamePrefixRes.descriptionMatch);
assert.equal(basenamePrefixRes.labelMatch.length, 1);
assert.equal(basenamePrefixRes.labelMatch[0].start, 0);
assert.equal(basenamePrefixRes.labelMatch[0].end, 'som'.length);
assert.equal(basenamePrefixRes.labelMatch!.length, 1);
assert.equal(basenamePrefixRes.labelMatch![0].start, 0);
assert.equal(basenamePrefixRes.labelMatch![0].end, 'som'.length);
// Basename Camelcase
const basenameCamelcaseRes = scoreItem(resource, 'sF', true, ResourceAccessor, cache);
assert.ok(basenameCamelcaseRes.score);
assert.ok(!basenameCamelcaseRes.descriptionMatch);
assert.equal(basenameCamelcaseRes.labelMatch.length, 2);
assert.equal(basenameCamelcaseRes.labelMatch[0].start, 0);
assert.equal(basenameCamelcaseRes.labelMatch[0].end, 1);
assert.equal(basenameCamelcaseRes.labelMatch[1].start, 4);
assert.equal(basenameCamelcaseRes.labelMatch[1].end, 5);
assert.equal(basenameCamelcaseRes.labelMatch!.length, 2);
assert.equal(basenameCamelcaseRes.labelMatch![0].start, 0);
assert.equal(basenameCamelcaseRes.labelMatch![0].end, 1);
assert.equal(basenameCamelcaseRes.labelMatch![1].start, 4);
assert.equal(basenameCamelcaseRes.labelMatch![1].end, 5);
// Basename Match
const basenameRes = scoreItem(resource, 'of', true, ResourceAccessor, cache);
assert.ok(basenameRes.score);
assert.ok(!basenameRes.descriptionMatch);
assert.equal(basenameRes.labelMatch.length, 2);
assert.equal(basenameRes.labelMatch[0].start, 1);
assert.equal(basenameRes.labelMatch[0].end, 2);
assert.equal(basenameRes.labelMatch[1].start, 4);
assert.equal(basenameRes.labelMatch[1].end, 5);
assert.equal(basenameRes.labelMatch!.length, 2);
assert.equal(basenameRes.labelMatch![0].start, 1);
assert.equal(basenameRes.labelMatch![0].end, 2);
assert.equal(basenameRes.labelMatch![1].start, 4);
assert.equal(basenameRes.labelMatch![1].end, 5);
// Path Match
const pathRes = scoreItem(resource, 'xyz123', true, ResourceAccessor, cache);
assert.ok(pathRes.score);
assert.ok(pathRes.descriptionMatch);
assert.ok(pathRes.labelMatch);
assert.equal(pathRes.labelMatch.length, 1);
assert.equal(pathRes.labelMatch[0].start, 8);
assert.equal(pathRes.labelMatch[0].end, 11);
assert.equal(pathRes.descriptionMatch.length, 1);
assert.equal(pathRes.descriptionMatch[0].start, 1);
assert.equal(pathRes.descriptionMatch[0].end, 4);
assert.equal(pathRes.labelMatch!.length, 1);
assert.equal(pathRes.labelMatch![0].start, 8);
assert.equal(pathRes.labelMatch![0].end, 11);
assert.equal(pathRes.descriptionMatch!.length, 1);
assert.equal(pathRes.descriptionMatch![0].start, 1);
assert.equal(pathRes.descriptionMatch![0].end, 4);
// No Match
const noRes = scoreItem(resource, '987', true, ResourceAccessor, cache);
@@ -182,7 +182,7 @@ suite('Quick Open Scorer', () => {
test('scoreItem - invalid input', function () {
let res = scoreItem(null, null, true, ResourceAccessor, cache);
let res = scoreItem(null, null!, true, ResourceAccessor, cache);
assert.equal(res.score, 0);
res = scoreItem(null, 'null', true, ResourceAccessor, cache);
@@ -199,12 +199,12 @@ suite('Quick Open Scorer', () => {
assert.ok(pathRes.score);
assert.ok(pathRes.descriptionMatch);
assert.ok(pathRes.labelMatch);
assert.equal(pathRes.labelMatch.length, 1);
assert.equal(pathRes.labelMatch[0].start, 0);
assert.equal(pathRes.labelMatch[0].end, 7);
assert.equal(pathRes.descriptionMatch.length, 1);
assert.equal(pathRes.descriptionMatch[0].start, 23);
assert.equal(pathRes.descriptionMatch[0].end, 26);
assert.equal(pathRes.labelMatch!.length, 1);
assert.equal(pathRes.labelMatch![0].start, 0);
assert.equal(pathRes.labelMatch![0].end, 7);
assert.equal(pathRes.descriptionMatch!.length, 1);
assert.equal(pathRes.descriptionMatch![0].start, 23);
assert.equal(pathRes.descriptionMatch![0].end, 26);
});
test('scoreItem - avoid match scattering (bug #36119)', function () {
@@ -214,9 +214,9 @@ suite('Quick Open Scorer', () => {
assert.ok(pathRes.score);
assert.ok(pathRes.descriptionMatch);
assert.ok(pathRes.labelMatch);
assert.equal(pathRes.labelMatch.length, 1);
assert.equal(pathRes.labelMatch[0].start, 0);
assert.equal(pathRes.labelMatch[0].end, 9);
assert.equal(pathRes.labelMatch!.length, 1);
assert.equal(pathRes.labelMatch![0].start, 0);
assert.equal(pathRes.labelMatch![0].end, 9);
});
test('scoreItem - prefers more compact matches', function () {
@@ -227,12 +227,12 @@ suite('Quick Open Scorer', () => {
const res = scoreItem(resource, 'ad', true, ResourceAccessor, cache);
assert.ok(res.score);
assert.ok(res.descriptionMatch);
assert.ok(!res.labelMatch.length);
assert.equal(res.descriptionMatch.length, 2);
assert.equal(res.descriptionMatch[0].start, 11);
assert.equal(res.descriptionMatch[0].end, 12);
assert.equal(res.descriptionMatch[1].start, 13);
assert.equal(res.descriptionMatch[1].end, 14);
assert.ok(!res.labelMatch!.length);
assert.equal(res.descriptionMatch!.length, 2);
assert.equal(res.descriptionMatch![0].start, 11);
assert.equal(res.descriptionMatch![0].end, 12);
assert.equal(res.descriptionMatch![1].start, 13);
assert.equal(res.descriptionMatch![1].end, 14);
});
test('scoreItem - proper target offset', function () {
@@ -247,9 +247,9 @@ suite('Quick Open Scorer', () => {
const res = scoreItem(resource, 'de', true, ResourceAccessor, cache);
assert.equal(res.labelMatch.length, 1);
assert.equal(res.labelMatch[0].start, 1);
assert.equal(res.labelMatch[0].end, 3);
assert.equal(res.labelMatch!.length, 1);
assert.equal(res.labelMatch![0].start, 1);
assert.equal(res.labelMatch![0].end, 3);
});
test('scoreItem - proper target offset #3', function () {
@@ -257,19 +257,19 @@ suite('Quick Open Scorer', () => {
const res = scoreItem(resource, 'debug', true, ResourceAccessor, cache);
assert.equal(res.descriptionMatch.length, 3);
assert.equal(res.descriptionMatch[0].start, 9);
assert.equal(res.descriptionMatch[0].end, 10);
assert.equal(res.descriptionMatch[1].start, 36);
assert.equal(res.descriptionMatch[1].end, 37);
assert.equal(res.descriptionMatch[2].start, 40);
assert.equal(res.descriptionMatch[2].end, 41);
assert.equal(res.descriptionMatch!.length, 3);
assert.equal(res.descriptionMatch![0].start, 9);
assert.equal(res.descriptionMatch![0].end, 10);
assert.equal(res.descriptionMatch![1].start, 36);
assert.equal(res.descriptionMatch![1].end, 37);
assert.equal(res.descriptionMatch![2].start, 40);
assert.equal(res.descriptionMatch![2].end, 41);
assert.equal(res.labelMatch.length, 2);
assert.equal(res.labelMatch[0].start, 9);
assert.equal(res.labelMatch[0].end, 10);
assert.equal(res.labelMatch[1].start, 20);
assert.equal(res.labelMatch[1].end, 21);
assert.equal(res.labelMatch!.length, 2);
assert.equal(res.labelMatch![0].start, 9);
assert.equal(res.labelMatch![0].end, 10);
assert.equal(res.labelMatch![1].start, 20);
assert.equal(res.labelMatch![1].end, 21);
});
test('scoreItem - no match unless query contained in sequence', function () {

View File

@@ -3,7 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as WinJS from 'vs/base/common/winjs.base';
import * as Touch from 'vs/base/browser/touch';
import * as Mouse from 'vs/base/browser/mouseEvent';
import * as Keyboard from 'vs/base/browser/keyboardEvent';
@@ -13,6 +12,7 @@ import { Event } from 'vs/base/common/event';
import { IAction, IActionItem } from 'vs/base/common/actions';
import { Color } from 'vs/base/common/color';
import { IItemCollapseEvent, IItemExpandEvent } from 'vs/base/parts/tree/browser/treeModel';
import { IDragAndDropData } from 'vs/base/browser/dnd';
export interface ITree {
@@ -50,7 +50,7 @@ export interface ITree {
/**
* Sets the input of the tree.
*/
setInput(element: any): WinJS.Promise;
setInput(element: any): Promise<any>;
/**
* Returns the tree's input.
@@ -76,47 +76,42 @@ export interface ITree {
* Refreshes an element.
* Provide no arguments and it will refresh the input element.
*/
refresh(element?: any, recursive?: boolean): WinJS.Promise;
/**
* Updates an element's width.
*/
updateWidth(element: any): void;
refresh(element?: any, recursive?: boolean): Promise<any>;
/**
* Expands an element.
* The returned promise returns a boolean for whether the element was expanded or not.
*/
expand(element: any): WinJS.Promise;
expand(element: any): Promise<any>;
/**
* Expands several elements.
* The returned promise returns a boolean array for whether the elements were expanded or not.
*/
expandAll(elements?: any[]): WinJS.Promise;
expandAll(elements?: any[]): Promise<any>;
/**
* Collapses an element.
* The returned promise returns a boolean for whether the element was collapsed or not.
*/
collapse(element: any, recursive?: boolean): WinJS.Promise;
collapse(element: any, recursive?: boolean): Promise<any>;
/**
* Collapses several elements.
* Provide no arguments and it will recursively collapse all elements in the tree
* The returned promise returns a boolean for whether the elements were collapsed or not.
*/
collapseAll(elements?: any[], recursive?: boolean): WinJS.Promise;
collapseAll(elements?: any[], recursive?: boolean): Promise<any>;
/**
* Toggles an element's expansion state.
*/
toggleExpansion(element: any, recursive?: boolean): WinJS.Promise;
toggleExpansion(element: any, recursive?: boolean): Promise<any>;
/**
* Toggles several element's expansion state.
*/
toggleExpansionAll(elements: any[]): WinJS.Promise;
toggleExpansionAll(elements: any[]): Promise<any>;
/**
* Returns whether an element is expanded or not.
@@ -132,7 +127,7 @@ export interface ITree {
* Reveals an element in the tree. The relativeTop is a value between 0 and 1. The closer to 0 the more the
* element will scroll up to the top.
*/
reveal(element: any, relativeTop?: number): WinJS.Promise;
reveal(element: any, relativeTop?: number): Promise<any>;
/**
* Returns the relative top position of any given element, if visible.
@@ -378,12 +373,12 @@ export interface IDataSource {
/**
* Returns the element's children as an array in a promise.
*/
getChildren(tree: ITree, element: any): WinJS.Promise;
getChildren(tree: ITree, element: any): Promise<any>;
/**
* Returns the element's parent in a promise.
*/
getParent(tree: ITree, element: any): WinJS.Promise;
getParent(tree: ITree, element: any): Promise<any>;
/**
* Returns whether an element should be expanded when first added to the tree.
@@ -443,7 +438,7 @@ export interface IAccessibilityProvider {
*
* See also: https://www.w3.org/TR/wai-aria/states_and_properties#aria-label
*/
getAriaLabel(tree: ITree, element: any): string;
getAriaLabel(tree: ITree, element: any): string | null;
/**
* Given an element in the tree return its aria-posinset. Should be between 1 and aria-setsize
@@ -594,18 +589,13 @@ export const DRAG_OVER_ACCEPT_BUBBLE_DOWN = (autoExpand = false) => ({ accept: t
export const DRAG_OVER_ACCEPT_BUBBLE_UP_COPY: IDragOverReaction = { accept: true, bubble: DragOverBubble.BUBBLE_UP, effect: DragOverEffect.COPY };
export const DRAG_OVER_ACCEPT_BUBBLE_DOWN_COPY = (autoExpand = false) => ({ accept: true, bubble: DragOverBubble.BUBBLE_DOWN, effect: DragOverEffect.COPY, autoExpand });
export interface IDragAndDropData {
update(event: Mouse.DragMouseEvent): void;
getData(): any;
}
export interface IDragAndDrop {
/**
* Returns a uri if the given element should be allowed to drag.
* Returns null, otherwise.
*/
getDragURI(tree: ITree, element: any): string;
getDragURI(tree: ITree, element: any): string | null;
/**
* Returns a label to display when dragging the element.
@@ -621,7 +611,7 @@ export interface IDragAndDrop {
* Returns a DragOverReaction indicating whether sources can be
* dropped into target or some parent of the target.
*/
onDragOver(tree: ITree, data: IDragAndDropData, targetElement: any, originalEvent: Mouse.DragMouseEvent): IDragOverReaction;
onDragOver(tree: ITree, data: IDragAndDropData, targetElement: any, originalEvent: Mouse.DragMouseEvent): IDragOverReaction | null;
/**
* Handles the action of dropping sources into target.
@@ -754,5 +744,5 @@ export interface IActionProvider {
/**
* Returns an action item to render an action.
*/
getActionItem(tree: ITree, element: any, action: IAction): IActionItem;
getActionItem(tree: ITree, element: any, action: IAction): IActionItem | null;
}

View File

@@ -12,7 +12,8 @@ import * as dom from 'vs/base/browser/dom';
import * as mouse from 'vs/base/browser/mouseEvent';
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import * as _ from 'vs/base/parts/tree/browser/tree';
import { KeyCode, KeyMod, Keybinding, createKeybinding, SimpleKeybinding, createSimpleKeybinding } from 'vs/base/common/keyCodes';
import { IDragAndDropData } from 'vs/base/browser/dnd';
import { KeyCode, KeyMod, Keybinding, SimpleKeybinding, createSimpleKeybinding } from 'vs/base/common/keyCodes';
export interface IKeyBindingCallback {
(tree: _.ITree, event: IKeyboardEvent): void;
@@ -70,14 +71,14 @@ export class KeybindingDispatcher {
return false;
}
public set(keybinding: KeyCode, callback: IKeyBindingCallback) {
public set(keybinding: number, callback: IKeyBindingCallback) {
this._arr.push({
keybinding: createKeybinding(keybinding, platform.OS),
keybinding: createSimpleKeybinding(keybinding, platform.OS),
callback: callback
});
}
public dispatch(keybinding: SimpleKeybinding): IKeyBindingCallback {
public dispatch(keybinding: SimpleKeybinding): IKeyBindingCallback | null {
// Loop from the last to the first to handle overwrites
for (let i = this._arr.length - 1; i >= 0; i--) {
let item = this._arr[i];
@@ -189,9 +190,9 @@ export class DefaultController implements _.IController {
if (this.shouldToggleExpansion(element, event, origin)) {
if (tree.isExpanded(element)) {
tree.collapse(element).then(null, errors.onUnexpectedError);
tree.collapse(element).then(undefined, errors.onUnexpectedError);
} else {
tree.expand(element).then(null, errors.onUnexpectedError);
tree.expand(element).then(undefined, errors.onUnexpectedError);
}
}
}
@@ -225,7 +226,7 @@ export class DefaultController implements _.IController {
return false;
}
const twistieWidth = parseInt(twistieStyle.width) + parseInt(twistieStyle.paddingRight);
const twistieWidth = parseInt(twistieStyle.width!) + parseInt(twistieStyle.paddingRight!);
return event.browserEvent.offsetX <= twistieWidth;
}
@@ -281,7 +282,7 @@ export class DefaultController implements _.IController {
tree.clearHighlight(payload);
} else {
tree.focusPrevious(1, payload);
tree.reveal(tree.getFocus()).then(null, errors.onUnexpectedError);
tree.reveal(tree.getFocus()).then(undefined, errors.onUnexpectedError);
}
return true;
}
@@ -293,7 +294,7 @@ export class DefaultController implements _.IController {
tree.clearHighlight(payload);
} else {
tree.focusPreviousPage(payload);
tree.reveal(tree.getFocus()).then(null, errors.onUnexpectedError);
tree.reveal(tree.getFocus()).then(undefined, errors.onUnexpectedError);
}
return true;
}
@@ -305,7 +306,7 @@ export class DefaultController implements _.IController {
tree.clearHighlight(payload);
} else {
tree.focusNext(1, payload);
tree.reveal(tree.getFocus()).then(null, errors.onUnexpectedError);
tree.reveal(tree.getFocus()).then(undefined, errors.onUnexpectedError);
}
return true;
}
@@ -317,7 +318,7 @@ export class DefaultController implements _.IController {
tree.clearHighlight(payload);
} else {
tree.focusNextPage(payload);
tree.reveal(tree.getFocus()).then(null, errors.onUnexpectedError);
tree.reveal(tree.getFocus()).then(undefined, errors.onUnexpectedError);
}
return true;
}
@@ -329,7 +330,7 @@ export class DefaultController implements _.IController {
tree.clearHighlight(payload);
} else {
tree.focusFirst(payload);
tree.reveal(tree.getFocus()).then(null, errors.onUnexpectedError);
tree.reveal(tree.getFocus()).then(undefined, errors.onUnexpectedError);
}
return true;
}
@@ -341,7 +342,7 @@ export class DefaultController implements _.IController {
tree.clearHighlight(payload);
} else {
tree.focusLast(payload);
tree.reveal(tree.getFocus()).then(null, errors.onUnexpectedError);
tree.reveal(tree.getFocus()).then(undefined, errors.onUnexpectedError);
}
return true;
}
@@ -359,7 +360,7 @@ export class DefaultController implements _.IController {
return tree.reveal(tree.getFocus());
}
return undefined;
}).then(null, errors.onUnexpectedError);
}).then(undefined, errors.onUnexpectedError);
}
return true;
}
@@ -377,7 +378,7 @@ export class DefaultController implements _.IController {
return tree.reveal(tree.getFocus());
}
return undefined;
}).then(null, errors.onUnexpectedError);
}).then(undefined, errors.onUnexpectedError);
}
return true;
}
@@ -430,24 +431,24 @@ export class DefaultController implements _.IController {
export class DefaultDragAndDrop implements _.IDragAndDrop {
public getDragURI(tree: _.ITree, element: any): string {
public getDragURI(tree: _.ITree, element: any): string | null {
return null;
}
public onDragStart(tree: _.ITree, data: _.IDragAndDropData, originalEvent: mouse.DragMouseEvent): void {
public onDragStart(tree: _.ITree, data: IDragAndDropData, originalEvent: mouse.DragMouseEvent): void {
return;
}
public onDragOver(tree: _.ITree, data: _.IDragAndDropData, targetElement: any, originalEvent: mouse.DragMouseEvent): _.IDragOverReaction {
public onDragOver(tree: _.ITree, data: IDragAndDropData, targetElement: any, originalEvent: mouse.DragMouseEvent): _.IDragOverReaction | null {
return null;
}
public drop(tree: _.ITree, data: _.IDragAndDropData, targetElement: any, originalEvent: mouse.DragMouseEvent): void {
public drop(tree: _.ITree, data: IDragAndDropData, targetElement: any, originalEvent: mouse.DragMouseEvent): void {
return;
}
// {{SQL CARBON EDIT}}
public dropAbort(tree: _.ITree, data: _.IDragAndDropData): void { }
public dropAbort(tree: _.ITree, data: IDragAndDropData): void { }
}
export class DefaultFilter implements _.IFilter {
@@ -466,7 +467,7 @@ export class DefaultSorter implements _.ISorter {
export class DefaultAccessibilityProvider implements _.IAccessibilityProvider {
getAriaLabel(tree: _.ITree, element: any): string {
getAriaLabel(tree: _.ITree, element: any): string | null {
return null;
}
}
@@ -558,7 +559,7 @@ export class CollapseAllAction extends Action {
super('vs.tree.collapse', nls.localize('collapse', "Collapse"), 'monaco-tree-action collapse-all', enabled);
}
public run(context?: any): Thenable<any> {
public run(context?: any): Promise<any> {
if (this.viewer.getHighlight()) {
return Promise.resolve(); // Global action disabled if user is in edit mode from another action
}

View File

@@ -4,9 +4,9 @@
*--------------------------------------------------------------------------------------------*/
import * as _ from 'vs/base/parts/tree/browser/tree';
import * as Mouse from 'vs/base/browser/mouseEvent';
import { IDragAndDropData } from 'vs/base/browser/dnd';
export class ElementsDragAndDropData implements _.IDragAndDropData {
export class ElementsDragAndDropData implements IDragAndDropData {
private elements: any[];
@@ -14,7 +14,7 @@ export class ElementsDragAndDropData implements _.IDragAndDropData {
this.elements = elements;
}
public update(event: Mouse.DragMouseEvent): void {
public update(dataTransfer: DataTransfer): void {
// no-op
}
@@ -23,7 +23,7 @@ export class ElementsDragAndDropData implements _.IDragAndDropData {
}
}
export class ExternalElementsDragAndDropData implements _.IDragAndDropData {
export class ExternalElementsDragAndDropData implements IDragAndDropData {
private elements: any[];
@@ -31,7 +31,7 @@ export class ExternalElementsDragAndDropData implements _.IDragAndDropData {
this.elements = elements;
}
public update(event: Mouse.DragMouseEvent): void {
public update(dataTransfer: DataTransfer): void {
// no-op
}
@@ -40,7 +40,7 @@ export class ExternalElementsDragAndDropData implements _.IDragAndDropData {
}
}
export class DesktopDragAndDropData implements _.IDragAndDropData {
export class DesktopDragAndDropData implements IDragAndDropData {
private types: any[];
private files: any[];
@@ -50,15 +50,15 @@ export class DesktopDragAndDropData implements _.IDragAndDropData {
this.files = [];
}
public update(event: Mouse.DragMouseEvent): void {
if (event.dataTransfer.types) {
public update(dataTransfer: DataTransfer): void {
if (dataTransfer.types) {
this.types = [];
Array.prototype.push.apply(this.types, event.dataTransfer.types);
Array.prototype.push.apply(this.types, dataTransfer.types as any);
}
if (event.dataTransfer.files) {
if (dataTransfer.files) {
this.files = [];
Array.prototype.push.apply(this.files, event.dataTransfer.files);
Array.prototype.push.apply(this.files, dataTransfer.files as any);
this.files = this.files.filter(f => f.size || f.type);
}

View File

@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./tree';
import * as WinJS from 'vs/base/common/winjs.base';
import * as TreeDefaults from 'vs/base/parts/tree/browser/treeDefaults';
import * as Model from 'vs/base/parts/tree/browser/treeModel';
import * as View from './treeView';
@@ -21,13 +20,13 @@ export class TreeContext implements _.ITreeContext {
public options: _.ITreeOptions;
public dataSource: _.IDataSource;
public renderer: _.IRenderer;
public renderer?: _.IRenderer;
public controller: _.IController;
public dnd: _.IDragAndDrop;
public filter: _.IFilter;
public sorter: _.ISorter;
public sorter?: _.ISorter;
public accessibilityProvider: _.IAccessibilityProvider;
public styler: _.ITreeStyler;
public styler?: _.ITreeStyler;
constructor(tree: _.ITree, configuration: _.ITreeConfiguration, options: _.ITreeOptions = {}) {
this.tree = tree;
@@ -43,9 +42,9 @@ export class TreeContext implements _.ITreeContext {
this.controller = configuration.controller || new TreeDefaults.DefaultController({ clickBehavior: TreeDefaults.ClickBehavior.ON_MOUSE_UP, keyboardSupport: typeof options.keyboardSupport !== 'boolean' || options.keyboardSupport });
this.dnd = configuration.dnd || new TreeDefaults.DefaultDragAndDrop();
this.filter = configuration.filter || new TreeDefaults.DefaultFilter();
this.sorter = configuration.sorter || null;
this.sorter = configuration.sorter;
this.accessibilityProvider = configuration.accessibilityProvider || new TreeDefaults.DefaultAccessibilityProvider();
this.styler = configuration.styler || null;
this.styler = configuration.styler;
}
}
@@ -150,7 +149,7 @@ export class Tree implements _.ITree {
this.view.onHidden();
}
public setInput(element: any): WinJS.Promise {
public setInput(element: any): Promise<any> {
return this.model.setInput(element);
}
@@ -158,36 +157,31 @@ export class Tree implements _.ITree {
return this.model.getInput();
}
public refresh(element: any = null, recursive = true): WinJS.Promise {
public refresh(element: any = null, recursive = true): Promise<any> {
return this.model.refresh(element, recursive);
}
public updateWidth(element: any): void {
let item = this.model.getItem(element);
return this.view.updateWidth(item);
}
public expand(element: any): WinJS.Promise {
public expand(element: any): Promise<any> {
return this.model.expand(element);
}
public expandAll(elements: any[]): WinJS.Promise {
public expandAll(elements: any[]): Promise<any> {
return this.model.expandAll(elements);
}
public collapse(element: any, recursive: boolean = false): WinJS.Promise {
public collapse(element: any, recursive: boolean = false): Promise<any> {
return this.model.collapse(element, recursive);
}
public collapseAll(elements: any[] | null = null, recursive: boolean = false): WinJS.Promise {
public collapseAll(elements: any[] | null = null, recursive: boolean = false): Promise<any> {
return this.model.collapseAll(elements, recursive);
}
public toggleExpansion(element: any, recursive: boolean = false): WinJS.Promise {
public toggleExpansion(element: any, recursive: boolean = false): Promise<any> {
return this.model.toggleExpansion(element, recursive);
}
public toggleExpansionAll(elements: any[]): WinJS.Promise {
public toggleExpansionAll(elements: any[]): Promise<any> {
return this.model.toggleExpansionAll(elements);
}
@@ -199,13 +193,13 @@ export class Tree implements _.ITree {
return this.model.getExpandedElements();
}
public reveal(element: any, relativeTop: number | null = null): WinJS.Promise {
public reveal(element: any, relativeTop: number | null = null): Promise<any> {
return this.model.reveal(element, relativeTop);
}
public getRelativeTop(element: any): number {
let item = this.model.getItem(element);
return this.view.getRelativeTop(item);
const item = this.model.getItem(element);
return item ? this.view.getRelativeTop(item) : 0;
}
public getFirstVisibleElement(): any {
@@ -378,11 +372,11 @@ export class Tree implements _.ITree {
if (this.model !== null) {
this.model.dispose();
this.model = null;
this.model = null!; // StrictNullOverride Nulling out ok in dispose
}
if (this.view !== null) {
this.view.dispose();
this.view = null;
this.view = null!; // StrictNullOverride Nulling out ok in dispose
}
this._onDidChangeFocus.dispose();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -15,25 +15,20 @@ export interface IViewItem {
export class HeightMap {
private heightMap: IViewItem[];
private indexes: { [item: string]: number; };
private heightMap: IViewItem[] = [];
private indexes: { [item: string]: number; } = {};
constructor() {
this.heightMap = [];
this.indexes = {};
}
public getContentHeight(): number {
var last = this.heightMap[this.heightMap.length - 1];
getContentHeight(): number {
let last = this.heightMap[this.heightMap.length - 1];
return !last ? 0 : last.top + last.height;
}
public onInsertItems(iterator: INextIterator<Item>, afterItemId: string | null = null): number {
var item: Item;
var viewItem: IViewItem;
var i: number, j: number;
var totalSize: number;
var sizeDiff = 0;
onInsertItems(iterator: INextIterator<Item>, afterItemId: string | null = null): number | undefined {
let item: Item | null = null;
let viewItem: IViewItem;
let i: number, j: number;
let totalSize: number;
let sizeDiff = 0;
if (afterItemId === null) {
i = 0;
@@ -50,9 +45,9 @@ export class HeightMap {
totalSize = viewItem.top + viewItem.height;
}
var boundSplice = this.heightMap.splice.bind(this.heightMap, i, 0);
let boundSplice = this.heightMap.splice.bind(this.heightMap, i, 0);
var itemsToInsert: IViewItem[] = [];
let itemsToInsert: IViewItem[] = [];
while (item = iterator.next()) {
viewItem = this.createViewItem(item);
@@ -82,17 +77,17 @@ export class HeightMap {
return sizeDiff;
}
public onInsertItem(item: IViewItem): void {
onInsertItem(item: IViewItem): void {
// noop
}
// Contiguous items
public onRemoveItems(iterator: INextIterator<string>): void {
var itemId: string;
var viewItem: IViewItem;
var startIndex: number | null = null;
var i: number;
var sizeDiff = 0;
onRemoveItems(iterator: INextIterator<string>): void {
let itemId: string | null = null;
let viewItem: IViewItem;
let startIndex: number | null = null;
let i = 0;
let sizeDiff = 0;
while (itemId = iterator.next()) {
i = this.indexes[itemId];
@@ -112,7 +107,7 @@ export class HeightMap {
}
}
if (sizeDiff === 0) {
if (sizeDiff === 0 || startIndex === null) {
return;
}
@@ -126,22 +121,22 @@ export class HeightMap {
}
}
public onRemoveItem(item: IViewItem): void {
onRemoveItem(item: IViewItem): void {
// noop
}
public onRefreshItemSet(items: Item[]): void {
var sortedItems = items.sort((a, b) => this.indexes[a.id] - this.indexes[b.id]);
onRefreshItemSet(items: Item[]): void {
let sortedItems = items.sort((a, b) => this.indexes[a.id] - this.indexes[b.id]);
this.onRefreshItems(new ArrayIterator(sortedItems));
}
// Ordered, but not necessarily contiguous items
public onRefreshItems(iterator: INextIterator<Item>): void {
var item: Item;
var viewItem: IViewItem;
var newHeight: number;
var i: number, j: number | null = null;
var cummDiff = 0;
onRefreshItems(iterator: INextIterator<Item>): void {
let item: Item | null = null;
let viewItem: IViewItem;
let newHeight: number;
let i: number, j: number | null = null;
let cummDiff = 0;
while (item = iterator.next()) {
i = this.indexes[item.id];
@@ -171,31 +166,31 @@ export class HeightMap {
}
}
public onRefreshItem(item: IViewItem, needsRender: boolean = false): void {
onRefreshItem(item: IViewItem, needsRender: boolean = false): void {
// noop
}
public itemsCount(): number {
itemsCount(): number {
return this.heightMap.length;
}
public itemAt(position: number): string {
itemAt(position: number): string {
return this.heightMap[this.indexAt(position)].model.id;
}
public withItemsInRange(start: number, end: number, fn: (item: string) => void): void {
withItemsInRange(start: number, end: number, fn: (item: string) => void): void {
start = this.indexAt(start);
end = this.indexAt(end);
for (var i = start; i <= end; i++) {
for (let i = start; i <= end; i++) {
fn(this.heightMap[i].model.id);
}
}
public indexAt(position: number): number {
var left = 0;
var right = this.heightMap.length;
var center: number;
var item: IViewItem;
indexAt(position: number): number {
let left = 0;
let right = this.heightMap.length;
let center: number;
let item: IViewItem;
// Binary search
while (left < right) {
@@ -217,15 +212,15 @@ export class HeightMap {
return this.heightMap.length;
}
public indexAfter(position: number): number {
indexAfter(position: number): number {
return Math.min(this.indexAt(position) + 1, this.heightMap.length);
}
public itemAtIndex(index: number): IViewItem {
itemAtIndex(index: number): IViewItem {
return this.heightMap[index];
}
public itemAfter(item: IViewItem): IViewItem {
itemAfter(item: IViewItem): IViewItem {
return this.heightMap[this.indexes[item.model.id] + 1] || null;
}
@@ -233,8 +228,8 @@ export class HeightMap {
throw new Error('not implemented');
}
public dispose(): void {
this.heightMap = null;
this.indexes = null;
dispose(): void {
this.heightMap = [];
this.indexes = {};
}
}

View File

@@ -36,12 +36,12 @@ export class FakeRenderer {
class TreeContext implements _.ITreeContext {
public tree: _.ITree = null;
public tree: _.ITree = null!;
public options: _.ITreeOptions = { autoExpandSingleChildren: true };
public dataSource: _.IDataSource;
public renderer: _.IRenderer;
public controller: _.IController;
public dnd: _.IDragAndDrop;
public controller?: _.IController;
public dnd?: _.IDragAndDrop;
public filter: _.IFilter;
public sorter: _.ISorter;
@@ -72,7 +72,7 @@ class EventCounter {
this._count = 0;
}
public listen<T>(event: Event<T>, fn: (e: T) => void = null): () => void {
public listen<T>(event: Event<T>, fn: ((e: T) => void) | null = null): () => void {
let r = event(data => {
this._count++;
if (fn) {
@@ -105,7 +105,7 @@ class EventCounter {
}
}
var SAMPLE: any = {
const SAMPLE: any = {
ONE: { id: 'one' },
AB: {
@@ -169,18 +169,18 @@ class TestDataSource implements _.IDataSource {
return !!element.children;
}
public getChildren(tree, element): Thenable<any> {
public getChildren(tree, element): Promise<any> {
return Promise.resolve(element.children);
}
public getParent(tree, element): Thenable<any> {
public getParent(tree, element): Promise<any> {
throw new Error('Not implemented');
}
}
suite('TreeModel', () => {
var model: model.TreeModel;
var counter: EventCounter;
let model: model.TreeModel;
let counter: EventCounter;
setup(() => {
counter = new EventCounter();
@@ -313,7 +313,7 @@ suite('TreeModel', () => {
return model.setInput(SAMPLE.AB).then(() => {
return model.expandAll(['a', 'c']).then(() => {
// going internals
var r = (<any>model).registry;
const r = (<any>model).registry;
assert(r.getItem('a').intersects(r.getItem('a')));
assert(r.getItem('a').intersects(r.getItem('aa')));
@@ -331,8 +331,8 @@ suite('TreeModel', () => {
});
suite('TreeModel - TreeNavigator', () => {
var model: model.TreeModel;
var counter: EventCounter;
let model: model.TreeModel;
let counter: EventCounter;
setup(() => {
counter = new EventCounter();
@@ -348,24 +348,24 @@ suite('TreeModel - TreeNavigator', () => {
test('next()', () => {
return model.setInput(SAMPLE.AB).then(() => {
var nav = model.getNavigator();
assert.equal(nav.next().id, 'a');
assert.equal(nav.next().id, 'b');
assert.equal(nav.next().id, 'c');
const nav = model.getNavigator();
assert.equal(nav.next()!.id, 'a');
assert.equal(nav.next()!.id, 'b');
assert.equal(nav.next()!.id, 'c');
assert.equal(nav.next() && false, null);
});
});
test('previous()', () => {
return model.setInput(SAMPLE.AB).then(() => {
var nav = model.getNavigator();
const nav = model.getNavigator();
nav.next();
nav.next();
assert.equal(nav.next().id, 'c');
assert.equal(nav.previous().id, 'b');
assert.equal(nav.previous().id, 'a');
assert.equal(nav.next()!.id, 'c');
assert.equal(nav.previous()!.id, 'b');
assert.equal(nav.previous()!.id, 'a');
assert.equal(nav.previous() && false, null);
});
});
@@ -373,22 +373,22 @@ suite('TreeModel - TreeNavigator', () => {
test('parent()', () => {
return model.setInput(SAMPLE.AB).then(() => {
return model.expandAll([{ id: 'a' }, { id: 'c' }]).then(() => {
var nav = model.getNavigator();
const nav = model.getNavigator();
assert.equal(nav.next().id, 'a');
assert.equal(nav.next().id, 'aa');
assert.equal(nav.parent().id, 'a');
assert.equal(nav.next()!.id, 'a');
assert.equal(nav.next()!.id, 'aa');
assert.equal(nav.parent()!.id, 'a');
assert.equal(nav.next().id, 'aa');
assert.equal(nav.next().id, 'ab');
assert.equal(nav.parent().id, 'a');
assert.equal(nav.next()!.id, 'aa');
assert.equal(nav.next()!.id, 'ab');
assert.equal(nav.parent()!.id, 'a');
assert.equal(nav.next().id, 'aa');
assert.equal(nav.next().id, 'ab');
assert.equal(nav.next().id, 'b');
assert.equal(nav.next().id, 'c');
assert.equal(nav.next().id, 'ca');
assert.equal(nav.parent().id, 'c');
assert.equal(nav.next()!.id, 'aa');
assert.equal(nav.next()!.id, 'ab');
assert.equal(nav.next()!.id, 'b');
assert.equal(nav.next()!.id, 'c');
assert.equal(nav.next()!.id, 'ca');
assert.equal(nav.parent()!.id, 'c');
assert.equal(nav.parent() && false, null);
});
@@ -397,10 +397,10 @@ suite('TreeModel - TreeNavigator', () => {
test('next() - scoped', () => {
return model.setInput(SAMPLE.AB).then(() => {
var nav = model.getNavigator(SAMPLE.AB.children[0]);
const nav = model.getNavigator(SAMPLE.AB.children[0]);
return model.expand({ id: 'a' }).then(() => {
assert.equal(nav.next().id, 'aa');
assert.equal(nav.next().id, 'ab');
assert.equal(nav.next()!.id, 'aa');
assert.equal(nav.next()!.id, 'ab');
assert.equal(nav.next() && false, null);
});
});
@@ -408,11 +408,11 @@ suite('TreeModel - TreeNavigator', () => {
test('previous() - scoped', () => {
return model.setInput(SAMPLE.AB).then(() => {
var nav = model.getNavigator(SAMPLE.AB.children[0]);
const nav = model.getNavigator(SAMPLE.AB.children[0]);
return model.expand({ id: 'a' }).then(() => {
assert.equal(nav.next().id, 'aa');
assert.equal(nav.next().id, 'ab');
assert.equal(nav.previous().id, 'aa');
assert.equal(nav.next()!.id, 'aa');
assert.equal(nav.next()!.id, 'ab');
assert.equal(nav.previous()!.id, 'aa');
assert.equal(nav.previous() && false, null);
});
});
@@ -421,10 +421,10 @@ suite('TreeModel - TreeNavigator', () => {
test('parent() - scoped', () => {
return model.setInput(SAMPLE.AB).then(() => {
return model.expandAll([{ id: 'a' }, { id: 'c' }]).then(() => {
var nav = model.getNavigator(SAMPLE.AB.children[0]);
const nav = model.getNavigator(SAMPLE.AB.children[0]);
assert.equal(nav.next().id, 'aa');
assert.equal(nav.next().id, 'ab');
assert.equal(nav.next()!.id, 'aa');
assert.equal(nav.next()!.id, 'ab');
assert.equal(nav.parent() && false, null);
});
});
@@ -432,12 +432,12 @@ suite('TreeModel - TreeNavigator', () => {
test('next() - non sub tree only', () => {
return model.setInput(SAMPLE.AB).then(() => {
var nav = model.getNavigator(SAMPLE.AB.children[0], false);
const nav = model.getNavigator(SAMPLE.AB.children[0], false);
return model.expand({ id: 'a' }).then(() => {
assert.equal(nav.next().id, 'aa');
assert.equal(nav.next().id, 'ab');
assert.equal(nav.next().id, 'b');
assert.equal(nav.next().id, 'c');
assert.equal(nav.next()!.id, 'aa');
assert.equal(nav.next()!.id, 'ab');
assert.equal(nav.next()!.id, 'b');
assert.equal(nav.next()!.id, 'c');
assert.equal(nav.next() && false, null);
});
});
@@ -445,16 +445,16 @@ suite('TreeModel - TreeNavigator', () => {
test('previous() - non sub tree only', () => {
return model.setInput(SAMPLE.AB).then(() => {
var nav = model.getNavigator(SAMPLE.AB.children[0], false);
const nav = model.getNavigator(SAMPLE.AB.children[0], false);
return model.expand({ id: 'a' }).then(() => {
assert.equal(nav.next().id, 'aa');
assert.equal(nav.next().id, 'ab');
assert.equal(nav.next().id, 'b');
assert.equal(nav.next().id, 'c');
assert.equal(nav.previous().id, 'b');
assert.equal(nav.previous().id, 'ab');
assert.equal(nav.previous().id, 'aa');
assert.equal(nav.previous().id, 'a');
assert.equal(nav.next()!.id, 'aa');
assert.equal(nav.next()!.id, 'ab');
assert.equal(nav.next()!.id, 'b');
assert.equal(nav.next()!.id, 'c');
assert.equal(nav.previous()!.id, 'b');
assert.equal(nav.previous()!.id, 'ab');
assert.equal(nav.previous()!.id, 'aa');
assert.equal(nav.previous()!.id, 'a');
assert.equal(nav.previous() && false, null);
});
});
@@ -463,11 +463,11 @@ suite('TreeModel - TreeNavigator', () => {
test('parent() - non sub tree only', () => {
return model.setInput(SAMPLE.AB).then(() => {
return model.expandAll([{ id: 'a' }, { id: 'c' }]).then(() => {
var nav = model.getNavigator(SAMPLE.AB.children[0], false);
const nav = model.getNavigator(SAMPLE.AB.children[0], false);
assert.equal(nav.next().id, 'aa');
assert.equal(nav.next().id, 'ab');
assert.equal(nav.parent().id, 'a');
assert.equal(nav.next()!.id, 'aa');
assert.equal(nav.next()!.id, 'ab');
assert.equal(nav.parent()!.id, 'a');
assert.equal(nav.parent() && false, null);
});
});
@@ -477,9 +477,9 @@ suite('TreeModel - TreeNavigator', () => {
return model.setInput(SAMPLE.DEEP).then(() => {
return model.expand(SAMPLE.DEEP.children[0]).then(() => {
return model.expand(SAMPLE.DEEP.children[0].children[0]).then(() => {
var nav = model.getNavigator(SAMPLE.DEEP.children[0].children[0]);
assert.equal(nav.next().id, 'xa');
assert.equal(nav.next().id, 'xb');
const nav = model.getNavigator(SAMPLE.DEEP.children[0].children[0]);
assert.equal(nav.next()!.id, 'xa');
assert.equal(nav.next()!.id, 'xb');
assert.equal(nav.next() && false, null);
});
});
@@ -490,10 +490,10 @@ suite('TreeModel - TreeNavigator', () => {
return model.setInput(SAMPLE.DEEP).then(() => {
return model.expand(SAMPLE.DEEP.children[0]).then(() => {
return model.expand(SAMPLE.DEEP.children[0].children[0]).then(() => {
var nav = model.getNavigator(SAMPLE.DEEP.children[0].children[0]);
assert.equal(nav.next().id, 'xa');
assert.equal(nav.next().id, 'xb');
assert.equal(nav.previous().id, 'xa');
const nav = model.getNavigator(SAMPLE.DEEP.children[0].children[0]);
assert.equal(nav.next()!.id, 'xa');
assert.equal(nav.next()!.id, 'xb');
assert.equal(nav.previous()!.id, 'xa');
assert.equal(nav.previous() && false, null);
});
});
@@ -504,15 +504,15 @@ suite('TreeModel - TreeNavigator', () => {
return model.setInput(SAMPLE.AB).then(() => {
return model.expandAll([{ id: 'a' }, { id: 'c' }]).then(() => {
const nav = model.getNavigator();
assert.equal(nav.last().id, 'cb');
assert.equal(nav.last()!.id, 'cb');
});
});
});
});
suite('TreeModel - Expansion', () => {
var model: model.TreeModel;
var counter: EventCounter;
let model: model.TreeModel;
let counter: EventCounter;
setup(() => {
counter = new EventCounter();
@@ -530,24 +530,24 @@ suite('TreeModel - Expansion', () => {
return model.setInput(SAMPLE.AB).then(() => {
counter.listen(model.onExpandItem, (e) => {
assert.equal(e.item.id, 'a');
var nav = model.getNavigator(e.item);
const nav = model.getNavigator(e.item);
assert.equal(nav.next() && false, null);
});
counter.listen(model.onDidExpandItem, (e) => {
assert.equal(e.item.id, 'a');
var nav = model.getNavigator(e.item);
assert.equal(nav.next().id, 'aa');
assert.equal(nav.next().id, 'ab');
const nav = model.getNavigator(e.item);
assert.equal(nav.next()!.id, 'aa');
assert.equal(nav.next()!.id, 'ab');
assert.equal(nav.next() && false, null);
});
assert(!model.isExpanded(SAMPLE.AB.children[0]));
var nav = model.getNavigator();
assert.equal(nav.next().id, 'a');
assert.equal(nav.next().id, 'b');
assert.equal(nav.next().id, 'c');
let nav = model.getNavigator();
assert.equal(nav.next()!.id, 'a');
assert.equal(nav.next()!.id, 'b');
assert.equal(nav.next()!.id, 'c');
assert.equal(nav.next() && false, null);
assert.equal(model.getExpandedElements().length, 0);
@@ -556,14 +556,14 @@ suite('TreeModel - Expansion', () => {
assert(model.isExpanded(SAMPLE.AB.children[0]));
nav = model.getNavigator();
assert.equal(nav.next().id, 'a');
assert.equal(nav.next().id, 'aa');
assert.equal(nav.next().id, 'ab');
assert.equal(nav.next().id, 'b');
assert.equal(nav.next().id, 'c');
assert.equal(nav.next()!.id, 'a');
assert.equal(nav.next()!.id, 'aa');
assert.equal(nav.next()!.id, 'ab');
assert.equal(nav.next()!.id, 'b');
assert.equal(nav.next()!.id, 'c');
assert.equal(nav.next() && false, null);
var expandedElements = model.getExpandedElements();
const expandedElements = model.getExpandedElements();
assert.equal(expandedElements.length, 1);
assert.equal(expandedElements[0].id, 'a');
@@ -626,18 +626,18 @@ suite('TreeModel - Expansion', () => {
assert(!model.isExpanded(SAMPLE.AB.children[0]));
var nav = model.getNavigator();
assert.equal(nav.next().id, 'a');
assert.equal(nav.next().id, 'b');
assert.equal(nav.next().id, 'c');
let nav = model.getNavigator();
assert.equal(nav.next()!.id, 'a');
assert.equal(nav.next()!.id, 'b');
assert.equal(nav.next()!.id, 'c');
assert.equal(nav.next() && false, null);
var f: () => void = counter.listen(model.onRefreshItemChildren, (e) => {
const f: () => void = counter.listen(model.onRefreshItemChildren, (e) => {
assert.equal(e.item.id, 'a');
f();
});
var g: () => void = counter.listen(model.onDidRefreshItemChildren, (e) => {
const g: () => void = counter.listen(model.onDidRefreshItemChildren, (e) => {
assert.equal(e.item.id, 'a');
g();
});
@@ -646,11 +646,11 @@ suite('TreeModel - Expansion', () => {
assert(model.isExpanded(SAMPLE.AB.children[0]));
nav = model.getNavigator();
assert.equal(nav.next().id, 'a');
assert.equal(nav.next().id, 'aa');
assert.equal(nav.next().id, 'ab');
assert.equal(nav.next().id, 'b');
assert.equal(nav.next().id, 'c');
assert.equal(nav.next()!.id, 'a');
assert.equal(nav.next()!.id, 'aa');
assert.equal(nav.next()!.id, 'ab');
assert.equal(nav.next()!.id, 'b');
assert.equal(nav.next()!.id, 'c');
assert.equal(nav.next() && false, null);
assert.equal(counter.count, 2);
@@ -661,12 +661,12 @@ suite('TreeModel - Expansion', () => {
test('top level collapsed', () => {
return model.setInput(SAMPLE.AB).then(() => {
return model.collapseAll([{ id: 'a' }, { id: 'b' }, { id: 'c' }]).then(() => {
var nav = model.getNavigator();
assert.equal(nav.next().id, 'a');
assert.equal(nav.next().id, 'b');
assert.equal(nav.next().id, 'c');
assert.equal(nav.previous().id, 'b');
assert.equal(nav.previous().id, 'a');
const nav = model.getNavigator();
assert.equal(nav.next()!.id, 'a');
assert.equal(nav.next()!.id, 'b');
assert.equal(nav.next()!.id, 'c');
assert.equal(nav.previous()!.id, 'b');
assert.equal(nav.previous()!.id, 'a');
assert.equal(nav.previous() && false, null);
});
});
@@ -683,7 +683,7 @@ suite('TreeModel - Expansion', () => {
if (e === 'b') { return Promise.resolve(['b1']); }
return Promise.resolve([]);
},
getParent: (_, e): Thenable<any> => { throw new Error('not implemented'); },
getParent: (_, e): Promise<any> => { throw new Error('not implemented'); },
shouldAutoexpand: (_, e) => e === 'b'
}
});
@@ -712,9 +712,9 @@ class TestFilter implements _.IFilter {
}
suite('TreeModel - Filter', () => {
var model: model.TreeModel;
var counter: EventCounter;
var filter: TestFilter;
let model: model.TreeModel;
let counter: EventCounter;
let filter: TestFilter;
setup(() => {
counter = new EventCounter();
@@ -734,21 +734,21 @@ suite('TreeModel - Filter', () => {
return model.setInput(SAMPLE.AB).then(() => {
return model.expandAll([{ id: 'a' }, { id: 'c' }]).then(() => {
var nav = model.getNavigator();
assert.equal(nav.next().id, 'a');
assert.equal(nav.next().id, 'aa');
assert.equal(nav.next().id, 'ab');
assert.equal(nav.next().id, 'b');
assert.equal(nav.next().id, 'c');
assert.equal(nav.next().id, 'ca');
assert.equal(nav.next().id, 'cb');
const nav = model.getNavigator();
assert.equal(nav.next()!.id, 'a');
assert.equal(nav.next()!.id, 'aa');
assert.equal(nav.next()!.id, 'ab');
assert.equal(nav.next()!.id, 'b');
assert.equal(nav.next()!.id, 'c');
assert.equal(nav.next()!.id, 'ca');
assert.equal(nav.next()!.id, 'cb');
assert.equal(nav.previous().id, 'ca');
assert.equal(nav.previous().id, 'c');
assert.equal(nav.previous().id, 'b');
assert.equal(nav.previous().id, 'ab');
assert.equal(nav.previous().id, 'aa');
assert.equal(nav.previous().id, 'a');
assert.equal(nav.previous()!.id, 'ca');
assert.equal(nav.previous()!.id, 'c');
assert.equal(nav.previous()!.id, 'b');
assert.equal(nav.previous()!.id, 'ab');
assert.equal(nav.previous()!.id, 'aa');
assert.equal(nav.previous()!.id, 'a');
assert.equal(nav.previous() && false, null);
});
});
@@ -759,7 +759,7 @@ suite('TreeModel - Filter', () => {
return model.setInput(SAMPLE.AB).then(() => {
return model.refresh().then(() => {
var nav = model.getNavigator();
const nav = model.getNavigator();
assert.equal(nav.next() && false, null);
});
});
@@ -772,12 +772,12 @@ suite('TreeModel - Filter', () => {
return model.setInput(SAMPLE.AB).then(() => {
return model.expand({ id: 'a' }).then(() => {
var nav = model.getNavigator();
assert.equal(nav.next().id, 'a');
assert.equal(nav.next().id, 'aa');
assert.equal(nav.next().id, 'ab');
assert.equal(nav.previous().id, 'aa');
assert.equal(nav.previous().id, 'a');
const nav = model.getNavigator();
assert.equal(nav.next()!.id, 'a');
assert.equal(nav.next()!.id, 'aa');
assert.equal(nav.next()!.id, 'ab');
assert.equal(nav.previous()!.id, 'aa');
assert.equal(nav.previous()!.id, 'a');
assert.equal(nav.previous() && false, null);
});
});
@@ -789,11 +789,11 @@ suite('TreeModel - Filter', () => {
return model.setInput(SAMPLE.AB).then(() => {
return model.expand({ id: 'a' }).then(() => {
var nav = model.getNavigator();
assert.equal(nav.next().id, 'a');
assert.equal(nav.next().id, 'aa');
assert.equal(nav.next().id, 'b');
assert.equal(nav.next().id, 'c');
const nav = model.getNavigator();
assert.equal(nav.next()!.id, 'a');
assert.equal(nav.next()!.id, 'aa');
assert.equal(nav.next()!.id, 'b');
assert.equal(nav.next()!.id, 'c');
assert.equal(nav.next() && false, null);
});
});
@@ -806,14 +806,14 @@ suite('TreeModel - Filter', () => {
return model.setInput(SAMPLE.AB).then(() => {
return model.expand({ id: 'c' }).then(() => {
var nav = model.getNavigator();
assert.equal(nav.next().id, 'b');
assert.equal(nav.next().id, 'c');
assert.equal(nav.next().id, 'ca');
assert.equal(nav.next().id, 'cb');
assert.equal(nav.previous().id, 'ca');
assert.equal(nav.previous().id, 'c');
assert.equal(nav.previous().id, 'b');
const nav = model.getNavigator();
assert.equal(nav.next()!.id, 'b');
assert.equal(nav.next()!.id, 'c');
assert.equal(nav.next()!.id, 'ca');
assert.equal(nav.next()!.id, 'cb');
assert.equal(nav.previous()!.id, 'ca');
assert.equal(nav.previous()!.id, 'c');
assert.equal(nav.previous()!.id, 'b');
assert.equal(nav.previous() && false, null);
});
});
@@ -826,14 +826,14 @@ suite('TreeModel - Filter', () => {
return model.setInput(SAMPLE.AB).then(() => {
return model.expand({ id: 'c' }).then(() => {
var nav = model.getNavigator();
assert.equal(nav.next().id, 'b');
assert.equal(nav.next().id, 'c');
assert.equal(nav.next().id, 'ca');
assert.equal(nav.next().id, 'cb');
assert.equal(nav.previous().id, 'ca');
assert.equal(nav.previous().id, 'c');
assert.equal(nav.previous().id, 'b');
const nav = model.getNavigator();
assert.equal(nav.next()!.id, 'b');
assert.equal(nav.next()!.id, 'c');
assert.equal(nav.next()!.id, 'ca');
assert.equal(nav.next()!.id, 'cb');
assert.equal(nav.previous()!.id, 'ca');
assert.equal(nav.previous()!.id, 'c');
assert.equal(nav.previous()!.id, 'b');
assert.equal(nav.previous() && false, null);
});
});
@@ -844,16 +844,16 @@ suite('TreeModel - Filter', () => {
filter.fn = (e) => e.id !== 'b';
return model.setInput(SAMPLE.AB).then(() => {
var nav = model.getNavigator({ id: 'c' }, false);
assert.equal(nav.previous().id, 'a');
const nav = model.getNavigator({ id: 'c' }, false);
assert.equal(nav.previous()!.id, 'a');
assert.equal(nav.previous() && false, null);
});
});
});
suite('TreeModel - Traits', () => {
var model: model.TreeModel;
var counter: EventCounter;
let model: model.TreeModel;
let counter: EventCounter;
setup(() => {
counter = new EventCounter();
@@ -1079,7 +1079,7 @@ suite('TreeModel - Traits', () => {
class DynamicModel implements _.IDataSource {
private data: any;
public promiseFactory: { (): Thenable<any>; };
public promiseFactory: { (): Promise<any>; } | null;
private _onGetChildren = new Emitter<any>();
readonly onGetChildren: Event<any> = this._onGetChildren.event;
@@ -1124,24 +1124,24 @@ class DynamicModel implements _.IDataSource {
return !!this.data[element];
}
public getChildren(tree, element): Thenable<any> {
public getChildren(tree, element): Promise<any> {
this._onGetChildren.fire(element);
var result = this.promiseFactory ? this.promiseFactory() : Promise.resolve(null);
const result = this.promiseFactory ? this.promiseFactory() : Promise.resolve(null);
return result.then(() => {
this._onDidGetChildren.fire(element);
return Promise.resolve(this.data[element]);
});
}
public getParent(tree, element): Thenable<any> {
public getParent(tree, element): Promise<any> {
throw new Error('Not implemented');
}
}
suite('TreeModel - Dynamic data model', () => {
var model: model.TreeModel;
var dataModel: DynamicModel;
var counter: EventCounter;
let model: model.TreeModel;
let dataModel: DynamicModel;
let counter: EventCounter;
setup(() => {
counter = new EventCounter();
@@ -1167,8 +1167,8 @@ suite('TreeModel - Dynamic data model', () => {
return model.expandAll(['grandfather', 'father', 'son']).then(() => {
dataModel.removeChild('grandfather', 'father');
var items = ['baby', 'son', 'daughter', 'father'];
var times = 0;
const items = ['baby', 'son', 'daughter', 'father'];
let times = 0;
counter.listen(model.onDidDisposeItem, item => {
assert.equal(items[times++], item.id);
});
@@ -1187,17 +1187,17 @@ suite('TreeModel - Dynamic data model', () => {
dataModel.addChild('root', 'mega');
return model.setInput('root').then(() => {
var nav = model.getNavigator();
assert.equal(nav.next().id, 'super');
assert.equal(nav.next().id, 'hyper');
assert.equal(nav.next().id, 'mega');
let nav = model.getNavigator();
assert.equal(nav.next()!.id, 'super');
assert.equal(nav.next()!.id, 'hyper');
assert.equal(nav.next()!.id, 'mega');
assert.equal(nav.next() && false, null);
dataModel.removeChild('root', 'hyper');
return model.refresh().then(() => {
nav = model.getNavigator();
assert.equal(nav.next().id, 'super');
assert.equal(nav.next().id, 'mega');
assert.equal(nav.next()!.id, 'super');
assert.equal(nav.next()!.id, 'mega');
assert.equal(nav.next() && false, null);
dataModel.addChild('mega', 'micro');
@@ -1207,17 +1207,17 @@ suite('TreeModel - Dynamic data model', () => {
return model.refresh().then(() => {
return model.expand('mega').then(() => {
nav = model.getNavigator();
assert.equal(nav.next().id, 'super');
assert.equal(nav.next().id, 'mega');
assert.equal(nav.next().id, 'micro');
assert.equal(nav.next().id, 'nano');
assert.equal(nav.next().id, 'pico');
assert.equal(nav.next()!.id, 'super');
assert.equal(nav.next()!.id, 'mega');
assert.equal(nav.next()!.id, 'micro');
assert.equal(nav.next()!.id, 'nano');
assert.equal(nav.next()!.id, 'pico');
assert.equal(nav.next() && false, null);
model.collapse('mega');
nav = model.getNavigator();
assert.equal(nav.next().id, 'super');
assert.equal(nav.next().id, 'mega');
assert.equal(nav.next()!.id, 'super');
assert.equal(nav.next()!.id, 'mega');
assert.equal(nav.next() && false, null);
});
});
@@ -1237,13 +1237,13 @@ suite('TreeModel - Dynamic data model', () => {
return model.expand('super').then(() => {
var nav = model.getNavigator();
assert.equal(nav.next().id, 'super');
assert.equal(nav.next().id, 'apples');
assert.equal(nav.next().id, 'bananas');
assert.equal(nav.next().id, 'pears');
assert.equal(nav.next().id, 'hyper');
assert.equal(nav.next().id, 'mega');
let nav = model.getNavigator();
assert.equal(nav.next()!.id, 'super');
assert.equal(nav.next()!.id, 'apples');
assert.equal(nav.next()!.id, 'bananas');
assert.equal(nav.next()!.id, 'pears');
assert.equal(nav.next()!.id, 'hyper');
assert.equal(nav.next()!.id, 'mega');
assert.equal(nav.next() && false, null);
dataModel.move('bananas', 'super', 'hyper');
@@ -1253,12 +1253,12 @@ suite('TreeModel - Dynamic data model', () => {
return model.expandAll(['hyper', 'mega']).then(() => {
nav = model.getNavigator();
assert.equal(nav.next().id, 'super');
assert.equal(nav.next().id, 'pears');
assert.equal(nav.next().id, 'hyper');
assert.equal(nav.next().id, 'bananas');
assert.equal(nav.next().id, 'mega');
assert.equal(nav.next().id, 'apples');
assert.equal(nav.next()!.id, 'super');
assert.equal(nav.next()!.id, 'pears');
assert.equal(nav.next()!.id, 'hyper');
assert.equal(nav.next()!.id, 'bananas');
assert.equal(nav.next()!.id, 'mega');
assert.equal(nav.next()!.id, 'apples');
assert.equal(nav.next() && false, null);
});
});
@@ -1274,8 +1274,8 @@ suite('TreeModel - Dynamic data model', () => {
return model.setInput('root').then(() => {
return model.expand('grandfather').then(() => {
return model.collapse('father').then(() => {
var times = 0;
var listener = dataModel.onGetChildren((element) => {
let times = 0;
let listener = dataModel.onGetChildren((element) => {
times++;
assert.equal(element, 'grandfather');
});
@@ -1309,11 +1309,11 @@ suite('TreeModel - Dynamic data model', () => {
return model.expand('father').then(() => {
return model.expand('mother').then(() => {
var nav = model.getNavigator();
assert.equal(nav.next().id, 'father');
assert.equal(nav.next().id, 'son');
assert.equal(nav.next().id, 'mother');
assert.equal(nav.next().id, 'daughter');
let nav = model.getNavigator();
assert.equal(nav.next()!.id, 'father');
assert.equal(nav.next()!.id, 'son');
assert.equal(nav.next()!.id, 'mother');
assert.equal(nav.next()!.id, 'daughter');
assert.equal(nav.next() && false, null);
dataModel.removeChild('father', 'son');
@@ -1323,16 +1323,16 @@ suite('TreeModel - Dynamic data model', () => {
dataModel.promiseFactory = () => { return timeout(0); };
var getTimes = 0;
var gotTimes = 0;
var getListener = dataModel.onGetChildren((element) => { getTimes++; });
var gotListener = dataModel.onDidGetChildren((element) => { gotTimes++; });
let getTimes = 0;
let gotTimes = 0;
const getListener = dataModel.onGetChildren((element) => { getTimes++; });
const gotListener = dataModel.onDidGetChildren((element) => { gotTimes++; });
var p1 = model.refresh('father');
const p1 = model.refresh('father');
assert.equal(getTimes, 1);
assert.equal(gotTimes, 0);
var p2 = model.refresh('mother');
const p2 = model.refresh('mother');
assert.equal(getTimes, 2);
assert.equal(gotTimes, 0);
@@ -1341,10 +1341,10 @@ suite('TreeModel - Dynamic data model', () => {
assert.equal(gotTimes, 2);
nav = model.getNavigator();
assert.equal(nav.next().id, 'father');
assert.equal(nav.next().id, 'brother');
assert.equal(nav.next().id, 'mother');
assert.equal(nav.next().id, 'sister');
assert.equal(nav.next()!.id, 'father');
assert.equal(nav.next()!.id, 'brother');
assert.equal(nav.next()!.id, 'mother');
assert.equal(nav.next()!.id, 'sister');
assert.equal(nav.next() && false, null);
getListener.dispose();
@@ -1363,22 +1363,22 @@ suite('TreeModel - Dynamic data model', () => {
return model.setInput('root').then(() => {
return model.expand('grandfather').then(() => {
return model.expand('father').then(() => {
var nav = model.getNavigator();
assert.equal(nav.next().id, 'grandfather');
assert.equal(nav.next().id, 'father');
assert.equal(nav.next().id, 'son');
let nav = model.getNavigator();
assert.equal(nav.next()!.id, 'grandfather');
assert.equal(nav.next()!.id, 'father');
assert.equal(nav.next()!.id, 'son');
assert.equal(nav.next() && false, null);
var refreshTimes = 0;
let refreshTimes = 0;
counter.listen(model.onDidRefreshItem, (e) => { refreshTimes++; });
var getTimes = 0;
var getListener = dataModel.onGetChildren((element) => { getTimes++; });
let getTimes = 0;
const getListener = dataModel.onGetChildren((element) => { getTimes++; });
var gotTimes = 0;
var gotListener = dataModel.onDidGetChildren((element) => { gotTimes++; });
let gotTimes = 0;
const gotListener = dataModel.onDidGetChildren((element) => { gotTimes++; });
var p1Completes = [];
const p1Completes: Array<(value?: any) => void> = [];
dataModel.promiseFactory = () => { return new Promise((c) => { p1Completes.push(c); }); };
model.refresh('grandfather').then(() => {
@@ -1388,16 +1388,16 @@ suite('TreeModel - Dynamic data model', () => {
assert.equal(gotTimes, 0);
// unblock the first get
p1Completes.shift()();
p1Completes.shift()!();
// once the first get is unblocked, the second get should appear
assert.equal(refreshTimes, 2); // (+1) first father refresh
assert.equal(getTimes, 2);
assert.equal(gotTimes, 1);
var p2Complete;
let p2Complete;
dataModel.promiseFactory = () => { return new Promise((c) => { p2Complete = c; }); };
var p2 = model.refresh('father');
const p2 = model.refresh('father');
// same situation still
assert.equal(refreshTimes, 3); // (+1) second father refresh
@@ -1405,7 +1405,7 @@ suite('TreeModel - Dynamic data model', () => {
assert.equal(gotTimes, 1);
// unblock the second get
p1Completes.shift()();
p1Completes.shift()!();
// the third get should have appeared, it should've been waiting for the second one
assert.equal(refreshTimes, 4); // (+1) first son request
@@ -1421,9 +1421,9 @@ suite('TreeModel - Dynamic data model', () => {
return p2.then(() => {
nav = model.getNavigator();
assert.equal(nav.next().id, 'grandfather');
assert.equal(nav.next().id, 'father');
assert.equal(nav.next().id, 'son');
assert.equal(nav.next()!.id, 'grandfather');
assert.equal(nav.next()!.id, 'father');
assert.equal(nav.next()!.id, 'son');
assert.equal(nav.next() && false, null);
getListener.dispose();
@@ -1529,7 +1529,7 @@ suite('TreeModel - Dynamic data model', () => {
// delay expansions and refreshes
dataModel.promiseFactory = () => { return timeout(0); };
var promises: Thenable<any>[] = [];
const promises: Promise<any>[] = [];
promises.push(model.expand('father'));
dataModel.removeChild('root', 'father');
@@ -1549,7 +1549,7 @@ suite('TreeModel - Dynamic data model', () => {
});
suite('TreeModel - bugs', () => {
var counter: EventCounter;
let counter: EventCounter;
setup(() => {
counter = new EventCounter();
@@ -1573,17 +1573,17 @@ suite('TreeModel - bugs', () => {
if (e === 'bart') { return getBartChildren(); }
return Promise.resolve([]);
},
getParent: (_, e): Thenable<any> => { throw new Error('not implemented'); },
getParent: (_, e): Promise<any> => { throw new Error('not implemented'); },
}
});
let listeners = <any>[];
// helpers
var getGetRootChildren = (children: string[], millis = 0) => () => timeout(millis).then(() => children);
var getRootChildren = getGetRootChildren(['homer', 'bart', 'lisa', 'marge', 'maggie'], 0);
var getGetBartChildren = (millis = 0) => () => timeout(millis).then(() => ['milhouse', 'nelson']);
var getBartChildren = getGetBartChildren(0);
const getGetRootChildren = (children: string[], millis = 0) => () => timeout(millis).then(() => children);
let getRootChildren = getGetRootChildren(['homer', 'bart', 'lisa', 'marge', 'maggie'], 0);
const getGetBartChildren = (millis = 0) => () => timeout(millis).then(() => ['milhouse', 'nelson']);
const getBartChildren = getGetBartChildren(0);
// item expanding should not exist!
counter.listen(model.onExpandItem, () => { assert(false, 'should never receive item:expanding event'); });
@@ -1595,14 +1595,14 @@ suite('TreeModel - bugs', () => {
getRootChildren = getGetRootChildren(['homer', 'lisa', 'marge', 'maggie'], 10);
// refresh root
var p1 = model.refresh('root', true).then(() => {
const p1 = model.refresh('root', true).then(() => {
assert(true);
}, () => {
assert(false, 'should never reach this');
});
// at the same time, try to expand bart!
var p2 = model.expand('bart').then(() => {
const p2 = model.expand('bart').then(() => {
assert(false, 'should never reach this');
}, () => {
assert(true, 'bart should fail to expand since he was removed meanwhile');
@@ -1617,7 +1617,6 @@ suite('TreeModel - bugs', () => {
while (listeners.length > 0) { listeners.pop()(); }
listeners = null;
model.dispose();
model = null;
assert.equal(counter.count, 0);
});
@@ -1643,8 +1642,8 @@ suite('TreeModel - bugs', () => {
await model.expand('father');
let nav = model.getNavigator();
assert.equal(nav.next().id, 'father');
assert.equal(nav.next().id, 'son');
assert.equal(nav.next()!.id, 'father');
assert.equal(nav.next()!.id, 'son');
assert.equal(nav.next(), null);
await model.collapse('father');
@@ -1654,7 +1653,7 @@ suite('TreeModel - bugs', () => {
await model.expand('father');
nav = model.getNavigator();
assert.equal(nav.next().id, 'father');
assert.equal(nav.next()!.id, 'father');
assert.equal(nav.next(), null);
counter.dispose();

View File

@@ -17,9 +17,9 @@ function makeItem(id, height): any {
}
function makeItems(...args: any[]) {
var r = [];
let r: any[] = [];
for (var i = 0; i < args.length; i += 2) {
for (let i = 0; i < args.length; i += 2) {
r.push(makeItem(args[i], args[i + 1]));
}
@@ -27,8 +27,8 @@ function makeItems(...args: any[]) {
}
function makeNavigator(...args: any[]): any {
var items = makeItems.apply(null, args);
var i = 0;
let items = makeItems.apply(null, args);
let i = 0;
return {
next: function () {
@@ -50,7 +50,7 @@ class TestHeightMap extends HeightMap {
}
suite('TreeView - HeightMap', () => {
var rangeMap: HeightMap;
let rangeMap: HeightMap;
setup(() => {
rangeMap = new TestHeightMap();
@@ -59,7 +59,7 @@ suite('TreeView - HeightMap', () => {
teardown(() => {
rangeMap.dispose();
rangeMap = null;
rangeMap = null!;
});
test('simple', () => {
@@ -76,7 +76,7 @@ suite('TreeView - HeightMap', () => {
});
test('onInsertItems at beginning', () => {
var navigator = makeNavigator('x', 4, 'y', 20, 'z', 8);
let navigator = makeNavigator('x', 4, 'y', 20, 'z', 8);
rangeMap.onInsertItems(navigator);
assert.equal(rangeMap.itemAt(0), 'x');
@@ -97,7 +97,7 @@ suite('TreeView - HeightMap', () => {
});
test('onInsertItems in middle', () => {
var navigator = makeNavigator('x', 4, 'y', 20, 'z', 8);
let navigator = makeNavigator('x', 4, 'y', 20, 'z', 8);
rangeMap.onInsertItems(navigator, 'a');
assert.equal(rangeMap.itemAt(0), 'a');
@@ -118,7 +118,7 @@ suite('TreeView - HeightMap', () => {
});
test('onInsertItems at end', () => {
var navigator = makeNavigator('x', 4, 'y', 20, 'z', 8);
let navigator = makeNavigator('x', 4, 'y', 20, 'z', 8);
rangeMap.onInsertItems(navigator, 'd');
assert.equal(rangeMap.itemAt(0), 'a');
@@ -171,7 +171,7 @@ suite('TreeView - HeightMap', () => {
});
test('onRefreshItems at beginning', () => {
var navigator = makeNavigator('a', 1, 'b', 1);
let navigator = makeNavigator('a', 1, 'b', 1);
rangeMap.onRefreshItems(navigator);
assert.equal(rangeMap.itemAt(0), 'a');
@@ -184,7 +184,7 @@ suite('TreeView - HeightMap', () => {
});
test('onRefreshItems in middle', () => {
var navigator = makeNavigator('b', 40, 'c', 4);
let navigator = makeNavigator('b', 40, 'c', 4);
rangeMap.onRefreshItems(navigator);
assert.equal(rangeMap.itemAt(0), 'a');
@@ -199,7 +199,7 @@ suite('TreeView - HeightMap', () => {
});
test('onRefreshItems at end', () => {
var navigator = makeNavigator('d', 22);
let navigator = makeNavigator('d', 22);
rangeMap.onRefreshItems(navigator);
assert.equal(rangeMap.itemAt(0), 'a');
@@ -214,8 +214,8 @@ suite('TreeView - HeightMap', () => {
});
test('withItemsInRange', () => {
var i = 0;
var itemsInRange = ['a', 'b'];
let i = 0;
let itemsInRange = ['a', 'b'];
rangeMap.withItemsInRange(2, 27, function (item) { assert.equal(item, itemsInRange[i++]); });
assert.equal(i, itemsInRange.length);