mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-26 23:00:29 -04:00
Merge VS Code 1.31.1 (#4283)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ suite('IPC, Child Process', () => {
|
||||
service.onMarco(({ answer }) => {
|
||||
try {
|
||||
assert.equal(answer, 'polo');
|
||||
c(null);
|
||||
c(undefined);
|
||||
} catch (err) {
|
||||
e(err);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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 () {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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 = {};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user