From ab684da7e7e379bfbb95eb3e481563e7b1ab7903 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Mon, 29 Jan 2018 09:29:23 -0800 Subject: [PATCH] "Report Issue" command opens issue reporter, fixes #42269 --- .../issue/issueReporterMain.ts | 3 +- src/vs/workbench/electron-browser/actions.ts | 112 +----------------- .../electron-browser/main.contribution.ts | 5 +- 3 files changed, 8 insertions(+), 112 deletions(-) diff --git a/src/vs/code/electron-browser/issue/issueReporterMain.ts b/src/vs/code/electron-browser/issue/issueReporterMain.ts index db9d07052d2..dcd203b2c51 100644 --- a/src/vs/code/electron-browser/issue/issueReporterMain.ts +++ b/src/vs/code/electron-browser/issue/issueReporterMain.ts @@ -391,7 +391,8 @@ export class IssueReporter extends Disposable { } const issueTitle = (document.getElementById('issue-title')).value; - const baseUrl = `https://github.com/microsoft/vscode/issues/new?title=${issueTitle}&body=`; + const queryStringPrefix = product.reportIssueUrl.indexOf('?') === -1 ? '?' : '&'; + const baseUrl = `${product.reportIssueUrl}${queryStringPrefix}title=${issueTitle}&body=`; const issueBody = this.issueReporterModel.serialize(); shell.openExternal(baseUrl + encodeURIComponent(issueBody)); return true; diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index 94d13e96a34..5b89b7de0ce 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -8,7 +8,6 @@ import 'vs/css!./media/actions'; import URI from 'vs/base/common/uri'; -import * as collections from 'vs/base/common/collections'; import { TPromise } from 'vs/base/common/winjs.base'; import { Action } from 'vs/base/common/actions'; import { IWindowService, IWindowsService, MenuBarVisibility } from 'vs/platform/windows/common/windows'; @@ -21,7 +20,7 @@ import { IMessageService, Severity } from 'vs/platform/message/common/message'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; -import { IExtensionManagementService, LocalExtensionType, ILocalExtension, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IExtensionManagementService, LocalExtensionType, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import paths = require('vs/base/common/paths'); import { isMacintosh, isLinux, language } from 'vs/base/common/platform'; @@ -46,7 +45,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IExtensionService, ActivationTimes } from 'vs/platform/extensions/common/extensions'; import { getEntries } from 'vs/base/common/performance'; import { IEditor } from 'vs/platform/editor/common/editor'; -import { IIssueService } from 'vs/platform/issue/common/issue'; +import { IIssueService, IssueReporterData } from 'vs/platform/issue/common/issue'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { textLinkForeground, inputBackground, inputBorder, inputForeground, buttonBackground, buttonHoverBackground, buttonForeground, inputValidationErrorBorder, foreground, inputActiveOptionBorder } from 'vs/platform/theme/common/colorRegistry'; import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme'; @@ -750,7 +749,7 @@ export class CloseMessagesAction extends Action { export class OpenIssueReporterAction extends Action { public static readonly ID = 'workbench.action.openIssueReporter'; - public static readonly LABEL = nls.localize('openIssueReporter', "Open Issue Reporter"); + public static readonly LABEL = nls.localize({ key: 'reportIssueInEnglish', comment: ['Translate this to "Report Issue in English" in all languages please!'] }, "Report Issue"); constructor( id: string, @@ -782,7 +781,7 @@ export class OpenIssueReporterAction extends Action { zoomLevel: webFrame.getZoomLevel(), extensions }; - const issueReporterData = { + const issueReporterData: IssueReporterData = { styles, zoomLevel: webFrame.getZoomLevel(), enabledExtensions @@ -795,109 +794,6 @@ export class OpenIssueReporterAction extends Action { } } -export class ReportIssueAction extends Action { - - public static readonly ID = 'workbench.action.reportIssues'; - public static readonly LABEL = nls.localize({ key: 'reportIssueInEnglish', comment: ['Translate this to "Report Issue in English" in all languages please!'] }, "Report Issue"); - - constructor( - id: string, - label: string, - @IIntegrityService private integrityService: IIntegrityService, - @IExtensionManagementService private extensionManagementService: IExtensionManagementService, - @IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService, - @IEnvironmentService private environmentService: IEnvironmentService - ) { - super(id, label); - } - - private _optimisticIsPure(): TPromise { - let isPure = true; - let integrityPromise = this.integrityService.isPure().then(res => { - isPure = res.isPure; - }); - - return TPromise.any([TPromise.timeout(100), integrityPromise]).then(() => { - return isPure; - }); - } - - public run(): TPromise { - return this._optimisticIsPure().then(isPure => { - return this.extensionManagementService.getInstalled(LocalExtensionType.User).then(extensions => { - extensions = extensions.filter(extension => this.extensionEnablementService.isEnabled(extension.identifier)); - const issueUrl = this.generateNewIssueUrl(product.reportIssueUrl, pkg.name, pkg.version, product.commit, product.date, isPure, extensions, this.environmentService.disableExtensions); - - window.open(issueUrl); - - return TPromise.as(true); - }); - }); - } - - private generateNewIssueUrl(baseUrl: string, name: string, version: string, commit: string, date: string, isPure: boolean, extensions: ILocalExtension[], areExtensionsDisabled: boolean): string { - // Avoid backticks, these can trigger XSS detectors. (https://github.com/Microsoft/vscode/issues/13098) - const osVersion = `${os.type()} ${os.arch()} ${os.release()}`; - const queryStringPrefix = baseUrl.indexOf('?') === -1 ? '?' : '&'; - const body = encodeURIComponent( - `
    -
  • VSCode Version: ${name} ${version}${isPure ? '' : ' **[Unsupported]**'} (${product.commit || 'Commit unknown'}, ${product.date || 'Date unknown'})
  • -
  • OS Version: ${osVersion}
  • -
  • ${areExtensionsDisabled ? 'Extensions: Extensions are disabled' : this.generateExtensionTable(extensions)}
  • -
