@codingame/monaco-vscode-extension-gallery-service-override 3.2.2 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/extensionGallery.js +7 -1
  2. package/override/vs/platform/dialogs/common/dialogs.js +2 -0
  3. package/package.json +9 -9
  4. package/vscode/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.js +18 -16
  5. package/vscode/src/vs/platform/extensionManagement/common/extensionGalleryService.js +24 -23
  6. package/vscode/src/vs/platform/extensionManagement/common/extensionManagementIpc.js +5 -2
  7. package/vscode/src/vs/platform/extensionManagement/common/extensionTipsService.js +10 -0
  8. package/vscode/src/vs/workbench/contrib/extensions/browser/abstractRuntimeExtensionsEditor.js +33 -19
  9. package/vscode/src/vs/workbench/contrib/extensions/browser/configBasedRecommendations.js +1 -1
  10. package/vscode/src/vs/workbench/contrib/extensions/browser/deprecatedExtensionsChecker.js +8 -5
  11. package/vscode/src/vs/workbench/contrib/extensions/browser/exeBasedRecommendations.js +1 -1
  12. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionEditor.js +109 -40
  13. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionFeaturesTab.js +11 -8
  14. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionRecommendationNotificationService.js +31 -11
  15. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionRecommendationsService.js +35 -21
  16. package/vscode/src/vs/workbench/contrib/extensions/browser/extensions.contribution.js +54 -29
  17. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsList.js +6 -6
  18. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsViewer.js +11 -1
  19. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.js +18 -17
  20. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsViews.js +71 -31
  21. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.js +63 -20
  22. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.js +551 -134
  23. package/vscode/src/vs/workbench/contrib/extensions/browser/fileBasedRecommendations.js +3 -3
  24. package/vscode/src/vs/workbench/contrib/extensions/browser/keymapRecommendations.js +1 -1
  25. package/vscode/src/vs/workbench/contrib/extensions/browser/languageRecommendations.js +1 -1
  26. package/vscode/src/vs/workbench/contrib/extensions/browser/media/extension.css.js +1 -1
  27. package/vscode/src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css.js +1 -1
  28. package/vscode/src/vs/workbench/contrib/extensions/browser/remoteRecommendations.js +1 -1
  29. package/vscode/src/vs/workbench/contrib/extensions/browser/webRecommendations.js +1 -1
  30. package/vscode/src/vs/workbench/contrib/extensions/browser/workspaceRecommendations.js +78 -4
  31. package/vscode/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.js +7 -1
  32. package/vscode/src/vs/workbench/services/extensionManagement/browser/extensionsProfileScannerService.js +24 -0
  33. package/vscode/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.js +15 -8
  34. package/vscode/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.js +2 -2
  35. package/vscode/src/vs/workbench/services/extensionManagement/common/extensionManagementServerService.js +3 -2
  36. package/vscode/src/vs/workbench/services/extensionManagement/common/extensionManagementService.js +469 -57
  37. package/vscode/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.js +5 -2
  38. package/vscode/src/vs/workbench/services/extensionRecommendations/common/extensionIgnoredRecommendationsService.js +1 -0
  39. package/vscode/src/vs/workbench/services/extensions/browser/extensionsScannerService.js +33 -0
@@ -1,6 +1,8 @@
1
1
  import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
2
2
  import { append, $, addDisposableListener, setParentFlowTo } from 'vscode/vscode/vs/base/browser/dom';
3
3
  import { ActionBar } from 'vscode/vscode/vs/base/browser/ui/actionbar/actionbar';
4
+ import { getDefaultHoverDelegate } from 'vscode/vscode/vs/base/browser/ui/hover/hoverDelegateFactory';
5
+ import { setupCustomHover } from 'vscode/vscode/vs/base/browser/ui/hover/updatableHoverWidget';
4
6
  import { DomScrollableElement } from 'vscode/vscode/vs/base/browser/ui/scrollbar/scrollableElement';
5
7
  import { CheckboxActionViewItem } from 'vscode/vscode/vs/base/browser/ui/toggle/toggle';
6
8
  import { Action } from 'vscode/vscode/vs/base/common/actions';
@@ -33,15 +35,27 @@ import { IOpenerService } from 'vscode/vscode/vs/platform/opener/common/opener';
33
35
  import { IStorageService } from 'vscode/vscode/vs/platform/storage/common/storage';
34
36
  import { ITelemetryService } from 'vscode/vscode/vs/platform/telemetry/common/telemetry';
35
37
  import { defaultCheckboxStyles } from 'vscode/vscode/vs/platform/theme/browser/defaultStyles';
36
- import { editorBackground, textLinkForeground, textLinkActiveForeground, buttonHoverBackground, buttonForeground } from 'vscode/vscode/vs/platform/theme/common/colorRegistry';
38
+ import 'vscode/vscode/vs/platform/theme/common/colorUtils';
39
+ import { textLinkForeground, textLinkActiveForeground } from 'vscode/vscode/vs/platform/theme/common/colors/baseColors';
40
+ import 'vscode/vscode/vs/platform/theme/common/colors/chartsColors';
41
+ import { editorBackground } from 'vscode/vscode/vs/platform/theme/common/colors/editorColors';
42
+ import { buttonHoverBackground, buttonForeground } from 'vscode/vscode/vs/platform/theme/common/colors/inputColors';
43
+ import 'vscode/vscode/vs/platform/theme/common/colors/listColors';
44
+ import 'vscode/vscode/vs/platform/theme/common/colors/menuColors';
45
+ import 'vscode/vscode/vs/platform/theme/common/colors/minimapColors';
46
+ import 'vscode/vscode/vs/platform/theme/common/colors/miscColors';
47
+ import 'vscode/vscode/vs/platform/theme/common/colors/quickpickColors';
48
+ import 'vscode/vscode/vs/platform/theme/common/colors/searchColors';
37
49
  import { registerThemingParticipant, IThemeService } from 'vscode/vscode/vs/platform/theme/common/themeService';
50
+ import { IWorkspaceContextService } from 'vscode/vscode/vs/platform/workspace/common/workspace';
38
51
  import { EditorPane } from 'vscode/vscode/vs/workbench/browser/parts/editor/editorPane';
