Merge from vscode 4d91d96e5e121b38d33508cdef17868bab255eae

This commit is contained in:
ADS Merger
2020-06-18 04:32:54 +00:00
committed by AzureDataStudio
parent a971aee5bd
commit 5e7071e466
1002 changed files with 24201 additions and 13193 deletions

View File

@@ -639,7 +639,7 @@ export class ExtensionEditor extends BaseEditor {
if (!link) {
return;
}
// Whitelist supported schemes for links
// Only allow links with specific schemes
if (matchesScheme(link, Schemas.http) || matchesScheme(link, Schemas.https) || matchesScheme(link, Schemas.mailto)
|| (matchesScheme(link, Schemas.command) && URI.parse(link).path === ShowCurrentReleaseNotesActionId)
) {

View File

@@ -38,7 +38,7 @@ const ignoredRecommendationsStorageKey = 'extensionsAssistant/ignored_recommenda
export class ExtensionRecommendationsService extends Disposable implements IExtensionRecommendationsService {
_serviceBrand: undefined;
declare readonly _serviceBrand: undefined;
// Recommendations
private readonly fileBasedRecommendations: FileBasedRecommendations;

View File

@@ -947,7 +947,7 @@ export class EnableGloballyAction extends ExtensionAction {
this.enabled = false;
if (this.extension && this.extension.local) {
this.enabled = this.extension.state === ExtensionState.Installed
&& this.extension.enablementState === EnablementState.DisabledGlobally
&& this.extensionEnablementService.isDisabledGlobally(this.extension.local)
&& this.extensionEnablementService.canChangeEnablement(this.extension.local);
}
}
@@ -2216,7 +2216,7 @@ export abstract class AbstractConfigureRecommendedExtensionsAction extends Actio
return this.jsonEditingService.write(workspaceConfigurationFile,
[{
key: 'extensions',
path: ['extensions'],
value: {
recommendations: shouldRecommend ? insertInto : removeFrom,
unwantedRecommendations: shouldRecommend ? removeFrom : insertInto
@@ -2245,7 +2245,7 @@ export abstract class AbstractConfigureRecommendedExtensionsAction extends Actio
removeFrom = removeFrom.filter(x => x.toLowerCase() !== extensionIdLowerCase);
removeFromPromise = this.jsonEditingService.write(extensionsFileResource,
[{
key: shouldRecommend ? 'unwantedRecommendations' : 'recommendations',
path: shouldRecommend ? ['unwantedRecommendations'] : ['recommendations'],
value: removeFrom
}],
true);
@@ -2254,7 +2254,7 @@ export abstract class AbstractConfigureRecommendedExtensionsAction extends Actio
return removeFromPromise.then(() =>
this.jsonEditingService.write(extensionsFileResource,
[{
key: shouldRecommend ? 'recommendations' : 'unwantedRecommendations',
path: shouldRecommend ? ['recommendations'] : ['unwantedRecommendations'],
value: insertInto
}],
true)
@@ -2281,7 +2281,7 @@ export abstract class AbstractConfigureRecommendedExtensionsAction extends Actio
.then(content => {
const workspaceRecommendations = <IExtensionsConfigContent>json.parse(content.value.toString())['extensions'];
if (!workspaceRecommendations || !workspaceRecommendations.recommendations) {
return this.jsonEditingService.write(workspaceConfigurationFile, [{ key: 'extensions', value: { recommendations: [] } }], true)
return this.jsonEditingService.write(workspaceConfigurationFile, [{ path: ['extensions'], value: { recommendations: [] } }], true)
.then(() => this.fileService.readFile(workspaceConfigurationFile));
}
return content;

View File

@@ -21,6 +21,9 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten
import { IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { isLanguagePackExtension } from 'vs/platform/extensions/common/extensions';
import { registerThemingParticipant, IColorTheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
import { foreground, listActiveSelectionForeground, listActiveSelectionBackground, listInactiveSelectionForeground, listInactiveSelectionBackground, listFocusForeground, listFocusBackground, listHoverForeground, listHoverBackground } from 'vs/platform/theme/common/colorRegistry';
import { WORKBENCH_BACKGROUND } from 'vs/workbench/common/theme';
export interface IExtensionsViewState {
onFocus: Event<IExtension>;
@@ -122,10 +125,10 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
const extensionContainers: ExtensionContainers = this.instantiationService.createInstance(ExtensionContainers, [...actions, ...widgets, extensionTooltipAction]);
actionbar.push(actions, actionOptions);
const disposables = combinedDisposable(...actions, ...widgets, actionbar, extensionContainers, extensionTooltipAction);
const disposable = combinedDisposable(...actions, ...widgets, actionbar, extensionContainers, extensionTooltipAction);
return {
root, element, icon, name, /*installCount, ratings, */author, description, disposables: [disposables], actionbar,
root, element, icon, name, /*installCount, ratings, */author, description, disposables: [disposable], actionbar,
extensionDisposables: [],
set extension(extension: IExtension) {
extensionContainers.extension = extension;
@@ -158,15 +161,15 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
data.extensionDisposables = dispose(data.extensionDisposables);
let isDisabled: boolean = false;
const updateEnablement = async () => {
const runningExtensions = await this.extensionService.getExtensions();
isDisabled = false;
if (extension.local && !isLanguagePackExtension(extension.local.manifest)) {
const runningExtension = runningExtensions.filter(e => areSameExtensions({ id: e.identifier.value, uuid: e.uuid }, extension.identifier))[0];
const isSameExtensionRunning = runningExtension && extension.server === this.extensionManagementServerService.getExtensionManagementServer(runningExtension.extensionLocation);
toggleClass(data.root, 'disabled', !isSameExtensionRunning);
} else {
removeClass(data.root, 'disabled');
isDisabled = !(runningExtension && extension.server === this.extensionManagementServerService.getExtensionManagementServer(runningExtension.extensionLocation));
}
toggleClass(data.root, 'disabled', isDisabled);
};
updateEnablement();
this.extensionService.onDidChangeExtensions(() => updateEnablement(), this, data.extensionDisposables);
@@ -212,3 +215,49 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
data.disposables = dispose(data.disposables);
}
}
registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) => {
const foregroundColor = theme.getColor(foreground);
if (foregroundColor) {
const authorForeground = foregroundColor.transparent(.9).makeOpaque(WORKBENCH_BACKGROUND(theme));
collector.addRule(`.extensions-list .monaco-list .monaco-list-row:not(.disabled) .author { color: ${authorForeground}; }`);
const disabledExtensionForeground = foregroundColor.transparent(.5).makeOpaque(WORKBENCH_BACKGROUND(theme));
collector.addRule(`.extensions-list .monaco-list .monaco-list-row.disabled { color: ${disabledExtensionForeground}; }`);
}
const listActiveSelectionForegroundColor = theme.getColor(listActiveSelectionForeground);
const listActiveSelectionBackgroundColor = theme.getColor(listActiveSelectionBackground);
if (listActiveSelectionForegroundColor && listActiveSelectionBackgroundColor) {
const authorForeground = listActiveSelectionForegroundColor.transparent(.9).makeOpaque(listActiveSelectionBackgroundColor);
collector.addRule(`.extensions-list .monaco-list:focus .monaco-list-row:not(.disabled).selected .author { color: ${authorForeground}; }`);
const disabledExtensionForeground = listActiveSelectionForegroundColor.transparent(.5).makeOpaque(listActiveSelectionBackgroundColor);
collector.addRule(`.extensions-list .monaco-list:focus .monaco-list-row.disabled.selected { color: ${disabledExtensionForeground}; }`);
}
const listInactiveSelectionForegroundColor = theme.getColor(listInactiveSelectionForeground);
const listInactiveSelectionBackgroundColor = theme.getColor(listInactiveSelectionBackground);
if (listInactiveSelectionForegroundColor && listInactiveSelectionBackgroundColor) {
const authorForeground = listInactiveSelectionForegroundColor.transparent(.9).makeOpaque(listInactiveSelectionBackgroundColor);
collector.addRule(`.extensions-list .monaco-list .monaco-list-row:not(.disabled).selected .author { color: ${authorForeground}; }`);
const disabledExtensionForeground = listInactiveSelectionForegroundColor.transparent(.5).makeOpaque(listInactiveSelectionBackgroundColor);
collector.addRule(`.extensions-list .monaco-list .monaco-list-row.disabled.selected { color: ${disabledExtensionForeground}; }`);
}
const listFocusForegroundColor = theme.getColor(listFocusForeground);
const listFocusBackgroundColor = theme.getColor(listFocusBackground);
if (listFocusForegroundColor && listFocusBackgroundColor) {
const authorForeground = listFocusForegroundColor.transparent(.9).makeOpaque(listFocusBackgroundColor);
collector.addRule(`.extensions-list .monaco-list:focus .monaco-list-row:not(.disabled).focused .author { color: ${authorForeground}; }`);
const disabledExtensionForeground = listFocusForegroundColor.transparent(.5).makeOpaque(listFocusBackgroundColor);
collector.addRule(`.extensions-list .monaco-list:focus .monaco-list-row.disabled.focused { color: ${disabledExtensionForeground}; }`);
}
const listHoverForegroundColor = theme.getColor(listHoverForeground);
const listHoverBackgroundColor = theme.getColor(listHoverBackground);
if (listHoverForegroundColor && listHoverBackgroundColor) {
const authorForeground = listHoverForegroundColor.transparent(.9).makeOpaque(listHoverBackgroundColor);
collector.addRule(`.extensions-list .monaco-list .monaco-list-row:hover:not(.disabled):not(.selected):.not(.focused) .author { color: ${authorForeground}; }`);
const disabledExtensionForeground = listHoverForegroundColor.transparent(.5).makeOpaque(listHoverBackgroundColor);
collector.addRule(`.extensions-list .monaco-list .monaco-list-row.disabled:hover:not(.selected):.not(.focused) { color: ${disabledExtensionForeground}; }`);
}
});

View File

@@ -469,7 +469,7 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE
for (let index = 0; index < e.dataTransfer.files.length; index++) {
const path = e.dataTransfer.files.item(index)!.path;
if (path.indexOf('.vsix') !== -1) {
vsixPaths.push(URI.parse(path));
vsixPaths.push(URI.file(path));
}
}

View File

@@ -23,7 +23,6 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { attachBadgeStyler } from 'vs/platform/theme/common/styler';
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge';
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
@@ -100,7 +99,6 @@ export class ExtensionsListView extends ViewPane {
@IThemeService themeService: IThemeService,
@IExtensionService private readonly extensionService: IExtensionService,
@IExtensionsWorkbenchService protected extensionsWorkbenchService: IExtensionsWorkbenchService,
@IEditorService private readonly editorService: IEditorService,
@IExtensionRecommendationsService protected tipsService: IExtensionRecommendationsService,
@ITelemetryService telemetryService: ITelemetryService,
@IConfigurationService configurationService: IConfigurationService,
@@ -157,16 +155,11 @@ export class ExtensionsListView extends ViewPane {
this._register(this.list);
this._register(extensionsViewState);
const resourceNavigator = this._register(new ListResourceNavigator(this.list, { openOnFocus: false, openOnSelection: true, openOnSingleClick: true }));
this._register(Event.debounce(Event.filter(resourceNavigator.onDidOpenResource, e => e.element !== null), (last, event) => event, 75, true)(options => {
const resourceNavigator = this._register(new ListResourceNavigator(this.list, { openOnSingleClick: true }));
this._register(Event.debounce(Event.filter(resourceNavigator.onDidOpen, e => e.element !== null), (_, event) => event, 75, true)(options => {
this.openExtension(this.list!.model.get(options.element!), { sideByside: options.sideBySide, ...options.editorOptions });
}));
this._register(Event.chain(this.list.onPin)
.map(e => e.elements[0])
.filter(e => !!e)
.on(this.pin, this));
this.bodyTemplate = {
extensionsList,
messageBox,
@@ -323,33 +316,29 @@ export class ExtensionsListView extends ViewPane {
result = result
.filter(e => e.type === ExtensionType.System && (e.name.toLowerCase().indexOf(value) > -1 || e.displayName.toLowerCase().indexOf(value) > -1));
const isThemeExtension = (e: IExtension): boolean => {
return (Array.isArray(e.local?.manifest?.contributes?.themes) && e.local!.manifest!.contributes!.themes.length > 0)
|| (Array.isArray(e.local?.manifest?.contributes?.iconThemes) && e.local!.manifest!.contributes!.iconThemes.length > 0);
};
if (showThemesOnly) {
const themesExtensions = result.filter(e => {
return e.local
&& e.local.manifest
&& e.local.manifest.contributes
&& Array.isArray(e.local.manifest.contributes.themes)
&& e.local.manifest.contributes.themes.length;
});
const themesExtensions = result.filter(isThemeExtension);
return this.getPagedModel(this.sortExtensions(themesExtensions, options));
}
const isLangaugeBasicExtension = (e: IExtension): boolean => {
return FORCE_FEATURE_EXTENSIONS.indexOf(e.identifier.id) === -1
&& (Array.isArray(e.local?.manifest?.contributes?.grammars) && e.local!.manifest!.contributes!.grammars.length > 0);
};
if (showBasicsOnly) {
const basics = result.filter(e => {
return e.local && e.local.manifest
&& e.local.manifest.contributes
&& Array.isArray(e.local.manifest.contributes.grammars)
&& e.local.manifest.contributes.grammars.length
&& FORCE_FEATURE_EXTENSIONS.indexOf(e.local.identifier.id) === -1;
});
const basics = result.filter(isLangaugeBasicExtension);
return this.getPagedModel(this.sortExtensions(basics, options));
}
if (showFeaturesOnly) {
const others = result.filter(e => {
return e.local
&& e.local.manifest
&& e.local.manifest.contributes
&& (!Array.isArray(e.local.manifest.contributes.grammars) || FORCE_FEATURE_EXTENSIONS.indexOf(e.local.identifier.id) !== -1)
&& !Array.isArray(e.local.manifest.contributes.themes);
&& !isThemeExtension(e)
&& !isLangaugeBasicExtension(e);
});
return this.getPagedModel(this.sortExtensions(others, options));
}
@@ -850,14 +839,6 @@ export class ExtensionsListView extends ViewPane {
this.extensionsWorkbenchService.open(extension, options).then(undefined, err => this.onError(err));
}
private pin(): void {
const activeEditorPane = this.editorService.activeEditorPane;
if (activeEditorPane) {
activeEditorPane.group.pinEditor(activeEditorPane.input);
activeEditorPane.focus();
}
}
private onError(err: any): void {
if (isPromiseCanceledError(err)) {
return;
@@ -975,7 +956,6 @@ export class ServerExtensionsView extends ExtensionsListView {
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@IInstantiationService instantiationService: IInstantiationService,
@IExtensionService extensionService: IExtensionService,
@IEditorService editorService: IEditorService,
@IExtensionRecommendationsService tipsService: IExtensionRecommendationsService,
@ITelemetryService telemetryService: ITelemetryService,
@IConfigurationService configurationService: IConfigurationService,
@@ -991,7 +971,7 @@ export class ServerExtensionsView extends ExtensionsListView {
@IPreferencesService preferencesService: IPreferencesService,
) {
options.server = server;
super(options, notificationService, keybindingService, contextMenuService, instantiationService, themeService, extensionService, extensionsWorkbenchService, editorService, tipsService, telemetryService, configurationService, contextService, experimentService, extensionManagementServerService, productService, contextKeyService, viewDescriptorService, menuService, openerService, preferencesService);
super(options, notificationService, keybindingService, contextMenuService, instantiationService, themeService, extensionService, extensionsWorkbenchService, tipsService, telemetryService, configurationService, contextService, experimentService, extensionManagementServerService, productService, contextKeyService, viewDescriptorService, menuService, openerService, preferencesService);
this._register(onDidChangeTitle(title => this.updateTitle(title)));
}

View File

@@ -18,7 +18,7 @@ import {
InstallExtensionEvent, DidInstallExtensionEvent, DidUninstallExtensionEvent, IExtensionIdentifier, InstallOperation, DefaultIconPath
} from 'vs/platform/extensionManagement/common/extensionManagement';
import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData, areSameExtensions, getMaliciousExtensionsSet, groupByExtension, ExtensionIdentifierWithVersion } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData, areSameExtensions, getMaliciousExtensionsSet, groupByExtension, ExtensionIdentifierWithVersion, getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
import { IHostService } from 'vs/workbench/services/host/browser/host';
@@ -359,7 +359,16 @@ class Extensions extends Disposable {
}
async queryInstalled(): Promise<IExtension[]> {
const installed = await this.server.extensionManagementService.getInstalled();
const all = await this.server.extensionManagementService.getInstalled();
// dedup user and system extensions by giving priority to user extensions.
const installed = groupByExtension(all, r => r.identifier).reduce((result, extensions) => {
const extension = extensions.length === 1 ? extensions[0]
: extensions.find(e => e.type === ExtensionType.User) || extensions.find(e => e.type === ExtensionType.System);
result.push(extension!);
return result;
}, []);
const byId = index(this.installed, e => e.local ? e.local.identifier.id : e.identifier.id);
this.installed = installed.map(local => {
const extension = byId[local.identifier.id] || this.instantiationService.createInstance(Extension, this.stateProvider, this.server, local, undefined);
@@ -495,7 +504,7 @@ class Extensions extends Disposable {
export class ExtensionsWorkbenchService extends Disposable implements IExtensionsWorkbenchService, IURLHandler {
private static readonly SyncPeriod = 1000 * 60 * 60 * 12; // 12 hours
_serviceBrand: undefined;
declare readonly _serviceBrand: undefined;
private readonly localExtensions: Extensions | null = null;
private readonly remoteExtensions: Extensions | null = null;
@@ -563,8 +572,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
}
get local(): IExtension[] {
const result = [...this.installed];
const byId = groupByExtension(result, r => r.identifier);
const byId = groupByExtension(this.installed, r => r.identifier);
return byId.reduce((result, extensions) => { result.push(this.getPrimaryExtension(extensions)); return result; }, []);
}
@@ -807,19 +815,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
install(extension: URI | IExtension): Promise<IExtension> {
let extensionPolicy = this.configurationService.getValue<string>(ExtensionsPolicyKey); // {{SQL CARBON EDIT}} add line
if (extension instanceof URI) {
return this.installWithProgress(async () => {
// {{SQL CARBON EDIT}} - Wrap async call in try/catch.
// This is the error handler when installing local VSIX file.
// Prompt the user about the error detail.
try {
const { identifier } = await this.extensionService.install(extension);
return this.local.filter(local => areSameExtensions(local.identifier, identifier))[0];
} catch (error) {
this.notificationService.error(error);
return Promise.reject(error);
}
// {{SQL CARBON EDIT}} - End
});
return this.installWithProgress(() => this.installFromVSIX(extension));
}
if (extension.isMalicious) {
@@ -850,8 +846,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
return Promise.reject(new Error('Extension Not Allowed'));
}
}
await this.downloadOrBrowse(extension);
return this.local.filter(local => areSameExtensions(local.identifier, gallery.identifier))[0];
return this.downloadOrBrowse(extension);
}, gallery.displayName);
}
@@ -900,11 +895,11 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
return Promise.reject(new Error(nls.localize('incompatible', "Unable to install extension '{0}' as it is not compatible with Azure Data Studio '{1}'.", extension.gallery!.identifier.id, version))); // {{SQL CARBON EDIT}} Change vscode to ads
}
return this.installWithProgress(async () => {
await this.installFromGallery(extension, gallery);
const installed = await this.installFromGallery(extension, gallery);
if (extension.latestVersion !== version) {
this.ignoreAutoUpdate(new ExtensionIdentifierWithVersion(gallery.identifier, version));
}
return this.local.filter(local => areSameExtensions(local.identifier, gallery.identifier))[0];
return installed;
}
, gallery.displayName);
});
@@ -965,7 +960,19 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
}, () => installTask());
}
private async installFromGallery(extension: IExtension, gallery: IGalleryExtension): Promise<void> {
private async installFromVSIX(vsix: URI): Promise<IExtension> {
const manifest = await this.extensionService.getManifest(vsix);
const existingExtension = this.local.find(local => areSameExtensions(local.identifier, { id: getGalleryExtensionId(manifest.publisher, manifest.name) }));
const { identifier } = await this.extensionService.install(vsix);
if (existingExtension && existingExtension.latestVersion !== manifest.version) {
this.ignoreAutoUpdate(new ExtensionIdentifierWithVersion(identifier, manifest.version));
}
return this.local.filter(local => areSameExtensions(local.identifier, identifier))[0];
}
private async installFromGallery(extension: IExtension, gallery: IGalleryExtension): Promise<IExtension> {
this.installing.push(extension);
this._onChange.fire(extension);
try {
@@ -974,6 +981,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
const ids: string[] | undefined = extension.identifier.uuid ? [extension.identifier.uuid] : undefined;
const names: string[] | undefined = extension.identifier.uuid ? undefined : [extension.identifier.id];
this.queryGallery({ names, ids, pageSize: 1 }, CancellationToken.None);
return this.local.filter(local => areSameExtensions(local.identifier, gallery.identifier))[0];
} finally {
this.installing = this.installing.filter(e => e !== extension);
this._onChange.fire(this.local.filter(e => areSameExtensions(e.identifier, extension.identifier))[0]);

View File

@@ -154,7 +154,6 @@
.extension-list-item > .details > .footer > .author {
flex: 1;
font-size: 90%;
opacity: 0.9;
font-weight: 600;
}

View File

@@ -59,7 +59,6 @@
.monaco-action-bar .action-item.disabled .action-label.extension-action {
opacity: 1;
pointer-events: none;
}
.monaco-action-bar .action-item.disabled .action-label.extension-action.text {

View File

@@ -103,25 +103,14 @@
display: none;
}
.extensions-viewlet > .extensions .selected .extension-list-item > .details > .footer > .author,
.extensions-viewlet > .extensions .selected.focused .extension-list-item > .details > .footer > .author {
opacity: 1;
}
.extensions-viewlet.narrow > .extensions .extension-list-item > .details > .footer > .monaco-action-bar > .actions-container .extension-action {
max-width: 100px;
}
.monaco-workbench.vs .extensions-viewlet > .extensions .monaco-list-row.disabled > .bookmark,
.monaco-workbench.vs-dark .extensions-viewlet > .extensions .monaco-list-row.disabled > .bookmark,
.monaco-workbench.vs .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension-list-item > .icon-container > .icon,
.monaco-workbench.vs-dark .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension-list-item > .icon-container > .icon,
.monaco-workbench.vs .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension-list-item > .details > .header-container,
.monaco-workbench.vs-dark .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension-list-item > .details > .header-container,
.monaco-workbench.vs .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension-list-item > .details > .description,
.monaco-workbench.vs-dark .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension-list-item > .details > .description,
.monaco-workbench.vs .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension-list-item > .details > .footer > .author,
.monaco-workbench.vs-dark .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension-list-item > .details > .footer > .author {
.monaco-workbench.vs .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension-list-item > .details > .header-container .codicon,
.monaco-workbench.vs-dark .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension-list-item > .details > .header-container .codicon {
opacity: 0.5;
}

View File

@@ -72,7 +72,7 @@ export const SERVICE_ID = 'extensionsWorkbenchService';
export const IExtensionsWorkbenchService = createDecorator<IExtensionsWorkbenchService>(SERVICE_ID);
export interface IExtensionsWorkbenchService {
_serviceBrand: undefined;
readonly _serviceBrand: undefined;
onChange: Event<IExtension | undefined>;
local: IExtension[];
installed: IExtension[];

View File

@@ -3,25 +3,26 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Schemas } from 'vs/base/common/network';
import { URI } from 'vs/base/common/uri';
import { localize } from 'vs/nls';
import { EditorInput } from 'vs/workbench/common/editor';
import { IExtension } from 'vs/workbench/contrib/extensions/common/extensions';
import { URI } from 'vs/base/common/uri';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
export class ExtensionsInput extends EditorInput {
static readonly ID = 'workbench.extensions.input2';
get extension(): IExtension { return this._extension; }
get resource() {
return URI.from({
scheme: 'extension',
scheme: Schemas.extension,
path: this.extension.identifier.id
});
}
constructor(
private readonly _extension: IExtension
public readonly extension: IExtension
) {
super();
}
@@ -34,26 +35,15 @@ export class ExtensionsInput extends EditorInput {
return localize('extensionsInputName', "Extension: {0}", this.extension.displayName);
}
matches(other: unknown): boolean {
if (super.matches(other) === true) {
return true;
}
if (!(other instanceof ExtensionsInput)) {
return false;
}
const otherExtensionInput = other as ExtensionsInput;
// TODO@joao is this correct?
return this.extension === otherExtensionInput.extension;
}
resolve(): Promise<any> {
return Promise.resolve(null);
}
supportsSplitEditor(): boolean {
return false;
}
matches(other: unknown): boolean {
if (super.matches(other)) {
return true;
}
return other instanceof ExtensionsInput && areSameExtensions(this.extension.identifier, other.extension.identifier);
}
}

View File

@@ -15,7 +15,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
import { IElectronService } from 'vs/platform/electron/electron-sandbox/electron';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { randomPort } from 'vs/base/node/ports';
import product from 'vs/platform/product/common/product';
import { IProductService } from 'vs/platform/product/common/productService';
import { RuntimeExtensionsInput } from 'vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsInput';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { ExtensionHostProfiler } from 'vs/workbench/services/extensions/electron-browser/extensionHostProfiler';
@@ -23,7 +23,7 @@ import { CommandsRegistry } from 'vs/platform/commands/common/commands';
export class ExtensionHostProfileService extends Disposable implements IExtensionHostProfileService {
_serviceBrand: undefined;
declare readonly _serviceBrand: undefined;
private readonly _onDidChangeState: Emitter<void> = this._register(new Emitter<void>());
public readonly onDidChangeState: Event<void> = this._onDidChangeState.event;
@@ -49,6 +49,7 @@ export class ExtensionHostProfileService extends Disposable implements IExtensio
@IElectronService private readonly _electronService: IElectronService,
@IDialogService private readonly _dialogService: IDialogService,
@IStatusbarService private readonly _statusbarService: IStatusbarService,
@IProductService private readonly _productService: IProductService
) {
super();
this._profile = null;
@@ -57,7 +58,7 @@ export class ExtensionHostProfileService extends Disposable implements IExtensio
CommandsRegistry.registerCommand('workbench.action.extensionHostProfilder.stop', () => {
this.stopProfiling();
this._editorService.openEditor(this._instantiationService.createInstance(RuntimeExtensionsInput), { revealIfOpened: true });
this._editorService.openEditor(RuntimeExtensionsInput.instance, { revealIfOpened: true });
});
}
@@ -118,7 +119,7 @@ export class ExtensionHostProfileService extends Disposable implements IExtensio
return this._dialogService.confirm({
type: 'info',
message: nls.localize('restart1', "Profile Extensions"),
detail: nls.localize('restart2', "In order to profile extensions a restart is required. Do you want to restart '{0}' now?", product.nameLong),
detail: nls.localize('restart2', "In order to profile extensions a restart is required. Do you want to restart '{0}' now?", this._productService.nameLong),
primaryButton: nls.localize('restart3', "Restart"),
secondaryButton: nls.localize('cancel', "Cancel")
}).then(res => {

View File

@@ -50,7 +50,7 @@ class RuntimeExtensionsInputFactory implements IEditorInputFactory {
return '';
}
deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput {
return new RuntimeExtensionsInput();
return RuntimeExtensionsInput.instance;
}
}

View File

@@ -186,7 +186,7 @@ export class ExtensionsAutoProfiler extends Disposable implements IWorkbenchCont
),
[{
label: localize('show', 'Show Extensions'),
run: () => this._editorService.openEditor(new RuntimeExtensionsInput())
run: () => this._editorService.openEditor(RuntimeExtensionsInput.instance)
},
action
],

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as os from 'os';
import product from 'vs/platform/product/common/product';
import { IProductService } from 'vs/platform/product/common/productService';
import { Action } from 'vs/base/common/actions';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { URI } from 'vs/base/common/uri';
@@ -118,7 +118,8 @@ class ReportExtensionSlowAction extends Action {
readonly repoInfo: RepoInfo,
readonly profile: IExtensionHostProfile,
@IDialogService private readonly _dialogService: IDialogService,
@IOpenerService private readonly _openerService: IOpenerService
@IOpenerService private readonly _openerService: IOpenerService,
@IProductService private readonly _productService: IProductService
) {
super('report.slow', localize('cmd.report', "Report Issue"));
}
@@ -139,7 +140,7 @@ class ReportExtensionSlowAction extends Action {
- Extension Name: \`${this.extension.name}\`
- Extension Version: \`${this.extension.version}\`
- OS Version: \`${osVersion}\`
- VSCode version: \`${product.version}\`\n\n${message}`);
- VSCode version: \`${this._productService.version}\`\n\n${message}`);
const url = `${this.repoInfo.base}/${this.repoInfo.owner}/${this.repoInfo.repo}/issues/new/?body=${body}&title=${title}`;
this._openerService.open(URI.parse(url));

View File

@@ -6,7 +6,7 @@
import 'vs/css!./media/runtimeExtensionsEditor';
import * as nls from 'vs/nls';
import * as os from 'os';
import product from 'vs/platform/product/common/product';
import { IProductService } from 'vs/platform/product/common/productService';
import { Action, IAction } from 'vs/base/common/actions';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
@@ -62,7 +62,7 @@ export enum ProfileSessionState {
}
export interface IExtensionHostProfileService {
_serviceBrand: undefined;
readonly _serviceBrand: undefined;
readonly onDidChangeState: Event<void>;
readonly onDidChangeLastProfile: Event<void>;
@@ -127,7 +127,8 @@ export class RuntimeExtensionsEditor extends BaseEditor {
@ILabelService private readonly _labelService: ILabelService,
@IWorkbenchEnvironmentService private readonly _environmentService: IWorkbenchEnvironmentService,
@IOpenerService private readonly _openerService: IOpenerService,
@IClipboardService private readonly _clipboardService: IClipboardService
@IClipboardService private readonly _clipboardService: IClipboardService,
@IProductService private readonly _productService: IProductService
) {
super(RuntimeExtensionsEditor.ID, telemetryService, themeService, storageService);
@@ -339,7 +340,7 @@ export class RuntimeExtensionsEditor extends BaseEditor {
data.actionbar.push(this._instantiationService.createInstance(SlowExtensionAction, element.description, element.unresponsiveProfile), { icon: true, label: true });
}
if (isNonEmptyArray(element.status.runtimeErrors)) {
data.actionbar.push(new ReportExtensionIssueAction(element, this._openerService, this._clipboardService), { icon: true, label: true });
data.actionbar.push(new ReportExtensionIssueAction(element, this._openerService, this._clipboardService, this._productService), { icon: true, label: true });
}
let title: string;
@@ -372,6 +373,8 @@ export class RuntimeExtensionsEditor extends BaseEditor {
'{0} will be a glob pattern'
]
}, "Activated by {1} because searching for {0} took too long", glob, activationId);
} else if (activationEvent === 'onStartupFinished') {
title = nls.localize('startupFinishedActivation', "Activated by {0} after start-up finished", activationId);
} else if (/^onLanguage:/.test(activationEvent)) {
let language = activationEvent.substr('onLanguage:'.length);
title = nls.localize('languageActivation', "Activated by {1} because you opened a {0} file", language, activationId);
@@ -451,7 +454,7 @@ export class RuntimeExtensionsEditor extends BaseEditor {
const actions: IAction[] = [];
actions.push(new ReportExtensionIssueAction(e.element, this._openerService, this._clipboardService));
actions.push(new ReportExtensionIssueAction(e.element, this._openerService, this._clipboardService, this._productService));
actions.push(new Separator());
if (e.element.marketplaceInfo) {
@@ -492,14 +495,13 @@ export class ShowRuntimeExtensionsAction extends Action {
constructor(
id: string, label: string,
@IEditorService private readonly _editorService: IEditorService,
@IInstantiationService private readonly _instantiationService: IInstantiationService
@IEditorService private readonly _editorService: IEditorService
) {
super(id, label);
}
public async run(e?: any): Promise<any> {
await this._editorService.openEditor(this._instantiationService.createInstance(RuntimeExtensionsInput), { revealIfOpened: true });
await this._editorService.openEditor(RuntimeExtensionsInput.instance, { revealIfOpened: true });
}
}
@@ -518,7 +520,8 @@ export class ReportExtensionIssueAction extends Action {
unresponsiveProfile?: IExtensionHostProfile
},
@IOpenerService private readonly openerService: IOpenerService,
@IClipboardService private readonly clipboardService: IClipboardService
@IClipboardService private readonly clipboardService: IClipboardService,
@IProductService private readonly productService: IProductService
) {
super(ReportExtensionIssueAction._id, ReportExtensionIssueAction._label, 'extension-action report-issue');
this.enabled = extension.marketplaceInfo
@@ -542,7 +545,7 @@ export class ReportExtensionIssueAction extends Action {
if (!!baseUrl) {
baseUrl = `${baseUrl.indexOf('.git') !== -1 ? baseUrl.substr(0, baseUrl.length - 4) : baseUrl}/issues/new/`;
} else {
baseUrl = product.reportIssueUrl!;
baseUrl = this.productService.reportIssueUrl!;
}
let reason = 'Bug';
@@ -557,7 +560,7 @@ export class ReportExtensionIssueAction extends Action {
- Extension Name: \`${extension.description.name}\`
- Extension Version: \`${extension.description.version}\`
- OS Version: \`${osVersion}\`
- VSCode version: \`${product.version}\`\n\n${message}`
- VSCode version: \`${this.productService.version}\`\n\n${message}`
);
return `${baseUrl}${queryStringPrefix}body=${body}&title=${encodeURIComponent(title)}`;
@@ -574,6 +577,7 @@ export class DebugExtensionHostAction extends Action {
@IElectronService private readonly _electronService: IElectronService,
@IDialogService private readonly _dialogService: IDialogService,
@IExtensionService private readonly _extensionService: IExtensionService,
@IProductService private readonly productService: IProductService
) {
super(DebugExtensionHostAction.ID, DebugExtensionHostAction.LABEL, DebugExtensionHostAction.CSS_CLASS);
}
@@ -585,7 +589,7 @@ export class DebugExtensionHostAction extends Action {
const res = await this._dialogService.confirm({
type: 'info',
message: nls.localize('restart1', "Profile Extensions"),
detail: nls.localize('restart2', "In order to profile extensions a restart is required. Do you want to restart '{0}' now?", product.nameLong),
detail: nls.localize('restart2', "In order to profile extensions a restart is required. Do you want to restart '{0}' now?", this.productService.nameLong),
primaryButton: nls.localize('restart3', "Restart"),
secondaryButton: nls.localize('cancel', "Cancel")
});

View File

@@ -11,6 +11,15 @@ export class RuntimeExtensionsInput extends EditorInput {
static readonly ID = 'workbench.runtimeExtensions.input';
static _instance: RuntimeExtensionsInput;
static get instance() {
if (!RuntimeExtensionsInput._instance || RuntimeExtensionsInput._instance.isDisposed()) {
RuntimeExtensionsInput._instance = new RuntimeExtensionsInput();
}
return RuntimeExtensionsInput._instance;
}
readonly resource = URI.from({
scheme: 'runtime-extensions',
path: 'default'
@@ -24,18 +33,11 @@ export class RuntimeExtensionsInput extends EditorInput {
return nls.localize('extensionsInputName', "Running Extensions");
}
matches(other: unknown): boolean {
if (!(other instanceof RuntimeExtensionsInput)) {
return false;
}
return true;
}
resolve(): Promise<any> {
return Promise.resolve(null);
}
supportsSplitEditor(): boolean {
return false;
}
matches(other: unknown): boolean {
return other instanceof RuntimeExtensionsInput;
}
}

View File

@@ -99,11 +99,11 @@ async function setupTest() {
instantiationService.stub(IRemoteAgentService, RemoteAgentService);
instantiationService.stub(IExtensionManagementServerService, new class extends ExtensionManagementServerService {
private _localExtensionManagementServer: IExtensionManagementServer = { extensionManagementService: instantiationService.get(IExtensionManagementService), label: 'local', authority: 'vscode-local' };
#localExtensionManagementServer: IExtensionManagementServer = { extensionManagementService: instantiationService.get(IExtensionManagementService), label: 'local', authority: 'vscode-local' };
constructor() {
super(instantiationService.get(ISharedProcessService), instantiationService.get(IRemoteAgentService), instantiationService.get(IExtensionGalleryService), instantiationService.get(IConfigurationService), instantiationService.get(IProductService), instantiationService.get(ILogService), instantiationService.get(ILabelService));
}
get localExtensionManagementServer(): IExtensionManagementServer { return this._localExtensionManagementServer; }
get localExtensionManagementServer(): IExtensionManagementServer { return this.#localExtensionManagementServer; }
set localExtensionManagementServer(server: IExtensionManagementServer) { }
}());
@@ -727,7 +727,7 @@ suite('ExtensionsActions', () => {
.then(extensions => {
const testObject: ExtensionsActions.EnableGloballyAction = instantiationService.createInstance(ExtensionsActions.EnableGloballyAction);
testObject.extension = extensions[0];
assert.ok(!testObject.enabled);
assert.ok(testObject.enabled);
});
});
});

View File

@@ -99,11 +99,11 @@ suite('ExtensionsListView Tests', () => {
instantiationService.stub(IMenuService, new TestMenuService());
instantiationService.stub(IExtensionManagementServerService, new class extends ExtensionManagementServerService {
private _localExtensionManagementServer: IExtensionManagementServer = { extensionManagementService: instantiationService.get(IExtensionManagementService), label: 'local', authority: 'vscode-local' };
#localExtensionManagementServer: IExtensionManagementServer = { extensionManagementService: instantiationService.get(IExtensionManagementService), label: 'local', authority: 'vscode-local' };
constructor() {
super(instantiationService.get(ISharedProcessService), instantiationService.get(IRemoteAgentService), instantiationService.get(IExtensionGalleryService), instantiationService.get(IConfigurationService), instantiationService.get(IProductService), instantiationService.get(ILogService), instantiationService.get(ILabelService));
}
get localExtensionManagementServer(): IExtensionManagementServer { return this._localExtensionManagementServer; }
get localExtensionManagementServer(): IExtensionManagementServer { return this.#localExtensionManagementServer; }
set localExtensionManagementServer(server: IExtensionManagementServer) { }
}());