- ---- - -Steps to Reproduce: - -1. -2.` + (extensions.length ? ` - - -Reproduces without extensions: Yes/No` : '') - ); - - return `${baseUrl}${queryStringPrefix}body=${body}`; - } - - private generateExtensionTable(extensions: ILocalExtension[]): string { - const { nonThemes, themes } = collections.groupBy(extensions, ext => { - const manifestKeys = ext.manifest.contributes ? Object.keys(ext.manifest.contributes) : []; - const onlyTheme = !ext.manifest.activationEvents && manifestKeys.length === 1 && manifestKeys[0] === 'themes'; - return onlyTheme ? 'themes' : 'nonThemes'; - }); - - const themeExclusionStr = (themes && themes.length) ? `\n(${themes.length} theme extensions excluded)` : ''; - extensions = nonThemes || []; - - if (!extensions.length) { - return 'Extensions: none' + themeExclusionStr; - } - - let tableHeader = `Extension|Author (truncated)|Version ----|---|---`; - const table = extensions.map(e => { - return `${e.manifest.name}|${e.manifest.publisher.substr(0, 3)}|${e.manifest.version}`; - }).join('\n'); - - const extensionTable = `
Extensions (${extensions.length}) - -${tableHeader} -${table} -${themeExclusionStr} - -
`; - - // 2000 chars is browsers de-facto limit for URLs, 400 chars are allowed for other string parts of the issue URL - // http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers - if (encodeURIComponent(extensionTable).length > 1600) { - return 'the listing length exceeds browsers\' URL characters limit'; - } - - return extensionTable; - } -} - export class ReportPerformanceIssueAction extends Action { public static readonly ID = 'workbench.action.reportPerformanceIssue'; diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index d72fb4e04e6..39b3f42fc1b 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -14,7 +14,7 @@ import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'v import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions'; import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes'; import { isWindows, isLinux, isMacintosh } from 'vs/base/common/platform'; -import { KeybindingsReferenceAction, OpenDocumentationUrlAction, OpenIntroductoryVideosUrlAction, OpenTipsAndTricksUrlAction, OpenIssueReporterAction, ReportIssueAction, ReportPerformanceIssueAction, ZoomResetAction, ZoomOutAction, ZoomInAction, ToggleFullScreenAction, ToggleMenuBarAction, CloseWorkspaceAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, CloseMessagesAction, NavigateUpAction, NavigateDownAction, NavigateLeftAction, NavigateRightAction, IncreaseViewSizeAction, DecreaseViewSizeAction, ShowStartupPerformance, ToggleSharedProcessAction, QuickSwitchWindow, QuickOpenRecentAction, inRecentFilesPickerContextKey, ConfigureLocaleAction } from 'vs/workbench/electron-browser/actions'; +import { KeybindingsReferenceAction, OpenDocumentationUrlAction, OpenIntroductoryVideosUrlAction, OpenTipsAndTricksUrlAction, OpenIssueReporterAction, ReportPerformanceIssueAction, ZoomResetAction, ZoomOutAction, ZoomInAction, ToggleFullScreenAction, ToggleMenuBarAction, CloseWorkspaceAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, CloseMessagesAction, NavigateUpAction, NavigateDownAction, NavigateLeftAction, NavigateRightAction, IncreaseViewSizeAction, DecreaseViewSizeAction, ShowStartupPerformance, ToggleSharedProcessAction, QuickSwitchWindow, QuickOpenRecentAction, inRecentFilesPickerContextKey, ConfigureLocaleAction } from 'vs/workbench/electron-browser/actions'; import { MessagesVisibleContext } from 'vs/workbench/electron-browser/workbench'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { registerCommands } from 'vs/workbench/electron-browser/commands'; @@ -46,9 +46,8 @@ if (isMacintosh) { } workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(CloseWorkspaceAction, CloseWorkspaceAction.ID, CloseWorkspaceAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_F) }), 'File: Close Workspace', fileCategory); -workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenIssueReporterAction, OpenIssueReporterAction.ID, OpenIssueReporterAction.LABEL), 'Help: Open Issue Reporter', helpCategory); if (!!product.reportIssueUrl) { - workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(ReportIssueAction, ReportIssueAction.ID, ReportIssueAction.LABEL), 'Help: Report Issues', helpCategory); + workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenIssueReporterAction, OpenIssueReporterAction.ID, OpenIssueReporterAction.LABEL), 'Help: Open Issue Reporter', helpCategory); workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(ReportPerformanceIssueAction, ReportPerformanceIssueAction.ID, ReportPerformanceIssueAction.LABEL), 'Help: Report Performance Issue', helpCategory); }