diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts index 39905ac688b1a2beb1097bb7926b4585d242967d..9b6e4199aaeed5fbd04118570675f2015eb5ffa1 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts @@ -27,7 +27,7 @@ import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID, IExtension import { RatingsWidget, InstallCountWidget } from 'vs/workbench/parts/extensions/browser/extensionsWidgets'; import { EditorOptions } from 'vs/workbench/common/editor'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; -import { CombinedInstallAction, UpdateAction, EnableAction, DisableAction, ReloadAction, MaliciousStatusLabelAction, DisabledStatusLabelAction, IgnoreExtensionRecommendationAction, UndoIgnoreExtensionRecommendationAction } from 'vs/workbench/parts/extensions/electron-browser/extensionsActions'; +import { CombinedInstallAction, UpdateAction, ExtensionEditorDropDownAction, ReloadAction, MaliciousStatusLabelAction, DisabledStatusLabelAction, IgnoreExtensionRecommendationAction, UndoIgnoreExtensionRecommendationAction, EnableDropDownAction, DisableDropDownAction } from 'vs/workbench/parts/extensions/electron-browser/extensionsActions'; import { WebviewElement } from 'vs/workbench/parts/webview/electron-browser/webviewElement'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; @@ -48,6 +48,7 @@ import { ExtensionsTree, IExtensionData } from 'vs/workbench/parts/extensions/br import { ShowCurrentReleaseNotesAction } from 'vs/workbench/parts/update/electron-browser/update'; import { KeybindingParser } from 'vs/base/common/keybindingParser'; import { IStorageService } from 'vs/platform/storage/common/storage'; +import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; function renderBody(body: string): string { const styleSheetPath = require.toUrl('./media/markdown.css').replace('file://', 'vscode-core-resource://'); @@ -188,7 +189,8 @@ export class ExtensionEditor extends BaseEditor { @IOpenerService private readonly openerService: IOpenerService, @IPartService private readonly partService: IPartService, @IExtensionTipsService private readonly extensionTipsService: IExtensionTipsService, - @IStorageService storageService: IStorageService + @IStorageService storageService: IStorageService, + @IExtensionService private extensionService: IExtensionService ) { super(ExtensionEditor.ID, telemetryService, themeService, storageService); this.disposables = []; @@ -236,11 +238,8 @@ export class ExtensionEditor extends BaseEditor { this.extensionActionBar = new ActionBar(extensionActions, { animated: false, actionItemProvider: (action: Action) => { - if (action.id === EnableAction.ID) { - return (action).createActionItem(); - } - if (action.id === DisableAction.ID) { - return (action).createActionItem(); + if (action instanceof ExtensionEditorDropDownAction) { + return action.createActionItem(); } return null; } @@ -270,171 +269,172 @@ export class ExtensionEditor extends BaseEditor { } setInput(input: ExtensionsInput, options: EditorOptions, token: CancellationToken): Thenable { - this.activeElement = null; - this.editorLoadComplete = false; - const extension = input.extension; - - this.transientDisposables = dispose(this.transientDisposables); - - this.extensionReadme = new Cache(() => createCancelablePromise(token => extension.getReadme(token))); - this.extensionChangelog = new Cache(() => createCancelablePromise(token => extension.getChangelog(token))); - this.extensionManifest = new Cache(() => createCancelablePromise(token => extension.getManifest(token))); - this.extensionDependencies = new Cache(() => createCancelablePromise(token => this.extensionsWorkbenchService.loadDependencies(extension, token))); - - const onError = once(domEvent(this.icon, 'error')); - onError(() => this.icon.src = extension.iconUrlFallback, null, this.transientDisposables); - this.icon.src = extension.iconUrl; - - this.name.textContent = extension.displayName; - this.identifier.textContent = extension.id; - this.preview.style.display = extension.preview ? 'inherit' : 'none'; - this.builtin.style.display = extension.type === LocalExtensionType.System ? 'inherit' : 'none'; - - this.publisher.textContent = extension.publisherDisplayName; - this.description.textContent = extension.description; - - removeClass(this.header, 'recommendation-ignored'); - removeClass(this.header, 'recommended'); - - const extRecommendations = this.extensionTipsService.getAllRecommendationsWithReason(); - let recommendationsData = {}; - if (extRecommendations[extension.id.toLowerCase()]) { - addClass(this.header, 'recommended'); - this.recommendationText.textContent = extRecommendations[extension.id.toLowerCase()].reasonText; - recommendationsData = { recommendationReason: extRecommendations[extension.id.toLowerCase()].reasonId }; - } else if (this.extensionTipsService.getAllIgnoredRecommendations().global.indexOf(extension.id.toLowerCase()) !== -1) { - addClass(this.header, 'recommendation-ignored'); - this.recommendationText.textContent = localize('recommendationHasBeenIgnored', "You have chosen not to receive recommendations for this extension."); - } - else { - this.recommendationText.textContent = ''; - } - - /* __GDPR__ - "extensionGallery:openExtension" : { - "recommendationReason": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "${include}": [ - "${GalleryExtensionTelemetryData}" - ] - } - */ - this.telemetryService.publicLog('extensionGallery:openExtension', assign(extension.telemetryData, recommendationsData)); - - toggleClass(this.name, 'clickable', !!extension.url); - toggleClass(this.publisher, 'clickable', !!extension.url); - toggleClass(this.rating, 'clickable', !!extension.url); - if (extension.url) { - this.name.onclick = finalHandler(() => window.open(extension.url)); - this.rating.onclick = finalHandler(() => window.open(`${extension.url}#review-details`)); - this.publisher.onclick = finalHandler(() => { - this.viewletService.openViewlet(VIEWLET_ID, true) - .then(viewlet => viewlet as IExtensionsViewlet) - .then(viewlet => viewlet.search(`publisher:"${extension.publisherDisplayName}"`)); - }); - - if (extension.licenseUrl) { - this.license.onclick = finalHandler(() => window.open(extension.licenseUrl)); - this.license.style.display = 'initial'; - } else { - this.license.onclick = null; - this.license.style.display = 'none'; - } - } else { - this.name.onclick = null; - this.rating.onclick = null; - this.publisher.onclick = null; - this.license.onclick = null; - this.license.style.display = 'none'; - } - - if (extension.repository) { - this.repository.onclick = finalHandler(() => window.open(extension.repository)); - this.repository.style.display = 'initial'; - } - else { - this.repository.onclick = null; - this.repository.style.display = 'none'; - } + return this.extensionService.getExtensions() + .then(runningExtensions => { + this.activeElement = null; + this.editorLoadComplete = false; + const extension = input.extension; + + this.transientDisposables = dispose(this.transientDisposables); + + this.extensionReadme = new Cache(() => createCancelablePromise(token => extension.getReadme(token))); + this.extensionChangelog = new Cache(() => createCancelablePromise(token => extension.getChangelog(token))); + this.extensionManifest = new Cache(() => createCancelablePromise(token => extension.getManifest(token))); + this.extensionDependencies = new Cache(() => createCancelablePromise(token => this.extensionsWorkbenchService.loadDependencies(extension, token))); + + const onError = once(domEvent(this.icon, 'error')); + onError(() => this.icon.src = extension.iconUrlFallback, null, this.transientDisposables); + this.icon.src = extension.iconUrl; + + this.name.textContent = extension.displayName; + this.identifier.textContent = extension.id; + this.preview.style.display = extension.preview ? 'inherit' : 'none'; + this.builtin.style.display = extension.type === LocalExtensionType.System ? 'inherit' : 'none'; + + this.publisher.textContent = extension.publisherDisplayName; + this.description.textContent = extension.description; + + removeClass(this.header, 'recommendation-ignored'); + removeClass(this.header, 'recommended'); + + const extRecommendations = this.extensionTipsService.getAllRecommendationsWithReason(); + let recommendationsData = {}; + if (extRecommendations[extension.id.toLowerCase()]) { + addClass(this.header, 'recommended'); + this.recommendationText.textContent = extRecommendations[extension.id.toLowerCase()].reasonText; + recommendationsData = { recommendationReason: extRecommendations[extension.id.toLowerCase()].reasonId }; + } else if (this.extensionTipsService.getAllIgnoredRecommendations().global.indexOf(extension.id.toLowerCase()) !== -1) { + addClass(this.header, 'recommendation-ignored'); + this.recommendationText.textContent = localize('recommendationHasBeenIgnored', "You have chosen not to receive recommendations for this extension."); + } + else { + this.recommendationText.textContent = ''; + } - const install = this.instantiationService.createInstance(InstallCountWidget, this.installCount, { extension }); - this.transientDisposables.push(install); - - const ratings = this.instantiationService.createInstance(RatingsWidget, this.rating, { extension }); - this.transientDisposables.push(ratings); - - const maliciousStatusAction = this.instantiationService.createInstance(MaliciousStatusLabelAction, true); - const disabledStatusAction = this.instantiationService.createInstance(DisabledStatusLabelAction); - const installAction = this.instantiationService.createInstance(CombinedInstallAction); - const updateAction = this.instantiationService.createInstance(UpdateAction); - const enableAction = this.instantiationService.createInstance(EnableAction); - const disableAction = this.instantiationService.createInstance(DisableAction); - const reloadAction = this.instantiationService.createInstance(ReloadAction, true); - - installAction.extension = extension; - maliciousStatusAction.extension = extension; - disabledStatusAction.extension = extension; - updateAction.extension = extension; - enableAction.extension = extension; - disableAction.extension = extension; - reloadAction.extension = extension; - - this.extensionActionBar.clear(); - this.extensionActionBar.push([reloadAction, updateAction, enableAction, disableAction, installAction, maliciousStatusAction, disabledStatusAction], { icon: true, label: true }); - this.transientDisposables.push(enableAction, updateAction, reloadAction, disableAction, installAction, maliciousStatusAction, disabledStatusAction); - - const ignoreAction = this.instantiationService.createInstance(IgnoreExtensionRecommendationAction); - const undoIgnoreAction = this.instantiationService.createInstance(UndoIgnoreExtensionRecommendationAction); - ignoreAction.extension = extension; - undoIgnoreAction.extension = extension; - - this.extensionTipsService.onRecommendationChange(change => { - if (change.extensionId.toLowerCase() === extension.id.toLowerCase()) { - if (change.isRecommended) { - removeClass(this.header, 'recommendation-ignored'); - const extRecommendations = this.extensionTipsService.getAllRecommendationsWithReason(); - if (extRecommendations[extension.id.toLowerCase()]) { - addClass(this.header, 'recommended'); - this.recommendationText.textContent = extRecommendations[extension.id.toLowerCase()].reasonText; + /* __GDPR__ + "extensionGallery:openExtension" : { + "recommendationReason": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "${include}": [ + "${GalleryExtensionTelemetryData}" + ] + } + */ + this.telemetryService.publicLog('extensionGallery:openExtension', assign(extension.telemetryData, recommendationsData)); + + toggleClass(this.name, 'clickable', !!extension.url); + toggleClass(this.publisher, 'clickable', !!extension.url); + toggleClass(this.rating, 'clickable', !!extension.url); + if (extension.url) { + this.name.onclick = finalHandler(() => window.open(extension.url)); + this.rating.onclick = finalHandler(() => window.open(`${extension.url}#review-details`)); + this.publisher.onclick = finalHandler(() => { + this.viewletService.openViewlet(VIEWLET_ID, true) + .then(viewlet => viewlet as IExtensionsViewlet) + .then(viewlet => viewlet.search(`publisher:"${extension.publisherDisplayName}"`)); + }); + + if (extension.licenseUrl) { + this.license.onclick = finalHandler(() => window.open(extension.licenseUrl)); + this.license.style.display = 'initial'; + } else { + this.license.onclick = null; + this.license.style.display = 'none'; } } else { - addClass(this.header, 'recommendation-ignored'); - removeClass(this.header, 'recommended'); - this.recommendationText.textContent = localize('recommendationHasBeenIgnored', "You have chosen not to receive recommendations for this extension."); + this.name.onclick = null; + this.rating.onclick = null; + this.publisher.onclick = null; + this.license.onclick = null; + this.license.style.display = 'none'; + } + + if (extension.repository) { + this.repository.onclick = finalHandler(() => window.open(extension.repository)); + this.repository.style.display = 'initial'; + } + else { + this.repository.onclick = null; + this.repository.style.display = 'none'; } - } - }); - this.ignoreActionbar.clear(); - this.ignoreActionbar.push([ignoreAction, undoIgnoreAction], { icon: true, label: true }); - this.transientDisposables.push(ignoreAction, undoIgnoreAction); + const install = this.instantiationService.createInstance(InstallCountWidget, this.installCount, { extension }); + this.transientDisposables.push(install); + + const ratings = this.instantiationService.createInstance(RatingsWidget, this.rating, { extension }); + this.transientDisposables.push(ratings); + + const maliciousStatusAction = this.instantiationService.createInstance(MaliciousStatusLabelAction, true); + const disabledStatusAction = this.instantiationService.createInstance(DisabledStatusLabelAction); + const installAction = this.instantiationService.createInstance(CombinedInstallAction); + const updateAction = this.instantiationService.createInstance(UpdateAction); + const enableAction = this.instantiationService.createInstance(EnableDropDownAction, extension, runningExtensions); + const disableAction = this.instantiationService.createInstance(DisableDropDownAction, extension, runningExtensions); + const reloadAction = this.instantiationService.createInstance(ReloadAction, true); + + installAction.extension = extension; + maliciousStatusAction.extension = extension; + disabledStatusAction.extension = extension; + updateAction.extension = extension; + reloadAction.extension = extension; + + this.extensionActionBar.clear(); + this.extensionActionBar.push([reloadAction, updateAction, enableAction, disableAction, installAction, maliciousStatusAction, disabledStatusAction], { icon: true, label: true }); + this.transientDisposables.push(enableAction, updateAction, reloadAction, disableAction, installAction, maliciousStatusAction, disabledStatusAction); + + const ignoreAction = this.instantiationService.createInstance(IgnoreExtensionRecommendationAction); + const undoIgnoreAction = this.instantiationService.createInstance(UndoIgnoreExtensionRecommendationAction); + ignoreAction.extension = extension; + undoIgnoreAction.extension = extension; + + this.extensionTipsService.onRecommendationChange(change => { + if (change.extensionId.toLowerCase() === extension.id.toLowerCase()) { + if (change.isRecommended) { + removeClass(this.header, 'recommendation-ignored'); + const extRecommendations = this.extensionTipsService.getAllRecommendationsWithReason(); + if (extRecommendations[extension.id.toLowerCase()]) { + addClass(this.header, 'recommended'); + this.recommendationText.textContent = extRecommendations[extension.id.toLowerCase()].reasonText; + } + } else { + addClass(this.header, 'recommendation-ignored'); + removeClass(this.header, 'recommended'); + this.recommendationText.textContent = localize('recommendationHasBeenIgnored', "You have chosen not to receive recommendations for this extension."); + } + } + }); - this.content.innerHTML = ''; // Clear content before setting navbar actions. + this.ignoreActionbar.clear(); + this.ignoreActionbar.push([ignoreAction, undoIgnoreAction], { icon: true, label: true }); + this.transientDisposables.push(ignoreAction, undoIgnoreAction); - this.navbar.clear(); - this.navbar.onChange(this.onNavbarChange.bind(this, extension), this, this.transientDisposables); + this.content.innerHTML = ''; // Clear content before setting navbar actions. - if (extension.hasReadme()) { - this.navbar.push(NavbarSection.Readme, localize('details', "Details"), localize('detailstooltip', "Extension details, rendered from the extension's 'README.md' file")); - } - this.extensionManifest.get() - .promise - .then(manifest => { - if (extension.extensionPack.length) { - this.navbar.push(NavbarSection.ExtensionPack, localize('extensionPack', "Extension Pack"), localize('extensionsPack', "Set of extensions that can be installed together")); - } - if (manifest && manifest.contributes) { - this.navbar.push(NavbarSection.Contributions, localize('contributions', "Contributions"), localize('contributionstooltip', "Lists contributions to VS Code by this extension")); - } - if (extension.hasChangelog()) { - this.navbar.push(NavbarSection.Changelog, localize('changelog', "Changelog"), localize('changelogtooltip', "Extension update history, rendered from the extension's 'CHANGELOG.md' file")); - } - if (extension.dependencies.length) { - this.navbar.push(NavbarSection.Dependencies, localize('dependencies', "Dependencies"), localize('dependenciestooltip', "Lists extensions this extension depends on")); + this.navbar.clear(); + this.navbar.onChange(this.onNavbarChange.bind(this, extension), this, this.transientDisposables); + + if (extension.hasReadme()) { + this.navbar.push(NavbarSection.Readme, localize('details', "Details"), localize('detailstooltip', "Extension details, rendered from the extension's 'README.md' file")); } - this.editorLoadComplete = true; + this.extensionManifest.get() + .promise + .then(manifest => { + if (extension.extensionPack.length) { + this.navbar.push(NavbarSection.ExtensionPack, localize('extensionPack', "Extension Pack"), localize('extensionsPack', "Set of extensions that can be installed together")); + } + if (manifest && manifest.contributes) { + this.navbar.push(NavbarSection.Contributions, localize('contributions', "Contributions"), localize('contributionstooltip', "Lists contributions to VS Code by this extension")); + } + if (extension.hasChangelog()) { + this.navbar.push(NavbarSection.Changelog, localize('changelog', "Changelog"), localize('changelogtooltip', "Extension update history, rendered from the extension's 'CHANGELOG.md' file")); + } + if (extension.dependencies.length) { + this.navbar.push(NavbarSection.Dependencies, localize('dependencies', "Dependencies"), localize('dependenciestooltip', "Lists extensions this extension depends on")); + } + this.editorLoadComplete = true; + }); + + return super.setInput(input, options, token); }); - - return super.setInput(input, options, token); } focus(): void { diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts index 41978aa8bc36ebf7f074c961a80208392753b126..7ee2c5ad792c9e09368f5cc9d86ada299abaeed2 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts @@ -473,63 +473,30 @@ export abstract class DropDownAction extends Action { protected disposables: IDisposable[] = []; - private _extension: IExtension; - get extension(): IExtension { return this._extension; } - set extension(extension: IExtension) { - this._extension = extension; - this.getActions().forEach(action => action.extension = extension); - this.update(extension); - } - constructor( id: string, label: string, cssClass: string, enabled: boolean, - readonly actionsGroups: IExtensionAction[][], private readonly tabOnlyOnFocus: boolean, - @IInstantiationService private instantiationService: IInstantiationService + @IInstantiationService protected instantiationService: IInstantiationService ) { super(id, label, cssClass, enabled); - - for (const group of actionsGroups) { - for (const action of group) { - this.disposables.push(action); - if (action instanceof Action) { - action.onDidChange(({ enabled }) => { - if (!isUndefinedOrNull(enabled)) { - this.update(); - } - }, this, this.disposables); - } - } - } } private _actionItem: DropDownMenuActionItem; createActionItem(): DropDownMenuActionItem { - this._actionItem = this.instantiationService.createInstance(DropDownMenuActionItem, this, this.actionsGroups, this.tabOnlyOnFocus); + this._actionItem = this.instantiationService.createInstance(DropDownMenuActionItem, this, this.tabOnlyOnFocus); return this._actionItem; } - getActions(): IExtensionAction[] { - const actions: IExtensionAction[] = []; - const groups = this.actionsGroups; - for (const menuActions of groups) { - actions.push(...menuActions); - } - return actions; - } - - public run(): Promise { + public run({ actionGroups, disposeActionsOnHide }: { actionGroups: IAction[][], disposeActionsOnHide: boolean }): Thenable { if (this._actionItem) { - this._actionItem.showMenu(); + this._actionItem.showMenu(actionGroups, disposeActionsOnHide); } return Promise.resolve(null); } - protected abstract update(extension?: IExtension); - dispose(): void { dispose(this.disposables); super.dispose(); @@ -540,31 +507,28 @@ export class DropDownMenuActionItem extends ExtensionActionItem { private disposables: IDisposable[] = []; - private _menuActionGroups: IAction[][]; - - constructor(action: IAction, - menuActionGroups: IAction[][], + constructor(action: DropDownAction, tabOnlyOnFocus: boolean, @IContextMenuService private contextMenuService: IContextMenuService ) { super(null, action, { icon: true, label: true, tabOnlyOnFocus }); - this._menuActionGroups = menuActionGroups; } - public showMenu(): void { - const actions = this.getActions(); + public showMenu(menuActionGroups: IAction[][], disposeActionsOnHide: boolean): void { + const actions = this.getActions(menuActionGroups); let elementPosition = DOM.getDomNodePagePosition(this.element); const anchor = { x: elementPosition.left, y: elementPosition.top + elementPosition.height + 10 }; this.contextMenuService.showContextMenu({ getAnchor: () => anchor, getActions: () => actions, - actionRunner: this.actionRunner + actionRunner: this.actionRunner, + onHide: () => { if (disposeActionsOnHide) { dispose(actions); } } }); } - getActions(): IAction[] { + private getActions(menuActionGroups: IAction[][]): IAction[] { let actions: IAction[] = []; - for (const menuActions of this._menuActionGroups) { + for (const menuActions of menuActionGroups) { actions = [...actions, ...menuActions, new Separator()]; } return actions.length ? actions.slice(0, actions.length - 1) : actions; @@ -582,23 +546,20 @@ export class ManageExtensionAction extends DropDownAction { private static readonly Class = 'extension-action manage'; private static readonly HideManageExtensionClass = `${ManageExtensionAction.Class} hide`; + private _extension: IExtension; + get extension(): IExtension { return this._extension; } + set extension(extension: IExtension) { + this._extension = extension; + this.update(); + } + constructor( @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService, - @IInstantiationService instantiationService: IInstantiationService + @IInstantiationService instantiationService: IInstantiationService, + @IExtensionService private extensionService: IExtensionService ) { - const groups: IExtensionAction[][] = []; - groups.push([ - instantiationService.createInstance(EnableGloballyAction, EnableGloballyAction.LABEL), - instantiationService.createInstance(CombinedEnableForWorkspaceAction, CombinedEnableForWorkspaceAction.LABEL) - ]); - groups.push([ - instantiationService.createInstance(DisableGloballyAction, DisableGloballyAction.LABEL), - instantiationService.createInstance(DisableForWorkspaceAction, DisableForWorkspaceAction.LABEL) - ]); - groups.push([instantiationService.createInstance(UninstallAction)]); - groups.push([instantiationService.createInstance(InstallAnotherVersionAction)]); - groups.push([instantiationService.createInstance(ExtensionInfoAction)]); - super(ManageExtensionAction.ID, '', '', true, groups, true, instantiationService); + + super(ManageExtensionAction.ID, '', '', true, true, instantiationService); this.tooltip = localize('manage', "Manage"); @@ -614,7 +575,30 @@ export class ManageExtensionAction extends DropDownAction { this.update(); } - update(): void { + getActionGroups(runningExtensions: IExtensionDescription[]): IAction[][] { + const groups: IExtensionAction[][] = []; + groups.push([ + this.instantiationService.createInstance(EnableGloballyAction, this.extension), + this.instantiationService.createInstance(CombinedEnableForWorkspaceAction, this.extension, runningExtensions) + ]); + groups.push([ + this.instantiationService.createInstance(DisableGloballyAction, this.extension, runningExtensions), + this.instantiationService.createInstance(DisableForWorkspaceAction, this.extension, runningExtensions) + ]); + const uninstallAction = this.instantiationService.createInstance(UninstallAction); + uninstallAction.extension = this.extension; + groups.push([uninstallAction]); + groups.push([this.instantiationService.createInstance(InstallAnotherVersionAction, this.extension)]); + groups.push([this.instantiationService.createInstance(ExtensionInfoAction, this.extension)]); + + return groups; + } + + run(): Thenable { + return this.extensionService.getExtensions().then(runtimeExtensions => super.run({ actionGroups: this.getActionGroups(runtimeExtensions), disposeActionsOnHide: true })); + } + + private update(): void { this.class = ManageExtensionAction.HideManageExtensionClass; this.enabled = false; if (this.extension) { @@ -631,13 +615,7 @@ export class InstallAnotherVersionAction extends Action { static readonly ID = 'workbench.extensions.action.install.anotherVersion'; static LABEL = localize('install another version', "Install Another Version..."); - private disposables: IDisposable[] = []; - - private _extension: IExtension; - get extension(): IExtension { return this._extension; } - set extension(extension: IExtension) { this._extension = extension; this.update(); } - - constructor( + constructor(readonly extension: IExtension, @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService, @IExtensionGalleryService private extensionGalleryService: IExtensionGalleryService, @IQuickInputService private quickInputService: IQuickInputService, @@ -646,13 +624,6 @@ export class InstallAnotherVersionAction extends Action { @IOpenerService private openerService: IOpenerService ) { super(InstallAnotherVersionAction.ID, InstallAnotherVersionAction.LABEL); - extensionsWorkbenchService.onChange(extension => this.update(extension), this, this.disposables); - } - - private update(extension?: IExtension) { - if (extension && this.extension && !areSameExtensions(this.extension, extension)) { - return; - } this.enabled = this.extension && !!this.extension.gallery; } @@ -687,15 +658,11 @@ export class InstallAnotherVersionAction extends Action { } export class ExtensionInfoAction extends Action implements IExtensionAction { - static readonly ID = 'extensions.extensionInfo'; - static readonly LABEL = localize('extensionInfoAction', "Copy Extension information"); - - private _extension: IExtension; - get extension(): IExtension { return this._extension; } - set extension(extension: IExtension) { this._extension = extension; } + static readonly ID = 'extensions.extensionInfo'; + static readonly LABEL = localize('extensionInfoAction', "Copy Extension Information"); - constructor() { + constructor(readonly extension: IExtension) { super(ExtensionInfoAction.ID, ExtensionInfoAction.LABEL); } @@ -721,40 +688,20 @@ export class CombinedEnableForWorkspaceAction extends Action implements IExtensi static readonly ID = 'extensions.enableForWorkspace'; static LABEL = localize('enableForWorkspaceAction', "Enable (Workspace)"); - private disposables: IDisposable[] = []; - private enableForWorkspaceAction: EnableForWorkspaceAction; private installInRemoteServerAction: InstallInRemoteServerAction; + private disposables: IDisposable[] = []; - private _extension: IExtension; - get extension(): IExtension { return this._extension; } - set extension(extension: IExtension) { - this._extension = extension; - this.enableForWorkspaceAction.extension = extension; - this.installInRemoteServerAction.extension = extension; - this.update(); - } - - constructor(label: string, - @IWorkspaceContextService private workspaceContextService: IWorkspaceContextService, + constructor(readonly extension: IExtension, readonly runningExtensions: IExtensionDescription[], @IInstantiationService instantiationService: IInstantiationService ) { - super(EnableForWorkspaceAction.ID, label); + super(CombinedEnableForWorkspaceAction.ID, CombinedEnableForWorkspaceAction.LABEL); - this.enableForWorkspaceAction = instantiationService.createInstance(EnableForWorkspaceAction); - this.installInRemoteServerAction = instantiationService.createInstance(InstallInRemoteServerAction); - const actions = [this.enableForWorkspaceAction, this.installInRemoteServerAction]; + this.enableForWorkspaceAction = instantiationService.createInstance(EnableForWorkspaceAction, extension); + this.enableForWorkspaceAction.onDidChange(({ enabled }) => { if (!isUndefinedOrNull(enabled)) { this.update(); } }, this, this.disposables); + this.installInRemoteServerAction = instantiationService.createInstance(InstallInRemoteServerAction, extension, runningExtensions); + this.installInRemoteServerAction.onDidChange(({ enabled }) => { if (!isUndefinedOrNull(enabled)) { this.update(); } }, this, this.disposables); - this.disposables.push(...actions); - for (const action of actions) { - action.onDidChange(e => { - if (!isUndefinedOrNull(e.enabled)) { - this.update(); - } - }, this, this.disposables); - } - - this.disposables.push(this.workspaceContextService.onDidChangeWorkbenchState(() => this.update())); this.update(); } @@ -774,7 +721,8 @@ export class CombinedEnableForWorkspaceAction extends Action implements IExtensi dispose(): void { super.dispose(); - this.disposables = dispose(this.disposables); + this.enableForWorkspaceAction.dispose(); + this.installInRemoteServerAction.dispose(); } } @@ -785,22 +733,19 @@ export class EnableForWorkspaceAction extends Action implements IExtensionAction private disposables: IDisposable[] = []; - private _extension: IExtension; - get extension(): IExtension { return this._extension; } - set extension(extension: IExtension) { this._extension = extension; this.update(); } - - constructor( - @IWorkspaceContextService private workspaceContextService: IWorkspaceContextService, + constructor(readonly extension: IExtension, @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService, @IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService ) { super(EnableForWorkspaceAction.ID, EnableForWorkspaceAction.LABEL); - - this.disposables.push(this.workspaceContextService.onDidChangeWorkbenchState(() => this.update())); + this.disposables.push(extensionsWorkbenchService.onChange(e => this.update(e))); this.update(); } - private update(): void { + private update(extension?: IExtension): void { + if (extension && this.extension && !areSameExtensions(this.extension, extension)) { + return; + } this.enabled = false; if (this.extension) { this.enabled = this.extension.state === ExtensionState.Installed && (this.extension.enablementState === EnablementState.Disabled || this.extension.enablementState === EnablementState.WorkspaceDisabled) && this.extension.local && this.extensionEnablementService.canChangeEnablement(this.extension.local); @@ -813,7 +758,7 @@ export class EnableForWorkspaceAction extends Action implements IExtensionAction dispose(): void { super.dispose(); - this.disposables = dispose(this.disposables); + dispose(this.disposables); } } @@ -824,13 +769,7 @@ export class InstallInRemoteServerAction extends Action implements IExtensionAct private disposables: IDisposable[] = []; - private _extension: IExtension; - get extension(): IExtension { return this._extension; } - set extension(extension: IExtension) { this._extension = extension; this.update(); } - - private throttler: Throttler = new Throttler(); - - constructor( + constructor(readonly extension: IExtension, readonly runningExtensions: IExtensionDescription[], @IExtensionsWorkbenchService extensionWorkbenchService: IExtensionsWorkbenchService, @IExtensionManagementServerService private extensionManagementServerService: IExtensionManagementServerService, @IConfigurationService private configurationService: IConfigurationService, @@ -838,32 +777,28 @@ export class InstallInRemoteServerAction extends Action implements IExtensionAct @ILabelService private labelService: ILabelService, @IDialogService private dialogService: IDialogService, @IExtensionGalleryService private extensionGalleryService: IExtensionGalleryService, - @IExtensionService private extensionService: IExtensionService + @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService ) { super(InstallInRemoteServerAction.ID, InstallInRemoteServerAction.LABEL); - - this.disposables.push(extensionWorkbenchService.onChange(extension => this.update(extension))); + this.disposables.push(extensionsWorkbenchService.onChange(e => this.update(e))); this.update(); } - private async update(extension?: IExtension) { + private update(extension?: IExtension): void { if (extension && this.extension && !areSameExtensions(this.extension, extension)) { return; } this.enabled = false; - if (this.extension) { - if (this.extensionManagementServerService.remoteExtensionManagementServer - && this.extension && this.extension.locals && this.extension.locals.length > 0 - && !isUIExtension(this.extension.locals[0].manifest, this.configurationService) - && this.extension.state === ExtensionState.Installed) { - const installedInRemoteServer = this.extension.locals.some(local => { - const server = this.extensionManagementServerService.getExtensionManagementServer(local.location); - return server && server.authority === this.extensionManagementServerService.remoteExtensionManagementServer.authority; - }); - if (!installedInRemoteServer) { - const runningExtensions = await this.throttler.queue(() => this.extensionService.getExtensions()); - this.enabled = !runningExtensions.some(e => areSameExtensions({ id: e.id }, { id: this.extension.id })); - } + if (this.extensionManagementServerService.remoteExtensionManagementServer + && this.extension && this.extension.locals && this.extension.locals.length > 0 + && !isUIExtension(this.extension.locals[0].manifest, this.configurationService) + && this.extension.state === ExtensionState.Installed) { + const installedInRemoteServer = this.extension.locals.some(local => { + const server = this.extensionManagementServerService.getExtensionManagementServer(local.location); + return server && server.authority === this.extensionManagementServerService.remoteExtensionManagementServer.authority; + }); + if (!installedInRemoteServer) { + this.enabled = !this.runningExtensions.some(e => areSameExtensions({ id: e.id }, { id: this.extension.id })); } } } @@ -893,7 +828,7 @@ export class InstallInRemoteServerAction extends Action implements IExtensionAct dispose(): void { super.dispose(); - this.disposables = dispose(this.disposables); + dispose(this.disposables); } } @@ -904,22 +839,21 @@ export class EnableGloballyAction extends Action implements IExtensionAction { private disposables: IDisposable[] = []; - private _extension: IExtension; - get extension(): IExtension { return this._extension; } - set extension(extension: IExtension) { this._extension = extension; this.update(); } - - constructor(label: string, + constructor(readonly extension: IExtension, @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService, @IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService, @IExtensionManagementServerService private extensionManagementServerService: IExtensionManagementServerService, @IConfigurationService private configurationService: IConfigurationService ) { - super(EnableGloballyAction.ID, label); - + super(EnableGloballyAction.ID, EnableGloballyAction.LABEL); + this.disposables.push(extensionsWorkbenchService.onChange(e => this.update(e))); this.update(); } - private update(): void { + private update(extension?: IExtension): void { + if (extension && this.extension && !areSameExtensions(this.extension, extension)) { + return; + } this.enabled = false; if (this.extension && this.extension.locals && this.extension.local) { if (!isUIExtension(this.extension.local.manifest, this.configurationService) && this.extensionManagementServerService.remoteExtensionManagementServer) { @@ -940,61 +874,7 @@ export class EnableGloballyAction extends Action implements IExtensionAction { dispose(): void { super.dispose(); - this.disposables = dispose(this.disposables); - } -} - -export class EnableAction extends DropDownAction { - - static readonly ID = 'extensions.enable'; - private static readonly EnabledClass = 'extension-action enable'; - private static readonly EnabledDropDownClass = 'extension-action dropdown enable'; - private static readonly DisabledClass = `${EnableAction.EnabledClass} disabled`; - - constructor( - @IInstantiationService instantiationService: IInstantiationService, - @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService - ) { - super(EnableAction.ID, localize('enableAction', "Enable"), EnableAction.DisabledClass, false, [[ - instantiationService.createInstance(EnableGloballyAction, EnableGloballyAction.LABEL), - instantiationService.createInstance(CombinedEnableForWorkspaceAction, CombinedEnableForWorkspaceAction.LABEL) - ]], false, instantiationService); - - this.disposables.push(extensionsWorkbenchService.onChange(extension => { - if (extension && this.extension) { - if (areSameExtensions(this.extension, extension)) { - this.extension = extension; - } - } else { - this.update(); - } - })); - this.update(); - } - - protected update(): void { - const enabledActions = this.getActions().filter(a => a.enabled); - this.enabled = enabledActions.length > 0; - if (this.enabled) { - if (enabledActions.length === 1) { - this.label = enabledActions[0].label; - this.class = EnableAction.EnabledClass; - } else { - this.class = EnableAction.EnabledDropDownClass; - } - } else { - this.class = EnableAction.DisabledClass; - } - } - - public run(): Promise { - const enabledActions = this.getActions().filter(a => a.enabled); - if (enabledActions.length === 1) { - enabledActions[0].run(); - } else { - return super.run(); - } - return Promise.resolve(null); + dispose(this.disposables); } } @@ -1005,28 +885,22 @@ export class DisableForWorkspaceAction extends Action implements IExtensionActio private disposables: IDisposable[] = []; - private _extension: IExtension; - get extension(): IExtension { return this._extension; } - set extension(extension: IExtension) { this._extension = extension; this.update(); } - - private throttler: Throttler = new Throttler(); - - constructor(label: string, + constructor(readonly extension: IExtension, readonly runningExtensions: IExtensionDescription[], @IWorkspaceContextService private workspaceContextService: IWorkspaceContextService, @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService, - @IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService, - @IExtensionService private extensionService: IExtensionService + @IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService ) { - super(DisableForWorkspaceAction.ID, label); - + super(DisableForWorkspaceAction.ID, DisableForWorkspaceAction.LABEL); + this.disposables.push(extensionsWorkbenchService.onChange(e => this.update(e))); this.update(); - this.workspaceContextService.onDidChangeWorkbenchState(() => this.update(), this, this.disposables); } - private async update() { + private update(extension?: IExtension): void { + if (extension && this.extension && !areSameExtensions(this.extension, extension)) { + return; + } this.enabled = false; - const runningExtensions = await this.throttler.queue(() => this.extensionService.getExtensions()); - if (this.extension && runningExtensions.some(e => areSameExtensions({ id: e.id }, { id: this.extension.id }) && this.workspaceContextService.getWorkbenchState() !== WorkbenchState.EMPTY)) { + if (this.extension && this.runningExtensions.some(e => areSameExtensions({ id: e.id }, { id: this.extension.id }) && this.workspaceContextService.getWorkbenchState() !== WorkbenchState.EMPTY)) { this.enabled = this.extension.state === ExtensionState.Installed && (this.extension.enablementState === EnablementState.Enabled || this.extension.enablementState === EnablementState.WorkspaceEnabled) && this.extension.local && this.extensionEnablementService.canChangeEnablement(this.extension.local); } } @@ -1037,7 +911,7 @@ export class DisableForWorkspaceAction extends Action implements IExtensionActio dispose(): void { super.dispose(); - this.disposables = dispose(this.disposables); + dispose(this.disposables); } } @@ -1048,26 +922,21 @@ export class DisableGloballyAction extends Action implements IExtensionAction { private disposables: IDisposable[] = []; - private _extension: IExtension; - get extension(): IExtension { return this._extension; } - set extension(extension: IExtension) { this._extension = extension; this.update(); } - - private throttler: Throttler = new Throttler(); - - constructor(label: string, + constructor(readonly extension: IExtension, readonly runningExtensions: IExtensionDescription[], @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService, - @IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService, - @IExtensionService private extensionService: IExtensionService + @IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService ) { - super(DisableGloballyAction.ID, label); - + super(DisableGloballyAction.ID, DisableGloballyAction.LABEL); + this.disposables.push(extensionsWorkbenchService.onChange(e => this.update(e))); this.update(); } - private async update() { + private update(extension?: IExtension): void { + if (extension && this.extension && !areSameExtensions(this.extension, extension)) { + return; + } this.enabled = false; - const runningExtensions = await this.throttler.queue(() => this.extensionService.getExtensions()); - if (this.extension && runningExtensions.some(e => areSameExtensions({ id: e.id }, { id: this.extension.id }))) { + if (this.extension && this.runningExtensions.some(e => areSameExtensions({ id: e.id }, { id: this.extension.id }))) { this.enabled = this.extension.state === ExtensionState.Installed && (this.extension.enablementState === EnablementState.Enabled || this.extension.enablementState === EnablementState.WorkspaceEnabled) && this.extension.local && this.extensionEnablementService.canChangeEnablement(this.extension.local); } } @@ -1078,67 +947,86 @@ export class DisableGloballyAction extends Action implements IExtensionAction { dispose(): void { super.dispose(); - this.disposables = dispose(this.disposables); + dispose(this.disposables); } } -export class DisableAction extends DropDownAction { +export class ExtensionEditorDropDownAction extends DropDownAction { - static readonly ID = 'extensions.disable'; - - private static readonly EnabledClass = 'extension-action disable'; - private static readonly EnabledDropDownClass = 'extension-action dropdown enable'; - private static readonly DisabledClass = `${DisableAction.EnabledClass} disabled`; + private static readonly EnabledClass = 'extension-action extension-editor-dropdown-action'; + private static readonly EnabledDropDownClass = 'extension-action extension-editor-dropdown-action dropdown enable'; + private static readonly DisabledClass = `${ExtensionEditorDropDownAction.EnabledClass} disabled`; constructor( + id: string, label: string, + extension: IExtension, readonly actions: IAction[], @IInstantiationService instantiationService: IInstantiationService, @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService, ) { - super(DisableAction.ID, localize('disableAction', "Disable"), DisableAction.DisabledClass, false, [[ - instantiationService.createInstance(DisableGloballyAction, DisableGloballyAction.LABEL), - instantiationService.createInstance(DisableForWorkspaceAction, DisableForWorkspaceAction.LABEL) - ]], false, instantiationService); - - this.disposables.push(extensionsWorkbenchService.onChange(extension => { - if (extension && this.extension) { - if (areSameExtensions(this.extension, extension)) { - this.extension = extension; - } - } else { - this.update(); + super(id, label, ExtensionEditorDropDownAction.DisabledClass, false, false, instantiationService); + for (const action of this.actions) { + if (action instanceof Action) { + action.onDidChange(({ enabled }) => { + if (!isUndefinedOrNull(enabled)) { + this.update(); + } + }, this, this.disposables); } - })); + } this.update(); } - protected update(): void { - const enabledActions = this.getActions().filter(a => a.enabled); + private update(): void { + const enabledActions = this.actions.filter(a => a.enabled); this.enabled = enabledActions.length > 0; if (this.enabled) { if (enabledActions.length === 1) { this.label = enabledActions[0].label; - this.class = DisableAction.EnabledClass; + this.class = ExtensionEditorDropDownAction.EnabledClass; } else { - this.class = DisableAction.EnabledDropDownClass; + this.class = ExtensionEditorDropDownAction.EnabledDropDownClass; } } else { - this.class = DisableAction.DisabledClass; + this.class = ExtensionEditorDropDownAction.DisabledClass; } } - public run(): Promise { - const enabledActions = this.getActions().filter(a => a.enabled); + public run(): Thenable { + const enabledActions = this.actions.filter(a => a.enabled); if (enabledActions.length === 1) { enabledActions[0].run(); } else { - return super.run(); + return super.run({ actionGroups: [this.actions], disposeActionsOnHide: false }); } return Promise.resolve(null); } +} - dispose(): void { - super.dispose(); - this.disposables = dispose(this.disposables); +export class EnableDropDownAction extends ExtensionEditorDropDownAction { + + constructor( + extension: IExtension, runningExtensions: IExtensionDescription[], + @IInstantiationService instantiationService: IInstantiationService, + @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService, + ) { + super('extensions.enable', localize('enableAction', "Enable"), extension, [ + instantiationService.createInstance(EnableGloballyAction, extension), + instantiationService.createInstance(CombinedEnableForWorkspaceAction, extension, runningExtensions) + ], instantiationService, extensionsWorkbenchService); + } +} + +export class DisableDropDownAction extends ExtensionEditorDropDownAction { + + constructor( + extension: IExtension, runningExtensions: IExtensionDescription[], + @IInstantiationService instantiationService: IInstantiationService, + @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService, + ) { + super('extensions.disable', localize('disableAction', "Disable"), extension, [ + instantiationService.createInstance(DisableGloballyAction, extension, runningExtensions), + instantiationService.createInstance(DisableForWorkspaceAction, extension, runningExtensions) + ], instantiationService, extensionsWorkbenchService); } } diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts index d90d6bacc55288f461b1a26227319ae11efaaa6c..cc95f0455637dd8f81bb56aafca1f60a1802034a 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts @@ -27,7 +27,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { IModeService } from 'vs/editor/common/services/modeService'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge'; -import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; +import { ActionBar, Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { InstallWorkspaceRecommendedExtensionsAction, ConfigureWorkspaceFolderRecommendedExtensionsAction, ManageExtensionAction } from 'vs/workbench/parts/extensions/electron-browser/extensionsActions'; import { WorkbenchPagedList } from 'vs/platform/list/browser/listService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -41,6 +41,7 @@ import { IListContextMenuEvent, IListEvent } from 'vs/base/browser/ui/list/list' import { createErrorWithActions } from 'vs/base/common/errorsWithActions'; import { CancellationToken } from 'vs/base/common/cancellation'; import { getKeywordsForExtension } from 'vs/workbench/parts/extensions/electron-browser/extensionsUtils'; +import { IAction } from 'vs/base/common/actions'; export class ExtensionsListView extends ViewletPanel { @@ -162,14 +163,22 @@ export class ExtensionsListView extends ViewletPanel { private onContextMenu(e: IListContextMenuEvent): void { if (e.element) { - const manageExtensionAction = this.instantiationService.createInstance(ManageExtensionAction); - manageExtensionAction.extension = e.element; - if (manageExtensionAction.enabled) { - this.contextMenuService.showContextMenu({ - getAnchor: () => e.anchor, - getActions: () => manageExtensionAction.createActionItem().getActions() + this.extensionService.getExtensions() + .then(runningExtensions => { + const manageExtensionAction = this.instantiationService.createInstance(ManageExtensionAction); + manageExtensionAction.extension = e.element; + const groups = manageExtensionAction.getActionGroups(runningExtensions); + let actions: IAction[] = []; + for (const menuActions of groups) { + actions = [...actions, ...menuActions, new Separator()]; + } + if (manageExtensionAction.enabled) { + this.contextMenuService.showContextMenu({ + getAnchor: () => e.anchor, + getActions: () => actions.slice(0, actions.length - 1) + }); + } }); - } } } diff --git a/src/vs/workbench/parts/extensions/electron-browser/media/extensionActions.css b/src/vs/workbench/parts/extensions/electron-browser/media/extensionActions.css index 12f1b6f98ce58420781f1094211d9d622114e932..1e45e64de01d8ee594a68429c94750f191d95d55 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/media/extensionActions.css +++ b/src/vs/workbench/parts/extensions/electron-browser/media/extensionActions.css @@ -20,8 +20,7 @@ .monaco-action-bar .action-item .action-label.extension-action.multiserver.install:after, .monaco-action-bar .action-item .action-label.extension-action.multiserver.update:after, -.monaco-action-bar .action-item .action-label.extension-action.enable.dropdown:after, -.monaco-action-bar .action-item .action-label.extension-action.disable.dropdown:after { +.monaco-action-bar .action-item .action-label.extension-action.extension-editor-dropdown-action.dropdown:after { content: '▼'; padding-left: 2px; font-size: 80%; @@ -30,8 +29,7 @@ .monaco-action-bar .action-item.disabled .action-label.extension-action.install:not(.installing), .monaco-action-bar .action-item.disabled .action-label.extension-action.uninstall:not(.uninstalling), .monaco-action-bar .action-item.disabled .action-label.extension-action.update, -.monaco-action-bar .action-item.disabled .action-label.extension-action.enable, -.monaco-action-bar .action-item.disabled .action-label.extension-action.disable, +.monaco-action-bar .action-item.disabled .action-label.extension-action.extension-editor-dropdown-action, .monaco-action-bar .action-item.disabled .action-label.extension-action.reload, .monaco-action-bar .action-item.disabled .action-label.disable-status.hide, .monaco-action-bar .action-item.disabled .action-label.malicious-status.not-malicious { diff --git a/src/vs/workbench/parts/extensions/electron-browser/runtimeExtensionsEditor.ts b/src/vs/workbench/parts/extensions/electron-browser/runtimeExtensionsEditor.ts index ee32ea2855aece387391d35029e2e4d3fbc02acb..8a5eaf9bd75a90b35de45399f72d06f658c47ff6 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/runtimeExtensionsEditor.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/runtimeExtensionsEditor.ts @@ -23,7 +23,7 @@ import { ActionBar, Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import { RunOnceScheduler } from 'vs/base/common/async'; import { clipboard } from 'electron'; -import { LocalExtensionType } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { LocalExtensionType, EnablementState } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; import { writeFile } from 'vs/base/node/pfs'; @@ -31,7 +31,6 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { memoize } from 'vs/base/common/decorators'; import { isNonEmptyArray } from 'vs/base/common/arrays'; import { Event } from 'vs/base/common/event'; -import { DisableForWorkspaceAction, DisableGloballyAction } from 'vs/workbench/parts/extensions/electron-browser/extensionsActions'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { RuntimeExtensionsInput } from 'vs/workbench/services/extensions/electron-browser/runtimeExtensionsInput'; import { IDebugService } from 'vs/workbench/parts/debug/common/debug'; @@ -415,10 +414,9 @@ export class RuntimeExtensionsEditor extends BaseEditor { actions.push(new ReportExtensionIssueAction(e.element)); actions.push(new Separator()); - if (e.element.marketplaceInfo && e.element.marketplaceInfo.type === LocalExtensionType.User) { - actions.push(this._instantiationService.createInstance(DisableForWorkspaceAction, DisableForWorkspaceAction.LABEL)); - actions.push(this._instantiationService.createInstance(DisableGloballyAction, DisableGloballyAction.LABEL)); - actions.forEach((a: DisableForWorkspaceAction | DisableGloballyAction) => a.extension = e.element.marketplaceInfo); + if (e.element.marketplaceInfo) { + actions.push(new Action('runtimeExtensionsEditor.action.disableWorkspace', nls.localize('disable workspace', "Disable (Workspace)"), null, true, () => this._extensionsWorkbenchService.setEnablement(e.element.marketplaceInfo, EnablementState.WorkspaceDisabled))); + actions.push(new Action('runtimeExtensionsEditor.action.disable', nls.localize('disable', "Disable"), null, true, () => this._extensionsWorkbenchService.setEnablement(e.element.marketplaceInfo, EnablementState.Disabled))); actions.push(new Separator()); } const state = this._extensionHostProfileService.state; diff --git a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts index 1a6373d0b36f5bef6805d9fdeb00caeb977d766f..6e30c3233d3e1299e8ea4b5212679e038848bd71 100644 --- a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts @@ -371,7 +371,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, private autoUpdateDelayer: ThrottledDelayer; private disposables: IDisposable[] = []; - private readonly _onChange: Emitter = new Emitter(); + private readonly _onChange: Emitter = new Emitter({ leakWarningThreshold: 200 }); get onChange(): Event { return this._onChange.event; } private _extensionAllowedBadgeProviders: string[]; diff --git a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts index bfaf25fc2e5be16347692a7af6f17eb823431213..3604501800912db06e41c489f3c44c44aabe55cc 100644 --- a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts +++ b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts @@ -537,13 +537,12 @@ suite('ExtensionsActions Test', () => { }); test('Test EnableForWorkspaceAction when there extension is not disabled', () => { - const testObject: ExtensionsActions.EnableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.EnableForWorkspaceAction); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - testObject.extension = extensions[0]; + const testObject: ExtensionsActions.EnableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.EnableForWorkspaceAction, extensions[0]); assert.ok(!testObject.enabled); }); }); @@ -552,12 +551,11 @@ suite('ExtensionsActions Test', () => { const local = aLocalExtension('a'); return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) .then(() => { - const testObject: ExtensionsActions.EnableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.EnableForWorkspaceAction); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - testObject.extension = extensions[0]; + const testObject: ExtensionsActions.EnableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.EnableForWorkspaceAction, extensions[0]); assert.ok(testObject.enabled); }); }); @@ -567,12 +565,11 @@ suite('ExtensionsActions Test', () => { const local = aLocalExtension('a'); return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.WorkspaceDisabled) .then(() => { - const testObject: ExtensionsActions.EnableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.EnableForWorkspaceAction); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - testObject.extension = extensions[0]; + const testObject: ExtensionsActions.EnableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.EnableForWorkspaceAction, extensions[0]); assert.ok(testObject.enabled); }); }); @@ -583,31 +580,29 @@ suite('ExtensionsActions Test', () => { return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.WorkspaceDisabled)) .then(() => { - const testObject: ExtensionsActions.EnableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.EnableForWorkspaceAction); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - testObject.extension = extensions[0]; + const testObject: ExtensionsActions.EnableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.EnableForWorkspaceAction, extensions[0]); assert.ok(testObject.enabled); }); }); }); test('Test EnableGloballyAction when there is no extension', () => { - const testObject: ExtensionsActions.EnableGloballyAction = instantiationService.createInstance(ExtensionsActions.EnableGloballyAction, 'id'); + const testObject: ExtensionsActions.EnableGloballyAction = instantiationService.createInstance(ExtensionsActions.EnableGloballyAction); assert.ok(!testObject.enabled); }); test('Test EnableGloballyAction when the extension is not disabled', () => { const local = aLocalExtension('a'); - const testObject: ExtensionsActions.EnableGloballyAction = instantiationService.createInstance(ExtensionsActions.EnableGloballyAction, 'id'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - testObject.extension = extensions[0]; + const testObject: ExtensionsActions.EnableGloballyAction = instantiationService.createInstance(ExtensionsActions.EnableGloballyAction, extensions[0]); assert.ok(!testObject.enabled); }); }); @@ -616,12 +611,11 @@ suite('ExtensionsActions Test', () => { const local = aLocalExtension('a'); return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.WorkspaceDisabled) .then(() => { - const testObject: ExtensionsActions.EnableGloballyAction = instantiationService.createInstance(ExtensionsActions.EnableGloballyAction, 'id'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - testObject.extension = extensions[0]; + const testObject: ExtensionsActions.EnableGloballyAction = instantiationService.createInstance(ExtensionsActions.EnableGloballyAction, extensions[0]); assert.ok(!testObject.enabled); }); }); @@ -631,12 +625,11 @@ suite('ExtensionsActions Test', () => { const local = aLocalExtension('a'); return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) .then(() => { - const testObject: ExtensionsActions.EnableGloballyAction = instantiationService.createInstance(ExtensionsActions.EnableGloballyAction, 'id'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - testObject.extension = extensions[0]; + const testObject: ExtensionsActions.EnableGloballyAction = instantiationService.createInstance(ExtensionsActions.EnableGloballyAction, extensions[0]); assert.ok(testObject.enabled); }); }); @@ -647,106 +640,99 @@ suite('ExtensionsActions Test', () => { return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.WorkspaceDisabled)) .then(() => { - const testObject: ExtensionsActions.EnableGloballyAction = instantiationService.createInstance(ExtensionsActions.EnableGloballyAction, 'id'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - testObject.extension = extensions[0]; + const testObject: ExtensionsActions.EnableGloballyAction = instantiationService.createInstance(ExtensionsActions.EnableGloballyAction, extensions[0]); assert.ok(!testObject.enabled); }); }); }); test('Test EnableAction when there is no extension', () => { - const testObject: ExtensionsActions.EnableAction = instantiationService.createInstance(ExtensionsActions.EnableAction); + const testObject: ExtensionsActions.EnableDropDownAction = instantiationService.createInstance(ExtensionsActions.EnableDropDownAction); assert.ok(!testObject.enabled); }); - test('Test EnableAction when extension is installed and enabled', () => { - const testObject: ExtensionsActions.EnableAction = instantiationService.createInstance(ExtensionsActions.EnableAction); + test('Test EnableDropDownAction when extension is installed and enabled', () => { const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - testObject.extension = extensions[0]; + const testObject: ExtensionsActions.EnableDropDownAction = instantiationService.createInstance(ExtensionsActions.EnableDropDownAction, extensions[0], []); assert.ok(!testObject.enabled); }); }); - test('Test EnableAction when extension is installed and disabled globally', () => { + test('Test EnableDropDownAction when extension is installed and disabled globally', () => { const local = aLocalExtension('a'); return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) .then(() => { - const testObject: ExtensionsActions.EnableAction = instantiationService.createInstance(ExtensionsActions.EnableAction); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - testObject.extension = extensions[0]; + const testObject: ExtensionsActions.EnableDropDownAction = instantiationService.createInstance(ExtensionsActions.EnableDropDownAction, extensions[0], []); assert.ok(testObject.enabled); }); }); }); - test('Test EnableAction when extension is installed and disabled for workspace', () => { + test('Test EnableDropDownAction when extension is installed and disabled for workspace', () => { const local = aLocalExtension('a'); return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.WorkspaceDisabled) .then(() => { - const testObject: ExtensionsActions.EnableAction = instantiationService.createInstance(ExtensionsActions.EnableAction); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - testObject.extension = extensions[0]; + const testObject: ExtensionsActions.EnableDropDownAction = instantiationService.createInstance(ExtensionsActions.EnableDropDownAction, extensions[0], []); assert.ok(testObject.enabled); }); }); }); - test('Test EnableAction when extension is uninstalled', () => { - const testObject: ExtensionsActions.EnableAction = instantiationService.createInstance(ExtensionsActions.EnableAction); + test('Test EnableDropDownAction when extension is uninstalled', () => { const gallery = aGalleryExtension('a'); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); return instantiationService.get(IExtensionsWorkbenchService).queryGallery() .then(page => { - testObject.extension = page.firstPage[0]; + const testObject: ExtensionsActions.EnableDropDownAction = instantiationService.createInstance(ExtensionsActions.EnableDropDownAction, page.firstPage[0], []); assert.ok(!testObject.enabled); }); }); - test('Test EnableAction when extension is installing', () => { - const testObject: ExtensionsActions.EnableAction = instantiationService.createInstance(ExtensionsActions.EnableAction); + test('Test EnableDropDownAction when extension is installing', () => { const gallery = aGalleryExtension('a'); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); return instantiationService.get(IExtensionsWorkbenchService).queryGallery() .then(page => { - testObject.extension = page.firstPage[0]; + const testObject: ExtensionsActions.EnableDropDownAction = instantiationService.createInstance(ExtensionsActions.EnableDropDownAction, page.firstPage[0], []); installEvent.fire({ identifier: gallery.identifier, gallery }); assert.ok(!testObject.enabled); }); }); - test('Test EnableAction when extension is uninstalling', () => { - const testObject: ExtensionsActions.EnableAction = instantiationService.createInstance(ExtensionsActions.EnableAction); + test('Test EnableDropDownAction when extension is uninstalling', () => { const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - testObject.extension = extensions[0]; + const testObject: ExtensionsActions.EnableDropDownAction = instantiationService.createInstance(ExtensionsActions.EnableDropDownAction, extensions[0], []); uninstallEvent.fire(local.identifier); assert.ok(!testObject.enabled); }); }); test('Test DisableForWorkspaceAction when there is no extension', () => { - const testObject: ExtensionsActions.DisableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.DisableForWorkspaceAction, 'id'); + const testObject: ExtensionsActions.DisableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.DisableForWorkspaceAction); assert.ok(!testObject.enabled); }); @@ -755,12 +741,11 @@ suite('ExtensionsActions Test', () => { const local = aLocalExtension('a'); return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) .then(() => { - const testObject: ExtensionsActions.DisableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.DisableForWorkspaceAction, 'id'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - testObject.extension = extensions[0]; + const testObject: ExtensionsActions.DisableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.DisableForWorkspaceAction, extensions[0], []); assert.ok(!testObject.enabled); }); }); @@ -770,39 +755,29 @@ suite('ExtensionsActions Test', () => { const local = aLocalExtension('a'); return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) .then(() => { - const testObject: ExtensionsActions.DisableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.DisableForWorkspaceAction, 'id'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - testObject.extension = extensions[0]; + const testObject: ExtensionsActions.DisableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.DisableForWorkspaceAction, extensions[0], []); assert.ok(!testObject.enabled); }); }); }); test('Test DisableForWorkspaceAction when extension is enabled', () => { - instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ id: 'pub.a', extensionLocation: URI.file('pub.a') }]); - const testObject: ExtensionsActions.DisableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.DisableForWorkspaceAction, 'id'); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - assert.ok(!testObject.enabled); - return new Promise(c => { - testObject.onDidChange(() => { - if (testObject.enabled) { - c(); - } - }); - testObject.extension = extensions[0]; - }); + const testObject: ExtensionsActions.DisableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.DisableForWorkspaceAction, extensions[0], [{ id: 'pub.a', extensionLocation: URI.file('pub.a') }]); + assert.ok(testObject.enabled); }); }); test('Test DisableGloballyAction when there is no extension', () => { - const testObject: ExtensionsActions.DisableGloballyAction = instantiationService.createInstance(ExtensionsActions.DisableGloballyAction, 'id'); + const testObject: ExtensionsActions.DisableGloballyAction = instantiationService.createInstance(ExtensionsActions.DisableGloballyAction); assert.ok(!testObject.enabled); }); @@ -811,12 +786,11 @@ suite('ExtensionsActions Test', () => { const local = aLocalExtension('a'); return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) .then(() => { - const testObject: ExtensionsActions.DisableGloballyAction = instantiationService.createInstance(ExtensionsActions.DisableGloballyAction, 'id'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - testObject.extension = extensions[0]; + const testObject: ExtensionsActions.DisableGloballyAction = instantiationService.createInstance(ExtensionsActions.DisableGloballyAction, extensions[0], []); assert.ok(!testObject.enabled); }); }); @@ -826,127 +800,103 @@ suite('ExtensionsActions Test', () => { const local = aLocalExtension('a'); return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.WorkspaceDisabled) .then(() => { - const testObject: ExtensionsActions.DisableGloballyAction = instantiationService.createInstance(ExtensionsActions.DisableGloballyAction, 'id'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - testObject.extension = extensions[0]; + const testObject: ExtensionsActions.DisableGloballyAction = instantiationService.createInstance(ExtensionsActions.DisableGloballyAction, extensions[0], []); assert.ok(!testObject.enabled); }); }); }); test('Test DisableGloballyAction when the extension is enabled', () => { - instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ id: 'pub.a', extensionLocation: URI.file('pub.a') }]); - const testObject: ExtensionsActions.DisableGloballyAction = instantiationService.createInstance(ExtensionsActions.DisableGloballyAction, 'id'); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - assert.ok(!testObject.enabled); - return new Promise(c => { - testObject.onDidChange(() => { - if (testObject.enabled) { - c(); - } - }); - testObject.extension = extensions[0]; - }); + const testObject: ExtensionsActions.DisableGloballyAction = instantiationService.createInstance(ExtensionsActions.DisableGloballyAction, extensions[0], [{ id: 'pub.a', extensionLocation: URI.file('pub.a') }]); + assert.ok(testObject.enabled); }); }); - test('Test DisableAction when there is no extension', () => { - const testObject: ExtensionsActions.DisableAction = instantiationService.createInstance(ExtensionsActions.DisableAction); + test('Test DisableDropDownAction when there is no extension', () => { + const testObject: ExtensionsActions.DisableDropDownAction = instantiationService.createInstance(ExtensionsActions.DisableDropDownAction, null, []); assert.ok(!testObject.enabled); }); - test('Test DisableAction when extension is installed and enabled', () => { - instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ id: 'pub.a', extensionLocation: URI.file('pub.a') }]); - const testObject: ExtensionsActions.DisableAction = instantiationService.createInstance(ExtensionsActions.DisableAction); + test('Test DisableDropDownAction when extension is installed and enabled', () => { const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - assert.ok(!testObject.enabled); - return new Promise(c => { - testObject.onDidChange(() => { - if (testObject.enabled) { - c(); - } - }); - testObject.extension = extensions[0]; - }); + const testObject: ExtensionsActions.DisableDropDownAction = instantiationService.createInstance(ExtensionsActions.DisableDropDownAction, extensions[0], [{ id: 'pub.a', extensionLocation: URI.file('pub.a') }]); + assert.ok(testObject.enabled); }); }); - test('Test DisableAction when extension is installed and disabled globally', () => { + test('Test DisableDropDownAction when extension is installed and disabled globally', () => { const local = aLocalExtension('a'); return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) .then(() => { - const testObject: ExtensionsActions.DisableAction = instantiationService.createInstance(ExtensionsActions.DisableAction); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - testObject.extension = extensions[0]; + const testObject: ExtensionsActions.DisableDropDownAction = instantiationService.createInstance(ExtensionsActions.DisableDropDownAction, extensions[0], [{ id: 'pub.a', extensionLocation: URI.file('pub.a') }]); assert.ok(!testObject.enabled); }); }); }); - test('Test DisableAction when extension is installed and disabled for workspace', () => { + test('Test DisableDropDownAction when extension is installed and disabled for workspace', () => { const local = aLocalExtension('a'); return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.WorkspaceDisabled) .then(() => { - const testObject: ExtensionsActions.DisableAction = instantiationService.createInstance(ExtensionsActions.DisableAction); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - testObject.extension = extensions[0]; + const testObject: ExtensionsActions.DisableDropDownAction = instantiationService.createInstance(ExtensionsActions.DisableDropDownAction, extensions[0], [{ id: 'pub.a', extensionLocation: URI.file('pub.a') }]); assert.ok(!testObject.enabled); }); }); }); - test('Test DisableAction when extension is uninstalled', () => { - const testObject: ExtensionsActions.DisableAction = instantiationService.createInstance(ExtensionsActions.DisableAction); + test('Test DisableDropDownAction when extension is uninstalled', () => { const gallery = aGalleryExtension('a'); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); return instantiationService.get(IExtensionsWorkbenchService).queryGallery() .then(page => { - testObject.extension = page.firstPage[0]; + const testObject: ExtensionsActions.DisableDropDownAction = instantiationService.createInstance(ExtensionsActions.DisableDropDownAction, page.firstPage[0], [{ id: 'pub.a', extensionLocation: URI.file('pub.a') }]); assert.ok(!testObject.enabled); }); }); - test('Test DisableAction when extension is installing', () => { - const testObject: ExtensionsActions.DisableAction = instantiationService.createInstance(ExtensionsActions.DisableAction); + test('Test DisableDropDownAction when extension is installing', () => { const gallery = aGalleryExtension('a'); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); return instantiationService.get(IExtensionsWorkbenchService).queryGallery() .then(page => { - testObject.extension = page.firstPage[0]; + const testObject: ExtensionsActions.DisableDropDownAction = instantiationService.createInstance(ExtensionsActions.DisableDropDownAction, page.firstPage[0], [{ id: 'pub.a', extensionLocation: URI.file('pub.a') }]); installEvent.fire({ identifier: gallery.identifier, gallery }); assert.ok(!testObject.enabled); }); }); - test('Test DisableAction when extension is uninstalling', () => { - const testObject: ExtensionsActions.DisableAction = instantiationService.createInstance(ExtensionsActions.DisableAction); + test('Test DisableDropDownAction when extension is uninstalling', () => { const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - testObject.extension = extensions[0]; + const testObject: ExtensionsActions.DisableDropDownAction = instantiationService.createInstance(ExtensionsActions.DisableDropDownAction, extensions[0], [{ id: 'pub.a', extensionLocation: URI.file('pub.a') }]); uninstallEvent.fire(local.identifier); assert.ok(!testObject.enabled); });