Skip to content

Commit b7a44e4

Browse files
committed
Implement microsoft#17068
1 parent 982abc5 commit b7a44e4

10 files changed

Lines changed: 74 additions & 56 deletions

File tree

src/vs/workbench/parts/extensions/browser/extensionEditor.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
2525
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
2626
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
2727
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
28-
import { IExtensionManifest, IKeyBinding, IView, IExtensionTipsService } from 'vs/platform/extensionManagement/common/extensionManagement';
28+
import { IExtensionManifest, IKeyBinding, IView, IExtensionTipsService, LocalExtensionType } from 'vs/platform/extensionManagement/common/extensionManagement';
2929
import { ResolvedKeybinding, KeyMod, KeyCode } from 'vs/base/common/keyCodes';
3030
import { ExtensionsInput } from 'vs/workbench/parts/extensions/common/extensionsInput';
3131
import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID, IExtension, IExtensionDependencies } from 'vs/workbench/parts/extensions/common/extensions';
3232
import { Renderer, DataSource, Controller } from 'vs/workbench/parts/extensions/browser/dependenciesViewer';
3333
import { RatingsWidget, InstallCountWidget } from 'vs/workbench/parts/extensions/browser/extensionsWidgets';
3434
import { EditorOptions } from 'vs/workbench/common/editor';
3535
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
36-
import { CombinedInstallAction, UpdateAction, EnableAction, DisableAction, BuiltinStatusLabelAction, ReloadAction, MaliciousStatusLabelAction } from 'vs/workbench/parts/extensions/browser/extensionsActions';
36+
import { CombinedInstallAction, UpdateAction, EnableAction, DisableAction, ReloadAction, MaliciousStatusLabelAction } from 'vs/workbench/parts/extensions/browser/extensionsActions';
3737
import { Webview } from 'vs/workbench/parts/html/browser/webview';
3838
import { KeybindingIO } from 'vs/workbench/services/keybinding/common/keybindingIO';
3939
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
@@ -156,6 +156,7 @@ export class ExtensionEditor extends BaseEditor {
156156
private name: HTMLElement;
157157
private identifier: HTMLElement;
158158
private preview: HTMLElement;
159+
private builtin: HTMLElement;
159160
private license: HTMLElement;
160161
private publisher: HTMLElement;
161162
private installCount: HTMLElement;
@@ -220,7 +221,12 @@ export class ExtensionEditor extends BaseEditor {
220221
const title = append(details, $('.title'));
221222
this.name = append(title, $('span.name.clickable', { title: localize('name', "Extension name") }));
222223
this.identifier = append(title, $('span.identifier', { title: localize('extension id', "Extension identifier") }));
224+
223225
this.preview = append(title, $('span.preview', { title: localize('preview', "Preview") }));
226+
this.preview.textContent = localize('preview', "Preview");
227+
228+
this.builtin = append(title, $('span.builtin'));
229+
this.builtin.textContent = localize('builtin', "Built-in");
224230

225231
const subtitle = append(details, $('.subtitle'));
226232
this.publisher = append(subtitle, $('span.publisher.clickable', { title: localize('publisher', "Publisher name") }));
@@ -283,11 +289,8 @@ export class ExtensionEditor extends BaseEditor {
283289

284290
this.name.textContent = extension.displayName;
285291
this.identifier.textContent = extension.id;
286-
if (extension.preview) {
287-
this.preview.textContent = localize('preview', "Preview");
288-
} else {
289-
this.preview.textContent = null;
290-
}
292+
this.preview.style.display = extension.preview ? 'inherit' : 'none';
293+
this.builtin.style.display = extension.type === LocalExtensionType.System ? 'inherit' : 'none';
291294

292295
this.publisher.textContent = extension.publisherDisplayName;
293296
this.description.textContent = extension.description;
@@ -346,7 +349,6 @@ export class ExtensionEditor extends BaseEditor {
346349
const ratings = this.instantiationService.createInstance(RatingsWidget, this.rating, { extension });
347350
this.transientDisposables.push(ratings);
348351

349-
const builtinStatusAction = this.instantiationService.createInstance(BuiltinStatusLabelAction);
350352
const maliciousStatusAction = this.instantiationService.createInstance(MaliciousStatusLabelAction, true);
351353
const installAction = this.instantiationService.createInstance(CombinedInstallAction);
352354
const updateAction = this.instantiationService.createInstance(UpdateAction);
@@ -355,16 +357,15 @@ export class ExtensionEditor extends BaseEditor {
355357
const reloadAction = this.instantiationService.createInstance(ReloadAction);
356358

357359
installAction.extension = extension;
358-
builtinStatusAction.extension = extension;
359360
maliciousStatusAction.extension = extension;
360361
updateAction.extension = extension;
361362
enableAction.extension = extension;
362363
disableAction.extension = extension;
363364
reloadAction.extension = extension;
364365

365366
this.extensionActionBar.clear();
366-
this.extensionActionBar.push([reloadAction, updateAction, enableAction, disableAction, installAction, builtinStatusAction, maliciousStatusAction], { icon: true, label: true });
367-
this.transientDisposables.push(enableAction, updateAction, reloadAction, disableAction, installAction, builtinStatusAction, maliciousStatusAction);
367+
this.extensionActionBar.push([reloadAction, updateAction, enableAction, disableAction, installAction, maliciousStatusAction], { icon: true, label: true });
368+
this.transientDisposables.push(enableAction, updateAction, reloadAction, disableAction, installAction, maliciousStatusAction);
368369

369370
this.navbar.clear();
370371
this.navbar.onChange(this.onNavbarChange.bind(this, extension), this, this.transientDisposables);

src/vs/workbench/parts/extensions/browser/extensionsActions.ts

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ export class ManageExtensionAction extends Action {
392392
this.class = ManageExtensionAction.HideManageExtensionClass;
393393
this.tooltip = '';
394394
this.enabled = false;
395-
if (this.extension && this.extension.type !== LocalExtensionType.System) {
395+
if (this.extension) {
396396
const state = this.extension.state;
397397
this.enabled = state === ExtensionState.Installed;
398398
this.class = this.enabled || state === ExtensionState.Uninstalling ? ManageExtensionAction.Class : ManageExtensionAction.HideManageExtensionClass;
@@ -573,7 +573,7 @@ export class DisableForWorkspaceAction extends Action implements IExtensionActio
573573
private update(): void {
574574
this.enabled = false;
575575
if (this.extension && this.workspaceContextService.getWorkbenchState() !== WorkbenchState.EMPTY) {
576-
this.enabled = this.extension.type !== LocalExtensionType.System && (this.extension.enablementState === EnablementState.Enabled || this.extension.enablementState === EnablementState.WorkspaceEnabled) && this.extension.local && this.extensionEnablementService.canChangeEnablement(this.extension.local);
576+
this.enabled = (this.extension.enablementState === EnablementState.Enabled || this.extension.enablementState === EnablementState.WorkspaceEnabled) && this.extension.local && this.extensionEnablementService.canChangeEnablement(this.extension.local);
577577
}
578578
}
579579

@@ -611,7 +611,7 @@ export class DisableGloballyAction extends Action implements IExtensionAction {
611611
private update(): void {
612612
this.enabled = false;
613613
if (this.extension) {
614-
this.enabled = this.extension.type !== LocalExtensionType.System && (this.extension.enablementState === EnablementState.Enabled || this.extension.enablementState === EnablementState.WorkspaceEnabled) && this.extension.local && this.extensionEnablementService.canChangeEnablement(this.extension.local);
614+
this.enabled = (this.extension.enablementState === EnablementState.Enabled || this.extension.enablementState === EnablementState.WorkspaceEnabled) && this.extension.local && this.extensionEnablementService.canChangeEnablement(this.extension.local);
615615
}
616616
}
617617

@@ -665,7 +665,7 @@ export class DisableAction extends Action {
665665
return;
666666
}
667667

668-
this.enabled = this.extension.state === ExtensionState.Installed && this.extension.type !== LocalExtensionType.System && this._disableActions.some(a => a.enabled);
668+
this.enabled = this.extension.state === ExtensionState.Installed && this._disableActions.some(a => a.enabled);
669669
this.class = this.enabled ? DisableAction.EnabledClass : DisableAction.DisabledClass;
670670
}
671671

@@ -1004,6 +1004,29 @@ export class ClearExtensionsInputAction extends Action {
10041004
}
10051005
}
10061006

1007+
export class ShowBuiltInExtensionsAction extends Action {
1008+
1009+
static readonly ID = 'workbench.extensions.action.listBuiltInExtensions';
1010+
static LABEL = localize('showBuiltInExtensions', "Show Built-in Extensions");
1011+
1012+
constructor(
1013+
id: string,
1014+
label: string,
1015+
@IViewletService private viewletService: IViewletService
1016+
) {
1017+
super(id, label, null, true);
1018+
}
1019+
1020+
run(): TPromise<void> {
1021+
return this.viewletService.openViewlet(VIEWLET_ID, true)
1022+
.then(viewlet => viewlet as IExtensionsViewlet)
1023+
.then(viewlet => {
1024+
viewlet.search('@builtin ');
1025+
viewlet.focus();
1026+
});
1027+
}
1028+
}
1029+
10071030
export class ShowOutdatedExtensionsAction extends Action {
10081031

10091032
static readonly ID = 'workbench.extensions.action.listOutdatedExtensions';
@@ -1530,31 +1553,6 @@ export class ConfigureWorkspaceFolderRecommendedExtensionsAction extends Abstrac
15301553
}
15311554
}
15321555

1533-
export class BuiltinStatusLabelAction extends Action {
1534-
1535-
private static readonly Class = 'built-in-status';
1536-
1537-
private _extension: IExtension;
1538-
get extension(): IExtension { return this._extension; }
1539-
set extension(extension: IExtension) { this._extension = extension; this.update(); }
1540-
1541-
constructor() {
1542-
super('extensions.install', localize('builtin', "Built-in"), '', false);
1543-
}
1544-
1545-
private update(): void {
1546-
if (this.extension && this.extension.type === LocalExtensionType.System) {
1547-
this.class = `${BuiltinStatusLabelAction.Class} system`;
1548-
} else {
1549-
this.class = `${BuiltinStatusLabelAction.Class} user`;
1550-
}
1551-
}
1552-
1553-
run(): TPromise<any> {
1554-
return TPromise.as(null);
1555-
}
1556-
}
1557-
15581556
export class MaliciousStatusLabelAction extends Action {
15591557

15601558
private static readonly Class = 'malicious-status';

src/vs/workbench/parts/extensions/browser/extensionsList.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { IPagedRenderer } from 'vs/base/browser/ui/list/listPaging';
1616
import { once } from 'vs/base/common/event';
1717
import { domEvent } from 'vs/base/browser/event';
1818
import { IExtension, IExtensionsWorkbenchService } from 'vs/workbench/parts/extensions/common/extensions';
19-
import { InstallAction, UpdateAction, BuiltinStatusLabelAction, ManageExtensionAction, ReloadAction, extensionButtonProminentBackground, extensionButtonProminentForeground, MaliciousStatusLabelAction } from 'vs/workbench/parts/extensions/browser/extensionsActions';
19+
import { InstallAction, UpdateAction, ManageExtensionAction, ReloadAction, extensionButtonProminentBackground, extensionButtonProminentForeground, MaliciousStatusLabelAction } from 'vs/workbench/parts/extensions/browser/extensionsActions';
2020
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
2121
import { Label, RatingsWidget, InstallCountWidget } from 'vs/workbench/parts/extensions/browser/extensionsWidgets';
2222
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
@@ -96,15 +96,14 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
9696
const installCountWidget = this.instantiationService.createInstance(InstallCountWidget, installCount, { small: true });
9797
const ratingsWidget = this.instantiationService.createInstance(RatingsWidget, ratings, { small: true });
9898

99-
const builtinStatusAction = this.instantiationService.createInstance(BuiltinStatusLabelAction);
10099
const maliciousStatusAction = this.instantiationService.createInstance(MaliciousStatusLabelAction, false);
101100
const installAction = this.instantiationService.createInstance(InstallAction);
102101
const updateAction = this.instantiationService.createInstance(UpdateAction);
103102
const reloadAction = this.instantiationService.createInstance(ReloadAction);
104103
const manageAction = this.instantiationService.createInstance(ManageExtensionAction);
105104

106-
actionbar.push([reloadAction, updateAction, installAction, builtinStatusAction, maliciousStatusAction, manageAction], actionOptions);
107-
const disposables = [versionWidget, installCountWidget, ratingsWidget, builtinStatusAction, maliciousStatusAction, updateAction, reloadAction, manageAction, actionbar, bookmarkStyler];
105+
actionbar.push([reloadAction, updateAction, installAction, maliciousStatusAction, manageAction], actionOptions);
106+
const disposables = [versionWidget, installCountWidget, ratingsWidget, maliciousStatusAction, updateAction, reloadAction, manageAction, actionbar, bookmarkStyler];
108107

109108
return {
110109
root, element, icon, name, installCount, ratings, author, description, disposables,
@@ -113,7 +112,6 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
113112
versionWidget.extension = extension;
114113
installCountWidget.extension = extension;
115114
ratingsWidget.extension = extension;
116-
builtinStatusAction.extension = extension;
117115
maliciousStatusAction.extension = extension;
118116
installAction.extension = extension;
119117
updateAction.extension = extension;
Lines changed: 1 addition & 0 deletions
Loading

src/vs/workbench/parts/extensions/browser/media/extensionActions.css

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,10 @@
3030
.monaco-action-bar .action-item.disabled .action-label.extension-action.enable,
3131
.monaco-action-bar .action-item.disabled .action-label.extension-action.disable,
3232
.monaco-action-bar .action-item.disabled .action-label.extension-action.reload,
33-
.monaco-action-bar .action-item.disabled .action-label.built-in-status.user,
3433
.monaco-action-bar .action-item.disabled .action-label.malicious-status.not-malicious {
3534
display: none;
3635
}
3736

38-
.monaco-action-bar .action-item .action-label.built-in-status
3937
.monaco-action-bar .action-item .action-label.malicious-status {
4038
border-radius: 4px;
4139
color: inherit;
@@ -46,7 +44,6 @@
4644
line-height: initial;
4745
}
4846

49-
.extension-editor>.header>.details>.actions>.monaco-action-bar .action-item .action-label.built-in-status,
5047
.extension-editor>.header>.details>.actions>.monaco-action-bar .action-item .action-label.malicious-status {
5148
font-weight: normal;
5249
}

src/vs/workbench/parts/extensions/browser/media/extensionEditor.css

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@
6161
white-space: nowrap;
6262
}
6363

64+
.extension-editor > .header > .details > .title > .builtin {
65+
font-size: 10px;
66+
font-style: italic;
67+
margin-left: 10px;
68+
}
69+
6470
.vs .extension-editor > .header > .details > .title > .preview {
6571
color: white;
6672
}
@@ -337,4 +343,4 @@
337343
font-size: 90%;
338344
font-weight: 600;
339345
opacity: 0.6;
340-
}
346+
}

src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID, ExtensionS
2929
import {
3030
ShowEnabledExtensionsAction, ShowInstalledExtensionsAction, ShowRecommendedExtensionsAction, ShowPopularExtensionsAction, ShowDisabledExtensionsAction,
3131
ShowOutdatedExtensionsAction, ClearExtensionsInputAction, ChangeSortAction, UpdateAllAction, CheckForUpdatesAction, DisableAllAction, EnableAllAction,
32-
EnableAutoUpdateAction, DisableAutoUpdateAction
32+
EnableAutoUpdateAction, DisableAutoUpdateAction, ShowBuiltInExtensionsAction
3333
} from 'vs/workbench/parts/extensions/browser/extensionsActions';
3434
import { LocalExtensionType, IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
3535
import { InstallVSIXAction } from 'vs/workbench/parts/extensions/electron-browser/extensionsActions';
@@ -298,6 +298,7 @@ export class ExtensionsViewlet extends PersistentViewsViewlet implements IExtens
298298
this.instantiationService.createInstance(ShowOutdatedExtensionsAction, ShowOutdatedExtensionsAction.ID, ShowOutdatedExtensionsAction.LABEL),
299299
this.instantiationService.createInstance(ShowEnabledExtensionsAction, ShowEnabledExtensionsAction.ID, ShowEnabledExtensionsAction.LABEL),
300300
this.instantiationService.createInstance(ShowDisabledExtensionsAction, ShowDisabledExtensionsAction.ID, ShowDisabledExtensionsAction.LABEL),
301+
this.instantiationService.createInstance(ShowBuiltInExtensionsAction, ShowBuiltInExtensionsAction.ID, ShowBuiltInExtensionsAction.LABEL),
301302
this.instantiationService.createInstance(ShowRecommendedExtensionsAction, ShowRecommendedExtensionsAction.ID, ShowRecommendedExtensionsAction.LABEL),
302303
this.instantiationService.createInstance(ShowPopularExtensionsAction, ShowPopularExtensionsAction.ID, ShowPopularExtensionsAction.LABEL),
303304
new Separator(),

src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,18 @@ export class ExtensionsListView extends ViewsViewletPanel {
146146
case 'name': options = assign(options, { sortBy: SortBy.Title }); break;
147147
}
148148

149+
if (!value || ExtensionsListView.isBuiltInExtensionsQuery(value)) {
150+
// Show installed extensions
151+
value = value ? value.replace(/@builtin/g, '').replace(/@sort:(\w+)(-\w*)?/g, '').trim().toLowerCase() : '';
152+
153+
let result = await this.extensionsWorkbenchService.queryLocal();
154+
155+
result = result
156+
.filter(e => e.type === LocalExtensionType.System && e.name.toLowerCase().indexOf(value) > -1);
157+
158+
return new PagedModel(this.sortExtensions(result, options));
159+
}
160+
149161
if (!value || ExtensionsListView.isInstalledExtensionsQuery(value)) {
150162
// Show installed extensions
151163
value = value ? value.replace(/@installed/g, '').replace(/@sort:(\w+)(-\w*)?/g, '').trim().toLowerCase() : '';
@@ -470,6 +482,10 @@ export class ExtensionsListView extends ViewsViewletPanel {
470482
super.dispose();
471483
}
472484

485+
static isBuiltInExtensionsQuery(query: string): boolean {
486+
return /@builtin/i.test(query);
487+
}
488+
473489
static isInstalledExtensionsQuery(query: string): boolean {
474490
return /@installed/i.test(query);
475491
}

src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ class Extension implements IExtension {
138138
}
139139

140140
private get defaultIconUrl(): string {
141+
if (this.type === LocalExtensionType.System) {
142+
return require.toUrl('../browser/media/code-icon.svg');
143+
}
141144
return require.toUrl('../browser/media/defaultIcon.png');
142145
}
143146

@@ -588,10 +591,6 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService {
588591
}
589592

590593
setEnablement(extension: IExtension, enablementState: EnablementState): TPromise<void> {
591-
if (extension.type === LocalExtensionType.System) {
592-
return TPromise.wrap<void>(void 0);
593-
}
594-
595594
const enable = enablementState === EnablementState.Enabled || enablementState === EnablementState.WorkspaceEnabled;
596595
return this.promptAndSetEnablement(extension, enablementState, enable).then(reload => {
597596
/* __GDPR__

src/vs/workbench/services/extensions/electron-browser/extensionService.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -470,8 +470,9 @@ export class ExtensionService extends Disposable implements IExtensionService {
470470
let userMigratedSystemExtensions: IExtensionIdentifier[] = [{ id: BetterMergeId }];
471471

472472
system.forEach((systemExtension) => {
473-
// Disabling system extensions is not supported
474-
result[systemExtension.id] = systemExtension;
473+
if (disabledExtensions.every(disabled => !areSameExtensions(disabled, systemExtension))) {
474+
result[systemExtension.id] = systemExtension;
475+
}
475476
});
476477

477478
user.forEach((userExtension) => {

0 commit comments

Comments
 (0)