提交 3c5078e4 编写于 作者: J Joao Moreno

Merge branch 'master' of github.com:Microsoft/vscode

......@@ -43,7 +43,7 @@ const nodeModules = ['electron', 'original-fs']
// Build
const builtInExtensions = [
{ name: 'ms-vscode.node-debug', version: '1.17.2' },
{ name: 'ms-vscode.node-debug', version: '1.17.3' },
{ name: 'ms-vscode.node-debug2', version: '1.17.1' }
];
......
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var Rule = /** @class */ (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
var allowed = this.getOptions().ruleArguments[0];
return this.applyWithWalker(new AsyncRuleWalker(sourceFile, this.getOptions(), allowed));
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var AsyncRuleWalker = /** @class */ (function (_super) {
__extends(AsyncRuleWalker, _super);
function AsyncRuleWalker(file, opts, allowed) {
var _this = _super.call(this, file, opts) || this;
_this.allowed = allowed;
return _this;
}
AsyncRuleWalker.prototype.visitMethodDeclaration = function (node) {
this.visitFunctionLikeDeclaration(node);
};
AsyncRuleWalker.prototype.visitFunctionDeclaration = function (node) {
this.visitFunctionLikeDeclaration(node);
};
AsyncRuleWalker.prototype.visitFunctionLikeDeclaration = function (node) {
var _this = this;
var flags = ts.getCombinedModifierFlags(node);
if (!(flags & ts.ModifierFlags.Async)) {
return;
}
var path = node.getSourceFile().path;
var pathParts = path.split(/\\|\//);
if (pathParts.some(function (part) { return _this.allowed.some(function (allowed) { return part === allowed; }); })) {
return;
}
var message = "You are not allowed to use async function in this layer. Allowed layers are: [" + this.allowed + "]";
this.addFailureAtNode(node, message);
};
return AsyncRuleWalker;
}(Lint.RuleWalker));
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as ts from 'typescript';
import * as Lint from 'tslint';
export class Rule extends Lint.Rules.AbstractRule {
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
const allowed = this.getOptions().ruleArguments[0] as string[];
return this.applyWithWalker(new AsyncRuleWalker(sourceFile, this.getOptions(), allowed));
}
}
class AsyncRuleWalker extends Lint.RuleWalker {
constructor(file: ts.SourceFile, opts: Lint.IOptions, private allowed: string[]) {
super(file, opts);
}
protected visitMethodDeclaration(node: ts.MethodDeclaration): void {
this.visitFunctionLikeDeclaration(node);
}
protected visitFunctionDeclaration(node: ts.FunctionDeclaration): void {
this.visitFunctionLikeDeclaration(node);
}
private visitFunctionLikeDeclaration(node: ts.FunctionLikeDeclaration) {
const flags = ts.getCombinedModifierFlags(node);
if (!(flags & ts.ModifierFlags.Async)) {
return;
}
const path = (node.getSourceFile() as any).path;
const pathParts = path.split(/\\|\//);
if (pathParts.some(part => this.allowed.some(allowed => part === allowed))) {
return;
}
const message = `You are not allowed to use async function in this layer. Allowed layers are: [${this.allowed}]`;
this.addFailureAtNode(node, message);
}
}
......@@ -244,9 +244,9 @@ export abstract class HeaderView extends View {
protected abstract layoutBody(size: number): void;
}
export interface ICollapsibleViewOptions {
export interface IAbstractCollapsibleViewOptions {
sizing: ViewSizing;
ariaHeaderLabel: string;
ariaHeaderLabel?: string;
bodySize?: number;
initialState?: CollapsibleState;
}
......@@ -268,7 +268,7 @@ export abstract class AbstractCollapsibleView extends HeaderView {
private _previousSize: number = null;
private readonly viewSizing: ViewSizing;
constructor(initialSize: number | undefined, opts: ICollapsibleViewOptions) {
constructor(initialSize: number | undefined, opts: IAbstractCollapsibleViewOptions) {
super(initialSize, opts);
this.viewSizing = opts.sizing;
this.ariaHeaderLabel = opts.ariaHeaderLabel;
......@@ -493,6 +493,7 @@ export interface SplitViewStyles {
export class SplitView extends lifecycle.Disposable implements
sash.IHorizontalSashLayoutProvider,
sash.IVerticalSashLayoutProvider {
private orientation: Orientation;
private canDragAndDrop: boolean;
private el: HTMLElement;
......@@ -521,6 +522,10 @@ export class SplitView extends lifecycle.Disposable implements
private _onDidOrderChange: Emitter<void> = this._register(new Emitter<void>());
readonly onDidOrderChange: Event<void> = this._onDidOrderChange.event;
get length(): number {
return this.views.length;
}
constructor(container: HTMLElement, options?: IOptions) {
super();
options = options || {};
......@@ -560,18 +565,18 @@ export class SplitView extends lifecycle.Disposable implements
}
// The void space exists to handle the case where all other views are fixed size
this.addView(new VoidView(), 1, 0);
this.addView(new VoidView(), 0);
}
getView(index: number): IView | undefined {
return this.views[index];
}
getViews<T extends IView>(): T[] {
return <T[]>this.views.slice(0, this.views.length - 1);
}
addView(view: IView, initialWeight: number = 1, index = this.views.length - 1): void {
if (initialWeight <= 0) {
throw new Error('Initial weight must be a positive number.');
}
addView(view: IView, index = this.views.length - 1): void {
/**
* Reset size to null. This will layout newly added views to initial weights.
*/
......
......@@ -23,6 +23,7 @@ export interface IToolBarOptions {
actionItemProvider?: IActionItemProvider;
ariaLabel?: string;
getKeyBinding?: (action: IAction) => ResolvedKeybinding;
actionRunner?: IActionRunner;
}
/**
......@@ -49,6 +50,7 @@ export class ToolBar {
this.actionBar = new ActionBar($(element), {
orientation: options.orientation,
ariaLabel: options.ariaLabel,
actionRunner: options.actionRunner,
actionItemProvider: (action: Action) => {
// Return special action item for the toggle menu action
......
......@@ -58,8 +58,8 @@ export function getPathLabel(resource: URI | string, rootProvider?: IRootProvide
}
// convert c:\something => C:\something
if (platform.isWindows && resource.fsPath && resource.fsPath[1] === ':') {
return normalize(resource.fsPath.charAt(0).toUpperCase() + resource.fsPath.slice(1), true);
if (hasDriveLetter(resource.fsPath)) {
return normalize(normalizeDriveLetter(resource.fsPath), true);
}
// normalize and tildify (macOS, Linux only)
......@@ -71,6 +71,18 @@ export function getPathLabel(resource: URI | string, rootProvider?: IRootProvide
return res;
}
function hasDriveLetter(path: string): boolean {
return platform.isWindows && path && path[1] === ':';
}
export function normalizeDriveLetter(path: string): string {
if (hasDriveLetter(path)) {
return path.charAt(0).toUpperCase() + path.slice(1);
}
return path;
}
export function tildify(path: string, userHome: string): string {
if (path && (platform.isMacintosh || platform.isLinux) && isEqualOrParent(path, userHome, !platform.isLinux /* ignorecase */)) {
path = `~${path.substr(userHome.length)}`;
......
......@@ -12,14 +12,19 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment'
import { extname, join, dirname, isAbsolute, resolve, relative } from 'path';
import { mkdirp, writeFile, readFile } from 'vs/base/node/pfs';
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
import { isLinux } from 'vs/base/common/platform';
import { isLinux, isMacintosh, isWindows } from 'vs/base/common/platform';
import { delSync, readdirSync } from 'vs/base/node/extfs';
import Event, { Emitter } from 'vs/base/common/event';
import { ILogService } from 'vs/platform/log/common/log';
import { isEqual, isEqualOrParent } from 'vs/base/common/paths';
import { isEqual, isEqualOrParent, normalize } from 'vs/base/common/paths';
import { coalesce } from 'vs/base/common/arrays';
import { createHash } from 'crypto';
import * as json from 'vs/base/common/json';
import * as jsonEdit from 'vs/base/common/jsonEdit';
import { applyEdit } from 'vs/base/common/jsonFormatter';
import { normalizeDriveLetter } from 'vs/base/common/labels';
const SLASH = '/';
export class WorkspacesMainService implements IWorkspacesMainService {
......@@ -181,10 +186,11 @@ export class WorkspacesMainService implements IWorkspacesMainService {
}
// Read the contents of the workspace file and resolve it
return readFile(workspace.configPath).then(rawWorkspaceContents => {
return readFile(workspace.configPath).then(raw => {
const rawWorkspaceContents = raw.toString();
let storedWorkspace: IStoredWorkspace;
try {
storedWorkspace = this.doParseStoredWorkspace(workspace.configPath, rawWorkspaceContents.toString());
storedWorkspace = this.doParseStoredWorkspace(workspace.configPath, rawWorkspaceContents);
} catch (error) {
return TPromise.wrapError(error);
}
......@@ -192,6 +198,18 @@ export class WorkspacesMainService implements IWorkspacesMainService {
const sourceConfigFolder = dirname(workspace.configPath);
const targetConfigFolder = dirname(targetConfigPath);
// Determine which path separator to use:
// - macOS/Linux: slash
// - Windows: use slash if already used in that file
let useSlashesForPath = !isWindows;
if (isWindows) {
storedWorkspace.folders.forEach(folder => {
if (folder.path.indexOf(SLASH) >= 0) {
useSlashesForPath = true;
}
});
}
// Rewrite absolute paths to relative paths if the target workspace folder
// is a parent of the location of the workspace file itself. Otherwise keep
// using absolute paths.
......@@ -203,9 +221,32 @@ export class WorkspacesMainService implements IWorkspacesMainService {
if (isEqualOrParent(folder.path, targetConfigFolder, !isLinux)) {
folder.path = relative(targetConfigFolder, folder.path) || '.'; // absolute paths get converted to relative ones to workspace location if possible
}
// Windows gets special treatment:
// - normalize all paths to get nice casing of drive letters
// - convert to slashes if we want to use slashes for paths
if (isWindows) {
if (isAbsolute(folder.path)) {
if (useSlashesForPath) {
folder.path = normalize(folder.path, false /* do not use OS path separator */);
}
folder.path = normalizeDriveLetter(folder.path);
} else if (useSlashesForPath) {
folder.path = folder.path.replace(/[\\]/g, SLASH);
}
}
});
// Preserve as much of the existing workspace as possible by using jsonEdit
// and only changing the folders portion.
let newRawWorkspaceContents = rawWorkspaceContents;
const edits = jsonEdit.setProperty(rawWorkspaceContents, ['folders'], storedWorkspace.folders, { insertSpaces: false, tabSize: 4, eol: (isLinux || isMacintosh) ? '\n' : '\r\n' });
edits.forEach(edit => {
newRawWorkspaceContents = applyEdit(rawWorkspaceContents, edit);
});
return writeFile(targetConfigPath, JSON.stringify(storedWorkspace, null, '\t')).then(() => {
return writeFile(targetConfigPath, newRawWorkspaceContents).then(() => {
const savedWorkspaceIdentifier = { id: this.getWorkspaceId(targetConfigPath), configPath: targetConfigPath };
// Event
......
......@@ -245,6 +245,32 @@ suite('WorkspacesMainService', () => {
});
});
test('saveWorkspace (saved workspace, preserves comments)', done => {
return service.createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => {
const workspaceConfigPath = path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`);
const newWorkspaceConfigPath = path.join(os.tmpdir(), `mySavedWorkspace.${Date.now()}.${WORKSPACE_EXTENSION}`);
return service.saveWorkspace(workspace, workspaceConfigPath).then(savedWorkspace => {
const contents = fs.readFileSync(savedWorkspace.configPath).toString();
fs.writeFileSync(savedWorkspace.configPath, `// this is a comment\n${contents}`);
return service.saveWorkspace(savedWorkspace, newWorkspaceConfigPath).then(newSavedWorkspace => {
assert.ok(newSavedWorkspace.id);
assert.notEqual(newSavedWorkspace.id, workspace.id);
assert.equal(newSavedWorkspace.configPath, newWorkspaceConfigPath);
const savedContents = fs.readFileSync(newSavedWorkspace.configPath).toString();
assert.equal(0, savedContents.indexOf('// this is a comment'));
extfs.delSync(workspaceConfigPath);
extfs.delSync(newWorkspaceConfigPath);
done();
});
});
});
});
test('deleteUntitledWorkspaceSync (untitled)', done => {
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
assert.ok(fs.existsSync(workspace.configPath));
......
......@@ -35,86 +35,54 @@ import { SIDE_BAR_DRAG_AND_DROP_BACKGROUND, SIDE_BAR_SECTION_HEADER_FOREGROUND,
import { contrastBorder } from 'vs/platform/theme/common/colorRegistry';
export interface IViewOptions {
id: string;
name: string;
actionRunner: IActionRunner;
collapsed: boolean;
}
export interface IViewConstructorSignature {
new(initialSize: number, options: IViewOptions, ...services: { _serviceBrand: any; }[]): IView;
new(initialSize: number, options: IViewOptions, ...services: { _serviceBrand: any; }[]): IViewletView;
}
export interface IView extends IBaseView, IThemable {
export interface IViewletView extends IBaseView, IThemable {
id: string;
name: string;
getHeaderElement(): HTMLElement;
create(): TPromise<void>;
setVisible(visible: boolean): TPromise<void>;
isVisible(): boolean;
getActions(): IAction[];
getSecondaryActions(): IAction[];
getActionItem(action: IAction): IActionItem;
getActionsContext(): any;
showHeader(): boolean;
hideHeader(): boolean;
focusBody(): void;
isExpanded(): boolean;
expand(): void;
collapse(): void;
getOptimalWidth(): number;
shutdown(): void;
}
export interface ICollapsibleViewOptions extends IViewOptions {
ariaHeaderLabel?: string;
sizing: ViewSizing;
initialBodySize?: number;
}
export abstract class CollapsibleView extends AbstractCollapsibleView implements IView {
export abstract class CollapsibleView extends AbstractCollapsibleView implements IViewletView {
readonly id: string;
readonly name: string;
protected treeContainer: HTMLElement;
protected tree: ITree;
protected toDispose: IDisposable[];
protected toolBar: ToolBar;
protected actionRunner: IActionRunner;
protected isDisposed: boolean;
private _isVisible: boolean;
private dragHandler: DelayedDragHandler;
constructor(
......@@ -144,7 +112,7 @@ export abstract class CollapsibleView extends AbstractCollapsibleView implements
get draggableLabel(): string { return this.name; }
public create(): TPromise<void> {
create(): TPromise<void> {
return TPromise.as(null);
}
......@@ -152,7 +120,7 @@ export abstract class CollapsibleView extends AbstractCollapsibleView implements
return this.header;
}
public renderHeader(container: HTMLElement): void {
renderHeader(container: HTMLElement): void {
// Tool bar
this.toolBar = new ToolBar($('div.actions').appendTo(container).getHTMLElement(), this.contextMenuService, {
......@@ -184,15 +152,15 @@ export abstract class CollapsibleView extends AbstractCollapsibleView implements
return treeContainer;
}
public getViewer(): ITree {
getViewer(): ITree {
return this.tree;
}
public isVisible(): boolean {
isVisible(): boolean {
return this._isVisible;
}
public setVisible(visible: boolean): TPromise<void> {
setVisible(visible: boolean): TPromise<void> {
if (this._isVisible !== visible) {
this._isVisible = visible;
this.updateTreeVisibility(this.tree, visible && this.state === CollapsibleState.EXPANDED);
......@@ -201,7 +169,7 @@ export abstract class CollapsibleView extends AbstractCollapsibleView implements
return TPromise.as(null);
}
public focusBody(): void {
focusBody(): void {
this.focusTree();
}
......@@ -213,38 +181,38 @@ export abstract class CollapsibleView extends AbstractCollapsibleView implements
return this.tree.reveal(element, relativeTop);
}
public layoutBody(size: number): void {
layoutBody(size: number): void {
if (this.tree) {
this.treeContainer.style.height = size + 'px';
this.tree.layout(size);
}
}
public getActions(): IAction[] {
getActions(): IAction[] {
return [];
}
public getSecondaryActions(): IAction[] {
getSecondaryActions(): IAction[] {
return [];
}
public getActionItem(action: IAction): IActionItem {
getActionItem(action: IAction): IActionItem {
return null;
}
public getActionsContext(): any {
getActionsContext(): any {
return undefined;
}
public shutdown(): void {
shutdown(): void {
// Subclass to implement
}
public getOptimalWidth(): number {
getOptimalWidth(): number {
return 0;
}
public dispose(): void {
dispose(): void {
this.isDisposed = true;
this.treeContainer = null;
......@@ -300,33 +268,24 @@ export abstract class CollapsibleView extends AbstractCollapsibleView implements
}
export interface IViewletViewOptions extends IViewOptions {
viewletSettings: object;
}
export interface IViewState {
collapsed: boolean;
size: number | undefined;
isHidden: boolean;
order: number;
}
export class ViewsViewlet extends Viewlet {
protected viewletContainer: HTMLElement;
protected lastFocusedView: IView;
protected lastFocusedView: IViewletView;
private splitView: SplitView;
private viewHeaderContextMenuListeners: IDisposable[] = [];
protected dimension: Dimension;
private viewletSettings: object;
private readonly viewsContextKeys: Set<string> = new Set<string>();
protected viewsStates: Map<string, IViewState> = new Map<string, IViewState>();
private areExtensionsReady: boolean = false;
......@@ -339,7 +298,6 @@ export class ViewsViewlet extends Viewlet {
@IStorageService protected storageService: IStorageService,
@IInstantiationService protected instantiationService: IInstantiationService,
@IThemeService themeService: IThemeService,
@IWorkspaceContextService protected contextService: IWorkspaceContextService,
@IContextKeyService protected contextKeyService: IContextKeyService,
@IContextMenuService protected contextMenuService: IContextMenuService,
@IExtensionService extensionService: IExtensionService
......@@ -358,15 +316,15 @@ export class ViewsViewlet extends Viewlet {
});
}
public create(parent: Builder): TPromise<void> {
create(parent: Builder): TPromise<void> {
super.create(parent);
this.viewletContainer = DOM.append(parent.getHTMLElement(), DOM.$(''));
this.splitView = this._register(new SplitView(this.viewletContainer, { canChangeOrderByDragAndDrop: true }));
this.attachSplitViewStyler(this.splitView);
this._register(this.splitView.onFocus((view: IView) => this.lastFocusedView = view));
this._register(this.splitView.onFocus((view: IViewletView) => this.lastFocusedView = view));
this._register(this.splitView.onDidOrderChange(() => {
const views = this.splitView.getViews<IView>();
const views = this.splitView.getViews<IViewletView>();
for (let order = 0; order < views.length; order++) {
this.viewsStates.get(views[order].id).order = order;
}
......@@ -374,34 +332,34 @@ export class ViewsViewlet extends Viewlet {
return this.onViewsRegistered(ViewsRegistry.getViews(this.location))
.then(() => {
this.lastFocusedView = this.splitView.getViews<IView>()[0];
this.lastFocusedView = this.splitView.getViews<IViewletView>()[0];
this.focus();
});
}
public getTitle(): string {
getTitle(): string {
let title = Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlet(this.getId()).name;
if (this.showHeaderInTitleArea() && this.splitView.getViews<IView>()[0]) {
title += ': ' + this.splitView.getViews<IView>()[0].name;
if (this.showHeaderInTitleArea() && this.splitView.getViews<IViewletView>()[0]) {
title += ': ' + this.splitView.getViews<IViewletView>()[0].name;
}
return title;
}
public getActions(): IAction[] {
if (this.showHeaderInTitleArea() && this.splitView.getViews<IView>()[0]) {
return this.splitView.getViews<IView>()[0].getActions();
getActions(): IAction[] {
if (this.showHeaderInTitleArea() && this.splitView.getViews<IViewletView>()[0]) {
return this.splitView.getViews<IViewletView>()[0].getActions();
}
return [];
}
public getSecondaryActions(): IAction[] {
if (this.showHeaderInTitleArea() && this.splitView.getViews<IView>()[0]) {
return this.splitView.getViews<IView>()[0].getSecondaryActions();
getSecondaryActions(): IAction[] {
if (this.showHeaderInTitleArea() && this.splitView.getViews<IViewletView>()[0]) {
return this.splitView.getViews<IViewletView>()[0].getSecondaryActions();
}
return [];
}
public getContextMenuActions(): IAction[] {
getContextMenuActions(): IAction[] {
return this.getViewDescriptorsFromRegistry(true)
.filter(viewDescriptor => viewDescriptor.canToggleVisibility && this.contextKeyService.contextMatchesRules(viewDescriptor.when))
.map(viewDescriptor => (<IAction>{
......@@ -413,14 +371,14 @@ export class ViewsViewlet extends Viewlet {
}));
}
public setVisible(visible: boolean): TPromise<void> {
setVisible(visible: boolean): TPromise<void> {
return super.setVisible(visible)
.then(() => TPromise.join(this.splitView.getViews<IView>().filter(view => view.isVisible() !== visible)
.then(() => TPromise.join(this.splitView.getViews<IViewletView>().filter(view => view.isVisible() !== visible)
.map((view) => view.setVisible(visible))))
.then(() => void 0);
}
public focus(): void {
focus(): void {
super.focus();
if (this.lastFocusedView) {
......@@ -430,26 +388,26 @@ export class ViewsViewlet extends Viewlet {
}
}
public layout(dimension: Dimension): void {
layout(dimension: Dimension): void {
this.dimension = dimension;
this.layoutViews();
}
public getOptimalWidth(): number {
getOptimalWidth(): number {
const additionalMargin = 16;
const optimalWidth = Math.max(...this.splitView.getViews<IView>().map(view => view.getOptimalWidth() || 0));
const optimalWidth = Math.max(...this.splitView.getViews<IViewletView>().map(view => view.getOptimalWidth() || 0));
return optimalWidth + additionalMargin;
}
public shutdown(): void {
this.splitView.getViews<IView>().forEach((view) => view.shutdown());
shutdown(): void {
this.splitView.getViews<IViewletView>().forEach((view) => view.shutdown());
super.shutdown();
}
private layoutViews(): void {
if (this.splitView) {
this.splitView.layout(this.dimension.height);
for (const view of this.splitView.getViews<IView>()) {
for (const view of this.splitView.getViews<IViewletView>()) {
let viewState = this.updateViewStateSize(view);
this.viewsStates.set(view.id, viewState);
}
......@@ -470,7 +428,7 @@ export class ViewsViewlet extends Viewlet {
this.updateViews();
}
private onViewsRegistered(views: IViewDescriptor[]): TPromise<IView[]> {
private onViewsRegistered(views: IViewDescriptor[]): TPromise<IViewletView[]> {
this.viewsContextKeys.clear();
for (const viewDescriptor of this.getViewDescriptorsFromRegistry()) {
if (viewDescriptor.when) {
......@@ -483,7 +441,7 @@ export class ViewsViewlet extends Viewlet {
return this.updateViews();
}
private onViewsDeregistered(views: IViewDescriptor[]): TPromise<IView[]> {
private onViewsDeregistered(views: IViewDescriptor[]): TPromise<IViewletView[]> {
return this.updateViews(views);
}
......@@ -505,7 +463,7 @@ export class ViewsViewlet extends Viewlet {
}
}
protected updateViews(unregisteredViews: IViewDescriptor[] = []): TPromise<IView[]> {
protected updateViews(unregisteredViews: IViewDescriptor[] = []): TPromise<IViewletView[]> {
if (this.splitView) {
const registeredViews = this.getViewDescriptorsFromRegistry();
......@@ -529,10 +487,10 @@ export class ViewsViewlet extends Viewlet {
}, [[], [], unregisteredViews]);
const toCreate: IView[] = [];
const toCreate: IViewletView[] = [];
if (toAdd.length || toRemove.length) {
for (const view of this.splitView.getViews<IView>()) {
for (const view of this.splitView.getViews<IViewletView>()) {
let viewState = this.viewsStates.get(view.id);
if (!viewState || typeof viewState.size === 'undefined' || view.size !== viewState.size || !view.isExpanded() !== viewState.collapsed) {
viewState = this.updateViewStateSize(view);
......@@ -564,7 +522,7 @@ export class ViewsViewlet extends Viewlet {
toCreate.push(view);
this.attachViewStyler(view);
this.splitView.addView(view, viewState && viewState.size ? Math.max(viewState.size, 1) : viewDescriptor.size, index);
this.splitView.addView(view, index);
}
return TPromise.join(toCreate.map(view => view.create()))
......@@ -611,14 +569,14 @@ export class ViewsViewlet extends Viewlet {
}
if (this.showHeaderInTitleArea()) {
if (this.splitView.getViews<IView>()[0]) {
this.splitView.getViews<IView>()[0].hideHeader();
if (!this.splitView.getViews<IView>()[0].isExpanded()) {
this.splitView.getViews<IView>()[0].expand();
if (this.splitView.getViews<IViewletView>()[0]) {
this.splitView.getViews<IViewletView>()[0].hideHeader();
if (!this.splitView.getViews<IViewletView>()[0].isExpanded()) {
this.splitView.getViews<IViewletView>()[0].expand();
}
}
} else {
for (const view of this.splitView.getViews<IView>()) {
for (const view of this.splitView.getViews<IViewletView>()) {
view.showHeader();
}
}
......@@ -647,7 +605,7 @@ export class ViewsViewlet extends Viewlet {
return this.setVisible(this.isVisible());
}
private onContextMenu(event: StandardMouseEvent, view: IView): void {
private onContextMenu(event: StandardMouseEvent, view: IViewletView): void {
event.stopPropagation();
event.preventDefault();
......@@ -667,7 +625,7 @@ export class ViewsViewlet extends Viewlet {
if (!this.showHeaderInTitleWhenSingleView) {
return false;
}
if (this.splitView.getViews<IView>().length > 1) {
if (this.splitView.getViews<IViewletView>().length > 1) {
return false;
}
if (ViewLocation.getContributedViewLocation(this.location.id) && !this.areExtensionsReady) {
......@@ -705,32 +663,32 @@ export class ViewsViewlet extends Viewlet {
});
}
protected createView(viewDescriptor: IViewDescriptor, initialSize: number, options: IViewletViewOptions): IView {
protected createView(viewDescriptor: IViewDescriptor, initialSize: number, options: IViewletViewOptions): IViewletView {
return this.instantiationService.createInstance(viewDescriptor.ctor, initialSize, options);
}
protected get views(): IView[] {
return this.splitView ? this.splitView.getViews<IView>() : [];
protected get views(): IViewletView[] {
return this.splitView ? this.splitView.getViews<IViewletView>() : [];
}
protected getView(id: string): IView {
return this.splitView.getViews<IView>().filter(view => view.id === id)[0];
protected getView(id: string): IViewletView {
return this.splitView.getViews<IViewletView>().filter(view => view.id === id)[0];
}
private updateViewStateSize(view: IView): IViewState {
private updateViewStateSize(view: IViewletView): IViewState {
const currentState = this.viewsStates.get(view.id);
const newViewState = this.createViewState(view);
return currentState ? { ...currentState, collapsed: newViewState.collapsed, size: newViewState.size } : newViewState;
}
protected createViewState(view: IView): IViewState {
protected createViewState(view: IViewletView): IViewState {
const collapsed = !view.isExpanded();
const size = collapsed && view instanceof CollapsibleView ? view.previousSize : view.size;
return {
collapsed,
size: size && size > 0 ? size : void 0,
isHidden: false,
order: this.splitView.getViews<IView>().indexOf(view)
order: this.splitView.getViews<IViewletView>().indexOf(view)
};
}
}
......@@ -746,12 +704,12 @@ export class PersistentViewsViewlet extends ViewsViewlet {
@IStorageService storageService: IStorageService,
@IInstantiationService instantiationService: IInstantiationService,
@IThemeService themeService: IThemeService,
@IWorkspaceContextService contextService: IWorkspaceContextService,
@IWorkspaceContextService protected contextService: IWorkspaceContextService,
@IContextKeyService contextKeyService: IContextKeyService,
@IContextMenuService contextMenuService: IContextMenuService,
@IExtensionService extensionService: IExtensionService
) {
super(id, location, showHeaderInTitleWhenSingleView, telemetryService, storageService, instantiationService, themeService, contextService, contextKeyService, contextMenuService, extensionService);
super(id, location, showHeaderInTitleWhenSingleView, telemetryService, storageService, instantiationService, themeService, contextKeyService, contextMenuService, extensionService);
this.loadViewsStates();
}
......
......@@ -613,7 +613,7 @@ export class Process implements IProcess {
}
public clearThreads(removeThreads: boolean, reference: number = undefined): void {
if (reference) {
if (reference !== undefined && reference !== null) {
if (this.threads.has(reference)) {
const thread = this.threads.get(reference);
thread.clearCallStack();
......
......@@ -46,7 +46,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
import { inputForeground, inputBackground, inputBorder } from 'vs/platform/theme/common/colorRegistry';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ViewsRegistry, ViewLocation, IViewDescriptor } from 'vs/workbench/browser/parts/views/viewsRegistry';
import { PersistentViewsViewlet, IView } from 'vs/workbench/browser/parts/views/views';
import { PersistentViewsViewlet, IViewletView } from 'vs/workbench/browser/parts/views/views';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IContextKeyService, ContextKeyExpr, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey';
......@@ -310,7 +310,7 @@ export class ExtensionsViewlet extends PersistentViewsViewlet implements IExtens
await this.updateViews([], !!value);
}
protected async updateViews(unregisteredViews: IViewDescriptor[] = [], showAll = false): TPromise<IView[]> {
protected async updateViews(unregisteredViews: IViewDescriptor[] = [], showAll = false): TPromise<IViewletView[]> {
const created = await super.updateViews();
const toShow = showAll ? this.views : created;
if (toShow.length) {
......
......@@ -12,7 +12,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
import * as DOM from 'vs/base/browser/dom';
import { Builder } from 'vs/base/browser/builder';
import { VIEWLET_ID, ExplorerViewletVisibleContext, IFilesConfiguration, OpenEditorsVisibleContext, OpenEditorsVisibleCondition } from 'vs/workbench/parts/files/common/files';
import { PersistentViewsViewlet, IView, IViewletViewOptions } from 'vs/workbench/browser/parts/views/views';
import { PersistentViewsViewlet, IViewletView, IViewletViewOptions } from 'vs/workbench/browser/parts/views/views';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IConfigurationEditingService } from 'vs/workbench/services/configuration/common/configurationEditing';
import { ActionRunner, FileViewletState } from 'vs/workbench/parts/files/browser/views/explorerViewer';
......@@ -125,7 +125,7 @@ export class ExplorerViewlet extends PersistentViewsViewlet {
this.openEditorsVisibleContextKey.set(!this.contextService.hasWorkspace() || (<IFilesConfiguration>this.configurationService.getConfiguration()).explorer.openEditors.visible !== 0);
}
protected createView(viewDescriptor: IViewDescriptor, initialSize: number, options: IViewletViewOptions): IView {
protected createView(viewDescriptor: IViewDescriptor, initialSize: number, options: IViewletViewOptions): IViewletView {
if (viewDescriptor.id === ExplorerView.ID) {
// Create a delegating editor service for the explorer to be able to delay the refresh in the opened
// editors view above. This is a workaround for being able to double click on a file to make it pinned
......@@ -223,7 +223,7 @@ export class ExplorerViewlet extends PersistentViewsViewlet {
super.focus();
}
private hasSelectionOrFocus(view: IView): boolean {
private hasSelectionOrFocus(view: IViewletView): boolean {
if (!view) {
return false;
}
......
......@@ -12,7 +12,7 @@ import { chain } from 'vs/base/common/event';
import { onUnexpectedError } from 'vs/base/common/errors';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Builder } from 'vs/base/browser/builder';
import { PersistentViewsViewlet, CollapsibleView, IViewletViewOptions, IView, IViewOptions } from 'vs/workbench/browser/parts/views/views';
import { PersistentViewsViewlet, CollapsibleView, IViewletViewOptions, IViewletView, IViewOptions } from 'vs/workbench/browser/parts/views/views';
import { append, $, toggleClass, trackFocus } from 'vs/base/browser/dom';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { List } from 'vs/base/browser/ui/list/listWidget';
......@@ -545,14 +545,14 @@ export class SCMViewlet extends PersistentViewsViewlet {
await super.create(parent);
parent.addClass('scm-viewlet', 'empty');
append(parent.getHTMLElement(), $('div.empty-message', null, localize('no open repo', "There are no source controls active.")));
append(parent.getHTMLElement(), $('div.empty-message', null, localize('no open repo', "There are no source control providers active.")));
this.scmService.onDidAddRepository(this.onDidAddRepository, this, this.disposables);
this.scmService.onDidRemoveRepository(this.onDidRemoveRepository, this, this.disposables);
this.scmService.repositories.forEach(p => this.onDidAddRepository(p));
}
protected createView(viewDescriptor: IViewDescriptor, initialSize: number, options: IViewletViewOptions): IView {
protected createView(viewDescriptor: IViewDescriptor, initialSize: number, options: IViewletViewOptions): IViewletView {
if (viewDescriptor instanceof SourceControlViewDescriptor) {
return this.instantiationService.createInstance(SourceControlView, initialSize, viewDescriptor.repository, options);
}
......
......@@ -36,11 +36,19 @@ namespace schema {
export function isValidSnippet(extension: IExtensionPointUser<ISnippetsExtensionPoint[]>, snippet: ISnippetsExtensionPoint, modeService: IModeService): boolean {
if (!snippet.language || (typeof snippet.language !== 'string') || !modeService.isRegisteredMode(snippet.language)) {
extension.collector.error(localize('invalid.language', "Unknown language in `contributes.{0}.language`. Provided value: {0}", String(snippet.language)));
extension.collector.error(localize(
'invalid.language',
"Unknown language in `contributes.{0}.language`. Provided value: {1}",
extension.description.name, String(snippet.language)
));
return false;
} else if (!snippet.path || (typeof snippet.path !== 'string')) {
extension.collector.error(localize('invalid.path.0', "Expected string in `contributes.{0}.path`. Provided value: {0}", String(snippet.path)));
extension.collector.error(localize(
'invalid.path.0',
"Expected string in `contributes.{0}.path`. Provided value: {1}",
extension.description.name, String(snippet.path)
));
return false;
} else {
......
......@@ -15,10 +15,10 @@ describe('CSS', () => {
it('verifies quick outline', async () => {
await app.workbench.quickopen.openFile('style.css');
const outline = await app.workbench.editor.openOutline();
const elements = await outline.getQuickOpenElements();
await app.screenCapturer.capture('CSS Outline result');
assert.equal(elements.length, 2, `Did not find two outline elements`);
await outline.waitForQuickOpenElements(2);
});
it('verifies warnings for the empty rule', async () => {
......
......@@ -104,7 +104,7 @@ export class Debug extends Viewlet {
}
async console(text: string, type: string): Promise<string> {
await this.spectron.workbench.commandPallette.runCommand('Debug: Focus Debug Console');
await this.spectron.workbench.quickopen.runCommand('Debug: Focus Debug Console');
await this.spectron.client.waitForElement(REPL_FOCUSED);
await this.spectron.client.type(text);
await this.spectron.client.waitForElement(CONSOLE_INPUT_OUTPUT + ` .${type}`);
......
......@@ -18,9 +18,7 @@ describe('Editor', () => {
const outline = await app.workbench.editor.openOutline();
const symbols = await outline.getQuickOpenElements();
await app.screenCapturer.capture('Javascript Outline result');
assert.equal(symbols.length, 12, 'Quick outline elements count does not match to expected.');
await outline.waitForQuickOpenElements(12);
});
it(`finds 'All References' to 'app'`, async function () {
......
......@@ -35,7 +35,7 @@ export class Editor {
public async findReferences(term: string, line: number): Promise<References> {
await this.clickOnTerm(term, line);
await this.spectron.workbench.commandPallette.runCommand('Find All References');
await this.spectron.workbench.quickopen.runCommand('Find All References');
const references = new References(this.spectron);
await references.waitUntilOpen();
return references;
......@@ -43,7 +43,7 @@ export class Editor {
public async rename(term: string, line: number): Promise<Rename> {
await this.clickOnTerm(term, line);
await this.spectron.workbench.commandPallette.runCommand('Rename Symbol');
await this.spectron.workbench.quickopen.runCommand('Rename Symbol');
const rename = new Rename(term, this.spectron);
await rename.waitUntilOpen();
return rename;
......@@ -51,12 +51,12 @@ export class Editor {
public async gotoDefinition(term: string, line: number): Promise<void> {
await this.clickOnTerm(term, line);
await this.spectron.workbench.commandPallette.runCommand('Go to Definition');
await this.spectron.workbench.quickopen.runCommand('Go to Definition');
}
public async peekDefinition(term: string, line: number): Promise<References> {
await this.clickOnTerm(term, line);
await this.spectron.workbench.commandPallette.runCommand('Peek Definition');
await this.spectron.workbench.quickopen.runCommand('Peek Definition');
const peek = new References(this.spectron);
await peek.waitUntilOpen();
return peek;
......
......@@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { SpectronApplication } from '../../spectron/application';
describe('Explorer', () => {
......@@ -14,22 +13,19 @@ describe('Explorer', () => {
it('quick open search produces correct result', async function () {
await app.workbench.quickopen.openQuickOpen();
await app.client.type('.js');
const elements = await app.workbench.quickopen.getQuickOpenElements();
await app.client.keys(['Escape', 'NULL']);
await app.screenCapturer.capture('Quick open result');
assert.equal(elements.length, 7, 'There are 7 elements in quick open');
await app.workbench.quickopen.waitForQuickOpenElements(7);
await app.client.keys(['Escape', 'NULL']);
});
it('quick open respects fuzzy matching', async function () {
await app.workbench.quickopen.openQuickOpen();
await app.client.type('a.s');
const elements = await app.workbench.quickopen.getQuickOpenElements();
await app.workbench.quickopen.waitForQuickOpenElements(3);
await app.client.keys(['Escape', 'NULL']);
await app.screenCapturer.capture('fuzzy match result');
assert.equal(elements.length, 3, 'There are 3 elements in quick open');
});
});
\ No newline at end of file
......@@ -22,7 +22,7 @@ describe('Extensions', () => {
await app.reload();
await app.workbench.extensions.waitForExtensionsViewlet();
await app.workbench.commandPallette.runCommand('Smoke Test Check');
await app.workbench.quickopen.runCommand('Smoke Test Check');
const statusbarText = await app.workbench.statusbar.getStatusbarTextByTitle('smoke test');
await app.screenCapturer.capture('Statusbar');
......
......@@ -68,7 +68,7 @@ describe('Git', () => {
await app.workbench.scm.commit('first commit');
await app.client.waitForText(SYNC_STATUSBAR, ' 0↓ 1↑');
await app.workbench.commandPallette.runCommand('Git: Stage All Changes');
await app.workbench.quickopen.runCommand('Git: Stage All Changes');
await app.workbench.scm.waitForChange(c => c.name === 'index.jade' && c.type === 'Index Modified');
await app.workbench.scm.commit('second commit');
......
......@@ -5,7 +5,6 @@
import * as assert from 'assert';
import { SpectronApplication, CODE_WORKSPACE_PATH, VSCODE_BUILD } from '../../spectron/application';
import { QuickOpen } from '../quickopen/quickopen';
import { Window } from '../window';
describe('Multi Root', () => {
......@@ -19,12 +18,11 @@ describe('Multi Root', () => {
beforeEach(function () { app.screenCapturer.testName = this.currentTest.title; });
it('shows results from all folders', async function () {
let quickOpen = new QuickOpen(app);
await quickOpen.openQuickOpen();
await app.client.type('*.*');
const elements = await quickOpen.getQuickOpenElements();
await app.screenCapturer.capture('quick open result');
assert.equal(elements.length, 6);
await app.workbench.quickopen.openQuickOpen();
await app.workbench.quickopen.type('*.*');
await app.workbench.quickopen.waitForQuickOpenElements(6);
});
it('shows workspace name in title', async function () {
......
......@@ -8,6 +8,10 @@ import { Element } from 'webdriverio';
export class QuickOpen {
static QUICK_OPEN_HIDDEN = 'div.quick-open-widget[aria-hidden="true"]';
static QUICK_OPEN = 'div.quick-open-widget[aria-hidden="false"]';
static QUICK_OPEN_FOCUSSED_INPUT = `${QuickOpen.QUICK_OPEN} .quick-open-input input:focus`;
static QUICK_OPEN_FOCUSED_ELEMENT = `${QuickOpen.QUICK_OPEN} .quick-open-tree .monaco-tree-row.focused .monaco-highlighted-label`;
static QUICK_OPEN_ENTRY_SELECTOR = 'div[aria-label="Quick Picker"] .monaco-tree-rows.show-twisties .monaco-tree-row .quick-open-entry';
constructor(readonly spectron: SpectronApplication) {
......@@ -18,18 +22,34 @@ export class QuickOpen {
await this.waitForQuickOpenOpened();
}
public async openCommandPallette(): Promise<void> {
await this.spectron.command('workbench.action.showCommands');
await this.waitForQuickOpenOpened();
}
public async closeQuickOpen(): Promise<void> {
await this.spectron.command('workbench.action.closeQuickOpen');
await this.waitForQuickOpenClosed();
}
public async type(text: string): Promise<void> {
let prefix = await this.spectron.client.getValue(QuickOpen.QUICK_OPEN_FOCUSSED_INPUT);
await this.spectron.client.type(text);
await this.spectron.client.waitForValue(QuickOpen.QUICK_OPEN_FOCUSSED_INPUT, prefix + text);
}
public async getQuickOpenElements(): Promise<Element[]> {
return this.spectron.client.waitForElements(QuickOpen.QUICK_OPEN_ENTRY_SELECTOR);
}
public async waitForQuickOpenElements(count: number): Promise<Element[]> {
return this.spectron.client.waitForElements(QuickOpen.QUICK_OPEN_ENTRY_SELECTOR, elements => elements && elements.length === count);
}
public async openFile(fileName: string): Promise<void> {
await this.openQuickOpen();
await this.spectron.client.type(fileName);
await this.type(fileName);
await this.getQuickOpenElements();
await this.spectron.client.keys(['Enter', 'NULL']);
await this.spectron.client.waitForElement(`.tabs-container div[aria-selected="true"][aria-label="${fileName}, tab"]`);
......@@ -37,12 +57,25 @@ export class QuickOpen {
await this.spectron.workbench.waitForEditorFocus(fileName);
}
public async runCommand(commandText: string): Promise<void> {
await this.openCommandPallette();
// type the text
await this.type(commandText);
// wait for best choice to be focused
await this.spectron.client.waitForTextContent(QuickOpen.QUICK_OPEN_FOCUSED_ELEMENT, commandText);
// wait and click on best choice
await this.spectron.client.waitAndClick(QuickOpen.QUICK_OPEN_FOCUSED_ELEMENT);
}
protected waitForQuickOpenOpened(): Promise<Element> {
return this.spectron.client.waitForElement('.quick-open-widget .quick-open-input input:focus');
return this.spectron.client.waitForElement(QuickOpen.QUICK_OPEN_FOCUSSED_INPUT);
}
protected waitForQuickOpenClosed(): Promise<Element> {
return this.spectron.client.waitForElement('div.quick-open-widget[aria-hidden="true"]');
return this.spectron.client.waitForElement(QuickOpen.QUICK_OPEN_HIDDEN);
}
public async isQuickOpenVisible(): Promise<boolean> {
......
......@@ -16,7 +16,7 @@ export class Terminal {
public async showTerminal(): Promise<void> {
if (!await this.isVisible()) {
await this.spectron.workbench.commandPallette.runCommand('View: Toggle Integrated Terminal');
await this.spectron.workbench.quickopen.runCommand('View: Toggle Integrated Terminal');
await this.spectron.client.waitForElement(Terminal.TERMINAL_CURSOR);
await this.waitForTerminalText(text => text.length > 0, 'Waiting for Terminal to be ready');
}
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { QuickOpen } from '../quickopen/quickopen';
const QUICK_OPEN_INPUT = '.quick-open-widget .quick-open-input input';
const QUICK_OPEN_FOCUSED_ELEMENT = '.quick-open-widget .quick-open-tree .monaco-tree-row.focused .monaco-highlighted-label';
export class CommandPallette extends QuickOpen {
public async runCommand(commandText: string): Promise<void> {
// run command
await this.spectron.command('workbench.action.showCommands');
// wait for quick open
await this.waitForQuickOpenOpened();
// type the text
await this.spectron.client.keys([commandText, 'NULL']);
// wait for text to be in input box
await this.spectron.client.waitForValue(QUICK_OPEN_INPUT, `>${commandText}`);
// wait for best choice to be focused
await this.spectron.client.waitForTextContent(QUICK_OPEN_FOCUSED_ELEMENT, commandText);
// wait and click on best choice
await this.spectron.client.waitAndClick(QUICK_OPEN_FOCUSED_ELEMENT);
}
}
......@@ -16,21 +16,24 @@ describe('Dataloss', () => {
const textToType = 'Hello, Code', textToTypeInUntitled = 'Hello, Unitled Code', fileName = 'readme.md', untitled = 'Untitled-1';
await app.workbench.newUntitledFile();
await app.client.type(textToTypeInUntitled);
await app.screenCapturer.capture('Untitled file before reload');
await app.workbench.explorer.openFile(fileName);
await app.client.type(textToType);
await app.screenCapturer.capture(`${fileName} before reload`);
await app.screenCapturer.capture('Before reload');
await app.reload();
await app.screenCapturer.capture('After reload');
await app.workbench.waitForActiveOpen(fileName, true);
await app.screenCapturer.capture(`${fileName} after reload`);
let actual = await app.workbench.editor.getEditorFirstLineText();
await app.screenCapturer.capture(fileName + ' text');
assert.ok(actual.startsWith(textToType), `${actual} did not start with ${textToType}`);
await app.workbench.waitForOpen(untitled, true);
await app.workbench.selectTab('Untitled-1', true);
await app.screenCapturer.capture('Untitled file after reload');
actual = await app.workbench.editor.getEditorFirstLineText();
await app.screenCapturer.capture('Untitled file text');
assert.ok(actual.startsWith(textToTypeInUntitled), `${actual} did not start with ${textToTypeInUntitled}`);
});
});
\ No newline at end of file
......@@ -8,7 +8,6 @@ import { Explorer } from '../explorer/explorer';
import { ActivityBar } from '../activitybar/activityBar';
import { QuickOpen } from '../quickopen/quickopen';
import { Extensions } from '../extensions/extensions';
import { CommandPallette } from './commandPallette';
import { Search } from '../search/search';
import { Editor } from '../editor/editor';
import { SCM } from '../git/scm';
......@@ -23,7 +22,6 @@ export class Workbench {
readonly explorer: Explorer;
readonly activitybar: ActivityBar;
readonly commandPallette: CommandPallette;
readonly quickopen: QuickOpen;
readonly search: Search;
readonly extensions: Extensions;
......@@ -40,7 +38,6 @@ export class Workbench {
this.explorer = new Explorer(spectron);
this.activitybar = new ActivityBar(spectron);
this.quickopen = new QuickOpen(spectron);
this.commandPallette = new CommandPallette(spectron);
this.search = new Search(spectron);
this.extensions = new Extensions(spectron);
this.editor = new Editor(spectron);
......
......@@ -101,10 +101,10 @@ function getKeybindingPlatform(): string {
function toUri(path: string): string {
if (process.platform === 'win32') {
return `file:///${path.replace(/\\/g, '/')}`;
return `${path.replace(/\\/g, '/')}`;
}
return `file://${path}`;
return `${path}`;
}
async function setup(): Promise<void> {
......@@ -127,11 +127,16 @@ async function setup(): Promise<void> {
if (!fs.existsSync(workspacePath)) {
console.log('*** Creating workspace file...');
const workspace = {
id: (Date.now() + Math.round(Math.random() * 1000)).toString(),
folders: [
toUri(path.join(testRepoLocalDir, 'public')),
toUri(path.join(testRepoLocalDir, 'routes')),
toUri(path.join(testRepoLocalDir, 'views'))
{
path: toUri(path.join(testRepoLocalDir, 'public'))
},
{
path: toUri(path.join(testRepoLocalDir, 'routes'))
},
{
path: toUri(path.join(testRepoLocalDir, 'views'))
}
]
};
......
......@@ -79,7 +79,7 @@ export class SpectronApplication {
}
public async reload(): Promise<any> {
await this.workbench.commandPallette.runCommand('Reload Window');
await this.workbench.quickopen.runCommand('Reload Window');
// TODO @sandy: Find a proper condition to wait for reload
await this.wait(.5);
await this.checkWindowReady();
......@@ -165,7 +165,7 @@ export class SpectronApplication {
public command(command: string, capture?: boolean): Promise<any> {
const binding = this.keybindings.find(x => x['command'] === command);
if (!binding) {
return this.workbench.commandPallette.runCommand(command);
return this.workbench.quickopen.runCommand(command);
}
const keys: string = binding.key;
......
......@@ -391,16 +391,6 @@
}
],
"duplicate-imports": true,
"allow-async": [
true,
[
"node",
"electron-main",
"electron-browser",
"extensions",
"smoke"
]
],
"translation-remind": true
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册