@codingame/monaco-vscode-extension-gallery-service-override 1.83.9
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.
- package/extensionGallery.d.ts +12 -0
- package/extensionGallery.js +76 -0
- package/external/rollup-plugin-styles/dist/runtime/inject-css.js +3 -0
- package/external/tslib/tslib.es6.js +11 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/override/vs/platform/dialogs/common/dialogs.js +8 -0
- package/package.json +30 -0
- package/vscode/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.js +784 -0
- package/vscode/src/vs/platform/extensionManagement/common/extensionEnablementService.js +142 -0
- package/vscode/src/vs/platform/extensionManagement/common/extensionGalleryService.js +855 -0
- package/vscode/src/vs/platform/extensionManagement/common/extensionManagementIpc.js +119 -0
- package/vscode/src/vs/platform/extensionManagement/common/extensionTipsService.js +57 -0
- package/vscode/src/vs/platform/extensionManagement/common/unsupportedExtensionsMigration.js +58 -0
- package/vscode/src/vs/platform/externalServices/common/marketplace.js +17 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/abstractRuntimeExtensionsEditor.js +492 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/browserRuntimeExtensionsEditor.js +28 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/configBasedRecommendations.js +78 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/deprecatedExtensionsChecker.js +87 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/exeBasedRecommendations.js +60 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/extensionEditor.js +1868 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/extensionEnablementWorkspaceTrustTransitionParticipant.js +52 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/extensionRecommendationNotificationService.js +437 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/extensionRecommendations.js +17 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/extensionRecommendationsService.js +221 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/extensions.contribution.js +2063 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/extensions.web.contribution.js +13 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsActivationProgress.js +46 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsCompletionItemsProvider.js +65 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsDependencyChecker.js +98 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsList.js +224 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsQuickAccess.js +121 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsViewer.js +285 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.js +912 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsViews.js +1270 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.js +824 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.js +1730 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/fileBasedRecommendations.js +324 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/keymapRecommendations.js +28 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/languageRecommendations.js +28 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/media/extension.css.js +6 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css.js +6 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css.js +6 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/media/extensionsWidgets.css.js +6 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/media/runtimeExtensionsEditor.css.js +6 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/remoteRecommendations.js +29 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/unsupportedExtensionsMigrationContribution.js +26 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/webRecommendations.js +38 -0
- package/vscode/src/vs/workbench/contrib/extensions/browser/workspaceRecommendations.js +88 -0
- package/vscode/src/vs/workbench/contrib/extensions/common/extensionQuery.js +67 -0
- package/vscode/src/vs/workbench/contrib/extensions/common/extensionsInput.js +43 -0
- package/vscode/src/vs/workbench/contrib/extensions/common/extensionsUtils.js +104 -0
- package/vscode/src/vs/workbench/contrib/extensions/common/reportExtensionIssueAction.js +31 -0
- package/vscode/src/vs/workbench/contrib/extensions/common/runtimeExtensionsInput.js +41 -0
- package/vscode/src/vs/workbench/contrib/markdown/browser/markdownDocumentRenderer.js +207 -0
- package/vscode/src/vs/workbench/contrib/update/common/update.js +3 -0
- package/vscode/src/vs/workbench/services/extensionManagement/browser/builtinExtensionsScannerService.js +84 -0
- package/vscode/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.js +634 -0
- package/vscode/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.js +883 -0
- package/vscode/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.js +109 -0
- package/vscode/src/vs/workbench/services/extensionManagement/common/extensionManagementServerService.js +62 -0
- package/vscode/src/vs/workbench/services/extensionManagement/common/extensionManagementService.js +633 -0
- package/vscode/src/vs/workbench/services/extensionManagement/common/remoteExtensionManagementService.js +58 -0
- package/vscode/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.js +269 -0
- package/vscode/src/vs/workbench/services/extensionRecommendations/common/extensionIgnoredRecommendationsService.js +83 -0
- package/vscode/src/vs/workbench/services/remote/common/remoteExtensionsScanner.js +73 -0
|
@@ -0,0 +1,1270 @@
|
|
|
1
|
+
import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
|
|
2
|
+
import { localizeWithPath } from 'monaco-editor/esm/vs/nls.js';
|
|
3
|
+
import { DisposableStore, toDisposable, Disposable } from 'monaco-editor/esm/vs/base/common/lifecycle.js';
|
|
4
|
+
import { Event, Emitter } from 'monaco-editor/esm/vs/base/common/event.js';
|
|
5
|
+
import { isCancellationError, getErrorMessage } from 'monaco-editor/esm/vs/base/common/errors.js';
|
|
6
|
+
import { createErrorWithActions } from 'monaco-editor/esm/vs/base/common/errorMessage.js';
|
|
7
|
+
import { PagedModel, DelayedPagedModel } from 'monaco-editor/esm/vs/base/common/paging.js';
|
|
8
|
+
import { IExtensionManagementServerService, IWorkbenchExtensionManagementService, IWorkbenchExtensionEnablementService } from 'vscode/vscode/vs/workbench/services/extensionManagement/common/extensionManagement';
|
|
9
|
+
import { IExtensionRecommendationsService } from 'vscode/vscode/vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
|
|
10
|
+
import { areSameExtensions, getExtensionDependencies } from 'vscode/vscode/vs/platform/extensionManagement/common/extensionManagementUtil';
|
|
11
|
+
import { IKeybindingService } from 'monaco-editor/esm/vs/platform/keybinding/common/keybinding.js';
|
|
12
|
+
import { IContextMenuService } from 'monaco-editor/esm/vs/platform/contextview/browser/contextView.js';
|
|
13
|
+
import { append, $ } from 'monaco-editor/esm/vs/base/browser/dom.js';
|
|
14
|
+
import { IInstantiationService } from 'monaco-editor/esm/vs/platform/instantiation/common/instantiation.js';
|
|
15
|
+
import { Renderer, Delegate } from './extensionsList.js';
|
|
16
|
+
import { IExtensionsWorkbenchService } from 'vscode/vscode/vs/workbench/contrib/extensions/common/extensions';
|
|
17
|
+
import { Query } from '../common/extensionQuery.js';
|
|
18
|
+
import { toExtension, IExtensionService } from 'vscode/vscode/vs/workbench/services/extensions/common/extensions';
|
|
19
|
+
import { IThemeService } from 'monaco-editor/esm/vs/platform/theme/common/themeService.js';
|
|
20
|
+
import { ITelemetryService } from 'monaco-editor/esm/vs/platform/telemetry/common/telemetry.js';
|
|
21
|
+
import { CountBadge } from 'monaco-editor/esm/vs/base/browser/ui/countBadge/countBadge.js';
|
|
22
|
+
import { ManageExtensionAction, getContextMenuActions, ExtensionAction } from 'vscode/vscode/vs/workbench/contrib/extensions/browser/extensionsActions';
|
|
23
|
+
import { WorkbenchPagedList } from 'monaco-editor/esm/vs/platform/list/browser/listService.js';
|
|
24
|
+
import { IConfigurationService } from 'monaco-editor/esm/vs/platform/configuration/common/configuration.js';
|
|
25
|
+
import { Severity, INotificationService } from 'monaco-editor/esm/vs/platform/notification/common/notification.js';
|
|
26
|
+
import { ViewPane, ViewPaneShowActions } from 'vscode/vscode/vs/workbench/browser/parts/views/viewPane';
|
|
27
|
+
import { IWorkspaceContextService } from 'monaco-editor/esm/vs/platform/workspace/common/workspace.js';
|
|
28
|
+
import { coalesce, distinct, flatten } from 'monaco-editor/esm/vs/base/common/arrays.js';
|
|
29
|
+
import { alert } from 'monaco-editor/esm/vs/base/browser/ui/aria/aria.js';
|
|
30
|
+
import { CancellationToken } from 'monaco-editor/esm/vs/base/common/cancellation.js';
|
|
31
|
+
import { ActionRunner, Separator, Action } from 'monaco-editor/esm/vs/base/common/actions.js';
|
|
32
|
+
import { ExtensionIdentifierMap, isLanguagePackExtension } from 'monaco-editor/esm/vs/platform/extensions/common/extensions.js';
|
|
33
|
+
import { createCancelablePromise, ThrottledDelayer } from 'monaco-editor/esm/vs/base/common/async.js';
|
|
34
|
+
import { IProductService } from 'monaco-editor/esm/vs/platform/product/common/productService.js';
|
|
35
|
+
import { SeverityIcon } from 'monaco-editor/esm/vs/platform/severityIcon/browser/severityIcon.js';
|
|
36
|
+
import { IContextKeyService } from 'monaco-editor/esm/vs/platform/contextkey/common/contextkey.js';
|
|
37
|
+
import { SIDE_BAR_BACKGROUND } from 'vscode/vscode/vs/workbench/common/theme';
|
|
38
|
+
import { IViewDescriptorService } from 'vscode/vscode/vs/workbench/common/views';
|
|
39
|
+
import { IOpenerService } from 'monaco-editor/esm/vs/platform/opener/common/opener.js';
|
|
40
|
+
import { IPreferencesService } from 'vscode/vscode/vs/workbench/services/preferences/common/preferences';
|
|
41
|
+
import { IStorageService } from 'monaco-editor/esm/vs/platform/storage/common/storage.js';
|
|
42
|
+
import { IExtensionManifestPropertiesService } from 'vscode/vscode/vs/workbench/services/extensions/common/extensionManifestPropertiesService';
|
|
43
|
+
import { isVirtualWorkspace } from 'vscode/vscode/vs/platform/workspace/common/virtualWorkspace';
|
|
44
|
+
import { IWorkspaceTrustManagementService } from 'monaco-editor/esm/vs/platform/workspace/common/workspaceTrust.js';
|
|
45
|
+
import { IWorkbenchLayoutService } from 'vscode/vscode/vs/workbench/services/layout/browser/layoutService';
|
|
46
|
+
import { ILogService } from 'monaco-editor/esm/vs/platform/log/common/log.js';
|
|
47
|
+
import { isOfflineError } from 'vscode/vscode/vs/base/parts/request/common/request';
|
|
48
|
+
import { defaultCountBadgeStyles } from 'monaco-editor/esm/vs/platform/theme/browser/defaultStyles.js';
|
|
49
|
+
|
|
50
|
+
var ExtensionsListView_1;
|
|
51
|
+
const FORCE_FEATURE_EXTENSIONS = ['vscode.git', 'vscode.git-base', 'vscode.search-result'];
|
|
52
|
+
class ExtensionsViewState extends Disposable {
|
|
53
|
+
constructor() {
|
|
54
|
+
super(...arguments);
|
|
55
|
+
this._onFocus = this._register(( new Emitter()));
|
|
56
|
+
this.onFocus = this._onFocus.event;
|
|
57
|
+
this._onBlur = this._register(( new Emitter()));
|
|
58
|
+
this.onBlur = this._onBlur.event;
|
|
59
|
+
this.currentlyFocusedItems = [];
|
|
60
|
+
}
|
|
61
|
+
onFocusChange(extensions) {
|
|
62
|
+
this.currentlyFocusedItems.forEach(extension => this._onBlur.fire(extension));
|
|
63
|
+
this.currentlyFocusedItems = extensions;
|
|
64
|
+
this.currentlyFocusedItems.forEach(extension => this._onFocus.fire(extension));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function isLocalSortBy(value) {
|
|
68
|
+
switch (value) {
|
|
69
|
+
case "UpdateDate" : return true;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
let ExtensionsListView = class ExtensionsListView extends ViewPane {
|
|
73
|
+
static { ExtensionsListView_1 = this; }
|
|
74
|
+
static { this.RECENT_UPDATE_DURATION = 7 * 24 * 60 * 60 * 1000; }
|
|
75
|
+
constructor(options, viewletViewOptions, notificationService, keybindingService, contextMenuService, instantiationService, themeService, extensionService, extensionsWorkbenchService, extensionRecommendationsService, telemetryService, configurationService, contextService, extensionManagementServerService, extensionManifestPropertiesService, extensionManagementService, workspaceService, productService, contextKeyService, viewDescriptorService, openerService, preferencesService, storageService, workspaceTrustManagementService, extensionEnablementService, layoutService, logService) {
|
|
76
|
+
super({
|
|
77
|
+
...viewletViewOptions,
|
|
78
|
+
showActions: ViewPaneShowActions.Always,
|
|
79
|
+
maximumBodySize: options.flexibleHeight ? (storageService.getNumber(`${viewletViewOptions.id}.size`, 0 , 0) ? undefined : 0) : undefined
|
|
80
|
+
}, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService);
|
|
81
|
+
this.options = options;
|
|
82
|
+
this.notificationService = notificationService;
|
|
83
|
+
this.extensionService = extensionService;
|
|
84
|
+
this.extensionsWorkbenchService = extensionsWorkbenchService;
|
|
85
|
+
this.extensionRecommendationsService = extensionRecommendationsService;
|
|
86
|
+
this.contextService = contextService;
|
|
87
|
+
this.extensionManagementServerService = extensionManagementServerService;
|
|
88
|
+
this.extensionManifestPropertiesService = extensionManifestPropertiesService;
|
|
89
|
+
this.extensionManagementService = extensionManagementService;
|
|
90
|
+
this.workspaceService = workspaceService;
|
|
91
|
+
this.productService = productService;
|
|
92
|
+
this.preferencesService = preferencesService;
|
|
93
|
+
this.storageService = storageService;
|
|
94
|
+
this.workspaceTrustManagementService = workspaceTrustManagementService;
|
|
95
|
+
this.extensionEnablementService = extensionEnablementService;
|
|
96
|
+
this.layoutService = layoutService;
|
|
97
|
+
this.logService = logService;
|
|
98
|
+
this.list = null;
|
|
99
|
+
this.queryRequest = null;
|
|
100
|
+
this.contextMenuActionRunner = this._register(( new ActionRunner()));
|
|
101
|
+
if (this.options.onDidChangeTitle) {
|
|
102
|
+
this._register(this.options.onDidChangeTitle(title => this.updateTitle(title)));
|
|
103
|
+
}
|
|
104
|
+
this._register(this.contextMenuActionRunner.onDidRun(({ error }) => error && this.notificationService.error(error)));
|
|
105
|
+
this.registerActions();
|
|
106
|
+
}
|
|
107
|
+
registerActions() { }
|
|
108
|
+
renderHeader(container) {
|
|
109
|
+
container.classList.add('extension-view-header');
|
|
110
|
+
super.renderHeader(container);
|
|
111
|
+
if (!this.options.hideBadge) {
|
|
112
|
+
this.badge = ( new CountBadge(append(container, $('.count-badge-wrapper')), {}, defaultCountBadgeStyles));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
renderBody(container) {
|
|
116
|
+
super.renderBody(container);
|
|
117
|
+
const extensionsList = append(container, $('.extensions-list'));
|
|
118
|
+
const messageContainer = append(container, $('.message-container'));
|
|
119
|
+
const messageSeverityIcon = append(messageContainer, $(''));
|
|
120
|
+
const messageBox = append(messageContainer, $('.message'));
|
|
121
|
+
const delegate = ( new Delegate());
|
|
122
|
+
const extensionsViewState = ( new ExtensionsViewState());
|
|
123
|
+
const renderer = this.instantiationService.createInstance(Renderer, extensionsViewState, { hoverOptions: { position: () => { return this.layoutService.getSideBarPosition() === 0 ? 1 : 0 ; } } });
|
|
124
|
+
this.list = this.instantiationService.createInstance(WorkbenchPagedList, 'Extensions', extensionsList, delegate, [renderer], {
|
|
125
|
+
multipleSelectionSupport: false,
|
|
126
|
+
setRowLineHeight: false,
|
|
127
|
+
horizontalScrolling: false,
|
|
128
|
+
accessibilityProvider: {
|
|
129
|
+
getAriaLabel(extension) {
|
|
130
|
+
return getAriaLabelForExtension(extension);
|
|
131
|
+
},
|
|
132
|
+
getWidgetAriaLabel() {
|
|
133
|
+
return ( localizeWithPath(
|
|
134
|
+
'vs/workbench/contrib/extensions/browser/extensionsViews',
|
|
135
|
+
'extensions',
|
|
136
|
+
"Extensions"
|
|
137
|
+
));
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
overrideStyles: {
|
|
141
|
+
listBackground: SIDE_BAR_BACKGROUND
|
|
142
|
+
},
|
|
143
|
+
openOnSingleClick: true
|
|
144
|
+
});
|
|
145
|
+
this._register(this.list.onContextMenu(e => this.onContextMenu(e), this));
|
|
146
|
+
this._register(this.list.onDidChangeFocus(e => extensionsViewState.onFocusChange(coalesce(e.elements)), this));
|
|
147
|
+
this._register(this.list);
|
|
148
|
+
this._register(extensionsViewState);
|
|
149
|
+
this._register(Event.debounce(Event.filter(this.list.onDidOpen, e => e.element !== null), (_, event) => event, 75, true)(options => {
|
|
150
|
+
this.openExtension(options.element, { sideByside: options.sideBySide, ...options.editorOptions });
|
|
151
|
+
}));
|
|
152
|
+
this.bodyTemplate = {
|
|
153
|
+
extensionsList,
|
|
154
|
+
messageBox,
|
|
155
|
+
messageContainer,
|
|
156
|
+
messageSeverityIcon
|
|
157
|
+
};
|
|
158
|
+
if (this.queryResult) {
|
|
159
|
+
this.setModel(this.queryResult.model);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
layoutBody(height, width) {
|
|
163
|
+
super.layoutBody(height, width);
|
|
164
|
+
if (this.bodyTemplate) {
|
|
165
|
+
this.bodyTemplate.extensionsList.style.height = height + 'px';
|
|
166
|
+
}
|
|
167
|
+
this.list?.layout(height, width);
|
|
168
|
+
}
|
|
169
|
+
async show(query, refresh) {
|
|
170
|
+
if (this.queryRequest) {
|
|
171
|
+
if (!refresh && this.queryRequest.query === query) {
|
|
172
|
+
return this.queryRequest.request;
|
|
173
|
+
}
|
|
174
|
+
this.queryRequest.request.cancel();
|
|
175
|
+
this.queryRequest = null;
|
|
176
|
+
}
|
|
177
|
+
if (this.queryResult) {
|
|
178
|
+
this.queryResult.disposables.dispose();
|
|
179
|
+
this.queryResult = undefined;
|
|
180
|
+
}
|
|
181
|
+
const parsedQuery = Query.parse(query);
|
|
182
|
+
const options = {
|
|
183
|
+
sortOrder: 0
|
|
184
|
+
};
|
|
185
|
+
switch (parsedQuery.sortBy) {
|
|
186
|
+
case 'installs':
|
|
187
|
+
options.sortBy = 4 ;
|
|
188
|
+
break;
|
|
189
|
+
case 'rating':
|
|
190
|
+
options.sortBy = 12 ;
|
|
191
|
+
break;
|
|
192
|
+
case 'name':
|
|
193
|
+
options.sortBy = 2 ;
|
|
194
|
+
break;
|
|
195
|
+
case 'publishedDate':
|
|
196
|
+
options.sortBy = 10 ;
|
|
197
|
+
break;
|
|
198
|
+
case 'updateDate':
|
|
199
|
+
options.sortBy = "UpdateDate" ;
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
const request = createCancelablePromise(async (token) => {
|
|
203
|
+
try {
|
|
204
|
+
this.queryResult = await this.query(parsedQuery, options, token);
|
|
205
|
+
const model = this.queryResult.model;
|
|
206
|
+
this.setModel(model);
|
|
207
|
+
if (this.queryResult.onDidChangeModel) {
|
|
208
|
+
this.queryResult.disposables.add(this.queryResult.onDidChangeModel(model => {
|
|
209
|
+
if (this.queryResult) {
|
|
210
|
+
this.queryResult.model = model;
|
|
211
|
+
this.updateModel(model);
|
|
212
|
+
}
|
|
213
|
+
}));
|
|
214
|
+
}
|
|
215
|
+
return model;
|
|
216
|
+
}
|
|
217
|
+
catch (e) {
|
|
218
|
+
const model = ( new PagedModel([]));
|
|
219
|
+
if (!isCancellationError(e)) {
|
|
220
|
+
this.logService.error(e);
|
|
221
|
+
this.setModel(model, e);
|
|
222
|
+
}
|
|
223
|
+
return this.list ? this.list.model : model;
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
request.finally(() => this.queryRequest = null);
|
|
227
|
+
this.queryRequest = { query, request };
|
|
228
|
+
return request;
|
|
229
|
+
}
|
|
230
|
+
count() {
|
|
231
|
+
return this.queryResult?.model.length ?? 0;
|
|
232
|
+
}
|
|
233
|
+
showEmptyModel() {
|
|
234
|
+
const emptyModel = ( new PagedModel([]));
|
|
235
|
+
this.setModel(emptyModel);
|
|
236
|
+
return Promise.resolve(emptyModel);
|
|
237
|
+
}
|
|
238
|
+
async onContextMenu(e) {
|
|
239
|
+
if (e.element) {
|
|
240
|
+
const disposables = ( new DisposableStore());
|
|
241
|
+
const manageExtensionAction = disposables.add(this.instantiationService.createInstance(ManageExtensionAction));
|
|
242
|
+
const extension = e.element ? this.extensionsWorkbenchService.local.find(local => areSameExtensions(local.identifier, e.element.identifier) && (!e.element.server || e.element.server === local.server)) || e.element
|
|
243
|
+
: e.element;
|
|
244
|
+
manageExtensionAction.extension = extension;
|
|
245
|
+
let groups = [];
|
|
246
|
+
if (manageExtensionAction.enabled) {
|
|
247
|
+
groups = await manageExtensionAction.getActionGroups();
|
|
248
|
+
}
|
|
249
|
+
else if (extension) {
|
|
250
|
+
groups = await getContextMenuActions(extension, this.contextKeyService, this.instantiationService);
|
|
251
|
+
groups.forEach(group => group.forEach(extensionAction => {
|
|
252
|
+
if (extensionAction instanceof ExtensionAction) {
|
|
253
|
+
extensionAction.extension = extension;
|
|
254
|
+
}
|
|
255
|
+
}));
|
|
256
|
+
}
|
|
257
|
+
let actions = [];
|
|
258
|
+
for (const menuActions of groups) {
|
|
259
|
+
actions = [...actions, ...menuActions, ( new Separator())];
|
|
260
|
+
}
|
|
261
|
+
actions.pop();
|
|
262
|
+
this.contextMenuService.showContextMenu({
|
|
263
|
+
getAnchor: () => e.anchor,
|
|
264
|
+
getActions: () => actions,
|
|
265
|
+
actionRunner: this.contextMenuActionRunner,
|
|
266
|
+
onHide: () => disposables.dispose()
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
async query(query, options, token) {
|
|
271
|
+
const idRegex = /@id:(([a-z0-9A-Z][a-z0-9\-A-Z]*)\.([a-z0-9A-Z][a-z0-9\-A-Z]*))/g;
|
|
272
|
+
const ids = [];
|
|
273
|
+
let idMatch;
|
|
274
|
+
while ((idMatch = idRegex.exec(query.value)) !== null) {
|
|
275
|
+
const name = idMatch[1];
|
|
276
|
+
ids.push(name);
|
|
277
|
+
}
|
|
278
|
+
if (ids.length) {
|
|
279
|
+
const model = await this.queryByIds(ids, options, token);
|
|
280
|
+
return { model, disposables: ( new DisposableStore()) };
|
|
281
|
+
}
|
|
282
|
+
if (ExtensionsListView_1.isLocalExtensionsQuery(query.value, query.sortBy)) {
|
|
283
|
+
return this.queryLocal(query, options);
|
|
284
|
+
}
|
|
285
|
+
if (ExtensionsListView_1.isSearchPopularQuery(query.value)) {
|
|
286
|
+
query.value = query.value.replace('@popular', '');
|
|
287
|
+
options.sortBy = !options.sortBy ? 4 : options.sortBy;
|
|
288
|
+
}
|
|
289
|
+
else if (ExtensionsListView_1.isSearchRecentlyPublishedQuery(query.value)) {
|
|
290
|
+
query.value = query.value.replace('@recentlyPublished', '');
|
|
291
|
+
options.sortBy = !options.sortBy ? 10 : options.sortBy;
|
|
292
|
+
}
|
|
293
|
+
const galleryQueryOptions = { ...options, sortBy: isLocalSortBy(options.sortBy) ? undefined : options.sortBy };
|
|
294
|
+
const model = await this.queryGallery(query, galleryQueryOptions, token);
|
|
295
|
+
return { model, disposables: ( new DisposableStore()) };
|
|
296
|
+
}
|
|
297
|
+
async queryByIds(ids, options, token) {
|
|
298
|
+
const idsSet = ids.reduce((result, id) => { result.add(id.toLowerCase()); return result; }, ( new Set()));
|
|
299
|
+
const result = (await this.extensionsWorkbenchService.queryLocal(this.options.server))
|
|
300
|
+
.filter(e => ( idsSet.has(e.identifier.id.toLowerCase())));
|
|
301
|
+
const galleryIds = result.length ? ids.filter(id => result.every(r => !areSameExtensions(r.identifier, { id }))) : ids;
|
|
302
|
+
if (galleryIds.length) {
|
|
303
|
+
const galleryResult = await this.extensionsWorkbenchService.getExtensions(( galleryIds.map(id => ({ id }))), { source: 'queryById' }, token);
|
|
304
|
+
result.push(...galleryResult);
|
|
305
|
+
}
|
|
306
|
+
return this.getPagedModel(result);
|
|
307
|
+
}
|
|
308
|
+
async queryLocal(query, options) {
|
|
309
|
+
const local = await this.extensionsWorkbenchService.queryLocal(this.options.server);
|
|
310
|
+
let { extensions, canIncludeInstalledExtensions } = await this.filterLocal(local, this.extensionService.extensions, query, options);
|
|
311
|
+
const disposables = ( new DisposableStore());
|
|
312
|
+
const onDidChangeModel = disposables.add(( new Emitter()));
|
|
313
|
+
if (canIncludeInstalledExtensions) {
|
|
314
|
+
let isDisposed = false;
|
|
315
|
+
disposables.add(toDisposable(() => isDisposed = true));
|
|
316
|
+
disposables.add(Event.debounce(Event.any(Event.filter(this.extensionsWorkbenchService.onChange, e => e?.state === 1 ), this.extensionService.onDidChangeExtensions), () => undefined)(async () => {
|
|
317
|
+
const local = this.options.server ? this.extensionsWorkbenchService.installed.filter(e => e.server === this.options.server) : this.extensionsWorkbenchService.local;
|
|
318
|
+
const { extensions: newExtensions } = await this.filterLocal(local, this.extensionService.extensions, query, options);
|
|
319
|
+
if (!isDisposed) {
|
|
320
|
+
const mergedExtensions = this.mergeAddedExtensions(extensions, newExtensions);
|
|
321
|
+
if (mergedExtensions) {
|
|
322
|
+
extensions = mergedExtensions;
|
|
323
|
+
onDidChangeModel.fire(( new PagedModel(extensions)));
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}));
|
|
327
|
+
}
|
|
328
|
+
return {
|
|
329
|
+
model: ( new PagedModel(extensions)),
|
|
330
|
+
onDidChangeModel: onDidChangeModel.event,
|
|
331
|
+
disposables
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
async filterLocal(local, runningExtensions, query, options) {
|
|
335
|
+
const value = query.value;
|
|
336
|
+
let extensions = [];
|
|
337
|
+
let canIncludeInstalledExtensions = true;
|
|
338
|
+
if (/@builtin/i.test(value)) {
|
|
339
|
+
extensions = this.filterBuiltinExtensions(local, query, options);
|
|
340
|
+
canIncludeInstalledExtensions = false;
|
|
341
|
+
}
|
|
342
|
+
else if (/@installed/i.test(value)) {
|
|
343
|
+
extensions = this.filterInstalledExtensions(local, runningExtensions, query, options);
|
|
344
|
+
}
|
|
345
|
+
else if (/@outdated/i.test(value)) {
|
|
346
|
+
extensions = this.filterOutdatedExtensions(local, query, options);
|
|
347
|
+
}
|
|
348
|
+
else if (/@disabled/i.test(value)) {
|
|
349
|
+
extensions = this.filterDisabledExtensions(local, runningExtensions, query, options);
|
|
350
|
+
}
|
|
351
|
+
else if (/@enabled/i.test(value)) {
|
|
352
|
+
extensions = this.filterEnabledExtensions(local, runningExtensions, query, options);
|
|
353
|
+
}
|
|
354
|
+
else if (/@workspaceUnsupported/i.test(value)) {
|
|
355
|
+
extensions = this.filterWorkspaceUnsupportedExtensions(local, query, options);
|
|
356
|
+
}
|
|
357
|
+
else if (/@deprecated/i.test(query.value)) {
|
|
358
|
+
extensions = await this.filterDeprecatedExtensions(local, query, options);
|
|
359
|
+
}
|
|
360
|
+
else if (/@recentlyUpdated/i.test(query.value)) {
|
|
361
|
+
extensions = this.filterRecentlyUpdatedExtensions(local, query, options);
|
|
362
|
+
}
|
|
363
|
+
return { extensions, canIncludeInstalledExtensions };
|
|
364
|
+
}
|
|
365
|
+
filterBuiltinExtensions(local, query, options) {
|
|
366
|
+
let value = query.value;
|
|
367
|
+
const showThemesOnly = /@builtin:themes/i.test(value);
|
|
368
|
+
if (showThemesOnly) {
|
|
369
|
+
value = value.replace(/@builtin:themes/g, '');
|
|
370
|
+
}
|
|
371
|
+
const showBasicsOnly = /@builtin:basics/i.test(value);
|
|
372
|
+
if (showBasicsOnly) {
|
|
373
|
+
value = value.replace(/@builtin:basics/g, '');
|
|
374
|
+
}
|
|
375
|
+
const showFeaturesOnly = /@builtin:features/i.test(value);
|
|
376
|
+
if (showFeaturesOnly) {
|
|
377
|
+
value = value.replace(/@builtin:features/g, '');
|
|
378
|
+
}
|
|
379
|
+
value = value.replace(/@builtin/g, '').replace(/@sort:(\w+)(-\w*)?/g, '').trim().toLowerCase();
|
|
380
|
+
const result = local
|
|
381
|
+
.filter(e => e.isBuiltin && (e.name.toLowerCase().indexOf(value) > -1 || e.displayName.toLowerCase().indexOf(value) > -1));
|
|
382
|
+
const isThemeExtension = (e) => {
|
|
383
|
+
return (Array.isArray(e.local?.manifest?.contributes?.themes) && e.local.manifest.contributes.themes.length > 0)
|
|
384
|
+
|| (Array.isArray(e.local?.manifest?.contributes?.iconThemes) && e.local.manifest.contributes.iconThemes.length > 0);
|
|
385
|
+
};
|
|
386
|
+
if (showThemesOnly) {
|
|
387
|
+
const themesExtensions = result.filter(isThemeExtension);
|
|
388
|
+
return this.sortExtensions(themesExtensions, options);
|
|
389
|
+
}
|
|
390
|
+
const isLanguageBasicExtension = (e) => {
|
|
391
|
+
return FORCE_FEATURE_EXTENSIONS.indexOf(e.identifier.id) === -1
|
|
392
|
+
&& (Array.isArray(e.local?.manifest?.contributes?.grammars) && e.local.manifest.contributes.grammars.length > 0);
|
|
393
|
+
};
|
|
394
|
+
if (showBasicsOnly) {
|
|
395
|
+
const basics = result.filter(isLanguageBasicExtension);
|
|
396
|
+
return this.sortExtensions(basics, options);
|
|
397
|
+
}
|
|
398
|
+
if (showFeaturesOnly) {
|
|
399
|
+
const others = result.filter(e => {
|
|
400
|
+
return e.local
|
|
401
|
+
&& e.local.manifest
|
|
402
|
+
&& !isThemeExtension(e)
|
|
403
|
+
&& !isLanguageBasicExtension(e);
|
|
404
|
+
});
|
|
405
|
+
return this.sortExtensions(others, options);
|
|
406
|
+
}
|
|
407
|
+
return this.sortExtensions(result, options);
|
|
408
|
+
}
|
|
409
|
+
parseCategories(value) {
|
|
410
|
+
const categories = [];
|
|
411
|
+
value = value.replace(/\bcategory:("([^"]*)"|([^"]\S*))(\s+|\b|$)/g, (_, quotedCategory, category) => {
|
|
412
|
+
const entry = (category || quotedCategory || '').toLowerCase();
|
|
413
|
+
if (categories.indexOf(entry) === -1) {
|
|
414
|
+
categories.push(entry);
|
|
415
|
+
}
|
|
416
|
+
return '';
|
|
417
|
+
});
|
|
418
|
+
return { value, categories };
|
|
419
|
+
}
|
|
420
|
+
filterInstalledExtensions(local, runningExtensions, query, options) {
|
|
421
|
+
let { value, categories } = this.parseCategories(query.value);
|
|
422
|
+
value = value.replace(/@installed/g, '').replace(/@sort:(\w+)(-\w*)?/g, '').trim().toLowerCase();
|
|
423
|
+
const matchingText = (e) => (e.name.toLowerCase().indexOf(value) > -1 || e.displayName.toLowerCase().indexOf(value) > -1)
|
|
424
|
+
&& (!categories.length || ( categories.some(category => ( (e.local && e.local.manifest.categories || []).some(c => c.toLowerCase() === category)))));
|
|
425
|
+
let result;
|
|
426
|
+
if (options.sortBy !== undefined) {
|
|
427
|
+
result = local.filter(e => !e.isBuiltin && matchingText(e));
|
|
428
|
+
result = this.sortExtensions(result, options);
|
|
429
|
+
}
|
|
430
|
+
else {
|
|
431
|
+
result = local.filter(e => (!e.isBuiltin || e.outdated || e.reloadRequiredStatus !== undefined) && matchingText(e));
|
|
432
|
+
const runningExtensionsById = runningExtensions.reduce((result, e) => { result.set(e.identifier.value, e); return result; }, ( new ExtensionIdentifierMap()));
|
|
433
|
+
const defaultSort = (e1, e2) => {
|
|
434
|
+
const running1 = runningExtensionsById.get(e1.identifier.id);
|
|
435
|
+
const isE1Running = !!running1 && this.extensionManagementServerService.getExtensionManagementServer(toExtension(running1)) === e1.server;
|
|
436
|
+
const running2 = runningExtensionsById.get(e2.identifier.id);
|
|
437
|
+
const isE2Running = running2 && this.extensionManagementServerService.getExtensionManagementServer(toExtension(running2)) === e2.server;
|
|
438
|
+
if ((isE1Running && isE2Running)) {
|
|
439
|
+
return e1.displayName.localeCompare(e2.displayName);
|
|
440
|
+
}
|
|
441
|
+
const isE1LanguagePackExtension = e1.local && isLanguagePackExtension(e1.local.manifest);
|
|
442
|
+
const isE2LanguagePackExtension = e2.local && isLanguagePackExtension(e2.local.manifest);
|
|
443
|
+
if (!isE1Running && !isE2Running) {
|
|
444
|
+
if (isE1LanguagePackExtension) {
|
|
445
|
+
return -1;
|
|
446
|
+
}
|
|
447
|
+
if (isE2LanguagePackExtension) {
|
|
448
|
+
return 1;
|
|
449
|
+
}
|
|
450
|
+
return e1.displayName.localeCompare(e2.displayName);
|
|
451
|
+
}
|
|
452
|
+
if ((isE1Running && isE2LanguagePackExtension) || (isE2Running && isE1LanguagePackExtension)) {
|
|
453
|
+
return e1.displayName.localeCompare(e2.displayName);
|
|
454
|
+
}
|
|
455
|
+
return isE1Running ? -1 : 1;
|
|
456
|
+
};
|
|
457
|
+
const outdated = [];
|
|
458
|
+
const reloadRequired = [];
|
|
459
|
+
const noActionRequired = [];
|
|
460
|
+
result.forEach(e => {
|
|
461
|
+
if (e.outdated && !e.pinned) {
|
|
462
|
+
outdated.push(e);
|
|
463
|
+
}
|
|
464
|
+
else if (e.reloadRequiredStatus) {
|
|
465
|
+
reloadRequired.push(e);
|
|
466
|
+
}
|
|
467
|
+
else {
|
|
468
|
+
noActionRequired.push(e);
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
result = [...outdated.sort(defaultSort), ...reloadRequired.sort(defaultSort), ...noActionRequired.sort(defaultSort)];
|
|
472
|
+
}
|
|
473
|
+
return result;
|
|
474
|
+
}
|
|
475
|
+
filterOutdatedExtensions(local, query, options) {
|
|
476
|
+
let { value, categories } = this.parseCategories(query.value);
|
|
477
|
+
value = value.replace(/@outdated/g, '').replace(/@sort:(\w+)(-\w*)?/g, '').trim().toLowerCase();
|
|
478
|
+
const result = local
|
|
479
|
+
.sort((e1, e2) => e1.displayName.localeCompare(e2.displayName))
|
|
480
|
+
.filter(extension => extension.outdated
|
|
481
|
+
&& (extension.name.toLowerCase().indexOf(value) > -1 || extension.displayName.toLowerCase().indexOf(value) > -1)
|
|
482
|
+
&& (!categories.length || ( categories.some(category => !!extension.local && ( extension.local.manifest.categories.some(c => c.toLowerCase() === category))))));
|
|
483
|
+
return this.sortExtensions(result, options);
|
|
484
|
+
}
|
|
485
|
+
filterDisabledExtensions(local, runningExtensions, query, options) {
|
|
486
|
+
let { value, categories } = this.parseCategories(query.value);
|
|
487
|
+
value = value.replace(/@disabled/g, '').replace(/@sort:(\w+)(-\w*)?/g, '').trim().toLowerCase();
|
|
488
|
+
const result = local
|
|
489
|
+
.sort((e1, e2) => e1.displayName.localeCompare(e2.displayName))
|
|
490
|
+
.filter(e => runningExtensions.every(r => !areSameExtensions({ id: r.identifier.value, uuid: r.uuid }, e.identifier))
|
|
491
|
+
&& (e.name.toLowerCase().indexOf(value) > -1 || e.displayName.toLowerCase().indexOf(value) > -1)
|
|
492
|
+
&& (!categories.length || ( categories.some(category => ( (e.local && e.local.manifest.categories || []).some(c => c.toLowerCase() === category))))));
|
|
493
|
+
return this.sortExtensions(result, options);
|
|
494
|
+
}
|
|
495
|
+
filterEnabledExtensions(local, runningExtensions, query, options) {
|
|
496
|
+
let { value, categories } = this.parseCategories(query.value);
|
|
497
|
+
value = value ? value.replace(/@enabled/g, '').replace(/@sort:(\w+)(-\w*)?/g, '').trim().toLowerCase() : '';
|
|
498
|
+
local = local.filter(e => !e.isBuiltin);
|
|
499
|
+
const result = local
|
|
500
|
+
.sort((e1, e2) => e1.displayName.localeCompare(e2.displayName))
|
|
501
|
+
.filter(e => ( runningExtensions.some(
|
|
502
|
+
r => areSameExtensions({ id: r.identifier.value, uuid: r.uuid }, e.identifier)
|
|
503
|
+
))
|
|
504
|
+
&& (e.name.toLowerCase().indexOf(value) > -1 || e.displayName.toLowerCase().indexOf(value) > -1)
|
|
505
|
+
&& (!categories.length || ( categories.some(category => ( (e.local && e.local.manifest.categories || []).some(c => c.toLowerCase() === category))))));
|
|
506
|
+
return this.sortExtensions(result, options);
|
|
507
|
+
}
|
|
508
|
+
filterWorkspaceUnsupportedExtensions(local, query, options) {
|
|
509
|
+
const queryString = query.value;
|
|
510
|
+
const match = queryString.match(/^\s*@workspaceUnsupported(?::(untrusted|virtual)(Partial)?)?(?:\s+([^\s]*))?/i);
|
|
511
|
+
if (!match) {
|
|
512
|
+
return [];
|
|
513
|
+
}
|
|
514
|
+
const type = match[1]?.toLowerCase();
|
|
515
|
+
const partial = !!match[2];
|
|
516
|
+
const nameFilter = match[3]?.toLowerCase();
|
|
517
|
+
if (nameFilter) {
|
|
518
|
+
local = local.filter(extension => extension.name.toLowerCase().indexOf(nameFilter) > -1 || extension.displayName.toLowerCase().indexOf(nameFilter) > -1);
|
|
519
|
+
}
|
|
520
|
+
const hasVirtualSupportType = (extension, supportType) => {
|
|
521
|
+
return extension.local && this.extensionManifestPropertiesService.getExtensionVirtualWorkspaceSupportType(extension.local.manifest) === supportType;
|
|
522
|
+
};
|
|
523
|
+
const hasRestrictedSupportType = (extension, supportType) => {
|
|
524
|
+
if (!extension.local) {
|
|
525
|
+
return false;
|
|
526
|
+
}
|
|
527
|
+
const enablementState = this.extensionEnablementService.getEnablementState(extension.local);
|
|
528
|
+
if (enablementState !== 8 && enablementState !== 9 &&
|
|
529
|
+
enablementState !== 0 && enablementState !== 5 ) {
|
|
530
|
+
return false;
|
|
531
|
+
}
|
|
532
|
+
if (this.extensionManifestPropertiesService.getExtensionUntrustedWorkspaceSupportType(extension.local.manifest) === supportType) {
|
|
533
|
+
return true;
|
|
534
|
+
}
|
|
535
|
+
if (supportType === false) {
|
|
536
|
+
const dependencies = getExtensionDependencies(( local.map(ext => ext.local)), extension.local);
|
|
537
|
+
return ( dependencies.some(
|
|
538
|
+
ext => this.extensionManifestPropertiesService.getExtensionUntrustedWorkspaceSupportType(ext.manifest) === supportType
|
|
539
|
+
));
|
|
540
|
+
}
|
|
541
|
+
return false;
|
|
542
|
+
};
|
|
543
|
+
const inVirtualWorkspace = isVirtualWorkspace(this.workspaceService.getWorkspace());
|
|
544
|
+
const inRestrictedWorkspace = !this.workspaceTrustManagementService.isWorkspaceTrusted();
|
|
545
|
+
if (type === 'virtual') {
|
|
546
|
+
local = local.filter(extension => inVirtualWorkspace && hasVirtualSupportType(extension, partial ? 'limited' : false) && !(inRestrictedWorkspace && hasRestrictedSupportType(extension, false)));
|
|
547
|
+
}
|
|
548
|
+
else if (type === 'untrusted') {
|
|
549
|
+
local = local.filter(extension => hasRestrictedSupportType(extension, partial ? 'limited' : false) && !(inVirtualWorkspace && hasVirtualSupportType(extension, false)));
|
|
550
|
+
}
|
|
551
|
+
else {
|
|
552
|
+
local = local.filter(extension => inVirtualWorkspace && !hasVirtualSupportType(extension, true) || inRestrictedWorkspace && !hasRestrictedSupportType(extension, true));
|
|
553
|
+
}
|
|
554
|
+
return this.sortExtensions(local, options);
|
|
555
|
+
}
|
|
556
|
+
async filterDeprecatedExtensions(local, query, options) {
|
|
557
|
+
const value = query.value.replace(/@deprecated/g, '').replace(/@sort:(\w+)(-\w*)?/g, '').trim().toLowerCase();
|
|
558
|
+
const extensionsControlManifest = await this.extensionManagementService.getExtensionsControlManifest();
|
|
559
|
+
const deprecatedExtensionIds = ( Object.keys(extensionsControlManifest.deprecated));
|
|
560
|
+
local = local.filter(e => deprecatedExtensionIds.includes(e.identifier.id) && (!value || e.name.toLowerCase().indexOf(value) > -1 || e.displayName.toLowerCase().indexOf(value) > -1));
|
|
561
|
+
return this.sortExtensions(local, options);
|
|
562
|
+
}
|
|
563
|
+
filterRecentlyUpdatedExtensions(local, query, options) {
|
|
564
|
+
let { value, categories } = this.parseCategories(query.value);
|
|
565
|
+
const currentTime = Date.now();
|
|
566
|
+
local = local.filter(e => !e.isBuiltin && !e.outdated && e.local?.updated && e.local?.installedTimestamp !== undefined && currentTime - e.local.installedTimestamp < ExtensionsListView_1.RECENT_UPDATE_DURATION);
|
|
567
|
+
value = value.replace(/@recentlyUpdated/g, '').replace(/@sort:(\w+)(-\w*)?/g, '').trim().toLowerCase();
|
|
568
|
+
const result = local.filter(e => (e.name.toLowerCase().indexOf(value) > -1 || e.displayName.toLowerCase().indexOf(value) > -1) &&
|
|
569
|
+
(!categories.length || ( categories.some(category => ( (e.local && e.local.manifest.categories || []).some(c => c.toLowerCase() === category))))));
|
|
570
|
+
options.sortBy = options.sortBy ?? "UpdateDate" ;
|
|
571
|
+
return this.sortExtensions(result, options);
|
|
572
|
+
}
|
|
573
|
+
mergeAddedExtensions(extensions, newExtensions) {
|
|
574
|
+
const oldExtensions = [...extensions];
|
|
575
|
+
const findPreviousExtensionIndex = (from) => {
|
|
576
|
+
let index = -1;
|
|
577
|
+
const previousExtensionInNew = newExtensions[from];
|
|
578
|
+
if (previousExtensionInNew) {
|
|
579
|
+
index = oldExtensions.findIndex(e => areSameExtensions(e.identifier, previousExtensionInNew.identifier));
|
|
580
|
+
if (index === -1) {
|
|
581
|
+
return findPreviousExtensionIndex(from - 1);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
return index;
|
|
585
|
+
};
|
|
586
|
+
let hasChanged = false;
|
|
587
|
+
for (let index = 0; index < newExtensions.length; index++) {
|
|
588
|
+
const extension = newExtensions[index];
|
|
589
|
+
if (extensions.every(r => !areSameExtensions(r.identifier, extension.identifier))) {
|
|
590
|
+
hasChanged = true;
|
|
591
|
+
extensions.splice(findPreviousExtensionIndex(index - 1) + 1, 0, extension);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
return hasChanged ? extensions : undefined;
|
|
595
|
+
}
|
|
596
|
+
async queryGallery(query, options, token) {
|
|
597
|
+
const hasUserDefinedSortOrder = options.sortBy !== undefined;
|
|
598
|
+
if (!hasUserDefinedSortOrder && !query.value.trim()) {
|
|
599
|
+
options.sortBy = 4 ;
|
|
600
|
+
}
|
|
601
|
+
if (this.isRecommendationsQuery(query)) {
|
|
602
|
+
return this.queryRecommendations(query, options, token);
|
|
603
|
+
}
|
|
604
|
+
const text = query.value;
|
|
605
|
+
if (/\bext:([^\s]+)\b/g.test(text)) {
|
|
606
|
+
options.text = text;
|
|
607
|
+
options.source = 'file-extension-tags';
|
|
608
|
+
return this.extensionsWorkbenchService.queryGallery(options, token).then(pager => this.getPagedModel(pager));
|
|
609
|
+
}
|
|
610
|
+
let preferredResults = [];
|
|
611
|
+
if (text) {
|
|
612
|
+
options.text = text.substring(0, 350);
|
|
613
|
+
options.source = 'searchText';
|
|
614
|
+
if (!hasUserDefinedSortOrder) {
|
|
615
|
+
const manifest = await this.extensionManagementService.getExtensionsControlManifest();
|
|
616
|
+
const search = manifest.search;
|
|
617
|
+
if (Array.isArray(search)) {
|
|
618
|
+
for (const s of search) {
|
|
619
|
+
if (s.query && s.query.toLowerCase() === text.toLowerCase() && Array.isArray(s.preferredResults)) {
|
|
620
|
+
preferredResults = s.preferredResults;
|
|
621
|
+
break;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
else {
|
|
628
|
+
options.source = 'viewlet';
|
|
629
|
+
}
|
|
630
|
+
const pager = await this.extensionsWorkbenchService.queryGallery(options, token);
|
|
631
|
+
let positionToUpdate = 0;
|
|
632
|
+
for (const preferredResult of preferredResults) {
|
|
633
|
+
for (let j = positionToUpdate; j < pager.firstPage.length; j++) {
|
|
634
|
+
if (areSameExtensions(pager.firstPage[j].identifier, { id: preferredResult })) {
|
|
635
|
+
if (positionToUpdate !== j) {
|
|
636
|
+
const preferredExtension = pager.firstPage.splice(j, 1)[0];
|
|
637
|
+
pager.firstPage.splice(positionToUpdate, 0, preferredExtension);
|
|
638
|
+
positionToUpdate++;
|
|
639
|
+
}
|
|
640
|
+
break;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
return this.getPagedModel(pager);
|
|
645
|
+
}
|
|
646
|
+
sortExtensions(extensions, options) {
|
|
647
|
+
switch (options.sortBy) {
|
|
648
|
+
case 4 :
|
|
649
|
+
extensions = extensions.sort((e1, e2) => typeof e2.installCount === 'number' && typeof e1.installCount === 'number' ? e2.installCount - e1.installCount : NaN);
|
|
650
|
+
break;
|
|
651
|
+
case "UpdateDate" :
|
|
652
|
+
extensions = extensions.sort((e1, e2) => typeof e2.local?.installedTimestamp === 'number' && typeof e1.local?.installedTimestamp === 'number' ? e2.local.installedTimestamp - e1.local.installedTimestamp :
|
|
653
|
+
typeof e2.local?.installedTimestamp === 'number' ? 1 :
|
|
654
|
+
typeof e1.local?.installedTimestamp === 'number' ? -1 : NaN);
|
|
655
|
+
break;
|
|
656
|
+
case 6 :
|
|
657
|
+
case 12 :
|
|
658
|
+
extensions = extensions.sort((e1, e2) => typeof e2.rating === 'number' && typeof e1.rating === 'number' ? e2.rating - e1.rating : NaN);
|
|
659
|
+
break;
|
|
660
|
+
default:
|
|
661
|
+
extensions = extensions.sort((e1, e2) => e1.displayName.localeCompare(e2.displayName));
|
|
662
|
+
break;
|
|
663
|
+
}
|
|
664
|
+
if (options.sortOrder === 2 ) {
|
|
665
|
+
extensions = extensions.reverse();
|
|
666
|
+
}
|
|
667
|
+
return extensions;
|
|
668
|
+
}
|
|
669
|
+
isRecommendationsQuery(query) {
|
|
670
|
+
return ExtensionsListView_1.isWorkspaceRecommendedExtensionsQuery(query.value)
|
|
671
|
+
|| ExtensionsListView_1.isKeymapsRecommendedExtensionsQuery(query.value)
|
|
672
|
+
|| ExtensionsListView_1.isLanguageRecommendedExtensionsQuery(query.value)
|
|
673
|
+
|| ExtensionsListView_1.isExeRecommendedExtensionsQuery(query.value)
|
|
674
|
+
|| ExtensionsListView_1.isRemoteRecommendedExtensionsQuery(query.value)
|
|
675
|
+
|| /@recommended:all/i.test(query.value)
|
|
676
|
+
|| ExtensionsListView_1.isSearchRecommendedExtensionsQuery(query.value)
|
|
677
|
+
|| ExtensionsListView_1.isRecommendedExtensionsQuery(query.value);
|
|
678
|
+
}
|
|
679
|
+
async queryRecommendations(query, options, token) {
|
|
680
|
+
if (ExtensionsListView_1.isWorkspaceRecommendedExtensionsQuery(query.value)) {
|
|
681
|
+
return this.getWorkspaceRecommendationsModel(query, options, token);
|
|
682
|
+
}
|
|
683
|
+
if (ExtensionsListView_1.isKeymapsRecommendedExtensionsQuery(query.value)) {
|
|
684
|
+
return this.getKeymapRecommendationsModel(query, options, token);
|
|
685
|
+
}
|
|
686
|
+
if (ExtensionsListView_1.isLanguageRecommendedExtensionsQuery(query.value)) {
|
|
687
|
+
return this.getLanguageRecommendationsModel(query, options, token);
|
|
688
|
+
}
|
|
689
|
+
if (ExtensionsListView_1.isExeRecommendedExtensionsQuery(query.value)) {
|
|
690
|
+
return this.getExeRecommendationsModel(query, options, token);
|
|
691
|
+
}
|
|
692
|
+
if (ExtensionsListView_1.isRemoteRecommendedExtensionsQuery(query.value)) {
|
|
693
|
+
return this.getRemoteRecommendationsModel(query, options, token);
|
|
694
|
+
}
|
|
695
|
+
if (/@recommended:all/i.test(query.value)) {
|
|
696
|
+
return this.getAllRecommendationsModel(options, token);
|
|
697
|
+
}
|
|
698
|
+
if (ExtensionsListView_1.isSearchRecommendedExtensionsQuery(query.value) ||
|
|
699
|
+
(ExtensionsListView_1.isRecommendedExtensionsQuery(query.value) && options.sortBy !== undefined)) {
|
|
700
|
+
return this.searchRecommendations(query, options, token);
|
|
701
|
+
}
|
|
702
|
+
if (ExtensionsListView_1.isRecommendedExtensionsQuery(query.value)) {
|
|
703
|
+
return this.getOtherRecommendationsModel(query, options, token);
|
|
704
|
+
}
|
|
705
|
+
return ( new PagedModel([]));
|
|
706
|
+
}
|
|
707
|
+
async getInstallableRecommendations(recommendations, options, token) {
|
|
708
|
+
const result = [];
|
|
709
|
+
if (recommendations.length) {
|
|
710
|
+
const extensions = await this.extensionsWorkbenchService.getExtensions(( recommendations.map(id => ({ id }))), { source: options.source }, token);
|
|
711
|
+
for (const extension of extensions) {
|
|
712
|
+
if (extension.gallery && !extension.deprecationInfo && (await this.extensionManagementService.canInstall(extension.gallery))) {
|
|
713
|
+
result.push(extension);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
return result;
|
|
718
|
+
}
|
|
719
|
+
async getWorkspaceRecommendations() {
|
|
720
|
+
const recommendations = await this.extensionRecommendationsService.getWorkspaceRecommendations();
|
|
721
|
+
const { important } = await this.extensionRecommendationsService.getConfigBasedRecommendations();
|
|
722
|
+
for (const configBasedRecommendation of important) {
|
|
723
|
+
if (!recommendations.find(extensionId => extensionId === configBasedRecommendation)) {
|
|
724
|
+
recommendations.push(configBasedRecommendation);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
return recommendations;
|
|
728
|
+
}
|
|
729
|
+
async getWorkspaceRecommendationsModel(query, options, token) {
|
|
730
|
+
const recommendations = await this.getWorkspaceRecommendations();
|
|
731
|
+
const installableRecommendations = (await this.getInstallableRecommendations(recommendations, { ...options, source: 'recommendations-workspace' }, token));
|
|
732
|
+
const result = coalesce(( recommendations.map(
|
|
733
|
+
id => installableRecommendations.find(i => areSameExtensions(i.identifier, { id }))
|
|
734
|
+
)));
|
|
735
|
+
return ( new PagedModel(result));
|
|
736
|
+
}
|
|
737
|
+
async getKeymapRecommendationsModel(query, options, token) {
|
|
738
|
+
const value = query.value.replace(/@recommended:keymaps/g, '').trim().toLowerCase();
|
|
739
|
+
const recommendations = this.extensionRecommendationsService.getKeymapRecommendations();
|
|
740
|
+
const installableRecommendations = (await this.getInstallableRecommendations(recommendations, { ...options, source: 'recommendations-keymaps' }, token))
|
|
741
|
+
.filter(extension => extension.identifier.id.toLowerCase().indexOf(value) > -1);
|
|
742
|
+
return ( new PagedModel(installableRecommendations));
|
|
743
|
+
}
|
|
744
|
+
async getLanguageRecommendationsModel(query, options, token) {
|
|
745
|
+
const value = query.value.replace(/@recommended:languages/g, '').trim().toLowerCase();
|
|
746
|
+
const recommendations = this.extensionRecommendationsService.getLanguageRecommendations();
|
|
747
|
+
const installableRecommendations = (await this.getInstallableRecommendations(recommendations, { ...options, source: 'recommendations-languages' }, token))
|
|
748
|
+
.filter(extension => extension.identifier.id.toLowerCase().indexOf(value) > -1);
|
|
749
|
+
return ( new PagedModel(installableRecommendations));
|
|
750
|
+
}
|
|
751
|
+
async getRemoteRecommendationsModel(query, options, token) {
|
|
752
|
+
const value = query.value.replace(/@recommended:remotes/g, '').trim().toLowerCase();
|
|
753
|
+
const recommendations = this.extensionRecommendationsService.getRemoteRecommendations();
|
|
754
|
+
const installableRecommendations = (await this.getInstallableRecommendations(recommendations, { ...options, source: 'recommendations-remotes' }, token))
|
|
755
|
+
.filter(extension => extension.identifier.id.toLowerCase().indexOf(value) > -1);
|
|
756
|
+
return ( new PagedModel(installableRecommendations));
|
|
757
|
+
}
|
|
758
|
+
async getExeRecommendationsModel(query, options, token) {
|
|
759
|
+
const exe = query.value.replace(/@exe:/g, '').trim().toLowerCase();
|
|
760
|
+
const { important, others } = await this.extensionRecommendationsService.getExeBasedRecommendations(exe.startsWith('"') ? exe.substring(1, exe.length - 1) : exe);
|
|
761
|
+
const installableRecommendations = await this.getInstallableRecommendations([...important, ...others], { ...options, source: 'recommendations-exe' }, token);
|
|
762
|
+
return ( new PagedModel(installableRecommendations));
|
|
763
|
+
}
|
|
764
|
+
async getOtherRecommendationsModel(query, options, token) {
|
|
765
|
+
const otherRecommendations = await this.getOtherRecommendations();
|
|
766
|
+
const installableRecommendations = await this.getInstallableRecommendations(otherRecommendations, { ...options, source: 'recommendations-other', sortBy: undefined }, token);
|
|
767
|
+
const result = coalesce(( otherRecommendations.map(
|
|
768
|
+
id => installableRecommendations.find(i => areSameExtensions(i.identifier, { id }))
|
|
769
|
+
)));
|
|
770
|
+
return ( new PagedModel(result));
|
|
771
|
+
}
|
|
772
|
+
async getOtherRecommendations() {
|
|
773
|
+
const local = ( (await this.extensionsWorkbenchService.queryLocal(this.options.server))
|
|
774
|
+
.map(e => e.identifier.id.toLowerCase()));
|
|
775
|
+
const workspaceRecommendations = ( (await this.getWorkspaceRecommendations())
|
|
776
|
+
.map(extensionId => extensionId.toLowerCase()));
|
|
777
|
+
return distinct(flatten(await Promise.all([
|
|
778
|
+
this.extensionRecommendationsService.getImportantRecommendations(),
|
|
779
|
+
this.extensionRecommendationsService.getFileBasedRecommendations(),
|
|
780
|
+
this.extensionRecommendationsService.getOtherRecommendations()
|
|
781
|
+
])).filter(extensionId => !local.includes(extensionId.toLowerCase()) && !workspaceRecommendations.includes(extensionId.toLowerCase())), extensionId => extensionId.toLowerCase());
|
|
782
|
+
}
|
|
783
|
+
async getAllRecommendationsModel(options, token) {
|
|
784
|
+
const local = ( (await this.extensionsWorkbenchService.queryLocal(this.options.server)).map(e => e.identifier.id.toLowerCase()));
|
|
785
|
+
const allRecommendations = distinct(flatten(await Promise.all([
|
|
786
|
+
this.getWorkspaceRecommendations(),
|
|
787
|
+
this.extensionRecommendationsService.getImportantRecommendations(),
|
|
788
|
+
this.extensionRecommendationsService.getFileBasedRecommendations(),
|
|
789
|
+
this.extensionRecommendationsService.getOtherRecommendations()
|
|
790
|
+
])).filter(extensionId => !local.includes(extensionId.toLowerCase())), extensionId => extensionId.toLowerCase());
|
|
791
|
+
const installableRecommendations = await this.getInstallableRecommendations(allRecommendations, { ...options, source: 'recommendations-all', sortBy: undefined }, token);
|
|
792
|
+
const result = coalesce(( allRecommendations.map(
|
|
793
|
+
id => installableRecommendations.find(i => areSameExtensions(i.identifier, { id }))
|
|
794
|
+
)));
|
|
795
|
+
return ( new PagedModel(result.slice(0, 8)));
|
|
796
|
+
}
|
|
797
|
+
async searchRecommendations(query, options, token) {
|
|
798
|
+
const value = query.value.replace(/@recommended/g, '').trim().toLowerCase();
|
|
799
|
+
const recommendations = distinct([...(await this.getWorkspaceRecommendations()), ...(await this.getOtherRecommendations())]);
|
|
800
|
+
const installableRecommendations = (await this.getInstallableRecommendations(recommendations, { ...options, source: 'recommendations', sortBy: undefined }, token))
|
|
801
|
+
.filter(extension => extension.identifier.id.toLowerCase().indexOf(value) > -1);
|
|
802
|
+
const result = coalesce(( recommendations.map(
|
|
803
|
+
id => installableRecommendations.find(i => areSameExtensions(i.identifier, { id }))
|
|
804
|
+
)));
|
|
805
|
+
return ( new PagedModel(this.sortExtensions(result, options)));
|
|
806
|
+
}
|
|
807
|
+
setModel(model, error, donotResetScrollTop) {
|
|
808
|
+
if (this.list) {
|
|
809
|
+
this.list.model = ( new DelayedPagedModel(model));
|
|
810
|
+
if (!donotResetScrollTop) {
|
|
811
|
+
this.list.scrollTop = 0;
|
|
812
|
+
}
|
|
813
|
+
this.updateBody(error);
|
|
814
|
+
}
|
|
815
|
+
if (this.badge) {
|
|
816
|
+
this.badge.setCount(this.count());
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
updateModel(model) {
|
|
820
|
+
if (this.list) {
|
|
821
|
+
this.list.model = ( new DelayedPagedModel(model));
|
|
822
|
+
this.updateBody();
|
|
823
|
+
}
|
|
824
|
+
if (this.badge) {
|
|
825
|
+
this.badge.setCount(this.count());
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
updateBody(error) {
|
|
829
|
+
if (this.bodyTemplate) {
|
|
830
|
+
const count = this.count();
|
|
831
|
+
this.bodyTemplate.extensionsList.classList.toggle('hidden', count === 0);
|
|
832
|
+
this.bodyTemplate.messageContainer.classList.toggle('hidden', count > 0);
|
|
833
|
+
if (count === 0 && this.isBodyVisible()) {
|
|
834
|
+
if (error) {
|
|
835
|
+
if (isOfflineError(error)) {
|
|
836
|
+
this.bodyTemplate.messageSeverityIcon.className = SeverityIcon.className(Severity.Warning);
|
|
837
|
+
this.bodyTemplate.messageBox.textContent = ( localizeWithPath(
|
|
838
|
+
'vs/workbench/contrib/extensions/browser/extensionsViews',
|
|
839
|
+
'offline error',
|
|
840
|
+
"Unable to search the Marketplace when offline, please check your network connection."
|
|
841
|
+
));
|
|
842
|
+
}
|
|
843
|
+
else {
|
|
844
|
+
this.bodyTemplate.messageSeverityIcon.className = SeverityIcon.className(Severity.Error);
|
|
845
|
+
this.bodyTemplate.messageBox.textContent = ( localizeWithPath(
|
|
846
|
+
'vs/workbench/contrib/extensions/browser/extensionsViews',
|
|
847
|
+
'error',
|
|
848
|
+
"Error while fetching extensions. {0}",
|
|
849
|
+
getErrorMessage(error)
|
|
850
|
+
));
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
else {
|
|
854
|
+
this.bodyTemplate.messageSeverityIcon.className = '';
|
|
855
|
+
this.bodyTemplate.messageBox.textContent = ( localizeWithPath(
|
|
856
|
+
'vs/workbench/contrib/extensions/browser/extensionsViews',
|
|
857
|
+
'no extensions found',
|
|
858
|
+
"No extensions found."
|
|
859
|
+
));
|
|
860
|
+
}
|
|
861
|
+
alert(this.bodyTemplate.messageBox.textContent);
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
this.updateSize();
|
|
865
|
+
}
|
|
866
|
+
updateSize() {
|
|
867
|
+
if (this.options.flexibleHeight) {
|
|
868
|
+
this.maximumBodySize = this.list?.model.length ? Number.POSITIVE_INFINITY : 0;
|
|
869
|
+
this.storageService.store(`${this.id}.size`, this.list?.model.length || 0, 0 , 1 );
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
openExtension(extension, options) {
|
|
873
|
+
extension = this.extensionsWorkbenchService.local.filter(e => areSameExtensions(e.identifier, extension.identifier))[0] || extension;
|
|
874
|
+
this.extensionsWorkbenchService.open(extension, options).then(undefined, err => this.onError(err));
|
|
875
|
+
}
|
|
876
|
+
onError(err) {
|
|
877
|
+
if (isCancellationError(err)) {
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
const message = err && err.message || '';
|
|
881
|
+
if (/ECONNREFUSED/.test(message)) {
|
|
882
|
+
const error = createErrorWithActions(( localizeWithPath(
|
|
883
|
+
'vs/workbench/contrib/extensions/browser/extensionsViews',
|
|
884
|
+
'suggestProxyError',
|
|
885
|
+
"Marketplace returned 'ECONNREFUSED'. Please check the 'http.proxy' setting."
|
|
886
|
+
)), [
|
|
887
|
+
( new Action('open user settings', ( localizeWithPath(
|
|
888
|
+
'vs/workbench/contrib/extensions/browser/extensionsViews',
|
|
889
|
+
'open user settings',
|
|
890
|
+
"Open User Settings"
|
|
891
|
+
)), undefined, true, () => this.preferencesService.openUserSettings()))
|
|
892
|
+
]);
|
|
893
|
+
this.notificationService.error(error);
|
|
894
|
+
return;
|
|
895
|
+
}
|
|
896
|
+
this.notificationService.error(err);
|
|
897
|
+
}
|
|
898
|
+
getPagedModel(arg) {
|
|
899
|
+
if (Array.isArray(arg)) {
|
|
900
|
+
return ( new PagedModel(arg));
|
|
901
|
+
}
|
|
902
|
+
const pager = {
|
|
903
|
+
total: arg.total,
|
|
904
|
+
pageSize: arg.pageSize,
|
|
905
|
+
firstPage: arg.firstPage,
|
|
906
|
+
getPage: (pageIndex, cancellationToken) => arg.getPage(pageIndex, cancellationToken)
|
|
907
|
+
};
|
|
908
|
+
return ( new PagedModel(pager));
|
|
909
|
+
}
|
|
910
|
+
dispose() {
|
|
911
|
+
super.dispose();
|
|
912
|
+
if (this.queryRequest) {
|
|
913
|
+
this.queryRequest.request.cancel();
|
|
914
|
+
this.queryRequest = null;
|
|
915
|
+
}
|
|
916
|
+
if (this.queryResult) {
|
|
917
|
+
this.queryResult.disposables.dispose();
|
|
918
|
+
this.queryResult = undefined;
|
|
919
|
+
}
|
|
920
|
+
this.list = null;
|
|
921
|
+
}
|
|
922
|
+
static isLocalExtensionsQuery(query, sortBy) {
|
|
923
|
+
return this.isInstalledExtensionsQuery(query)
|
|
924
|
+
|| this.isOutdatedExtensionsQuery(query)
|
|
925
|
+
|| this.isEnabledExtensionsQuery(query)
|
|
926
|
+
|| this.isDisabledExtensionsQuery(query)
|
|
927
|
+
|| this.isBuiltInExtensionsQuery(query)
|
|
928
|
+
|| this.isSearchBuiltInExtensionsQuery(query)
|
|
929
|
+
|| this.isBuiltInGroupExtensionsQuery(query)
|
|
930
|
+
|| this.isSearchDeprecatedExtensionsQuery(query)
|
|
931
|
+
|| this.isSearchWorkspaceUnsupportedExtensionsQuery(query)
|
|
932
|
+
|| this.isSearchRecentlyUpdatedQuery(query)
|
|
933
|
+
|| this.isSearchExtensionUpdatesQuery(query)
|
|
934
|
+
|| this.isSortInstalledExtensionsQuery(query, sortBy);
|
|
935
|
+
}
|
|
936
|
+
static isSearchBuiltInExtensionsQuery(query) {
|
|
937
|
+
return /@builtin\s.+/i.test(query);
|
|
938
|
+
}
|
|
939
|
+
static isBuiltInExtensionsQuery(query) {
|
|
940
|
+
return /^\s*@builtin$/i.test(query.trim());
|
|
941
|
+
}
|
|
942
|
+
static isBuiltInGroupExtensionsQuery(query) {
|
|
943
|
+
return /^\s*@builtin:.+$/i.test(query.trim());
|
|
944
|
+
}
|
|
945
|
+
static isSearchWorkspaceUnsupportedExtensionsQuery(query) {
|
|
946
|
+
return /^\s*@workspaceUnsupported(:(untrusted|virtual)(Partial)?)?(\s|$)/i.test(query);
|
|
947
|
+
}
|
|
948
|
+
static isInstalledExtensionsQuery(query) {
|
|
949
|
+
return /@installed/i.test(query);
|
|
950
|
+
}
|
|
951
|
+
static isOutdatedExtensionsQuery(query) {
|
|
952
|
+
return /@outdated/i.test(query);
|
|
953
|
+
}
|
|
954
|
+
static isEnabledExtensionsQuery(query) {
|
|
955
|
+
return /@enabled/i.test(query);
|
|
956
|
+
}
|
|
957
|
+
static isDisabledExtensionsQuery(query) {
|
|
958
|
+
return /@disabled/i.test(query);
|
|
959
|
+
}
|
|
960
|
+
static isSearchDeprecatedExtensionsQuery(query) {
|
|
961
|
+
return /@deprecated\s?.*/i.test(query);
|
|
962
|
+
}
|
|
963
|
+
static isRecommendedExtensionsQuery(query) {
|
|
964
|
+
return /^@recommended$/i.test(query.trim());
|
|
965
|
+
}
|
|
966
|
+
static isSearchRecommendedExtensionsQuery(query) {
|
|
967
|
+
return /@recommended\s.+/i.test(query);
|
|
968
|
+
}
|
|
969
|
+
static isWorkspaceRecommendedExtensionsQuery(query) {
|
|
970
|
+
return /@recommended:workspace/i.test(query);
|
|
971
|
+
}
|
|
972
|
+
static isExeRecommendedExtensionsQuery(query) {
|
|
973
|
+
return /@exe:.+/i.test(query);
|
|
974
|
+
}
|
|
975
|
+
static isRemoteRecommendedExtensionsQuery(query) {
|
|
976
|
+
return /@recommended:remotes/i.test(query);
|
|
977
|
+
}
|
|
978
|
+
static isKeymapsRecommendedExtensionsQuery(query) {
|
|
979
|
+
return /@recommended:keymaps/i.test(query);
|
|
980
|
+
}
|
|
981
|
+
static isLanguageRecommendedExtensionsQuery(query) {
|
|
982
|
+
return /@recommended:languages/i.test(query);
|
|
983
|
+
}
|
|
984
|
+
static isSortInstalledExtensionsQuery(query, sortBy) {
|
|
985
|
+
return (sortBy !== undefined && sortBy !== '' && query === '') || (!sortBy && /^@sort:\S*$/i.test(query));
|
|
986
|
+
}
|
|
987
|
+
static isSearchPopularQuery(query) {
|
|
988
|
+
return /@popular/i.test(query);
|
|
989
|
+
}
|
|
990
|
+
static isSearchRecentlyPublishedQuery(query) {
|
|
991
|
+
return /@recentlyPublished/i.test(query);
|
|
992
|
+
}
|
|
993
|
+
static isSearchRecentlyUpdatedQuery(query) {
|
|
994
|
+
return /@recentlyUpdated/i.test(query);
|
|
995
|
+
}
|
|
996
|
+
static isSearchExtensionUpdatesQuery(query) {
|
|
997
|
+
return /@updates/i.test(query);
|
|
998
|
+
}
|
|
999
|
+
static isSortUpdateDateQuery(query) {
|
|
1000
|
+
return /@sort:updateDate/i.test(query);
|
|
1001
|
+
}
|
|
1002
|
+
focus() {
|
|
1003
|
+
super.focus();
|
|
1004
|
+
if (!this.list) {
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1007
|
+
if (!(this.list.getFocus().length || this.list.getSelection().length)) {
|
|
1008
|
+
this.list.focusNext();
|
|
1009
|
+
}
|
|
1010
|
+
this.list.domFocus();
|
|
1011
|
+
}
|
|
1012
|
+
};
|
|
1013
|
+
ExtensionsListView = ExtensionsListView_1 = ( __decorate([
|
|
1014
|
+
( __param(2, INotificationService)),
|
|
1015
|
+
( __param(3, IKeybindingService)),
|
|
1016
|
+
( __param(4, IContextMenuService)),
|
|
1017
|
+
( __param(5, IInstantiationService)),
|
|
1018
|
+
( __param(6, IThemeService)),
|
|
1019
|
+
( __param(7, IExtensionService)),
|
|
1020
|
+
( __param(8, IExtensionsWorkbenchService)),
|
|
1021
|
+
( __param(9, IExtensionRecommendationsService)),
|
|
1022
|
+
( __param(10, ITelemetryService)),
|
|
1023
|
+
( __param(11, IConfigurationService)),
|
|
1024
|
+
( __param(12, IWorkspaceContextService)),
|
|
1025
|
+
( __param(13, IExtensionManagementServerService)),
|
|
1026
|
+
( __param(14, IExtensionManifestPropertiesService)),
|
|
1027
|
+
( __param(15, IWorkbenchExtensionManagementService)),
|
|
1028
|
+
( __param(16, IWorkspaceContextService)),
|
|
1029
|
+
( __param(17, IProductService)),
|
|
1030
|
+
( __param(18, IContextKeyService)),
|
|
1031
|
+
( __param(19, IViewDescriptorService)),
|
|
1032
|
+
( __param(20, IOpenerService)),
|
|
1033
|
+
( __param(21, IPreferencesService)),
|
|
1034
|
+
( __param(22, IStorageService)),
|
|
1035
|
+
( __param(23, IWorkspaceTrustManagementService)),
|
|
1036
|
+
( __param(24, IWorkbenchExtensionEnablementService)),
|
|
1037
|
+
( __param(25, IWorkbenchLayoutService)),
|
|
1038
|
+
( __param(26, ILogService))
|
|
1039
|
+
], ExtensionsListView));
|
|
1040
|
+
class DefaultPopularExtensionsView extends ExtensionsListView {
|
|
1041
|
+
async show() {
|
|
1042
|
+
const query = this.extensionManagementServerService.webExtensionManagementServer && !this.extensionManagementServerService.localExtensionManagementServer && !this.extensionManagementServerService.remoteExtensionManagementServer ? '@web' : '';
|
|
1043
|
+
return super.show(query);
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
class ServerInstalledExtensionsView extends ExtensionsListView {
|
|
1047
|
+
async show(query) {
|
|
1048
|
+
query = query ? query : '@installed';
|
|
1049
|
+
if (!ExtensionsListView.isLocalExtensionsQuery(query) || ExtensionsListView.isSortInstalledExtensionsQuery(query)) {
|
|
1050
|
+
query = query += ' @installed';
|
|
1051
|
+
}
|
|
1052
|
+
return super.show(query.trim());
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
class EnabledExtensionsView extends ExtensionsListView {
|
|
1056
|
+
async show(query) {
|
|
1057
|
+
query = query || '@enabled';
|
|
1058
|
+
return ExtensionsListView.isEnabledExtensionsQuery(query) ? super.show(query) :
|
|
1059
|
+
ExtensionsListView.isSortInstalledExtensionsQuery(query) ? super.show('@enabled ' + query) : this.showEmptyModel();
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
class DisabledExtensionsView extends ExtensionsListView {
|
|
1063
|
+
async show(query) {
|
|
1064
|
+
query = query || '@disabled';
|
|
1065
|
+
return ExtensionsListView.isDisabledExtensionsQuery(query) ? super.show(query) :
|
|
1066
|
+
ExtensionsListView.isSortInstalledExtensionsQuery(query) ? super.show('@disabled ' + query) : this.showEmptyModel();
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
class OutdatedExtensionsView extends ExtensionsListView {
|
|
1070
|
+
async show(query) {
|
|
1071
|
+
query = query ? query : '@outdated';
|
|
1072
|
+
if (ExtensionsListView.isSearchExtensionUpdatesQuery(query)) {
|
|
1073
|
+
query = query.replace('@updates', '@outdated');
|
|
1074
|
+
}
|
|
1075
|
+
const model = await super.show(query.trim());
|
|
1076
|
+
this.setExpanded(model.length > 0);
|
|
1077
|
+
return model;
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
class RecentlyUpdatedExtensionsView extends ExtensionsListView {
|
|
1081
|
+
async show(query) {
|
|
1082
|
+
query = query ? query : '@recentlyUpdated';
|
|
1083
|
+
if (ExtensionsListView.isSearchExtensionUpdatesQuery(query)) {
|
|
1084
|
+
query = query.replace('@updates', '@recentlyUpdated');
|
|
1085
|
+
}
|
|
1086
|
+
return super.show(query.trim());
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
class BuiltInFeatureExtensionsView extends ExtensionsListView {
|
|
1090
|
+
async show(query) {
|
|
1091
|
+
return (query && query.trim() !== '@builtin') ? this.showEmptyModel() : super.show('@builtin:features');
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
class BuiltInThemesExtensionsView extends ExtensionsListView {
|
|
1095
|
+
async show(query) {
|
|
1096
|
+
return (query && query.trim() !== '@builtin') ? this.showEmptyModel() : super.show('@builtin:themes');
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
class BuiltInProgrammingLanguageExtensionsView extends ExtensionsListView {
|
|
1100
|
+
async show(query) {
|
|
1101
|
+
return (query && query.trim() !== '@builtin') ? this.showEmptyModel() : super.show('@builtin:basics');
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
function toSpecificWorkspaceUnsupportedQuery(query, qualifier) {
|
|
1105
|
+
if (!query) {
|
|
1106
|
+
return '@workspaceUnsupported:' + qualifier;
|
|
1107
|
+
}
|
|
1108
|
+
const match = query.match(( new RegExp(`@workspaceUnsupported(:${qualifier})?(\\s|$)`, 'i')));
|
|
1109
|
+
if (match) {
|
|
1110
|
+
if (!match[1]) {
|
|
1111
|
+
return query.replace(/@workspaceUnsupported/gi, '@workspaceUnsupported:' + qualifier);
|
|
1112
|
+
}
|
|
1113
|
+
return query;
|
|
1114
|
+
}
|
|
1115
|
+
return undefined;
|
|
1116
|
+
}
|
|
1117
|
+
class UntrustedWorkspaceUnsupportedExtensionsView extends ExtensionsListView {
|
|
1118
|
+
async show(query) {
|
|
1119
|
+
const updatedQuery = toSpecificWorkspaceUnsupportedQuery(query, 'untrusted');
|
|
1120
|
+
return updatedQuery ? super.show(updatedQuery) : this.showEmptyModel();
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
class UntrustedWorkspacePartiallySupportedExtensionsView extends ExtensionsListView {
|
|
1124
|
+
async show(query) {
|
|
1125
|
+
const updatedQuery = toSpecificWorkspaceUnsupportedQuery(query, 'untrustedPartial');
|
|
1126
|
+
return updatedQuery ? super.show(updatedQuery) : this.showEmptyModel();
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
class VirtualWorkspaceUnsupportedExtensionsView extends ExtensionsListView {
|
|
1130
|
+
async show(query) {
|
|
1131
|
+
const updatedQuery = toSpecificWorkspaceUnsupportedQuery(query, 'virtual');
|
|
1132
|
+
return updatedQuery ? super.show(updatedQuery) : this.showEmptyModel();
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
class VirtualWorkspacePartiallySupportedExtensionsView extends ExtensionsListView {
|
|
1136
|
+
async show(query) {
|
|
1137
|
+
const updatedQuery = toSpecificWorkspaceUnsupportedQuery(query, 'virtualPartial');
|
|
1138
|
+
return updatedQuery ? super.show(updatedQuery) : this.showEmptyModel();
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
class DeprecatedExtensionsView extends ExtensionsListView {
|
|
1142
|
+
async show(query) {
|
|
1143
|
+
return ExtensionsListView.isSearchDeprecatedExtensionsQuery(query) ? super.show(query) : this.showEmptyModel();
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
class SearchMarketplaceExtensionsView extends ExtensionsListView {
|
|
1147
|
+
constructor() {
|
|
1148
|
+
super(...arguments);
|
|
1149
|
+
this.reportSearchFinishedDelayer = this._register(( new ThrottledDelayer(2000)));
|
|
1150
|
+
this.searchWaitPromise = Promise.resolve();
|
|
1151
|
+
}
|
|
1152
|
+
async show(query) {
|
|
1153
|
+
const queryPromise = super.show(query);
|
|
1154
|
+
this.reportSearchFinishedDelayer.trigger(() => this.reportSearchFinished());
|
|
1155
|
+
this.searchWaitPromise = queryPromise.then(null, null);
|
|
1156
|
+
return queryPromise;
|
|
1157
|
+
}
|
|
1158
|
+
async reportSearchFinished() {
|
|
1159
|
+
await this.searchWaitPromise;
|
|
1160
|
+
this.telemetryService.publicLog2('extensionsView:MarketplaceSearchFinished');
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
class DefaultRecommendedExtensionsView extends ExtensionsListView {
|
|
1164
|
+
constructor() {
|
|
1165
|
+
super(...arguments);
|
|
1166
|
+
this.recommendedExtensionsQuery = '@recommended:all';
|
|
1167
|
+
}
|
|
1168
|
+
renderBody(container) {
|
|
1169
|
+
super.renderBody(container);
|
|
1170
|
+
this._register(this.extensionRecommendationsService.onDidChangeRecommendations(() => {
|
|
1171
|
+
this.show('');
|
|
1172
|
+
}));
|
|
1173
|
+
}
|
|
1174
|
+
async show(query) {
|
|
1175
|
+
if (query && query.trim() !== this.recommendedExtensionsQuery) {
|
|
1176
|
+
return this.showEmptyModel();
|
|
1177
|
+
}
|
|
1178
|
+
const model = await super.show(this.recommendedExtensionsQuery);
|
|
1179
|
+
if (!( this.extensionsWorkbenchService.local.some(e => !e.isBuiltin))) {
|
|
1180
|
+
this.setExpanded(model.length > 0);
|
|
1181
|
+
}
|
|
1182
|
+
return model;
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
class RecommendedExtensionsView extends ExtensionsListView {
|
|
1186
|
+
constructor() {
|
|
1187
|
+
super(...arguments);
|
|
1188
|
+
this.recommendedExtensionsQuery = '@recommended';
|
|
1189
|
+
}
|
|
1190
|
+
renderBody(container) {
|
|
1191
|
+
super.renderBody(container);
|
|
1192
|
+
this._register(this.extensionRecommendationsService.onDidChangeRecommendations(() => {
|
|
1193
|
+
this.show('');
|
|
1194
|
+
}));
|
|
1195
|
+
}
|
|
1196
|
+
async show(query) {
|
|
1197
|
+
return (query && query.trim() !== this.recommendedExtensionsQuery) ? this.showEmptyModel() : super.show(this.recommendedExtensionsQuery);
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
class WorkspaceRecommendedExtensionsView extends ExtensionsListView {
|
|
1201
|
+
constructor() {
|
|
1202
|
+
super(...arguments);
|
|
1203
|
+
this.recommendedExtensionsQuery = '@recommended:workspace';
|
|
1204
|
+
}
|
|
1205
|
+
renderBody(container) {
|
|
1206
|
+
super.renderBody(container);
|
|
1207
|
+
this._register(this.extensionRecommendationsService.onDidChangeRecommendations(() => this.show(this.recommendedExtensionsQuery)));
|
|
1208
|
+
this._register(this.contextService.onDidChangeWorkbenchState(() => this.show(this.recommendedExtensionsQuery)));
|
|
1209
|
+
}
|
|
1210
|
+
async show(query) {
|
|
1211
|
+
const shouldShowEmptyView = query && query.trim() !== '@recommended' && query.trim() !== '@recommended:workspace';
|
|
1212
|
+
const model = await (shouldShowEmptyView ? this.showEmptyModel() : super.show(this.recommendedExtensionsQuery));
|
|
1213
|
+
this.setExpanded(model.length > 0);
|
|
1214
|
+
return model;
|
|
1215
|
+
}
|
|
1216
|
+
async getInstallableWorkspaceRecommendations() {
|
|
1217
|
+
const installed = (await this.extensionsWorkbenchService.queryLocal())
|
|
1218
|
+
.filter(l => l.enablementState !== 1 );
|
|
1219
|
+
const recommendations = (await this.getWorkspaceRecommendations())
|
|
1220
|
+
.filter(extensionId => installed.every(local => !areSameExtensions({ id: extensionId }, local.identifier)));
|
|
1221
|
+
return this.getInstallableRecommendations(recommendations, { source: 'install-all-workspace-recommendations' }, CancellationToken.None);
|
|
1222
|
+
}
|
|
1223
|
+
async installWorkspaceRecommendations() {
|
|
1224
|
+
const installableRecommendations = await this.getInstallableWorkspaceRecommendations();
|
|
1225
|
+
if (installableRecommendations.length) {
|
|
1226
|
+
await this.extensionManagementService.installGalleryExtensions(( installableRecommendations.map(i => ({ extension: i.gallery, options: {} }))));
|
|
1227
|
+
}
|
|
1228
|
+
else {
|
|
1229
|
+
this.notificationService.notify({
|
|
1230
|
+
severity: Severity.Info,
|
|
1231
|
+
message: ( localizeWithPath(
|
|
1232
|
+
'vs/workbench/contrib/extensions/browser/extensionsViews',
|
|
1233
|
+
'no local extensions',
|
|
1234
|
+
"There are no extensions to install."
|
|
1235
|
+
))
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
function getAriaLabelForExtension(extension) {
|
|
1241
|
+
if (!extension) {
|
|
1242
|
+
return '';
|
|
1243
|
+
}
|
|
1244
|
+
const publisher = extension.publisherDomain?.verified ? ( localizeWithPath(
|
|
1245
|
+
'vs/workbench/contrib/extensions/browser/extensionsViews',
|
|
1246
|
+
'extension.arialabel.verifiedPublisher',
|
|
1247
|
+
"Verified Publisher {0}",
|
|
1248
|
+
extension.publisherDisplayName
|
|
1249
|
+
)) : ( localizeWithPath(
|
|
1250
|
+
'vs/workbench/contrib/extensions/browser/extensionsViews',
|
|
1251
|
+
'extension.arialabel.publisher',
|
|
1252
|
+
"Publisher {0}",
|
|
1253
|
+
extension.publisherDisplayName
|
|
1254
|
+
));
|
|
1255
|
+
const deprecated = extension?.deprecationInfo ? ( localizeWithPath(
|
|
1256
|
+
'vs/workbench/contrib/extensions/browser/extensionsViews',
|
|
1257
|
+
'extension.arialabel.deprecated',
|
|
1258
|
+
"Deprecated"
|
|
1259
|
+
)) : '';
|
|
1260
|
+
const rating = extension?.rating ? ( localizeWithPath(
|
|
1261
|
+
'vs/workbench/contrib/extensions/browser/extensionsViews',
|
|
1262
|
+
'extension.arialabel.rating',
|
|
1263
|
+
"Rated {0} out of 5 stars by {1} users",
|
|
1264
|
+
extension.rating.toFixed(2),
|
|
1265
|
+
extension.ratingCount
|
|
1266
|
+
)) : '';
|
|
1267
|
+
return `${extension.displayName}, ${deprecated ? `${deprecated}, ` : ''}${extension.version}, ${publisher}, ${extension.description} ${rating ? `, ${rating}` : ''}`;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
export { BuiltInFeatureExtensionsView, BuiltInProgrammingLanguageExtensionsView, BuiltInThemesExtensionsView, DefaultPopularExtensionsView, DefaultRecommendedExtensionsView, DeprecatedExtensionsView, DisabledExtensionsView, EnabledExtensionsView, ExtensionsListView, OutdatedExtensionsView, RecentlyUpdatedExtensionsView, RecommendedExtensionsView, SearchMarketplaceExtensionsView, ServerInstalledExtensionsView, UntrustedWorkspacePartiallySupportedExtensionsView, UntrustedWorkspaceUnsupportedExtensionsView, VirtualWorkspacePartiallySupportedExtensionsView, VirtualWorkspaceUnsupportedExtensionsView, WorkspaceRecommendedExtensionsView, getAriaLabelForExtension };
|