39
52
  import { ExtensionFeaturesTab } from './extensionFeaturesTab.js';
40
- import { InstallDropdownAction, ReloadAction, ExtensionStatusLabelAction, ActionWithDropDownAction, UpdateAction, ToggleAutoUpdateForExtensionAction, SetColorThemeAction, SetFileIconThemeAction, SetProductIconThemeAction, SetLanguageAction, ClearLanguageAction, EnableDropDownAction, DisableDropDownAction, RemoteInstallAction, LocalInstallAction, WebInstallAction, InstallingLabelAction, UninstallAction, MigrateDeprecatedExtensionAction, InstallAnotherVersionAction, TogglePreReleaseExtensionAction, ExtensionEditorManageExtensionAction, ExtensionDropDownAction, ExtensionActionWithDropdownActionViewItem, ExtensionStatusAction } from 'vscode/vscode/vs/workbench/contrib/extensions/browser/extensionsActions';
53
+ import { InstallDropdownAction, ExtensionRuntimeStateAction, ExtensionStatusLabelAction, ActionWithDropDownAction, UpdateAction, ToggleAutoUpdateForExtensionAction, SetColorThemeAction, SetFileIconThemeAction, SetProductIconThemeAction, SetLanguageAction, ClearLanguageAction, EnableDropDownAction, DisableDropDownAction, RemoteInstallAction, LocalInstallAction, WebInstallAction, InstallingLabelAction, UninstallAction, MigrateDeprecatedExtensionAction, InstallAnotherVersionAction, TogglePreReleaseExtensionAction, ExtensionEditorManageExtensionAction, ExtensionDropDownAction, ExtensionActionWithDropdownActionViewItem, ExtensionStatusAction } from 'vscode/vscode/vs/workbench/contrib/extensions/browser/extensionsActions';
41
54
  import { Delegate } from './extensionsList.js';
42
55
  import { ExtensionsTree, ExtensionData, ExtensionsGridView, getExtensions } from './extensionsViewer.js';
43
56
  import { RemoteBadgeWidget, VerifiedPublisherWidget, InstallCountWidget, RatingsWidget, SponsorWidget, ExtensionStatusWidget, ExtensionWidget, ExtensionRecommendationWidget, onClick } from './extensionsWidgets.js';
44
57
  import { ExtensionContainers, VIEWLET_ID, IExtensionsWorkbenchService } from 'vscode/vscode/vs/workbench/contrib/extensions/common/extensions';
58
+ import { IExplorerService } from 'vscode/vscode/vs/workbench/contrib/files/browser/files';
45
59
  import { renderMarkdownDocument, DEFAULT_MARKDOWN_STYLES } from 'vscode/vscode/vs/workbench/contrib/markdown/browser/markdownDocumentRenderer';
46
60
  import { ShowCurrentReleaseNotesActionId } from 'vscode/vscode/vs/workbench/contrib/update/common/update';
47
61
  import { KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_FOCUSED, IWebviewService } from 'vscode/vscode/vs/workbench/contrib/webview/browser/webview';
@@ -49,6 +63,9 @@ import { IEditorService } from 'vscode/vscode/vs/workbench/services/editor/commo
49
63
  import { IExtensionRecommendationsService } from 'vscode/vscode/vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
50
64
  import { IExtensionService } from 'vscode/vscode/vs/workbench/services/extensions/common/extensions';
51
65
  import { IPaneCompositePartService } from 'vscode/vscode/vs/workbench/services/panecomposite/browser/panecomposite';
66
+ import { IViewsService } from 'vscode/vscode/vs/workbench/services/views/common/viewsService';
67
+ import { VIEW_ID } from 'vscode/vscode/vs/workbench/contrib/files/common/files';
68
+ import { IUriIdentityService } from 'vscode/vscode/vs/platform/uriIdentity/common/uriIdentity';
52
69
 
53
70
  var ExtensionEditor_1;
