Fix last of merge issues

This commit is contained in:
David Storey 2015-12-12 01:04:08 -08:00
parent 206f9a84d2
commit 3b40a57b00
27 changed files with 988 additions and 729 deletions

View file

@ -3,4 +3,4 @@
"container": "debuggers",
"zip": "e6b9b29/node-debug.zip",
"output": ""
}
}

View file

@ -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[];
}

View file

@ -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[];
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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');

View file

@ -138,5 +138,11 @@ export interface IEnvironment {
aiConfig: {
key: string;
asimovKey: string;
},
sendASmile: {
submitUrl: string,
reportIssueUrl: string,
requestFeatureUrl: string
}
}

View file

@ -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));
}
});
}
}

View file

@ -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']
};

View file

@ -50,6 +50,11 @@ export interface IProductConfiguration {
key: string;
asimovKey: string;
},
sendASmile: {
submitUrl: string,
reportIssueUrl: string,
requestFeatureUrl: string
},
documentationUrl: string,
releaseNotesUrl: string,
twitterUrl: string,

View file

@ -116,6 +116,11 @@ export interface IWindowConfiguration extends env.ICommandLineArguments {
aiConfig: {
key: string;
asimovKey: string;
},
sendASmile: {
submitUrl: string,
reportIssueUrl: string,
requestFeatureUrl: string
}
}

View file

@ -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;

View file

@ -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);

View file

@ -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

View 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;
}
}

View 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="#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

View 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

View 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;
}

View 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

View 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

View 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

View 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

View file

@ -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 */
));
}

View 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)
});
}
}

View file

@ -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;
}

View file

@ -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();
});
});
});
});

View file

@ -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'