Fix last of merge issues
|
@ -3,4 +3,4 @@
|
|||
"container": "debuggers",
|
||||
"zip": "e6b9b29/node-debug.zip",
|
||||
"output": ""
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
declare module 'native-keymap' {
|
||||
|
||||
export interface INativeKeyMap {
|
||||
key_code: string;
|
||||
value: string;
|
||||
withShift: string;
|
||||
withAltGr: string;
|
||||
withShiftAltGr: string;
|
||||
}
|
||||
|
||||
export function getKeyMap(): INativeKeyMap[];
|
||||
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
declare module 'native-keymap' {
|
||||
|
||||
export interface INativeKeyMap {
|
||||
key_code: string;
|
||||
value: string;
|
||||
withShift: string;
|
||||
withAltGr: string;
|
||||
withShiftAltGr: string;
|
||||
}
|
||||
|
||||
export function getKeyMap(): INativeKeyMap[];
|
||||
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
declare module 'windows-mutex' {
|
||||
export class Mutex {
|
||||
constructor(name: string);
|
||||
isActive(): boolean;
|
||||
release(): void;
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
declare module 'windows-mutex' {
|
||||
export class Mutex {
|
||||
constructor(name: string);
|
||||
isActive(): boolean;
|
||||
release(): void;
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ import { globals } from 'vs/base/common/platform';
|
|||
|
||||
export const workersCount = environment('workersCount', 2);
|
||||
export const enableTasks = environment('enableTasks');
|
||||
export const enableSendASmile = environment('enableSendASmile');
|
||||
export const enableJavaScriptRewriting = environment('enableJavaScriptRewriting');
|
||||
export const enableTypeScriptServiceMode = environment('enableTypeScriptServiceMode');
|
||||
export const enableTypeScriptServiceModeForJS = environment('enableTypeScriptServiceModeForJS');
|
||||
|
|
|
@ -138,5 +138,11 @@ export interface IEnvironment {
|
|||
aiConfig: {
|
||||
key: string;
|
||||
asimovKey: string;
|
||||
},
|
||||
|
||||
sendASmile: {
|
||||
submitUrl: string,
|
||||
reportIssueUrl: string,
|
||||
requestFeatureUrl: string
|
||||
}
|
||||
}
|
|
@ -1,255 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import URI from 'vs/base/common/uri';
|
||||
import Event, {Emitter} from 'vs/base/common/event';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import {DefaultFilter} from 'vs/editor/common/modes/modesFilters';
|
||||
import {TPromise} from 'vs/base/common/winjs.base';
|
||||
import {onUnexpectedError} from 'vs/base/common/errors';
|
||||
import {sequence} from 'vs/base/common/async';
|
||||
import {Range as EditorRange} from 'vs/editor/common/core/range';
|
||||
import {IDisposable} from 'vs/base/common/lifecycle';
|
||||
import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService';
|
||||
import {Remotable, IThreadService} from 'vs/platform/thread/common/thread';
|
||||
import * as vscode from 'vscode';
|
||||
import * as typeConverters from 'vs/workbench/api/common/pluginHostTypeConverters';
|
||||
import * as types from 'vs/workbench/api/common/pluginHostTypes';
|
||||
import {IPosition, IRange, ISingleEditOperation} from 'vs/editor/common/editorCommon';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import {CancellationTokenSource} from 'vs/base/common/cancellation';
|
||||
import {PluginHostModelService} from 'vs/workbench/api/common/pluginHostDocuments';
|
||||
import {IMarkerService, IMarker} from 'vs/platform/markers/common/markers';
|
||||
import {PluginHostCommands, MainThreadCommands} from 'vs/workbench/api/common/pluginHostCommands';
|
||||
import {DeclarationRegistry} from 'vs/editor/contrib/goToDeclaration/common/goToDeclaration';
|
||||
import {ExtraInfoRegistry} from 'vs/editor/contrib/hover/common/hover';
|
||||
import {OccurrencesRegistry} from 'vs/editor/contrib/wordHighlighter/common/wordHighlighter';
|
||||
import {ReferenceRegistry} from 'vs/editor/contrib/referenceSearch/common/referenceSearch';
|
||||
import {IQuickFix2, QuickFixRegistry, getQuickFixes} from 'vs/editor/contrib/quickFix/common/quickFix';
|
||||
import {IOutline} from 'vs/editor/contrib/quickOpen/common/quickOpen';
|
||||
import LanguageFeatureRegistry from 'vs/editor/common/modes/languageFeatureRegistry';
|
||||
import {NavigateTypesSupportRegistry, INavigateTypesSupport, ITypeBearing} from 'vs/workbench/parts/search/common/search'
|
||||
import {RenameRegistry} from 'vs/editor/contrib/rename/common/rename';
|
||||
import {FormatRegistry, FormatOnTypeRegistry} from 'vs/editor/contrib/format/common/format';
|
||||
import {ICodeLensData} from 'vs/editor/contrib/codelens/common/codelens';
|
||||
|
||||
export class ExtHostLanguageFeatureCommands {
|
||||
|
||||
private _commands: PluginHostCommands;
|
||||
private _disposables: IDisposable[] = [];
|
||||
|
||||
constructor(commands: PluginHostCommands) {
|
||||
this._commands = commands;
|
||||
|
||||
this._register('vscode.executeWorkspaceSymbolProvider', this._executeWorkspaceSymbolProvider);
|
||||
this._register('vscode.executeDefinitionProvider', this._executeDefinitionProvider);
|
||||
this._register('vscode.executeHoverProvider', this._executeHoverProvider);
|
||||
this._register('vscode.executeDocumentHighlights', this._executeDocumentHighlights);
|
||||
this._register('vscode.executeReferenceProvider', this._executeReferenceProvider);
|
||||
this._register('vscode.executeDocumentRenameProvider', this._executeDocumentRenameProvider);
|
||||
this._register('vscode.executeSignatureHelpProvider', this._executeSignatureHelpProvider);
|
||||
this._register('vscode.executeDocumentSymbolProvider', this._executeDocumentSymbolProvider);
|
||||
this._register('vscode.executeCompletionItemProvider', this._executeCompletionItemProvider);
|
||||
this._register('vscode.executeCodeActionProvider', this._executeCodeActionProvider);
|
||||
this._register('vscode.executeCodeLensProvider', this._executeCodeLensProvider);
|
||||
this._register('vscode.executeFormatDocumentProvider', this._executeFormatDocumentProvider);
|
||||
this._register('vscode.executeFormatRangeProvider', this._executeFormatRangeProvider);
|
||||
this._register('vscode.executeFormatOnTypeProvider', this._executeFormatOnTypeProvider);
|
||||
}
|
||||
|
||||
private _register(id: string, callback: (...args: any[]) => any): void {
|
||||
this._disposables.push(this._commands.registerCommand(id, callback, this));
|
||||
}
|
||||
|
||||
// --- command impl
|
||||
|
||||
private _executeWorkspaceSymbolProvider(query: string): Thenable<types.SymbolInformation[]> {
|
||||
return this._commands.executeCommand<ITypeBearing[]>('_executeWorkspaceSymbolProvider', { query }).then(value => {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(typeConverters.toSymbolInformation);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _executeDefinitionProvider(resource: URI, position: types.Position): Thenable<types.Location[]> {
|
||||
const args = {
|
||||
resource,
|
||||
position: position && typeConverters.fromPosition(position)
|
||||
};
|
||||
return this._commands.executeCommand<modes.IReference[]>('_executeDefinitionProvider', args).then(value => {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(typeConverters.toLocation)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _executeHoverProvider(resource: URI, position: types.Position): Thenable<types.Hover[]> {
|
||||
const args = {
|
||||
resource,
|
||||
position: position && typeConverters.fromPosition(position)
|
||||
};
|
||||
return this._commands.executeCommand<modes.IComputeExtraInfoResult[]>('_executeHoverProvider', args).then(value => {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(typeConverters.toHover)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _executeDocumentHighlights(resource: URI, position: types.Position): Thenable<types.DocumentHighlight[]> {
|
||||
const args = {
|
||||
resource,
|
||||
position: position && typeConverters.fromPosition(position)
|
||||
};
|
||||
return this._commands.executeCommand<modes.IOccurence[]>('_executeDocumentHighlights', args).then(value => {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(typeConverters.toDocumentHighlight)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _executeReferenceProvider(resource: URI, position: types.Position): Thenable<types.Location[]> {
|
||||
const args = {
|
||||
resource,
|
||||
position: position && typeConverters.fromPosition(position)
|
||||
};
|
||||
return this._commands.executeCommand<modes.IReference[]>('_executeDocumentHighlights', args).then(value => {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(typeConverters.toLocation)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _executeDocumentRenameProvider(resource: URI, position: types.Position, newName: string): Thenable<types.WorkspaceEdit> {
|
||||
const args = {
|
||||
resource,
|
||||
position: position && typeConverters.fromPosition(position),
|
||||
newName
|
||||
};
|
||||
return this._commands.executeCommand<modes.IRenameResult>('_executeDocumentRenameProvider', args).then(value => {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
if (value.rejectReason) {
|
||||
return TPromise.wrapError(value.rejectReason);
|
||||
}
|
||||
let workspaceEdit = new types.WorkspaceEdit();
|
||||
for (let edit of value.edits) {
|
||||
workspaceEdit.replace(edit.resource, typeConverters.toRange(edit.range), edit.newText);
|
||||
}
|
||||
return workspaceEdit;
|
||||
});
|
||||
}
|
||||
|
||||
private _executeSignatureHelpProvider(resource: URI, position: types.Position, triggerCharacter: string): Thenable<types.SignatureHelp> {
|
||||
const args = {
|
||||
resource,
|
||||
position: position && typeConverters.fromPosition(position),
|
||||
triggerCharacter
|
||||
};
|
||||
return this._commands.executeCommand<modes.IParameterHints>('_executeSignatureHelpProvider', args).then(value => {
|
||||
if (value) {
|
||||
return typeConverters.SignatureHelp.to(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _executeCompletionItemProvider(resource: URI, position: types.Position, triggerCharacter: string): Thenable<types.CompletionItem[]> {
|
||||
const args = {
|
||||
resource,
|
||||
position: position && typeConverters.fromPosition(position),
|
||||
triggerCharacter
|
||||
};
|
||||
return this._commands.executeCommand<modes.ISuggestResult[][]>('_executeCompletionItemProvider', args).then(value => {
|
||||
if (value) {
|
||||
let items: types.CompletionItem[] = [];
|
||||
for (let group of value) {
|
||||
for (let suggestions of group) {
|
||||
for (let suggestion of suggestions.suggestions) {
|
||||
const item = typeConverters.Suggest.to(suggestion);
|
||||
items.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _executeDocumentSymbolProvider(resource: URI): Thenable<types.SymbolInformation[]> {
|
||||
const args = {
|
||||
resource
|
||||
};
|
||||
return this._commands.executeCommand<IOutline>('_executeDocumentSymbolProvider', args).then(value => {
|
||||
if (value && Array.isArray(value.entries)) {
|
||||
return value.entries.map(typeConverters.SymbolInformation.fromOutlineEntry);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _executeCodeActionProvider(resource: URI, range: types.Range): Thenable<vscode.Command[]> {
|
||||
const args = {
|
||||
resource,
|
||||
range: typeConverters.fromRange(range)
|
||||
};
|
||||
return this._commands.executeCommand<IQuickFix2[]>('_executeCodeActionProvider', args).then(value => {
|
||||
if (!Array.isArray(value)) {
|
||||
return;
|
||||
}
|
||||
return value.map(quickFix => typeConverters.Command.to(quickFix.command));
|
||||
});
|
||||
}
|
||||
|
||||
private _executeCodeLensProvider(resource: URI): Thenable<vscode.CodeLens[]>{
|
||||
const args = { resource };
|
||||
return this._commands.executeCommand<ICodeLensData[]>('_executeCodeLensProvider', args).then(value => {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(item => {
|
||||
return new types.CodeLens(typeConverters.toRange(item.symbol.range),
|
||||
typeConverters.Command.to(item.symbol.command));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _executeFormatDocumentProvider(resource: URI, options: vscode.FormattingOptions): Thenable<vscode.TextEdit[]> {
|
||||
const args = {
|
||||
resource,
|
||||
options
|
||||
};
|
||||
return this._commands.executeCommand<ISingleEditOperation[]>('_executeFormatDocumentProvider', args).then(value => {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(edit => new types.TextEdit(typeConverters.toRange(edit.range), edit.text));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _executeFormatRangeProvider(resource: URI, range: types.Range, options: vscode.FormattingOptions): Thenable<vscode.TextEdit[]> {
|
||||
const args = {
|
||||
resource,
|
||||
range: typeConverters.fromRange(range),
|
||||
options
|
||||
};
|
||||
return this._commands.executeCommand<ISingleEditOperation[]>('_executeFormatRangeProvider', args).then(value => {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(edit => new types.TextEdit(typeConverters.toRange(edit.range), edit.text));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _executeFormatOnTypeProvider(resource: URI, position: types.Position, ch:string, options: vscode.FormattingOptions): Thenable<vscode.TextEdit[]> {
|
||||
const args = {
|
||||
resource,
|
||||
position: typeConverters.fromPosition(position),
|
||||
ch,
|
||||
options
|
||||
};
|
||||
return this._commands.executeCommand<ISingleEditOperation[]>('_executeFormatOnTypeProvider', args).then(value => {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(edit => new types.TextEdit(typeConverters.toRange(edit.range), edit.text));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -147,6 +147,7 @@
|
|||
'platform': remote.process.platform,
|
||||
'enableTasks': hasWorkspaceContext,
|
||||
'enableJavaScriptRewriting': true,
|
||||
'enableSendASmile' : !!configuration.sendASmile,
|
||||
'enableTypeScriptServiceMode': true || !process.env['VSCODE_TSWORKER'],
|
||||
'enableTypeScriptServiceModeForJS': !!process.env['CODE_TSJS']
|
||||
};
|
||||
|
|
|
@ -50,6 +50,11 @@ export interface IProductConfiguration {
|
|||
key: string;
|
||||
asimovKey: string;
|
||||
},
|
||||
sendASmile: {
|
||||
submitUrl: string,
|
||||
reportIssueUrl: string,
|
||||
requestFeatureUrl: string
|
||||
},
|
||||
documentationUrl: string,
|
||||
releaseNotesUrl: string,
|
||||
twitterUrl: string,
|
||||
|
|
|
@ -116,6 +116,11 @@ export interface IWindowConfiguration extends env.ICommandLineArguments {
|
|||
aiConfig: {
|
||||
key: string;
|
||||
asimovKey: string;
|
||||
},
|
||||
sendASmile: {
|
||||
submitUrl: string,
|
||||
reportIssueUrl: string,
|
||||
requestFeatureUrl: string
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -554,6 +554,7 @@ export class WindowsManager {
|
|||
configuration.updateChannel = UpdateManager.channel;
|
||||
configuration.recentPaths = this.getRecentlyOpenedPaths(workspacePath, filesToOpen);
|
||||
configuration.aiConfig = env.product.aiConfig;
|
||||
configuration.sendASmile = env.product.sendASmile;
|
||||
configuration.enableTelemetry = env.product.enableTelemetry;
|
||||
configuration.userEnv = userEnv;
|
||||
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/debug.contribution';
|
||||
import nls = require('vs/nls');
|
||||
import { CommonEditorRegistry, ContextKey, EditorActionDescriptor } from 'vs/editor/common/editorCommonExtensions';
|
||||
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import platform = require('vs/platform/platform');
|
||||
import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { IKeybindings } from 'vs/platform/keybinding/common/keybindingService';
|
||||
import { EditorBrowserRegistry } from 'vs/editor/browser/editorBrowserExtensions';
|
||||
import wbaregistry = require('vs/workbench/browser/actionRegistry');
|
||||
import actionbarregistry = require('vs/workbench/browser/actionBarRegistry');
|
||||
import viewlet = require('vs/workbench/browser/viewlet');
|
||||
import wbext = require('vs/workbench/common/contributions');
|
||||
import baseeditor = require('vs/workbench/browser/parts/editor/baseEditor');
|
||||
import * as debug from 'vs/workbench/parts/debug/common/debug';
|
||||
import { DebugEditorModelManager } from 'vs/workbench/parts/debug/browser/debugEditorModelManager'
|
||||
import dbgactions = require('vs/workbench/parts/debug/browser/debugActions');
|
||||
import editorinputs = require('vs/workbench/parts/debug/browser/debugEditorInputs');
|
||||
import repleditor = require('vs/workbench/parts/debug/browser/replEditor');
|
||||
import debugwidget = require('vs/workbench/parts/debug/browser/debugActionsWidget');
|
||||
import { DebugEditorContribution } from 'vs/workbench/parts/debug/browser/debugEditorContribution';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/common/viewletService';
|
||||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
|
||||
import IDebugService = debug.IDebugService;
|
||||
|
||||
class OpenDebugViewletAction extends viewlet.ToggleViewletAction {
|
||||
public static ID = debug.VIEWLET_ID;
|
||||
public static LABEL = nls.localize('toggleDebugViewlet', "Show Debug");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IViewletService viewletService: IViewletService,
|
||||
@IWorkbenchEditorService editorService: IWorkbenchEditorService
|
||||
) {
|
||||
super(id, label, debug.VIEWLET_ID, viewletService, editorService);
|
||||
}
|
||||
}
|
||||
|
||||
EditorBrowserRegistry.registerEditorContribution(DebugEditorContribution);
|
||||
CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(dbgactions.ToggleBreakpointAction, dbgactions.ToggleBreakpointAction.ID, nls.localize('toggleBreakpointAction', "Debug: Toggle Breakpoint"), {
|
||||
context: ContextKey.EditorTextFocus,
|
||||
primary: KeyCode.F9
|
||||
}));
|
||||
CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(dbgactions.SelectionToReplAction, dbgactions.SelectionToReplAction.ID, nls.localize('debugEvaluate', "Debug: Evaluate")));
|
||||
CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(dbgactions.SelectionToWatchExpressionsAction, dbgactions.SelectionToWatchExpressionsAction.ID, nls.localize('addToWatch', "Debug: Add to Watch")));
|
||||
CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(dbgactions.RunToCursorAction, dbgactions.RunToCursorAction.ID, nls.localize('runToCursor', "Debug: Run to Cursor")));
|
||||
|
||||
// Register Viewlet
|
||||
(<viewlet.IViewletRegistry>platform.Registry.as(viewlet.Extensions.Viewlets)).registerViewlet(new viewlet.ViewletDescriptor(
|
||||
'vs/workbench/parts/debug/browser/debugViewlet',
|
||||
'DebugViewlet',
|
||||
debug.VIEWLET_ID,
|
||||
nls.localize('debug', "Debug"),
|
||||
'debug',
|
||||
40
|
||||
));
|
||||
|
||||
var openViewletKb: IKeybindings = {
|
||||
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_D
|
||||
};
|
||||
|
||||
// Register repl editor
|
||||
platform.Registry.as(baseeditor.Extensions.Editors).registerEditor(
|
||||
new baseeditor.EditorDescriptor(repleditor.Repl.ID, 'Repl', 'vs/workbench/parts/debug/browser/replEditor', 'Repl'),
|
||||
new SyncDescriptor(editorinputs.ReplEditorInput));
|
||||
|
||||
let actionBarRegistry = <actionbarregistry.IActionBarRegistry> platform.Registry.as(actionbarregistry.Extensions.Actionbar);
|
||||
actionBarRegistry.registerActionBarContributor(actionbarregistry.Scope.EDITOR, repleditor.ReplEditorActionContributor);
|
||||
(<baseeditor.IEditorRegistry>platform.Registry.as(baseeditor.Extensions.Editors)).registerEditorInputFactory(editorinputs.ReplEditorInput.ID, repleditor.ReplInputFactory);
|
||||
|
||||
// Register Action to Open Viewlet
|
||||
var registry = (<wbaregistry.IWorkbenchActionRegistry> platform.Registry.as(wbaregistry.Extensions.WorkbenchActions));
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenDebugViewletAction, OpenDebugViewletAction.ID, OpenDebugViewletAction.LABEL, openViewletKb), nls.localize('view', "View"));
|
||||
|
||||
(<wbext.IWorkbenchContributionsRegistry>platform.Registry.as(wbext.Extensions.Workbench)).registerWorkbenchContribution(DebugEditorModelManager);
|
||||
(<wbext.IWorkbenchContributionsRegistry>platform.Registry.as(wbext.Extensions.Workbench)).registerWorkbenchContribution(debugwidget.DebugActionsWidget);
|
||||
|
||||
var debugCategory = nls.localize('debugCategory', "Debug");
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(
|
||||
dbgactions.StartDebugAction, dbgactions.StartDebugAction.ID, dbgactions.StartDebugAction.LABEL, { primary: KeyCode.F5 }, [{ key: debug.CONTEXT_IN_DEBUG_MODE, operator: KeybindingsRegistry.KEYBINDING_CONTEXT_OPERATOR_NOT_EQUAL, operand: true }]), debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(dbgactions.StepOverDebugAction, dbgactions.StepOverDebugAction.ID, dbgactions.StepOverDebugAction.LABEL, { primary: KeyCode.F10 }, [{ key: debug.CONTEXT_IN_DEBUG_MODE }]), debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(dbgactions.StepIntoDebugAction, dbgactions.StepIntoDebugAction.ID, dbgactions.StepIntoDebugAction.LABEL, { primary: KeyCode.F11 }, [{ key: debug.CONTEXT_IN_DEBUG_MODE }], KeybindingsRegistry.WEIGHT.workbenchContrib(1)), debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(dbgactions.StepOutDebugAction, dbgactions.StepOutDebugAction.ID, dbgactions.StepOutDebugAction.LABEL, { primary: KeyMod.Shift | KeyCode.F11 }, [{ key: debug.CONTEXT_IN_DEBUG_MODE }]), debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(dbgactions.RestartDebugAction, dbgactions.RestartDebugAction.ID, dbgactions.RestartDebugAction.LABEL), debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(dbgactions.StopDebugAction, dbgactions.StopDebugAction.ID, dbgactions.StopDebugAction.LABEL, { primary: KeyMod.Shift | KeyCode.F5 }, [{ key: debug.CONTEXT_IN_DEBUG_MODE }]), debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(dbgactions.ContinueAction, dbgactions.ContinueAction.ID, dbgactions.ContinueAction.LABEL, { primary: KeyCode.F5 }, [{ key: debug.CONTEXT_IN_DEBUG_MODE }]), debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(dbgactions.PauseAction, dbgactions.PauseAction.ID, dbgactions.PauseAction.LABEL), debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(dbgactions.ConfigureAction, dbgactions.ConfigureAction.ID, dbgactions.ConfigureAction.LABEL), debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(dbgactions.OpenReplAction, dbgactions.OpenReplAction.ID, dbgactions.OpenReplAction.LABEL), debugCategory);
|
|
@ -1 +0,0 @@
|
|||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><g fill="#007ACC"><circle cx="8" cy="8" r="5"/></g></g></svg>
|
Before Width: | Height: | Size: 179 B |
291
src/vs/workbench/parts/feedback/browser/feedback.ts
Normal file
|
@ -0,0 +1,291 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./media/feedback';
|
||||
import nls = require('vs/nls');
|
||||
import types = require('vs/base/common/types');
|
||||
import {IDisposable} from 'vs/base/common/lifecycle';
|
||||
import {Builder, $} from 'vs/base/browser/builder';
|
||||
import errors = require('vs/base/common/errors');
|
||||
import DOM = require('vs/base/browser/dom');
|
||||
import {Promise} from 'vs/base/common/winjs.base';
|
||||
import {Dropdown} from 'vs/base/browser/ui/dropdown/dropdown';
|
||||
import {IXHRResponse} from 'vs/base/common/http';
|
||||
import {IContextViewService, IContextMenuService} from 'vs/platform/contextview/browser/contextView';
|
||||
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
|
||||
|
||||
const STATUS_TIMEOUT = 500;
|
||||
|
||||
export interface IFeedback {
|
||||
feedback: string;
|
||||
alias: string;
|
||||
sentiment: number;
|
||||
}
|
||||
|
||||
export interface IFeedbackService {
|
||||
submitFeedback(feedback: IFeedback): Promise;
|
||||
}
|
||||
|
||||
export interface IFeedbackDropdownOptions {
|
||||
contextViewProvider: IContextViewService;
|
||||
feedbackService?: IFeedbackService;
|
||||
}
|
||||
|
||||
enum FormEvent {
|
||||
SENDING,
|
||||
SENT,
|
||||
SEND_ERROR
|
||||
};
|
||||
|
||||
export class FeedbackDropdown extends Dropdown {
|
||||
|
||||
protected feedback: string;
|
||||
protected alias: string;
|
||||
protected sentiment: number;
|
||||
protected aliasEnabled: boolean;
|
||||
protected isSendingFeedback: boolean;
|
||||
protected autoHideTimeout: number;
|
||||
|
||||
protected feedbackService: IFeedbackService;
|
||||
|
||||
protected feedbackForm: HTMLFormElement;
|
||||
protected feedbackDescriptionInput: HTMLTextAreaElement;
|
||||
protected feedbackAliasInput: HTMLInputElement;
|
||||
protected smileyInput: Builder;
|
||||
protected frownyInput: Builder;
|
||||
protected sendButton: Builder;
|
||||
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
options: IFeedbackDropdownOptions,
|
||||
@ITelemetryService protected telemetryService: ITelemetryService
|
||||
) {
|
||||
super(container, {
|
||||
contextViewProvider: options.contextViewProvider,
|
||||
labelRenderer: (container: HTMLElement): IDisposable => {
|
||||
$(container).addClass('send-feedback');
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
this.$el.addClass('send-feedback');
|
||||
this.$el.title(nls.localize('sendFeedback', "Send Feedback"));
|
||||
|
||||
this.feedbackService = options.feedbackService;
|
||||
|
||||
this.feedback = '';
|
||||
this.alias = '';
|
||||
this.aliasEnabled = false;
|
||||
this.sentiment = 1;
|
||||
|
||||
this.feedbackForm = null;
|
||||
this.feedbackDescriptionInput = null;
|
||||
this.feedbackAliasInput = null;
|
||||
|
||||
this.smileyInput = null;
|
||||
this.frownyInput = null;
|
||||
|
||||
this.sendButton = null;
|
||||
}
|
||||
|
||||
public renderContents(container: HTMLElement): IDisposable {
|
||||
let $form = $('form.feedback-form').attr({
|
||||
action: 'javascript:void(0);',
|
||||
tabIndex: '-1'
|
||||
}).appendTo(container);
|
||||
|
||||
$(container).addClass('monaco-menu-container');
|
||||
|
||||
this.feedbackForm = <HTMLFormElement>$form.getHTMLElement();
|
||||
|
||||
$('h2.title').text(nls.localize("label.sendASmile", "Let us know how we're doing")).appendTo($form);
|
||||
|
||||
this.invoke($('div.cancel'), () => {
|
||||
this.hide();
|
||||
}).appendTo($form);
|
||||
|
||||
$('h3').text(nls.localize("sentiment", "How was your experience?")).appendTo($form);
|
||||
|
||||
let $feedbackSentiment = $('div.feedback-sentiment').appendTo($form);
|
||||
|
||||
|
||||
this.smileyInput = $('div').addClass('sentiment smile').attr({
|
||||
'aria-checked': 'false',
|
||||
'aria-label': nls.localize('smileCaption', "Happy"),
|
||||
'tabindex': 0,
|
||||
'role': 'checkbox'
|
||||
});
|
||||
this.invoke(this.smileyInput, () => { this.setSentiment(true); }).appendTo($feedbackSentiment);
|
||||
|
||||
this.frownyInput = $('div').addClass('sentiment frown').attr({
|
||||
'aria-checked': 'false',
|
||||
'aria-label': nls.localize('frownCaption', "Sad"),
|
||||
'tabindex': 0,
|
||||
'role': 'checkbox'
|
||||
});
|
||||
|
||||
this.invoke(this.frownyInput, () => { this.setSentiment(false); }).appendTo($feedbackSentiment);
|
||||
|
||||
if (this.sentiment === 1) {
|
||||
this.smileyInput.addClass('checked').attr('aria-checked', 'true');
|
||||
} else {
|
||||
this.frownyInput.addClass('checked').attr('aria-checked', 'true');
|
||||
}
|
||||
|
||||
$('h3').text(nls.localize("commentsHeader", "Comments")).appendTo($form);
|
||||
|
||||
this.feedbackDescriptionInput = <HTMLTextAreaElement>$('textarea.feedback-description').attr({
|
||||
rows: 8,
|
||||
'aria-label': nls.localize("commentsHeader", "Comments")
|
||||
})
|
||||
.text(this.feedback).attr('required', 'required')
|
||||
.on('keyup', () => {
|
||||
this.feedbackDescriptionInput.value ? this.sendButton.removeAttribute('disabled') : this.sendButton.attr('disabled', '');
|
||||
})
|
||||
.appendTo($form).domFocus().getHTMLElement();
|
||||
|
||||
let aliasHeaderText = nls.localize('aliasHeader', "Add e-mail address");
|
||||
|
||||
this.feedbackAliasInput = <HTMLInputElement>$('input.feedback-alias')
|
||||
.type('text')
|
||||
.text(aliasHeaderText)
|
||||
.attr('type', 'email')
|
||||
.attr('placeholder', nls.localize('aliasPlaceholder', "Optional e-mail address"))
|
||||
.value(this.alias)
|
||||
.attr('aria-label', aliasHeaderText)
|
||||
.appendTo($form)
|
||||
.getHTMLElement();
|
||||
|
||||
let $buttons = $('div.form-buttons').appendTo($form);
|
||||
|
||||
this.sendButton = this.invoke($('input.send').type('submit').attr('disabled', '').value(nls.localize('send', "Send")).appendTo($buttons), () => {
|
||||
if (this.isSendingFeedback) {
|
||||
return;
|
||||
}
|
||||
this.onSubmit().then(null, function() { });
|
||||
});
|
||||
|
||||
return {
|
||||
dispose: () => {
|
||||
this.feedbackForm = null;
|
||||
this.feedbackDescriptionInput = null;
|
||||
this.feedbackAliasInput = null;
|
||||
this.smileyInput = null;
|
||||
this.frownyInput = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected setSentiment(smile: boolean): void {
|
||||
if (smile) {
|
||||
this.smileyInput.addClass('checked');
|
||||
this.smileyInput.attr('aria-checked', 'true');
|
||||
this.frownyInput.removeClass('checked');
|
||||
this.frownyInput.attr('aria-checked', 'false');
|
||||
} else {
|
||||
this.frownyInput.addClass('checked');
|
||||
this.frownyInput.attr('aria-checked', 'true');
|
||||
this.smileyInput.removeClass('checked');
|
||||
this.smileyInput.attr('aria-checked', 'false');
|
||||
}
|
||||
this.sentiment = smile ? 1 : 0;
|
||||
}
|
||||
|
||||
protected invoke(element: Builder, callback: () => void): Builder {
|
||||
element.on('click', callback);
|
||||
element.on('keypress', (e) => {
|
||||
if (e instanceof KeyboardEvent) {
|
||||
let keyboardEvent = <KeyboardEvent>e;
|
||||
if (keyboardEvent.keyCode === 13 || keyboardEvent.keyCode === 32) { // Enter or Spacebar
|
||||
callback();
|
||||
}
|
||||
}
|
||||
});
|
||||
return element;
|
||||
}
|
||||
|
||||
public hide(): void {
|
||||
if (this.feedbackDescriptionInput) {
|
||||
this.feedback = this.feedbackDescriptionInput.value;
|
||||
}
|
||||
|
||||
if (this.feedbackAliasInput) {
|
||||
this.alias = this.feedbackAliasInput.value;
|
||||
}
|
||||
|
||||
if (this.autoHideTimeout) {
|
||||
clearTimeout(this.autoHideTimeout);
|
||||
this.autoHideTimeout = null;
|
||||
}
|
||||
|
||||
super.hide();
|
||||
}
|
||||
|
||||
public onEvent(e: Event, activeElement: HTMLElement): void {
|
||||
if (e instanceof KeyboardEvent) {
|
||||
let keyboardEvent = <KeyboardEvent>e;
|
||||
if (keyboardEvent.keyCode === 27) { // Escape
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected onSubmit(): Promise {
|
||||
if ((this.feedbackForm.checkValidity && !this.feedbackForm.checkValidity())) {
|
||||
return Promise.as(null);
|
||||
}
|
||||
|
||||
this.changeFormStatus(FormEvent.SENDING);
|
||||
|
||||
return this.feedbackService.submitFeedback({
|
||||
feedback: this.feedbackDescriptionInput.value,
|
||||
alias: this.feedbackAliasInput.value,
|
||||
sentiment: this.sentiment
|
||||
}).then((response: IXHRResponse) => {
|
||||
setTimeout(() => { this.changeFormStatus(FormEvent.SENT); }, STATUS_TIMEOUT);
|
||||
return '';
|
||||
}, (xhr: IXHRResponse) => {
|
||||
setTimeout(() => { this.changeFormStatus(FormEvent.SEND_ERROR); }, STATUS_TIMEOUT);
|
||||
return Promise.wrapError(new errors.ConnectionError(xhr));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private changeFormStatus(event: FormEvent): void {
|
||||
switch (event) {
|
||||
case FormEvent.SENDING:
|
||||
this.isSendingFeedback = true;
|
||||
this.sendButton.setClass('send in-progress');
|
||||
this.sendButton.value(nls.localize('feedbackSending', "Sending..."));
|
||||
break;
|
||||
case FormEvent.SENT:
|
||||
this.isSendingFeedback = false;
|
||||
this.sendButton.setClass('send success').value(nls.localize('feedbackSent', "Thanks :)"));
|
||||
this.resetForm();
|
||||
this.autoHideTimeout = setTimeout(() => {
|
||||
this.hide();
|
||||
}, 1000);
|
||||
this.sendButton.off(['click', 'keypress']);
|
||||
this.invoke(this.sendButton, () => {
|
||||
this.hide();
|
||||
this.sendButton.off(['click', 'keypress']);
|
||||
});
|
||||
break;
|
||||
case FormEvent.SEND_ERROR:
|
||||
this.isSendingFeedback = false;
|
||||
this.sendButton.setClass('send error').value(nls.localize('feedbackSendingError', "Try again"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected resetForm(): void {
|
||||
this.feedbackDescriptionInput ? this.feedbackDescriptionInput.value = '' : null;
|
||||
this.feedbackAliasInput ? this.feedbackAliasInput.value = '' : null;
|
||||
this.sentiment = 1;
|
||||
this.aliasEnabled = false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="3 3 16 16" enable-background="new 3 3 16 16"><polygon fill="#C5C5C5" points="12.597,11.042 15.4,13.845 13.844,15.4 11.042,12.598 8.239,15.4 6.683,13.845 9.485,11.042 6.683,8.239 8.238,6.683 11.042,9.486 13.845,6.683 15.4,8.239"/></svg>
|
After Width: | Height: | Size: 307 B |
1
src/vs/workbench/parts/feedback/browser/media/close.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="3 3 16 16" enable-background="new 3 3 16 16"><polygon fill="#656565" points="12.597,11.042 15.4,13.845 13.844,15.4 11.042,12.598 8.239,15.4 6.683,13.845 9.485,11.042 6.683,8.239 8.238,6.683 11.042,9.486 13.845,6.683 15.4,8.239"/></svg>
|
After Width: | Height: | Size: 307 B |
399
src/vs/workbench/parts/feedback/browser/media/feedback.css
Normal file
|
@ -0,0 +1,399 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
.monaco-shell .feedback-form {
|
||||
width: 420px;
|
||||
top: 30px;
|
||||
right: 6px;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form h2 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: "Segoe WPC", "Segoe UI", "SFUIDisplay-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback";
|
||||
font-weight: normal;
|
||||
font-size: 1.8em;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form h3 {
|
||||
margin: 1em 0 0;
|
||||
padding: 0;
|
||||
font-weight: normal;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .content {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .content > div {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .content .contactus {
|
||||
padding: 10px;
|
||||
border: solid 1px #B4BABF;
|
||||
background-color: #EBF2F9;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.monaco-shell.vs-dark .feedback-form .content .contactus {
|
||||
border: solid 1px #44444C;
|
||||
background-color: #333337;
|
||||
}
|
||||
|
||||
|
||||
.monaco-shell .feedback-form .content .channels {
|
||||
margin-top: 5px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.monaco-shell .char-counter {
|
||||
padding-left: 3px;
|
||||
}
|
||||
|
||||
/* TODO @C5 review link color */
|
||||
.monaco-shell .feedback-form .content .channels a {
|
||||
color: #007ACC;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.monaco-shell.vs-dark .feedback-form .content .channels a {
|
||||
color: #75BEFF;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .feedback-alias, .monaco-shell .feedback-form .feedback-description {
|
||||
resize: none;
|
||||
font-size: 1.1em;
|
||||
margin: 6px 0 0;
|
||||
width: 100%;
|
||||
padding: 3px 2px;
|
||||
-webkit-box-sizing: border-box;
|
||||
-o-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-ms-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .feedback-empty {
|
||||
margin-top: .2em;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .feedback-alias-checkbox {
|
||||
display: inline-block;
|
||||
vertical-align: text-top;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .feedback-alias {
|
||||
height: 26px;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .feedback-alias:disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .cancel {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
margin: .5em 0 0 0;
|
||||
padding: .5em;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .form-buttons {
|
||||
margin-top: 18px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .send {
|
||||
padding: .5em 1.5em;
|
||||
font-size: 1.1em;
|
||||
margin: 0;
|
||||
width: 15%;
|
||||
-webkit-box-sizing: border-box;
|
||||
-o-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-ms-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
|
||||
-webkit-transition: width 200ms ease-out;
|
||||
transition: width 200ms ease-out;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .send.in-progress {
|
||||
width: 22%;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .send.success,
|
||||
.monaco-shell .feedback-form .send.error {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .feedback-sentiment span {
|
||||
color:rgb(111, 111, 111);
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .sentiment {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
display: inline-block;
|
||||
margin: .5em 0;
|
||||
cursor: pointer;
|
||||
|
||||
-webkit-box-sizing: border-box;
|
||||
-o-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-ms-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .sentiment:hover {
|
||||
background-color: #eaeaea;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .sentiment.checked {
|
||||
border: 1px solid #39F;
|
||||
}
|
||||
|
||||
/* Statusbar */
|
||||
.monaco-shell .statusbar-item > .dropdown.send-feedback {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.monaco-shell .statusbar-item > .dropdown.send-feedback:hover {
|
||||
background-color: rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
.monaco-shell .statusbar-item > .dropdown.send-feedback > .dropdown-label.send-feedback {
|
||||
background: url('smiley.svg') center center no-repeat;
|
||||
width: 26px;
|
||||
}
|
||||
|
||||
/* Theming */
|
||||
.monaco-shell.vs .feedback-form {
|
||||
color: black;
|
||||
background: #F6F6F6;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form h2 {
|
||||
color: #007ACC;
|
||||
}
|
||||
|
||||
.monaco-shell.vs .feedback-form h3 {
|
||||
color: #646465;
|
||||
}
|
||||
|
||||
|
||||
.monaco-shell.vs .feedback-form .feedback-alias, .monaco-shell.vs .feedback-form .feedback-description {
|
||||
font-family: inherit;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
|
||||
.monaco-shell.vs .feedback-form .cancel {
|
||||
background: url('close.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.monaco-shell.vs .feedback-form .cancel:hover {
|
||||
background-color: #eaeaea;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .form-buttons .send {
|
||||
background-color: #007ACC;
|
||||
color: white;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .form-buttons .send.in-progress,
|
||||
.monaco-shell .feedback-form .form-buttons .send:hover {
|
||||
background-color: #006BB3;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .form-buttons .send:disabled {
|
||||
pointer-events: none;
|
||||
cursor: not-allowed;
|
||||
opacity: .65;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .form-buttons .send.success {
|
||||
background-color: #2d883e;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .form-buttons .send.error {
|
||||
background-color: #E51400;
|
||||
}
|
||||
|
||||
.monaco-shell.vs-dark .feedback-form {
|
||||
background: #252526;
|
||||
box-shadow: 0 2px 8px #000;
|
||||
}
|
||||
|
||||
.monaco-shell.vs-dark .feedback-form h2 {
|
||||
color: #75BEFF;
|
||||
}
|
||||
|
||||
.monaco-shell.vs-dark .feedback-form h3 {
|
||||
font-weight: normal;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.monaco-shell.vs-dark .feedback-form .sentiment:hover {
|
||||
background-color: #1e1e1e;
|
||||
}
|
||||
|
||||
.monaco-shell.vs-dark .feedback-form .sentiment.checked {
|
||||
border-color: #75BEFF;
|
||||
}
|
||||
|
||||
.monaco-shell.vs-dark .feedback-form .feedback-alias, .monaco-shell.vs-dark .feedback-form .feedback-description {
|
||||
font-family: inherit;
|
||||
border: 1px solid transparent;
|
||||
background-color: #333337;
|
||||
color: #D4D4D4;
|
||||
}
|
||||
|
||||
.monaco-shell.vs-dark .feedback-form .cancel {
|
||||
background: url('close-dark.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.monaco-shell.vs-dark .feedback-form .cancel:hover {
|
||||
background-color: #1e1e1e;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .sentiment.smile {
|
||||
background-image: url('happy.svg');
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .sentiment.frown {
|
||||
background-image: url('sad.svg');
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .infotip {
|
||||
background-image: url('info.svg');
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
display: inline-block;
|
||||
vertical-align: text-bottom;
|
||||
box-sizing: border-box;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .privacyLink {
|
||||
float: left;
|
||||
color: #007ACC !Important;
|
||||
}
|
||||
.monaco-shell.vs-dark .feedback-form .privacyLink {
|
||||
color: #75BEFF !Important;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .privacyLink:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* High Contrast Theming */
|
||||
.monaco-shell .hc-black .feedback-form {
|
||||
background-color: #0C141F;
|
||||
}
|
||||
|
||||
.monaco-shell.hc-black .feedback-form h2 {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.monaco-shell.hc-black .feedback-form .feedback-alias, .monaco-shell.hc-black .feedback-form .feedback-description {
|
||||
border: 1px solid #6FC3DF;
|
||||
background-color: #000;
|
||||
color: #D4D4D4;
|
||||
}
|
||||
|
||||
.monaco-shell.hc-black .feedback-form .content .contactus {
|
||||
padding: 10px;
|
||||
border: solid 1px #B4BABF;
|
||||
background-color: #0C141F;
|
||||
float: right;
|
||||
}
|
||||
.monaco-shell.hc-black .feedback-form .cancel {
|
||||
background: none;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.monaco-shell.hc-black .feedback-form .cancel:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.monaco-shell.hc-black .feedback-form .cancel:before {
|
||||
content: url('close-dark.svg');
|
||||
position: relative;
|
||||
top: 4px;
|
||||
left: 6px;
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.monaco-shell.hc-black .feedback-form .form-buttons .send,
|
||||
.monaco-shell.hc-black .feedback-form .form-buttons .send.in-progress,
|
||||
.monaco-shell.hc-black .feedback-form .form-buttons .send.success {
|
||||
background-color: #0C141F;
|
||||
color: #D4D4D4;
|
||||
border: 1px solid #6FC3DF;
|
||||
}
|
||||
|
||||
.monaco-shell.hc-black .feedback-form .form-buttons .send:hover {
|
||||
background-color: #0C141F;
|
||||
}
|
||||
|
||||
.monaco-shell.hc-black .feedback-form .sentiment {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.monaco-shell.hc-black .feedback-form .sentiment.checked {
|
||||
border: 1px solid #DF740C;
|
||||
}
|
||||
|
||||
.monaco-shell.hc-black .feedback-form .sentiment:before {
|
||||
height: 21px;
|
||||
width: 21px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: 4px;
|
||||
left: 4px;
|
||||
}
|
||||
|
||||
.monaco-shell.hc-black .feedback-form .sentiment.smile:before {
|
||||
content: url('happy.svg');
|
||||
}
|
||||
|
||||
.monaco-shell.hc-black .feedback-form .sentiment.frown:before {
|
||||
content: url('sad.svg');
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .infotip {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.monaco-shell .feedback-form .infotip:before {
|
||||
content: url('info.svg');
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.monaco-shell.hc-black .feedback-form .privacyLink {
|
||||
color: white !Important;
|
||||
}
|
1
src/vs/workbench/parts/feedback/browser/media/happy.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 16 16" enable-background="new 0 0 16 16"><g><path fill="#fc0" d="M8 1c-3.866 0-7 3.134-7 7s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7z"/><path fill="#424242" d="M11 6.5c0 .5-.447.5-1 .5s-1 0-1-.5c0-1.104 1-1.5 1-1.5s1 .396 1 1.5z"/><path fill="#424242" d="M10.943 9.025c-.457 1.177-1.644 2.058-2.943 2.058s-2.455-.881-2.899-2.058h-.952c.455 1.709 1.999 2.975 3.851 2.975 1.853 0 3.396-1.266 3.851-2.975h-.908z"/><path fill="#424242" d="M7 6.5s-.447.5-1 .5-1 0-1-.5c0-1.104 1-1.5 1-1.5s1 .396 1 1.5z"/></g></svg>
|
After Width: | Height: | Size: 580 B |
1
src/vs/workbench/parts/feedback/browser/media/info.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M8 1c-3.865 0-7 3.135-7 7s3.135 7 7 7 7-3.135 7-7-3.135-7-7-7zm1 12h-2v-7h2v7zm0-8h-2v-2h2v2z" fill="#1BA1E2"/><path d="M7 6h2v7h-2v-7zm0-1h2v-2h-2v2z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 243 B |
1
src/vs/workbench/parts/feedback/browser/media/sad.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 16 16" enable-background="new 0 0 16 16"><g><circle fill="#fc0" cx="8" cy="8" r="7"/><path fill="#424242" d="M10.973 6.5c0 .5-.447.5-1 .5s-1 0-1-.5c0-1.104 1-1.5 1-1.5s1 .396 1 1.5z"/><path fill="#424242" d="M6.973 6.5c0 .5-.447.5-1 .5s-1 0-1-.5c0-1.104 1-1.5 1-1.5s1 .396 1 1.5z"/><path fill="#424242" d="M5.104 12c.459-1.146 1.593-2 2.869-2 1.277 0 2.439.854 2.912 2h.916c-.475-1.678-1.998-2.917-3.828-2.917s-3.355 1.239-3.83 2.917h.961z"/></g></svg>
|
After Width: | Height: | Size: 528 B |
1
src/vs/workbench/parts/feedback/browser/media/smiley.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#fff" d="M8 1c-3.866 0-7 3.134-7 7s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7zm2.45 2.8c.58 0 1.05.627 1.05 1.4 0 .773-.47 1.4-1.05 1.4-.58 0-1.05-.627-1.05-1.4 0-.773.47-1.4 1.05-1.4zm-4.9 0c.58 0 1.05.627 1.05 1.4 0 .773-.47 1.4-1.05 1.4s-1.05-.627-1.05-1.4c0-.773.47-1.4 1.05-1.4zm6.901 5.775c-.668 1.884-2.456 3.15-4.451 3.15-1.995 0-3.784-1.266-4.451-3.149-.097-.273.046-.573.319-.67.275-.097.574.047.67.32.519 1.465 1.91 2.45 3.461 2.45s2.941-.984 3.461-2.45c.097-.273.4-.417.67-.32.274.096.418.396.321.669z"/></svg>
|
After Width: | Height: | Size: 590 B |
|
@ -0,0 +1,19 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import {Registry} from 'vs/platform/platform';
|
||||
import * as Flags from 'vs/base/common/flags';
|
||||
import {StatusbarAlignment, IStatusbarRegistry, Extensions, StatusbarItemDescriptor} from 'vs/workbench/browser/parts/statusbar/statusbar';
|
||||
import {FeedbackStatusbarItem} from 'vs/workbench/parts/feedback/electron-browser/feedback';
|
||||
|
||||
// Register Statusbar item
|
||||
if (Flags.enableSendASmile) {
|
||||
(<IStatusbarRegistry>Registry.as(Extensions.Statusbar)).registerStatusbarItem(new StatusbarItemDescriptor(
|
||||
FeedbackStatusbarItem,
|
||||
StatusbarAlignment.RIGHT,
|
||||
-100 /* Low Priority */
|
||||
));
|
||||
}
|
251
src/vs/workbench/parts/feedback/electron-browser/feedback.ts
Normal file
|
@ -0,0 +1,251 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import nls = require('vs/nls');
|
||||
import pal = require('vs/base/common/platform');
|
||||
import {Promise} from 'vs/base/common/winjs.base';
|
||||
import {IDisposable} from 'vs/base/common/lifecycle';
|
||||
import {$} from 'vs/base/browser/builder';
|
||||
import {IStatusbarItem} from 'vs/workbench/browser/parts/statusbar/statusbar';
|
||||
import {FeedbackDropdown, IFeedback, IFeedbackService, IFeedbackDropdownOptions} from 'vs/workbench/parts/feedback/browser/feedback';
|
||||
import {IContextViewService} from 'vs/platform/contextview/browser/contextView';
|
||||
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
|
||||
import {IRequestService} from 'vs/platform/request/common/request';
|
||||
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
|
||||
import {IWorkspaceContextService} from 'vs/workbench/services/workspace/common/contextService';
|
||||
|
||||
import os = require('os');
|
||||
|
||||
class NativeFeedbackService implements IFeedbackService {
|
||||
|
||||
private serviceUrl: string;
|
||||
private appName: string;
|
||||
private appVersion: string;
|
||||
|
||||
constructor(
|
||||
@IRequestService private requestService: IRequestService,
|
||||
@IWorkspaceContextService private contextService: IWorkspaceContextService
|
||||
) {
|
||||
const env = contextService.getConfiguration().env;
|
||||
if (env.sendASmile) {
|
||||
this.serviceUrl = env.sendASmile.submitUrl;
|
||||
}
|
||||
|
||||
this.appName = env.appName;
|
||||
this.appVersion = env.version;
|
||||
}
|
||||
|
||||
public submitFeedback(feedback: IFeedback): Promise {
|
||||
let data = JSON.stringify({
|
||||
version: 1,
|
||||
user: feedback.alias,
|
||||
userType: 'External',
|
||||
text: feedback.feedback,
|
||||
source: 'Send a smile',
|
||||
sentiment: feedback.sentiment,
|
||||
tags: [
|
||||
{ type: 'product', value: this.appName },
|
||||
{ type: 'product-version', value: this.appVersion }
|
||||
]
|
||||
});
|
||||
|
||||
return this.requestService.makeRequest({
|
||||
type: 'POST',
|
||||
url: this.serviceUrl,
|
||||
data: data,
|
||||
headers: {
|
||||
'Content-Type': 'application/json; charset=utf8',
|
||||
'Content-Length': data.length
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class NativeFeedbackDropdown extends FeedbackDropdown {
|
||||
private static MAX_FEEDBACK_CHARS: number = 140;
|
||||
|
||||
private appVersion: string;
|
||||
private requestFeatureLink: string;
|
||||
private reportIssueLink: string;
|
||||
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
options: IFeedbackDropdownOptions,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@IWorkspaceContextService private contextService: IWorkspaceContextService
|
||||
) {
|
||||
super(container, options, telemetryService);
|
||||
|
||||
const env = contextService.getConfiguration().env;
|
||||
this.appVersion = env.version;
|
||||
this.requestFeatureLink = env.sendASmile.requestFeatureUrl;
|
||||
this.reportIssueLink = env.sendASmile.reportIssueUrl;
|
||||
}
|
||||
|
||||
public renderContents(container: HTMLElement): IDisposable {
|
||||
let $form = $('form.feedback-form').attr({
|
||||
action: 'javascript:void(0);',
|
||||
tabIndex: '-1'
|
||||
}).appendTo(container);
|
||||
|
||||
$(container).addClass('monaco-menu-container');
|
||||
|
||||
this.feedbackForm = <HTMLFormElement>$form.getHTMLElement();
|
||||
|
||||
$('h2.title').text(nls.localize("label.sendASmile", "Let us know how we're doing")).appendTo($form);
|
||||
|
||||
this.invoke($('div.cancel'), () => {
|
||||
this.hide();
|
||||
}).appendTo($form);
|
||||
|
||||
let $content = $('div.content').appendTo($form);
|
||||
|
||||
let $sentimentContainer = $('div').appendTo($content);
|
||||
$('span').text(nls.localize("sentiment", "How was your experience?")).appendTo($sentimentContainer);
|
||||
|
||||
let $feedbackSentiment = $('div.feedback-sentiment').appendTo($sentimentContainer);
|
||||
|
||||
|
||||
this.smileyInput = $('div').addClass('sentiment smile').attr({
|
||||
'aria-checked': 'false',
|
||||
'aria-label': nls.localize('smileCaption', "Happy"),
|
||||
'tabindex': 0,
|
||||
'role': 'checkbox'
|
||||
});
|
||||
this.invoke(this.smileyInput, () => { this.setSentiment(true); }).appendTo($feedbackSentiment);
|
||||
|
||||
this.frownyInput = $('div').addClass('sentiment frown').attr({
|
||||
'aria-checked': 'false',
|
||||
'aria-label': nls.localize('frownCaption', "Sad"),
|
||||
'tabindex': 0,
|
||||
'role': 'checkbox'
|
||||
});
|
||||
|
||||
this.invoke(this.frownyInput, () => { this.setSentiment(false); }).appendTo($feedbackSentiment);
|
||||
|
||||
if (this.sentiment === 1) {
|
||||
this.smileyInput.addClass('checked').attr('aria-checked', 'true');
|
||||
} else {
|
||||
this.frownyInput.addClass('checked').attr('aria-checked', 'true');
|
||||
}
|
||||
|
||||
let $contactUs = $('div.contactus').appendTo($content);
|
||||
|
||||
$('span').text(nls.localize("other ways to contact us", "Other ways to contact us")).appendTo($contactUs);
|
||||
|
||||
let $contactUsContainer = $('div.channels').appendTo($contactUs);
|
||||
|
||||
$('div').append($('a').attr('target', '_blank').attr('href', this.getReportIssueLink()).text(nls.localize("submit a bug", "Submit a bug")))
|
||||
.appendTo($contactUsContainer);
|
||||
|
||||
$('div').append($('a').attr('target', '_blank').attr('href', this.requestFeatureLink).text(nls.localize("request a missing feature", "Request a missing feature")))
|
||||
.appendTo($contactUsContainer);
|
||||
|
||||
let $charCounter = $('span.char-counter').text('(' + NativeFeedbackDropdown.MAX_FEEDBACK_CHARS + ' ' + nls.localize("characters left", "characters left") + ')');
|
||||
|
||||
$('h3').text(nls.localize("tell us why?", "Tell us why?"))
|
||||
.append($charCounter)
|
||||
.appendTo($form);
|
||||
|
||||
this.feedbackDescriptionInput = <HTMLTextAreaElement>$('textarea.feedback-description').attr({
|
||||
rows: 3,
|
||||
maxlength: NativeFeedbackDropdown.MAX_FEEDBACK_CHARS,
|
||||
'aria-label': nls.localize("commentsHeader", "Comments")
|
||||
})
|
||||
.text(this.feedback).attr('required', 'required')
|
||||
.on('keyup', () => {
|
||||
$charCounter.text('(' + (NativeFeedbackDropdown.MAX_FEEDBACK_CHARS - this.feedbackDescriptionInput.value.length) + ' ' + nls.localize("characters left", "characters left") + ')');
|
||||
this.feedbackDescriptionInput.value ? this.sendButton.removeAttribute('disabled') : this.sendButton.attr('disabled', '');
|
||||
})
|
||||
.appendTo($form).domFocus().getHTMLElement();
|
||||
|
||||
let aliasHeaderText = nls.localize('aliasHeader', "Add e-mail address");
|
||||
|
||||
this.feedbackAliasInput = <HTMLInputElement>$('input.feedback-alias')
|
||||
.type('text')
|
||||
.text(aliasHeaderText)
|
||||
.attr('type', 'email')
|
||||
.attr('placeholder', nls.localize('aliasPlaceholder', "Optional e-mail address"))
|
||||
.value(this.alias)
|
||||
.attr('aria-label', aliasHeaderText)
|
||||
.appendTo($form)
|
||||
.getHTMLElement();
|
||||
|
||||
let $buttons = $('div.form-buttons').appendTo($form);
|
||||
|
||||
this.sendButton = this.invoke($('input.send').type('submit').attr('disabled', '').value(nls.localize('send', "Send")).appendTo($buttons), () => {
|
||||
if (this.isSendingFeedback) {
|
||||
return;
|
||||
}
|
||||
this.onSubmit().then(null, function() { });
|
||||
});
|
||||
|
||||
return {
|
||||
dispose: () => {
|
||||
this.feedbackForm = null;
|
||||
this.feedbackDescriptionInput = null;
|
||||
this.feedbackAliasInput = null;
|
||||
this.smileyInput = null;
|
||||
this.frownyInput = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private getReportIssueLink(): string {
|
||||
let reportIssueLink = this.reportIssueLink;
|
||||
let result = reportIssueLink + '&' + this.getReportIssuesQueryString() + '#vscode';
|
||||
return result;
|
||||
}
|
||||
|
||||
private getReportIssuesQueryString(): string {
|
||||
|
||||
let queryString: { [key: string]: any; } = Object.create(null);
|
||||
queryString['version'] = this.appVersion;
|
||||
let platform: number;
|
||||
switch (pal.platform) {
|
||||
case pal.Platform.Windows:
|
||||
platform = 3;
|
||||
break;
|
||||
case pal.Platform.Mac:
|
||||
platform = 2;
|
||||
break;
|
||||
case pal.Platform.Linux:
|
||||
platform = 1;
|
||||
break;
|
||||
default:
|
||||
platform = 0;
|
||||
}
|
||||
|
||||
queryString['platform'] = platform;
|
||||
queryString['osversion'] = os.release();
|
||||
queryString['sessionid'] = this.telemetryService.getSessionId();
|
||||
|
||||
let queryStringArray: string[] = [];
|
||||
for (let p in queryString) {
|
||||
queryStringArray.push(encodeURIComponent(p) + '=' + encodeURIComponent(queryString[p]));
|
||||
}
|
||||
|
||||
let result = queryStringArray.join('&');
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export class FeedbackStatusbarItem implements IStatusbarItem {
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IContextViewService private contextViewService: IContextViewService
|
||||
) {
|
||||
}
|
||||
|
||||
public render(element: HTMLElement): IDisposable {
|
||||
return this.instantiationService.createInstance(NativeFeedbackDropdown, element, {
|
||||
contextViewProvider: this.contextViewService,
|
||||
feedbackService: this.instantiationService.createInstance(NativeFeedbackService)
|
||||
});
|
||||
}
|
||||
}
|
|
@ -334,10 +334,6 @@ export class Model extends EventEmitter.EventEmitter implements Git.IModel {
|
|||
return this.repositoryRoot;
|
||||
}
|
||||
|
||||
public getRepositoryRoot(): string {
|
||||
return this.repositoryRoot;
|
||||
}
|
||||
|
||||
public getStatus(): Git.IStatusModel {
|
||||
return this.status;
|
||||
}
|
||||
|
|
|
@ -1,311 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import {setUnexpectedErrorHandler, errorHandler} from 'vs/base/common/errors';
|
||||
import {create} from 'vs/base/common/types';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import {TPromise} from 'vs/base/common/winjs.base';
|
||||
import {PluginHostDocument} from 'vs/workbench/api/common/pluginHostDocuments';
|
||||
import * as types from 'vs/workbench/api/common/pluginHostTypes';
|
||||
import {Range as CodeEditorRange} from 'vs/editor/common/core/range';
|
||||
import * as EditorCommon from 'vs/editor/common/editorCommon';
|
||||
import {Model as EditorModel} from 'vs/editor/common/model/model';
|
||||
import threadService from './testThreadService'
|
||||
import {create as createInstantiationService} from 'vs/platform/instantiation/common/instantiationService';
|
||||
import {MarkerService} from 'vs/platform/markers/common/markerService';
|
||||
import {IMarkerService} from 'vs/platform/markers/common/markers';
|
||||
import {IThreadService} from 'vs/platform/thread/common/thread';
|
||||
import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService';
|
||||
import {KeybindingsRegistry} from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import {IModelService} from 'vs/editor/common/services/modelService';
|
||||
import {ExtHostLanguageFeatures, MainThreadLanguageFeatures} from 'vs/workbench/api/common/extHostLanguageFeatures';
|
||||
import {ExtHostLanguageFeatureCommands} from 'vs/workbench/api/common/extHostLanguageFeatureCommands';
|
||||
import {PluginHostCommands, MainThreadCommands} from 'vs/workbench/api/common/pluginHostCommands';
|
||||
import {PluginHostModelService} from 'vs/workbench/api/common/pluginHostDocuments';
|
||||
import {SyncDescriptor0} from 'vs/platform/instantiation/common/descriptors';
|
||||
import {LanguageSelector} from 'vs/editor/common/modes/languageSelector';
|
||||
import {OutlineRegistry, getOutlineEntries} from 'vs/editor/contrib/quickOpen/common/quickOpen';
|
||||
import {CodeLensRegistry, getCodeLensData} from 'vs/editor/contrib/codelens/common/codelens';
|
||||
import {DeclarationRegistry, getDeclarationsAtPosition} from 'vs/editor/contrib/goToDeclaration/common/goToDeclaration';
|
||||
import {ExtraInfoRegistry, getExtraInfoAtPosition} from 'vs/editor/contrib/hover/common/hover';
|
||||
import {OccurrencesRegistry, getOccurrencesAtPosition} from 'vs/editor/contrib/wordHighlighter/common/wordHighlighter';
|
||||
import {ReferenceRegistry, findReferences} from 'vs/editor/contrib/referenceSearch/common/referenceSearch';
|
||||
import {getQuickFixes} from 'vs/editor/contrib/quickFix/common/quickFix';
|
||||
import {getNavigateToItems} from 'vs/workbench/parts/search/common/search';
|
||||
import {rename} from 'vs/editor/contrib/rename/common/rename';
|
||||
import {getParameterHints} from 'vs/editor/contrib/parameterHints/common/parameterHints';
|
||||
|
||||
const defaultSelector = { scheme: 'far' };
|
||||
const model: EditorCommon.IModel = new EditorModel(
|
||||
[
|
||||
'This is the first line',
|
||||
'This is the second line',
|
||||
'This is the third line',
|
||||
].join('\n'),
|
||||
undefined,
|
||||
URI.parse('far://testing/file.b'));
|
||||
|
||||
let extHost: ExtHostLanguageFeatures;
|
||||
let mainThread: MainThreadLanguageFeatures;
|
||||
let commands: PluginHostCommands;
|
||||
let disposables: vscode.Disposable[] = [];
|
||||
|
||||
suite('ExtHostLanguageFeatureCommands', function() {
|
||||
|
||||
suiteSetup(() => {
|
||||
|
||||
let instantiationService = createInstantiationService();
|
||||
threadService.setInstantiationService(instantiationService);
|
||||
instantiationService.addSingleton(IMarkerService, new MarkerService(threadService));
|
||||
instantiationService.addSingleton(IThreadService, threadService);
|
||||
instantiationService.addSingleton(IModelService, <IModelService> {
|
||||
serviceId: IModelService,
|
||||
getModel():any { return model; },
|
||||
createModel():any { throw new Error(); },
|
||||
destroyModel():any { throw new Error(); },
|
||||
getModels():any { throw new Error(); },
|
||||
onModelAdded: undefined,
|
||||
onModelModeChanged: undefined,
|
||||
onModelRemoved: undefined
|
||||
});
|
||||
instantiationService.addSingleton(IKeybindingService, <IKeybindingService>{
|
||||
executeCommand(id, args):any {
|
||||
let handler = KeybindingsRegistry.getCommands()[id];
|
||||
return TPromise.as(instantiationService.invokeFunction(handler, args));
|
||||
}
|
||||
})
|
||||
|
||||
threadService.getRemotable(PluginHostModelService)._acceptModelAdd({
|
||||
isDirty: false,
|
||||
versionId: model.getVersionId(),
|
||||
modeId: model.getModeId(),
|
||||
url: model.getAssociatedResource(),
|
||||
value: {
|
||||
EOL: model.getEOL(),
|
||||
lines: model.getValue().split(model.getEOL()),
|
||||
BOM: '',
|
||||
length: -1
|
||||
},
|
||||
});
|
||||
|
||||
threadService.getRemotable(MainThreadCommands);
|
||||
commands = threadService.getRemotable(PluginHostCommands);
|
||||
new ExtHostLanguageFeatureCommands(commands);
|
||||
mainThread = threadService.getRemotable(MainThreadLanguageFeatures);
|
||||
extHost = threadService.getRemotable(ExtHostLanguageFeatures);
|
||||
});
|
||||
|
||||
suiteTeardown(() => {
|
||||
model.dispose();
|
||||
});
|
||||
|
||||
teardown(function(done) {
|
||||
while (disposables.length) {
|
||||
disposables.pop().dispose();
|
||||
}
|
||||
threadService.sync()
|
||||
.then(() => done(), err => done(err));
|
||||
});
|
||||
|
||||
// --- workspace symbols
|
||||
|
||||
test('WorkspaceSymbols, invalid arguments', function(done) {
|
||||
let promises = [
|
||||
commands.executeCommand('vscode.executeWorkspaceSymbolProvider'),
|
||||
commands.executeCommand('vscode.executeWorkspaceSymbolProvider', null),
|
||||
commands.executeCommand('vscode.executeWorkspaceSymbolProvider', undefined),
|
||||
commands.executeCommand('vscode.executeWorkspaceSymbolProvider', true)
|
||||
];
|
||||
|
||||
threadService.sync().then(() => {
|
||||
TPromise.join(<any[]>promises).then(undefined, (err: any[]) => {
|
||||
assert.equal(err.length, 4);
|
||||
done();
|
||||
return [];
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('WorkspaceSymbols, ⇔ back and forth', function(done) {
|
||||
|
||||
disposables.push(extHost.registerWorkspaceSymbolProvider(<vscode.WorkspaceSymbolProvider>{
|
||||
provideWorkspaceSymbols(query): any {
|
||||
return [
|
||||
new types.SymbolInformation(query, types.SymbolKind.Array, new types.Range(0, 0, 1, 1), URI.parse('far://testing/first')),
|
||||
new types.SymbolInformation(query, types.SymbolKind.Array, new types.Range(0, 0, 1, 1), URI.parse('far://testing/second'))
|
||||
]
|
||||
}
|
||||
}));
|
||||
|
||||
disposables.push(extHost.registerWorkspaceSymbolProvider(<vscode.WorkspaceSymbolProvider>{
|
||||
provideWorkspaceSymbols(query): any {
|
||||
return [
|
||||
new types.SymbolInformation(query, types.SymbolKind.Array, new types.Range(0, 0, 1, 1), URI.parse('far://testing/first'))
|
||||
]
|
||||
}
|
||||
}));
|
||||
|
||||
threadService.sync().then(() => {
|
||||
commands.executeCommand<vscode.SymbolInformation[]>('vscode.executeWorkspaceSymbolProvider', 'testing').then(value => {
|
||||
|
||||
for (let info of value) {
|
||||
assert.ok(info instanceof types.SymbolInformation);
|
||||
assert.equal(info.name, 'testing');
|
||||
assert.equal(info.kind, types.SymbolKind.Array);
|
||||
}
|
||||
assert.equal(value.length, 3);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// --- definition
|
||||
|
||||
test('Definition, invalid arguments', function(done) {
|
||||
let promises = [
|
||||
commands.executeCommand('vscode.executeDefinitionProvider'),
|
||||
commands.executeCommand('vscode.executeDefinitionProvider', null),
|
||||
commands.executeCommand('vscode.executeDefinitionProvider', undefined),
|
||||
commands.executeCommand('vscode.executeDefinitionProvider', true, false)
|
||||
];
|
||||
|
||||
threadService.sync().then(() => {
|
||||
TPromise.join(<any[]>promises).then(undefined, (err: any[]) => {
|
||||
assert.equal(err.length, 4);
|
||||
done();
|
||||
return [];
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('Definition, ⇔ back and forth', function(done) {
|
||||
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
|
||||
provideDefinition(doc: any): any {
|
||||
return new types.Location(doc.uri, new types.Range(0, 0, 0, 0));
|
||||
}
|
||||
}));
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
|
||||
provideDefinition(doc: any): any {
|
||||
return [
|
||||
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
|
||||
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
|
||||
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
|
||||
]
|
||||
}
|
||||
}));
|
||||
|
||||
threadService.sync().then(() => {
|
||||
commands.executeCommand<vscode.Location[]>('vscode.executeDefinitionProvider', model.getAssociatedResource(), new types.Position(0, 0)).then(values => {
|
||||
assert.equal(values.length, 4);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// --- outline
|
||||
|
||||
test('Outline, back and forth', function(done) {
|
||||
disposables.push(extHost.registerDocumentSymbolProvider(defaultSelector, <vscode.DocumentSymbolProvider>{
|
||||
provideDocumentSymbols(): any {
|
||||
return [
|
||||
new types.SymbolInformation('testing1', types.SymbolKind.Enum, new types.Range(1, 0, 1, 0)),
|
||||
new types.SymbolInformation('testing2', types.SymbolKind.Enum, new types.Range(0, 1, 0, 3)),
|
||||
]
|
||||
}
|
||||
}));
|
||||
|
||||
threadService.sync().then(() => {
|
||||
commands.executeCommand<vscode.SymbolInformation[]>('vscode.executeDocumentSymbolProvider', model.getAssociatedResource()).then(values => {
|
||||
assert.equal(values.length, 2);
|
||||
let [first, second] = values;
|
||||
assert.equal(first.name, 'testing2');
|
||||
assert.equal(second.name, 'testing1');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// --- suggest
|
||||
|
||||
test('Suggest, back and forth', function(done) {
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
|
||||
provideCompletionItems(doc, pos): any {
|
||||
let a = new types.CompletionItem('item1');
|
||||
let b = new types.CompletionItem('item2');
|
||||
b.textEdit = types.TextEdit.replace(new types.Range(0, 0, 0, 4), 'foo');
|
||||
return [a, b];
|
||||
}
|
||||
}, []));
|
||||
|
||||
threadService.sync().then(() => {
|
||||
commands.executeCommand<vscode.CompletionItem[]>('vscode.executeCompletionItemProvider', model.getAssociatedResource(), new types.Position(0, 0)).then(values => {
|
||||
assert.equal(values.length, 2);
|
||||
let [first, second] = values;
|
||||
assert.equal(first.label, 'item1');
|
||||
assert.equal(first.textEdit.newText, 'item1');
|
||||
assert.equal(first.textEdit.range.start.line, 0);
|
||||
assert.equal(first.textEdit.range.start.character, 0);
|
||||
assert.equal(first.textEdit.range.end.line, 0);
|
||||
assert.equal(first.textEdit.range.end.character, 0);
|
||||
|
||||
assert.equal(second.label, 'item2');
|
||||
assert.equal(second.textEdit.newText, 'foo');
|
||||
assert.equal(second.textEdit.range.start.line, 0);
|
||||
assert.equal(second.textEdit.range.start.character, 0);
|
||||
assert.equal(second.textEdit.range.end.line, 0);
|
||||
assert.equal(second.textEdit.range.end.character, 4);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// --- quickfix
|
||||
|
||||
test('QuickFix, back and forth', function(done) {
|
||||
disposables.push(extHost.registerCodeActionProvider(defaultSelector, <vscode.CodeActionProvider>{
|
||||
provideCodeActions(): any {
|
||||
return [{ command: 'testing', title: 'Title', arguments: [1, 2, true] }];
|
||||
}
|
||||
}));
|
||||
|
||||
threadService.sync().then(() => {
|
||||
commands.executeCommand<vscode.Command[]>('vscode.executeCodeActionProvider', model.getAssociatedResource(), new types.Range(0, 0, 1, 1)).then(value => {
|
||||
assert.equal(value.length, 1);
|
||||
let [first] = value;
|
||||
assert.equal(first.title, 'Title');
|
||||
assert.equal(first.command, 'testing');
|
||||
assert.deepEqual(first.arguments, [1, 2, true]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// --- code lens
|
||||
|
||||
test('CodeLens, back and forth', function(done) {
|
||||
disposables.push(extHost.registerCodeLensProvider(defaultSelector, <vscode.CodeLensProvider>{
|
||||
provideCodeLenses(): any {
|
||||
return [new types.CodeLens(new types.Range(0, 0, 1, 1), { title: 'Title', command: 'cmd', arguments: [1, 2, true] })];
|
||||
}
|
||||
}));
|
||||
|
||||
threadService.sync().then(() => {
|
||||
commands.executeCommand<vscode.CodeLens[]>('vscode.executeCodeLensProvider', model.getAssociatedResource()).then(value => {
|
||||
assert.equal(value.length, 1);
|
||||
let [first] = value;
|
||||
|
||||
assert.equal(first.command.title, 'Title');
|
||||
assert.equal(first.command.command, 'cmd');
|
||||
assert.deepEqual(first.command.arguments, [1, 2, true]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -71,6 +71,8 @@ define([
|
|||
|
||||
'vs/workbench/parts/themes/electron-browser/themes.contribution',
|
||||
|
||||
'vs/workbench/parts/feedback/electron-browser/feedback.contribution',
|
||||
|
||||
'vs/workbench/electron-browser/main.contribution',
|
||||
'vs/workbench/electron-browser/main'
|
||||
|
||||
|
|