54
71
  class NavBar extends Disposable {
@@ -107,11 +124,12 @@ class ExtensionWithDifferentGalleryVersionWidget extends ExtensionWidget {
107
124
  class VersionWidget extends ExtensionWithDifferentGalleryVersionWidget {
108
125
  constructor(container) {
109
126
  super();
110
- this.element = append(container, $('code.version', { title: ( localizeWithPath(
127
+ this.element = append(container, $('code.version'));
128
+ this._register(setupCustomHover(getDefaultHoverDelegate('mouse'), this.element, ( localizeWithPath(
111
129
  'vs/workbench/contrib/extensions/browser/extensionEditor',
112
130
  'extension version',
113
131
  "Extension Version"
114
- )) }));
132
+ ))));
115
133
  this.render();
116
134
  }
117
135
  render() {
@@ -124,8 +142,8 @@ class VersionWidget extends ExtensionWithDifferentGalleryVersionWidget {
124
142
  let ExtensionEditor = class ExtensionEditor extends EditorPane {
125
143
  static { ExtensionEditor_1 = this; }
126
144
  static { this.ID = 'workbench.editor.extension'; }
127
- constructor(telemetryService, instantiationService, paneCompositeService, extensionsWorkbenchService, extensionGalleryService, themeService, notificationService, openerService, extensionRecommendationsService, storageService, extensionService, webviewService, languageService, contextMenuService, contextKeyService) {
128
- super(ExtensionEditor_1.ID, telemetryService, themeService, storageService);
145
+ constructor(group, telemetryService, instantiationService, paneCompositeService, extensionsWorkbenchService, extensionGalleryService, themeService, notificationService, openerService, extensionRecommendationsService, storageService, extensionService, webviewService, languageService, contextMenuService, contextKeyService, contextService, explorerService, viewsService, uriIdentityService) {
146
+ super(ExtensionEditor_1.ID, group, telemetryService, themeService, storageService);
129
147
  this.instantiationService = instantiationService;
130
148
  this.paneCompositeService = paneCompositeService;
131
149
  this.extensionsWorkbenchService = extensionsWorkbenchService;
@@ -138,6 +156,10 @@ let ExtensionEditor = class ExtensionEditor extends EditorPane {
138
156
  this.languageService = languageService;
139
157
  this.contextMenuService = contextMenuService;
140
158
  this.contextKeyService = contextKeyService;
159
+ this.contextService = contextService;
160
+ this.explorerService = explorerService;
161
+ this.viewsService = viewsService;
162
+ this.uriIdentityService = uriIdentityService;
141
163
  this._scopedContextKeyService = this._register(( new MutableDisposable()));
142
164
  this.initialScrollProgress = ( new Map());
143
165
  this.currentIdentifier = '';
@@ -166,17 +188,19 @@ let ExtensionEditor = class ExtensionEditor extends EditorPane {
166
188
  const remoteBadge = this.instantiationService.createInstance(RemoteBadgeWidget, iconContainer, true);
167
189
  const details = append(header, $('.details'));
168
190
  const title = append(details, $('.title'));
169
- const name = append(title, $('span.name.clickable', { title: ( localizeWithPath(
191
+ const name = append(title, $('span.name.clickable', { role: 'heading', tabIndex: 0 }));
192
+ this._register(setupCustomHover(getDefaultHoverDelegate('mouse'), name, ( localizeWithPath(
170
193
  'vs/workbench/contrib/extensions/browser/extensionEditor',
171
194
  'name',
172
195
  "Extension name"
173
- )), role: 'heading', tabIndex: 0 }));
196
+ ))));
174
197
  const versionWidget = ( new VersionWidget(title));
175
- const preview = append(title, $('span.preview', { title: ( localizeWithPath(
198
+ const preview = append(title, $('span.preview'));
199
+ this._register(setupCustomHover(getDefaultHoverDelegate('mouse'), preview, ( localizeWithPath(
176
200
  'vs/workbench/contrib/extensions/browser/extensionEditor',
177
201
  'preview',
178
202
  "Preview"
179
- )) }));
203
+ ))));
180
204
  preview.textContent = ( localizeWithPath(
181
205
  'vs/workbench/contrib/extensions/browser/extensionEditor',
182
206
  'preview',
@@ -189,25 +213,30 @@ let ExtensionEditor = class ExtensionEditor extends EditorPane {
189
213
  "Built-in"
190
214
  ));
191
215
  const subtitle = append(details, $('.subtitle'));
192
- const publisher = append(append(subtitle, $('.subtitle-entry')), $('.publisher.clickable', { title: ( localizeWithPath(
216
+ const publisher = append(append(subtitle, $('.subtitle-entry')), $('.publisher.clickable', { tabIndex: 0 }));
217
+ this._register(setupCustomHover(getDefaultHoverDelegate('mouse'), publisher, ( localizeWithPath(
193
218
  'vs/workbench/contrib/extensions/browser/extensionEditor',
194
219
  'publisher',
195
220
  "Publisher"
196
- )), tabIndex: 0 }));
221
+ ))));
197
222
  publisher.setAttribute('role', 'button');
198
223
  const publisherDisplayName = append(publisher, $('.publisher-name'));
199
224
  const verifiedPublisherWidget = this.instantiationService.createInstance(VerifiedPublisherWidget, append(publisher, $('.verified-publisher')), false);
200
- const installCount = append(append(subtitle, $('.subtitle-entry')), $('span.install', { title: ( localizeWithPath(
225
+ const resource = append(append(subtitle, $('.subtitle-entry.resource')), $('', { tabIndex: 0 }));
226
+ resource.setAttribute('role', 'button');
227
+ const installCount = append(append(subtitle, $('.subtitle-entry')), $('span.install', { tabIndex: 0 }));
228
+ this._register(setupCustomHover(getDefaultHoverDelegate('mouse'), installCount, ( localizeWithPath(
201
229
  'vs/workbench/contrib/extensions/browser/extensionEditor',
202
230
  'install count',
203
231
  "Install count"
204
- )), tabIndex: 0 }));
232
+ ))));
205
233
  const installCountWidget = this.instantiationService.createInstance(InstallCountWidget, installCount, false);
206
- const rating = append(append(subtitle, $('.subtitle-entry')), $('span.rating.clickable', { title: ( localizeWithPath(
234
+ const rating = append(append(subtitle, $('.subtitle-entry')), $('span.rating.clickable', { tabIndex: 0 }));
235
+ this._register(setupCustomHover(getDefaultHoverDelegate('mouse'), rating, ( localizeWithPath(
207
236
  'vs/workbench/contrib/extensions/browser/extensionEditor',
208
237
  'rating',
209
238
  "Rating"
210
- )), tabIndex: 0 }));
239
+ ))));
211
240
  rating.setAttribute('role', 'link');
212
241
  const ratingsWidget = this.instantiationService.createInstance(RatingsWidget, rating, false);
213
242
  const sponsorWidget = this.instantiationService.createInstance(SponsorWidget, append(subtitle, $('.subtitle-entry')));
@@ -222,7 +251,7 @@ let ExtensionEditor = class ExtensionEditor extends EditorPane {
222
251
  const description = append(details, $('.description'));
223
252
  const installAction = this.instantiationService.createInstance(InstallDropdownAction);
224
253
  const actions = [
225
- this.instantiationService.createInstance(ReloadAction),
254
+ this.instantiationService.createInstance(ExtensionRuntimeStateAction),
226
255
  this.instantiationService.createInstance(ExtensionStatusLabelAction),
227
256
  this.instantiationService.createInstance(ActionWithDropDownAction, 'extensions.updateActions', '', [[this.instantiationService.createInstance(UpdateAction, true)], [this.instantiationService.createInstance(ToggleAutoUpdateForExtensionAction, true, [true, 'onlyEnabledExtensions'])]]),
228
257
  this.instantiationService.createInstance(SetColorThemeAction),
@@ -253,14 +282,14 @@ let ExtensionEditor = class ExtensionEditor extends EditorPane {
253
282
  ];
254
283
  const actionsAndStatusContainer = append(details, $('.actions-status-container'));
255
284
  const extensionActionBar = this._register(( new ActionBar(actionsAndStatusContainer, {
256
- actionViewItemProvider: (action) => {
285
+ actionViewItemProvider: (action, options) => {
257
286
  if (action instanceof ExtensionDropDownAction) {
258
- return action.createActionViewItem();
287
+ return action.createActionViewItem(options);
259
288
  }
260
289
  if (action instanceof ActionWithDropDownAction) {
261
290
  return ( new ExtensionActionWithDropdownActionViewItem(
262
291
  action,
263
- { icon: true, label: true, menuActionsOrProvider: { getActions: () => action.menuActions }, menuActionClassNames: (action.class || '').split(' ') },
292
+ { ...options, icon: true, label: true, menuActionsOrProvider: { getActions: () => action.menuActions }, menuActionClassNames: (action.class || '').split(' ') },
264
293
  this.contextMenuService
265
294
  ));
266
295
  }
@@ -268,7 +297,7 @@ let ExtensionEditor = class ExtensionEditor extends EditorPane {
268
297
  return ( new CheckboxActionViewItem(
269
298
  undefined,
270
299
  action,
271
- { icon: true, label: true, checkboxStyles: defaultCheckboxStyles }
300
+ { ...options, icon: true, label: true, checkboxStyles: defaultCheckboxStyles }
272
301
  ));
273
302
  }
274
303
  return undefined;
@@ -320,6 +349,7 @@ let ExtensionEditor = class ExtensionEditor extends EditorPane {
320
349
  preview,
321
350
  publisher,
322
351
  publisherDisplayName,
352
+ resource,
323
353
  rating,
324
354
  actionsAndStatusContainer,
325
355
  extensionActionBar,
@@ -368,6 +398,12 @@ let ExtensionEditor = class ExtensionEditor extends EditorPane {
368
398
  }
369
399
  }
370
400
  async getGalleryVersionToShow(extension, preRelease) {
401
+ if (extension.resourceExtension) {
402
+ return null;
403
+ }
404
+ if (extension.local?.source === 'resource') {
405
+ return null;
406
+ }
371
407
  if (isUndefined(preRelease)) {
372
408
  return null;
373
409
  }
@@ -412,6 +448,33 @@ let ExtensionEditor = class ExtensionEditor extends EditorPane {
412
448
  template.description.textContent = extension.description;
413
449
  template.publisher.classList.toggle('clickable', !!extension.url);
414
450
  template.publisherDisplayName.textContent = extension.publisherDisplayName;
451
+ template.publisher.parentElement?.classList.toggle('hide', !!extension.resourceExtension || extension.local?.source === 'resource');
452
+ const location = extension.resourceExtension?.location ?? (extension.local?.source === 'resource' ? extension.local?.location : undefined);
453
+ template.resource.parentElement?.classList.toggle('hide', !location);
454
+ if (location) {
455
+ const workspaceFolder = this.contextService.getWorkspaceFolder(location);
456
+ if (workspaceFolder && extension.isWorkspaceScoped) {
457
+ template.resource.parentElement?.classList.add('clickable');
458
+ this.transientDisposables.add(setupCustomHover(getDefaultHoverDelegate('mouse'), template.resource, this.uriIdentityService.extUri.relativePath(workspaceFolder.uri, location)));
459
+ template.resource.textContent = ( localizeWithPath(
460
+ 'vs/workbench/contrib/extensions/browser/extensionEditor',
461
+ 'workspace extension',
462
+ "Workspace Extension"
463
+ ));
464
+ this.transientDisposables.add(onClick(template.resource, () => {
465
+ this.viewsService.openView(VIEW_ID, true).then(() => this.explorerService.select(location, true));
466
+ }));
467
+ }
468
+ else {
469
+ template.resource.parentElement?.classList.remove('clickable');
470
+ this.transientDisposables.add(setupCustomHover(getDefaultHoverDelegate('mouse'), template.resource, location.path));
471
+ template.resource.textContent = ( localizeWithPath(
472
+ 'vs/workbench/contrib/extensions/browser/extensionEditor',
473
+ 'local extension',
474
+ "Local Extension"
475
+ ));
476
+ }
477
+ }
415
478
  template.installCount.parentElement?.classList.toggle('hide', !extension.url);
416
479
  template.rating.parentElement?.classList.toggle('hide', !extension.url);
417
480
  template.rating.classList.toggle('clickable', !!extension.url);
@@ -574,12 +637,12 @@ let ExtensionEditor = class ExtensionEditor extends EditorPane {
574
637
  extension: undefined,
575
638
  }));
576
639
  webview.initialScrollProgress = this.initialScrollProgress.get(webviewIndex) || 0;
577
- webview.claim(this, this.scopedContextKeyService);
640
+ webview.claim(this, this.window, this.scopedContextKeyService);
578
641
  setParentFlowTo(webview.container, container);
579
642
  webview.layoutWebviewOverElement(container);
580
643
  webview.setHtml(body);
581
- webview.claim(this, undefined);
582
- this.contentDisposables.add(webview.onDidFocus(() => this.fireOnDidFocus()));
644
+ webview.claim(this, this.window, undefined);
645
+ this.contentDisposables.add(webview.onDidFocus(() => this._onDidFocus?.fire()));
583
646
  this.contentDisposables.add(webview.onDidScroll(() => this.initialScrollProgress.set(webviewIndex, webview.initialScrollProgress)));
584
647
  const removeLayoutParticipant = insert(this.layoutParticipants, {
585
648
  layout: () => {
@@ -845,7 +908,9 @@ let ExtensionEditor = class ExtensionEditor extends EditorPane {
845
908
  ))));
846
909
  const resourcesElement = append(extensionResourcesContainer, $('.resources'));
847
910
  for (const [label, uri] of resources) {
848
- this.transientDisposables.add(onClick(append(resourcesElement, $('a.resource', { title: ( uri.toString()), tabindex: '0' }, label)), () => this.openerService.open(uri)));
911
+ const resource = append(resourcesElement, $('a.resource', { tabindex: '0' }, label));
912
+ this.transientDisposables.add(onClick(resource, () => this.openerService.open(uri)));
913
+ this.transientDisposables.add(setupCustomHover(getDefaultHoverDelegate('mouse'), resource, ( uri.toString())));
849
914
  }
850
915
  }
851
916
  }
@@ -993,21 +1058,25 @@ let ExtensionEditor = class ExtensionEditor extends EditorPane {
993
1058
  }
994
1059
  };
995
1060
  ExtensionEditor = ExtensionEditor_1 = ( __decorate([
996
- ( __param(0, ITelemetryService)),
997
- ( __param(1, IInstantiationService)),
998
- ( __param(2, IPaneCompositePartService)),
999
- ( __param(3, IExtensionsWorkbenchService)),
1000
- ( __param(4, IExtensionGalleryService)),
1001
- ( __param(5, IThemeService)),
1002
- ( __param(6, INotificationService)),
1003
- ( __param(7, IOpenerService)),
1004
- ( __param(8, IExtensionRecommendationsService)),
1005
- ( __param(9, IStorageService)),
1006
- ( __param(10, IExtensionService)),
1007
- ( __param(11, IWebviewService)),
1008
- ( __param(12, ILanguageService)),
1009
- ( __param(13, IContextMenuService)),
1010
- ( __param(14, IContextKeyService))
1061
+ ( __param(1, ITelemetryService)),
1062
+ ( __param(2, IInstantiationService)),
1063
+ ( __param(3, IPaneCompositePartService)),
1064
+ ( __param(4, IExtensionsWorkbenchService)),
1065
+ ( __param(5, IExtensionGalleryService)),
1066
+ ( __param(6, IThemeService)),
1067
+ ( __param(7, INotificationService)),
1068
+ ( __param(8, IOpenerService)),
1069
+ ( __param(9, IExtensionRecommendationsService)),
1070
+ ( __param(10, IStorageService)),
1071
+ ( __param(11, IExtensionService)),
1072
+ ( __param(12, IWebviewService)),
1073
+ ( __param(13, ILanguageService)),
1074
+ ( __param(14, IContextMenuService)),
1075
+ ( __param(15, IContextKeyService)),
1076
+ ( __param(16, IWorkspaceContextService)),
1077
+ ( __param(17, IExplorerService)),
1078
+ ( __param(18, IViewsService)),
1079
+ ( __param(19, IUriIdentityService))
1011
1080
  ], ExtensionEditor));
1012
1081
  const contextKeyExpr = ( ContextKeyExpr.and(( ContextKeyExpr.equals('activeEditor', ExtensionEditor.ID)), ( EditorContextKeys.focus.toNegated())));
1013
1082
  registerAction2(class ShowExtensionEditorFindAction extends Action2 {
@@ -20,7 +20,7 @@ import { Themable, IThemeService } from 'vscode/vscode/vs/platform/theme/common/
20
20
  import { DomScrollableElement } from 'vscode/vscode/vs/base/browser/ui/scrollbar/scrollableElement';
21
21
  import '../../../../../../../override/vs/platform/dialogs/common/dialogs.js';
22
22
  import { ThemeIcon } from 'vscode/vscode/vs/base/common/themables';
23
- import Severity from 'vscode/vscode/vs/base/common/severity';
23
+ import Severity$1 from 'vscode/vscode/vs/base/common/severity';
24
24
  import { errorIcon, warningIcon, infoIcon } from 'vscode/vscode/vs/workbench/contrib/extensions/browser/extensionsIcons';
25
25
  import { SeverityIcon } from 'vscode/vscode/vs/platform/severityIcon/browser/severityIcon';
26
26
  import { KeybindingLabel } from 'vscode/vscode/vs/base/browser/ui/keybindingLabel/keybindingLabel';
@@ -105,7 +105,7 @@ let RuntimeStatusMarkdownRenderer = class RuntimeStatusMarkdownRenderer extends
105
105
  status.messages.length
106
106
  ))}\n`);
107
107
  for (const message of status.messages) {
108
- data.appendMarkdown(`$(${(message.type === Severity.Error ? Codicon.error : message.type === Severity.Warning ? Codicon.warning : Codicon.info).id}) ${message.message}\n\n`);
108
+ data.appendMarkdown(`$(${(message.type === Severity$1.Error ? Codicon.error : message.type === Severity$1.Warning ? Codicon.warning : Codicon.info).id}) ${message.message}\n\n`);
109
109
  }
110
110
  }
111
111
  }
@@ -116,10 +116,10 @@ let RuntimeStatusMarkdownRenderer = class RuntimeStatusMarkdownRenderer extends
116
116
  data.appendMarkdown(`\n ### ${feature.label}\n\n`);
117
117
  const status = accessData?.current?.status;
118
118
  if (status) {
119
- if (status?.severity === Severity.Error) {
119
+ if (status?.severity === Severity$1.Error) {
120
120
  data.appendMarkdown(`$(${errorIcon.id}) ${status.message}\n\n`);
121
121
  }
122
- if (status?.severity === Severity.Warning) {
122
+ if (status?.severity === Severity$1.Warning) {
123
123
  data.appendMarkdown(`$(${warningIcon.id}) ${status.message}\n\n`);
124
124
  }
125
125
  }
@@ -439,7 +439,7 @@ let ExtensionFeatureView = class ExtensionFeatureView extends Disposable {
439
439
  }
440
440
  const accessData = this.extensionFeaturesManagementService.getAccessData(this.extensionId, this.feature.id);
441
441
  if (accessData?.current?.status) {
442
- append(bodyContent, $('.feature-status', undefined, $(`span${ThemeIcon.asCSSSelector(accessData.current.status.severity === Severity.Error ? errorIcon : accessData.current.status.severity === Severity.Warning ? warningIcon : infoIcon)}`, undefined), $('span', undefined, accessData.current.status.message)));
442
+ append(bodyContent, $('.feature-status', undefined, $(`span${ThemeIcon.asCSSSelector(accessData.current.status.severity === Severity$1.Error ? errorIcon : accessData.current.status.severity === Severity$1.Warning ? warningIcon : infoIcon)}`, undefined), $('span', undefined, accessData.current.status.message)));
443
443
  }
444
444
  const featureContentElement = append(bodyContent, $('.feature-content'));
445
445
  if (this.feature.renderer) {
@@ -465,15 +465,17 @@ let ExtensionFeatureView = class ExtensionFeatureView extends Disposable {
465
465
  }
466
466
  renderTableData(container, renderer) {
467
467
  const tableData = this._register(renderer.render(this.manifest));
468
+ const tableDisposable = this._register(( new MutableDisposable()));
468
469
  if (tableData.onDidChange) {
469
470
  this._register(tableData.onDidChange(data => {
470
471
  clearNode(container);
471
- this.renderTable(data, container);
472
+ tableDisposable.value = this.renderTable(data, container);
472
473
  }));
473
474
  }
474
- this.renderTable(tableData.data, container);
475
+ tableDisposable.value = this.renderTable(tableData.data, container);
475
476
  }
476
477
  renderTable(tableData, container) {
478
+ const disposables = ( new DisposableStore());
477
479
  append(container, $('table', undefined, $('tr', undefined, ...( tableData.headers.map(header => $('th', undefined, header)))), ...( tableData.rows
478
480
  .map(row => {
479
481
  return $('tr', undefined, ...( row.map(rowData => {
@@ -490,7 +492,7 @@ let ExtensionFeatureView = class ExtensionFeatureView extends Disposable {
490
492
  }
491
493
  else if (item instanceof ResolvedKeybinding) {
492
494
  const element = $('');
493
- const kbl = ( new KeybindingLabel(element, OS, defaultKeybindingLabelStyles));
495
+ const kbl = disposables.add(( new KeybindingLabel(element, OS, defaultKeybindingLabelStyles)));
494
496
  kbl.set(item);
495
497
  result.push(element);
496
498
  }
@@ -502,6 +504,7 @@ let ExtensionFeatureView = class ExtensionFeatureView extends Disposable {
502
504
  })).flat());
503
505
  })));
504
506
  }))));
507
+ return disposables;
505
508
  }
506
509
  renderMarkdownData(container, renderer) {
507
510
  container.classList.add('markdown');
@@ -5,6 +5,7 @@ import { CancellationToken } from 'vscode/vscode/vs/base/common/cancellation';
5
5
  import { isCancellationError } from 'vscode/vscode/vs/base/common/errors';
6
6
  import { Event, Emitter } from 'vscode/vscode/vs/base/common/event';
7
7
  import { Disposable, DisposableStore, isDisposable, toDisposable, MutableDisposable } from 'vscode/vscode/vs/base/common/lifecycle';
8
+ import { isString } from 'vscode/vscode/vs/base/common/types';
8
9
  import { localizeWithPath } from 'vscode/vscode/vs/nls';
9
10
  import { IConfigurationService } from 'vscode/vscode/vs/platform/configuration/common/configuration';
10
11
  import { areSameExtensions } from 'vscode/vscode/vs/platform/extensionManagement/common/extensionManagementUtil';
@@ -13,6 +14,7 @@ import { IInstantiationService } from 'vscode/vscode/vs/platform/instantiation/c
13
14
  import { Severity, INotificationService, NotificationPriority } from 'vscode/vscode/vs/platform/notification/common/notification';
14
15
  import { IStorageService } from 'vscode/vscode/vs/platform/storage/common/storage';
15
16
  import { ITelemetryService } from 'vscode/vscode/vs/platform/telemetry/common/telemetry';
17
+ import { IUriIdentityService } from 'vscode/vscode/vs/platform/uriIdentity/common/uriIdentity';
16
18
  import { IUserDataSyncEnablementService } from 'vscode/vscode/vs/platform/userDataSync/common/userDataSync';
17
19
  import { SearchExtensionsAction } from 'vscode/vscode/vs/workbench/contrib/extensions/browser/extensionsActions';
18
20
  import { IExtensionsWorkbenchService } from 'vscode/vscode/vs/workbench/contrib/extensions/common/extensions';
@@ -71,7 +73,7 @@ let ExtensionRecommendationNotificationService = class ExtensionRecommendationNo
71
73
  get ignoredRecommendations() {
72
74
  return distinct(( [...JSON.parse(this.storageService.get(ignoreImportantExtensionRecommendationStorageKey, 0 , '[]'))].map(i => i.toLowerCase())));
73
75
  }
74
- constructor(configurationService, storageService, notificationService, telemetryService, instantiationService, extensionsWorkbenchService, extensionManagementService, extensionEnablementService, extensionIgnoredRecommendationsService, userDataSyncEnablementService, workbenchEnvironmentService) {
76
+ constructor(configurationService, storageService, notificationService, telemetryService, instantiationService, extensionsWorkbenchService, extensionManagementService, extensionEnablementService, extensionIgnoredRecommendationsService, userDataSyncEnablementService, workbenchEnvironmentService, uriIdentityService) {
75
77
  super();
76
78
  this.configurationService = configurationService;
77
79
  this.storageService = storageService;
@@ -84,6 +86,7 @@ let ExtensionRecommendationNotificationService = class ExtensionRecommendationNo
84
86
  this.extensionIgnoredRecommendationsService = extensionIgnoredRecommendationsService;
85
87
  this.userDataSyncEnablementService = userDataSyncEnablementService;
86
88
  this.workbenchEnvironmentService = workbenchEnvironmentService;
89
+ this.uriIdentityService = uriIdentityService;
87
90
  this.recommendedExtensions = [];
88
91
  this.recommendationSources = [];
89
92
  this.pendingNotificaitons = [];
@@ -135,7 +138,7 @@ let ExtensionRecommendationNotificationService = class ExtensionRecommendationNo
135
138
  }
136
139
  let installed = await this.extensionManagementService.getInstalled();
137
140
  installed = installed.filter(l => this.extensionEnablementService.getEnablementState(l) !== 1 );
138
- recommendations = recommendations.filter(extensionId => installed.every(local => !areSameExtensions({ id: extensionId }, local.identifier)));
141
+ recommendations = recommendations.filter(recommendation => installed.every(local => isString(recommendation) ? !areSameExtensions({ id: recommendation }, local.identifier) : !this.uriIdentityService.extUri.isEqual(recommendation, local.location)));
139
142
  if (!recommendations.length) {
140
143
  return;
141
144
  }
@@ -164,14 +167,14 @@ let ExtensionRecommendationNotificationService = class ExtensionRecommendationNo
164
167
  return "toomany" ;
165
168
  }
166
169
  this.recommendationSources.push(source);
167
- if (source === 3 && extensionIds.every(id => this.recommendedExtensions.includes(id))) {
170
+ if (source === 3 && extensionIds.every(id => isString(id) && this.recommendedExtensions.includes(id))) {
168
171
  return "ignored" ;
169
172
  }
170
173
  const extensions = await this.getInstallableExtensions(extensionIds);
171
174
  if (!extensions.length) {
172
175
  return "ignored" ;
173
176
  }
174
- this.recommendedExtensions = distinct([...this.recommendedExtensions, ...extensionIds]);
177
+ this.recommendedExtensions = distinct([...this.recommendedExtensions, ...extensionIds.filter(isString)]);
175
178
  let extensionsMessage = '';
176
179
  if (extensions.length === 1) {
177
180
  extensionsMessage = ( localizeWithPath(
@@ -392,14 +395,30 @@ let ExtensionRecommendationNotificationService = class ExtensionRecommendationNo
392
395
  this.hideVisibleNotificationPromise = undefined;
393
396
  this.visibleNotification = undefined;
394
397
  }
395
- async getInstallableExtensions(extensionIds) {
398
+ async getInstallableExtensions(recommendations) {
396
399
  const result = [];
397
- if (extensionIds.length) {
398
- const extensions = await this.extensionsWorkbenchService.getExtensions(( extensionIds.map(id => ({ id }))), { source: 'install-recommendations' }, CancellationToken.None);
399
- for (const extension of extensions) {
400
- if (extension.gallery && (await this.extensionManagementService.canInstall(extension.gallery))) {
401
- result.push(extension);
400
+ if (recommendations.length) {
401
+ const galleryExtensions = [];
402
+ const resourceExtensions = [];
403
+ for (const recommendation of recommendations) {
404
+ if (typeof recommendation === 'string') {
405
+ galleryExtensions.push(recommendation);
402
406
  }
407
+ else {
408
+ resourceExtensions.push(recommendation);
409
+ }
410
+ }
411
+ if (galleryExtensions.length) {
412
+ const extensions = await this.extensionsWorkbenchService.getExtensions(( galleryExtensions.map(id => ({ id }))), { source: 'install-recommendations' }, CancellationToken.None);
413
+ for (const extension of extensions) {
414
+ if (extension.gallery && (await this.extensionManagementService.canInstall(extension.gallery))) {
415
+ result.push(extension);
416
+ }
417
+ }
418
+ }
419
+ if (resourceExtensions.length) {
420
+ const extensions = await this.extensionsWorkbenchService.getResourceExtensions(resourceExtensions, true);
421
+ result.push(...extensions);
403
422
  }
404
423
  }
405
424
  return result;
@@ -440,7 +459,8 @@ ExtensionRecommendationNotificationService = ( __decorate([
440
459
  ( __param(7, IWorkbenchExtensionEnablementService)),
441
460
  ( __param(8, IExtensionIgnoredRecommendationsService)),
442
461
  ( __param(9, IUserDataSyncEnablementService)),
443
- ( __param(10, IWorkbenchEnvironmentService))
462
+ ( __param(10, IWorkbenchEnvironmentService)),
463
+ ( __param(11, IUriIdentityService))
444
464
  ], ExtensionRecommendationNotificationService));
445
465
 
446
466
  export { ExtensionRecommendationNotificationService };
@@ -4,7 +4,7 @@ import { IExtensionGalleryService, IExtensionManagementService } from 'vscode/vs
4
4
  import { IExtensionIgnoredRecommendationsService } from 'vscode/vscode/vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
5
5
  import { IInstantiationService } from 'vscode/vscode/vs/platform/instantiation/common/instantiation';
6
6
  import { ITelemetryService } from 'vscode/vscode/vs/platform/telemetry/common/telemetry';
7
- import { distinct, shuffle } from 'vscode/vscode/vs/base/common/arrays';
7
+ import { shuffle } from 'vscode/vscode/vs/base/common/arrays';
8
8
  import { Emitter, Event } from 'vscode/vscode/vs/base/common/event';
9
9
  import { IEnvironmentService } from 'vscode/vscode/vs/platform/environment/common/environment';
10
10
  import { ILifecycleService } from 'vscode/vscode/vs/workbench/services/lifecycle/common/lifecycle';
@@ -23,6 +23,7 @@ import { areSameExtensions } from 'vscode/vscode/vs/platform/extensionManagement
23
23
  import { RemoteRecommendations } from './remoteRecommendations.js';
24
24
  import { IRemoteExtensionsScannerService } from 'vscode/vscode/vs/platform/remote/common/remoteExtensionsScanner';
25
25
  import { IUserDataInitializationService } from 'vscode/vscode/vs/workbench/services/userData/browser/userDataInit';
26
+ import { isString } from 'vscode/vscode/vs/base/common/types';
26
27
 
27
28
  let ExtensionRecommendationsService = class ExtensionRecommendationsService extends Disposable {
28
29
  constructor(instantiationService, lifecycleService, galleryService, telemetryService, environmentService, extensionManagementService, extensionRecommendationsManagementService, extensionRecommendationNotificationService, extensionsWorkbenchService, remoteExtensionsScannerService, userDataInitializationService) {
@@ -103,9 +104,9 @@ let ExtensionRecommendationsService = class ExtensionRecommendationsService exte
103
104
  ...this.languageRecommendations.recommendations,
104
105
  ...this.webRecommendations.recommendations,
105
106
  ];
106
- for (const { extensionId, reason } of allRecommendations) {
107
- if (this.isExtensionAllowedToBeRecommended(extensionId)) {
108
- output[extensionId.toLowerCase()] = reason;
107
+ for (const { extension, reason } of allRecommendations) {
108
+ if (isString(extension) && this.isExtensionAllowedToBeRecommended(extension)) {
109
+ output[extension.toLowerCase()] = reason;
109
110
  }
110
111
  }
111
112
  return output;
@@ -113,8 +114,8 @@ let ExtensionRecommendationsService = class ExtensionRecommendationsService exte
113
114
  async getConfigBasedRecommendations() {
114
115
  await this.configBasedRecommendations.activate();
115
116
  return {
116
- important: this.toExtensionRecommendations(this.configBasedRecommendations.importantRecommendations),
117
- others: this.toExtensionRecommendations(this.configBasedRecommendations.otherRecommendations)
117
+ important: this.toExtensionIds(this.configBasedRecommendations.importantRecommendations),
118
+ others: this.toExtensionIds(this.configBasedRecommendations.otherRecommendations)
118
119
  };
119
120
  }
120
121
  async getOtherRecommendations() {
@@ -125,8 +126,7 @@ let ExtensionRecommendationsService = class ExtensionRecommendationsService exte
125
126
  ...this.exeBasedRecommendations.otherRecommendations,
126
127
  ...this.webRecommendations.recommendations
127
128
  ];
128
- const extensionIds = distinct(( recommendations.map(e => e.extensionId)))
129
- .filter(extensionId => this.isExtensionAllowedToBeRecommended(extensionId));
129
+ const extensionIds = this.toExtensionIds(recommendations);
130
130
  shuffle(extensionIds, this.sessionSeed);
131
131
  return extensionIds;
132
132
  }
@@ -137,35 +137,45 @@ let ExtensionRecommendationsService = class ExtensionRecommendationsService exte
137
137
  ...this.configBasedRecommendations.importantRecommendations,
138
138
  ...this.exeBasedRecommendations.importantRecommendations,
139
139
  ];
140
- const extensionIds = distinct(( recommendations.map(e => e.extensionId)))
141
- .filter(extensionId => this.isExtensionAllowedToBeRecommended(extensionId));
140
+ const extensionIds = this.toExtensionIds(recommendations);
142
141
  shuffle(extensionIds, this.sessionSeed);
143
142
  return extensionIds;
144
143
  }
145
144
  getKeymapRecommendations() {
146
- return this.toExtensionRecommendations(this.keymapRecommendations.recommendations);
145
+ return this.toExtensionIds(this.keymapRecommendations.recommendations);
147
146
  }
148
147
  getLanguageRecommendations() {
149
- return this.toExtensionRecommendations(this.languageRecommendations.recommendations);
148
+ return this.toExtensionIds(this.languageRecommendations.recommendations);
150
149
  }
151
150
  getRemoteRecommendations() {
152
- return this.toExtensionRecommendations(this.remoteRecommendations.recommendations);
151
+ return this.toExtensionIds(this.remoteRecommendations.recommendations);
153
152
  }
154
153
  async getWorkspaceRecommendations() {
155
154
  if (!this.isEnabled()) {
156
155
  return [];
157
156
  }
158
157
  await this.workspaceRecommendations.activate();
159
- return this.toExtensionRecommendations(this.workspaceRecommendations.recommendations);
158
+ const result = [];
159
+ for (const { extension } of this.workspaceRecommendations.recommendations) {
160
+ if (isString(extension)) {
161
+ if (!result.includes(extension.toLowerCase()) && this.isExtensionAllowedToBeRecommended(extension)) {
162
+ result.push(extension.toLowerCase());
163
+ }
164
+ }
165
+ else {
166
+ result.push(extension);
167
+ }
168
+ }
169
+ return result;
160
170
  }
161
171
  async getExeBasedRecommendations(exe) {
162
172
  await this.exeBasedRecommendations.activate();
163
173
  const { important, others } = exe ? this.exeBasedRecommendations.getRecommendations(exe)
164
174
  : { important: this.exeBasedRecommendations.importantRecommendations, others: this.exeBasedRecommendations.otherRecommendations };
165
- return { important: this.toExtensionRecommendations(important), others: this.toExtensionRecommendations(others) };
175
+ return { important: this.toExtensionIds(important), others: this.toExtensionIds(others) };
166
176
  }
167
177
  getFileBasedRecommendations() {
168
- return this.toExtensionRecommendations(this.fileBasedRecommendations.recommendations);
178
+ return this.toExtensionIds(this.fileBasedRecommendations.recommendations);
169
179
  }
170
180
  onDidInstallExtensions(results) {
171
181
  for (const e of results) {
@@ -178,9 +188,13 @@ let ExtensionRecommendationsService = class ExtensionRecommendationsService exte
178
188
  }
179
189
  }
180
190
  }
181
- toExtensionRecommendations(recommendations) {
182
- const extensionIds = distinct(( recommendations.map(e => e.extensionId)))
183
- .filter(extensionId => this.isExtensionAllowedToBeRecommended(extensionId));
191
+ toExtensionIds(recommendations) {
192
+ const extensionIds = [];
193
+ for (const { extension } of recommendations) {
194
+ if (isString(extension) && this.isExtensionAllowedToBeRecommended(extension) && !extensionIds.includes(extension.toLowerCase())) {
195
+ extensionIds.push(extension.toLowerCase());
196
+ }
197
+ }
184
198
  return extensionIds;
185
199
  }
186
200
  isExtensionAllowedToBeRecommended(extensionId) {
@@ -192,8 +206,8 @@ let ExtensionRecommendationsService = class ExtensionRecommendationsService exte
192
206
  ...this.workspaceRecommendations.recommendations,
193
207
  ...this.configBasedRecommendations.importantRecommendations.filter(recommendation => !recommendation.whenNotInstalled || recommendation.whenNotInstalled.every(id => installed.every(local => !areSameExtensions(local.identifier, { id }))))
194
208
  ]
195
- .map(({ extensionId }) => extensionId))
196
- .filter(extensionId => this.isExtensionAllowedToBeRecommended(extensionId));
209
+ .map(({ extension }) => extension))
210
+ .filter(extension => !isString(extension) || this.isExtensionAllowedToBeRecommended(extension));
197
211
  if (allowedRecommendations.length) {
198
212
  await this._registerP(timeout(5000));
199
213
  await this.extensionRecommendationNotificationService.promptWorkspaceRecommendations(allowedRecommendations);