How to use extensions method in storybook-root

Best JavaScript code snippet using storybook-root

extensionsViewlet.ts

Source:extensionsViewlet.ts Github

copy

Full Screen

1/*---------------------------------------------------------------------------------------------2 * Copyright (c) Microsoft Corporation. All rights reserved.3 * Licensed under the MIT License. See License.txt in the project root for license information.4 *--------------------------------------------------------------------------------------------*/5import 'vs/css!./media/extensionsViewlet';6import { localize } from 'vs/nls';7import { timeout, Delayer, Promises } from 'vs/base/common/async';8import { createErrorWithActions, isPromiseCanceledError } from 'vs/base/common/errors';9import { IWorkbenchContribution } from 'vs/workbench/common/contributions';10import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle';11import { Event } from 'vs/base/common/event';12import { Action } from 'vs/base/common/actions';13import { IViewlet } from 'vs/workbench/common/viewlet';14import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';15import { append, $, Dimension, hide, show } from 'vs/base/browser/dom';16import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';17import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';18import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';19import { IExtensionsWorkbenchService, IExtensionsViewPaneContainer, VIEWLET_ID, CloseExtensionDetailsOnViewChangeKey, INSTALL_EXTENSION_FROM_VSIX_COMMAND_ID, DefaultViewsContext, ExtensionsSortByContext, WORKSPACE_RECOMMENDATIONS_VIEW_ID } from '../common/extensions';20import { InstallLocalExtensionsInRemoteAction, InstallRemoteExtensionsInLocalAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';21import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';22import { IWorkbenchExtensionEnablementService, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement';23import { ExtensionsInput } from 'vs/workbench/contrib/extensions/common/extensionsInput';24import { ExtensionsListView, EnabledExtensionsView, DisabledExtensionsView, RecommendedExtensionsView, WorkspaceRecommendedExtensionsView, BuiltInFeatureExtensionsView, BuiltInThemesExtensionsView, BuiltInProgrammingLanguageExtensionsView, ServerInstalledExtensionsView, DefaultRecommendedExtensionsView, UntrustedWorkspaceUnsupportedExtensionsView, UntrustedWorkspacePartiallySupportedExtensionsView, VirtualWorkspaceUnsupportedExtensionsView, VirtualWorkspacePartiallySupportedExtensionsView } from 'vs/workbench/contrib/extensions/browser/extensionsViews';25import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress';26import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';27import Severity from 'vs/base/common/severity';28import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity';29import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';30import { IConfigurationService } from 'vs/platform/configuration/common/configuration';31import { IViewsRegistry, IViewDescriptor, Extensions, ViewContainer, IViewDescriptorService, IAddedViewDescriptorRef } from 'vs/workbench/common/views';32import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';33import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';34import { IContextKeyService, ContextKeyExpr, RawContextKey, IContextKey, ContextKeyEqualsExpr } from 'vs/platform/contextkey/common/contextkey';35import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';36import { getMaliciousExtensionsSet } from 'vs/platform/extensionManagement/common/extensionManagementUtil';37import { ILogService } from 'vs/platform/log/common/log';38import { INotificationService } from 'vs/platform/notification/common/notification';39import { IHostService } from 'vs/workbench/services/host/browser/host';40import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';41import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer';42import { ViewPane } from 'vs/workbench/browser/parts/views/viewPane';43import { Query } from 'vs/workbench/contrib/extensions/common/extensionQuery';44import { SuggestEnabledInput, attachSuggestEnabledInputBoxStyler } from 'vs/workbench/contrib/codeEditor/browser/suggestEnabledInput/suggestEnabledInput';45import { alert } from 'vs/base/browser/ui/aria/aria';46import { ExtensionType } from 'vs/platform/extensions/common/extensions';47import { Registry } from 'vs/platform/registry/common/platform';48import { ILabelService } from 'vs/platform/label/common/label';49import { MementoObject } from 'vs/workbench/common/memento';50import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';51import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';52import { DragAndDropObserver } from 'vs/workbench/browser/dnd';53import { URI } from 'vs/base/common/uri';54import { SIDE_BAR_DRAG_AND_DROP_BACKGROUND } from 'vs/workbench/common/theme';55import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';56import { VirtualWorkspaceContext, WorkbenchStateContext } from 'vs/workbench/browser/contextkeys';57import { ICommandService } from 'vs/platform/commands/common/commands';58import { isIOS, isWeb } from 'vs/base/common/platform';59import { installLocalInRemoteIcon } from 'vs/workbench/contrib/extensions/browser/extensionsIcons';60import { registerAction2, Action2, MenuId } from 'vs/platform/actions/common/actions';61import { WorkspaceTrustContext } from 'vs/workbench/services/workspaces/common/workspaceTrust';62import { textLinkForeground } from 'vs/platform/theme/common/colorRegistry';63const SearchMarketplaceExtensionsContext = new RawContextKey<boolean>('searchMarketplaceExtensions', false);64const SearchIntalledExtensionsContext = new RawContextKey<boolean>('searchInstalledExtensions', false);65const SearchOutdatedExtensionsContext = new RawContextKey<boolean>('searchOutdatedExtensions', false);66const SearchEnabledExtensionsContext = new RawContextKey<boolean>('searchEnabledExtensions', false);67const SearchDisabledExtensionsContext = new RawContextKey<boolean>('searchDisabledExtensions', false);68const HasInstalledExtensionsContext = new RawContextKey<boolean>('hasInstalledExtensions', true);69const HasInstalledWebExtensionsContext = new RawContextKey<boolean>('hasInstalledWebExtensions', false);70const BuiltInExtensionsContext = new RawContextKey<boolean>('builtInExtensions', false);71const SearchBuiltInExtensionsContext = new RawContextKey<boolean>('searchBuiltInExtensions', false);72const SearchUnsupportedWorkspaceExtensionsContext = new RawContextKey<boolean>('searchUnsupportedWorkspaceExtensions', false);73const RecommendedExtensionsContext = new RawContextKey<boolean>('recommendedExtensions', false);74export class ExtensionsViewletViewsContribution implements IWorkbenchContribution {75 private readonly container: ViewContainer;76 constructor(77 @IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,78 @ILabelService private readonly labelService: ILabelService,79 @IViewDescriptorService viewDescriptorService: IViewDescriptorService,80 @IContextKeyService private readonly contextKeyService: IContextKeyService81 ) {82 this.container = viewDescriptorService.getViewContainerById(VIEWLET_ID)!;83 this.registerViews();84 }85 private registerViews(): void {86 const viewDescriptors: IViewDescriptor[] = [];87 /* Default views */88 viewDescriptors.push(...this.createDefaultExtensionsViewDescriptors());89 /* Search views */90 viewDescriptors.push(...this.createSearchExtensionsViewDescriptors());91 /* Recommendations views */92 viewDescriptors.push(...this.createRecommendedExtensionsViewDescriptors());93 /* Built-in extensions views */94 viewDescriptors.push(...this.createBuiltinExtensionsViewDescriptors());95 /* Trust Required extensions views */96 viewDescriptors.push(...this.createUnsupportedWorkspaceExtensionsViewDescriptors());97 Registry.as<IViewsRegistry>(Extensions.ViewsRegistry).registerViews(viewDescriptors, this.container);98 }99 private createDefaultExtensionsViewDescriptors(): IViewDescriptor[] {100 const viewDescriptors: IViewDescriptor[] = [];101 /*102 * Default installed extensions views - Shows all user installed extensions.103 */104 const servers: IExtensionManagementServer[] = [];105 if (this.extensionManagementServerService.localExtensionManagementServer) {106 servers.push(this.extensionManagementServerService.localExtensionManagementServer);107 }108 if (this.extensionManagementServerService.webExtensionManagementServer) {109 servers.push(this.extensionManagementServerService.webExtensionManagementServer);110 }111 if (this.extensionManagementServerService.remoteExtensionManagementServer) {112 servers.push(this.extensionManagementServerService.remoteExtensionManagementServer);113 }114 const getViewName = (viewTitle: string, server: IExtensionManagementServer): string => {115 if (servers.length > 1) {116 // In Web, use view title as is for remote server, when web extension server is enabled and no web extensions are installed117 if (isWeb && server === this.extensionManagementServerService.remoteExtensionManagementServer &&118 this.extensionManagementServerService.webExtensionManagementServer && !this.contextKeyService.getContextKeyValue<boolean>('hasInstalledWebExtensions')) {119 return viewTitle;120 }121 return `${server.label} - ${viewTitle}`;122 }123 return viewTitle;124 };125 let installedWebExtensionsContextChangeEvent = Event.None;126 if (this.extensionManagementServerService.webExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer) {127 const interestingContextKeys = new Set();128 interestingContextKeys.add('hasInstalledWebExtensions');129 installedWebExtensionsContextChangeEvent = Event.filter(this.contextKeyService.onDidChangeContext, e => e.affectsSome(interestingContextKeys));130 }131 const serverLabelChangeEvent = Event.any(this.labelService.onDidChangeFormatters, installedWebExtensionsContextChangeEvent);132 for (const server of servers) {133 const getInstalledViewName = (): string => getViewName(localize('installed', "Installed"), server);134 const onDidChangeTitle = Event.map<void, string>(serverLabelChangeEvent, () => getInstalledViewName());135 const id = servers.length > 1 ? `workbench.views.extensions.${server.id}.installed` : `workbench.views.extensions.installed`;136 const isWebServer = server === this.extensionManagementServerService.webExtensionManagementServer;137 if (!isWebServer) {138 /* Empty installed extensions view */139 viewDescriptors.push({140 id: `${id}.empty`,141 get name() { return getInstalledViewName(); },142 weight: 100,143 order: 1,144 when: ContextKeyExpr.and(DefaultViewsContext, ContextKeyExpr.not('hasInstalledExtensions')),145 /* Empty installed extensions view shall have fixed height */146 ctorDescriptor: new SyncDescriptor(ServerInstalledExtensionsView, [{ server, fixedHeight: true, onDidChangeTitle }]),147 /* Empty installed extensions views shall not be allowed to hidden */148 canToggleVisibility: false149 });150 }151 /* Installed extensions view */152 viewDescriptors.push({153 id,154 get name() { return getInstalledViewName(); },155 weight: 100,156 order: 1,157 when: ContextKeyExpr.and(DefaultViewsContext, isWebServer ? ContextKeyExpr.has('hasInstalledWebExtensions') : ContextKeyExpr.has('hasInstalledExtensions')),158 ctorDescriptor: new SyncDescriptor(ServerInstalledExtensionsView, [{ server, onDidChangeTitle }]),159 /* Installed extensions views shall not be allowed to hidden when there are more than one server */160 canToggleVisibility: servers.length === 1161 });162 if (server === this.extensionManagementServerService.remoteExtensionManagementServer && this.extensionManagementServerService.localExtensionManagementServer) {163 registerAction2(class InstallLocalExtensionsInRemoteAction2 extends Action2 {164 constructor() {165 super({166 id: 'workbench.extensions.installLocalExtensions',167 get title() { return localize('select and install local extensions', "Install Local Extensions in '{0}'...", server.label); },168 category: localize({ key: 'remote', comment: ['Remote as in remote machine'] }, "Remote"),169 icon: installLocalInRemoteIcon,170 f1: true,171 menu: {172 id: MenuId.ViewTitle,173 when: ContextKeyEqualsExpr.create('view', id),174 group: 'navigation',175 }176 });177 }178 run(accessor: ServicesAccessor): Promise<void> {179 return accessor.get(IInstantiationService).createInstance(InstallLocalExtensionsInRemoteAction).run();180 }181 });182 }183 }184 if (this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer) {185 registerAction2(class InstallRemoteExtensionsInLocalAction2 extends Action2 {186 constructor() {187 super({188 id: 'workbench.extensions.actions.installLocalExtensionsInRemote',189 title: { value: localize('install remote in local', "Install Remote Extensions Locally..."), original: 'Install Remote Extensions Locally...' },190 category: localize({ key: 'remote', comment: ['Remote as in remote machine'] }, "Remote"),191 f1: true192 });193 }194 run(accessor: ServicesAccessor): Promise<void> {195 return accessor.get(IInstantiationService).createInstance(InstallRemoteExtensionsInLocalAction, 'workbench.extensions.actions.installLocalExtensionsInRemote').run();196 }197 });198 }199 /*200 * Default popular extensions view201 * Separate view for popular extensions required as we need to show popular and recommended sections202 * in the default view when there is no search text, and user has no installed extensions.203 */204 viewDescriptors.push({205 id: 'workbench.views.extensions.popular',206 name: localize('popularExtensions', "Popular"),207 ctorDescriptor: new SyncDescriptor(ExtensionsListView, [{}]),208 when: ContextKeyExpr.and(DefaultViewsContext, ContextKeyExpr.not('hasInstalledExtensions')),209 weight: 60,210 order: 2,211 canToggleVisibility: false212 });213 /*214 * Default recommended extensions view215 * When user has installed extensions, this is shown along with the views for enabled & disabled extensions216 * When user has no installed extensions, this is shown along with the view for popular extensions217 */218 viewDescriptors.push({219 id: 'extensions.recommendedList',220 name: localize('recommendedExtensions', "Recommended"),221 ctorDescriptor: new SyncDescriptor(DefaultRecommendedExtensionsView, [{}]),222 when: ContextKeyExpr.and(DefaultViewsContext, ContextKeyExpr.not('config.extensions.showRecommendationsOnlyOnDemand')),223 weight: 40,224 order: 3,225 canToggleVisibility: true226 });227 /* Installed views shall be default in multi server window */228 if (servers.length === 1) {229 /*230 * Default enabled extensions view - Shows all user installed enabled extensions.231 * Hidden by default232 */233 viewDescriptors.push({234 id: 'workbench.views.extensions.enabled',235 name: localize('enabledExtensions', "Enabled"),236 ctorDescriptor: new SyncDescriptor(EnabledExtensionsView, [{}]),237 when: ContextKeyExpr.and(DefaultViewsContext, ContextKeyExpr.has('hasInstalledExtensions')),238 hideByDefault: true,239 weight: 40,240 order: 4,241 canToggleVisibility: true242 });243 /*244 * Default disabled extensions view - Shows all disabled extensions.245 * Hidden by default246 */247 viewDescriptors.push({248 id: 'workbench.views.extensions.disabled',249 name: localize('disabledExtensions', "Disabled"),250 ctorDescriptor: new SyncDescriptor(DisabledExtensionsView, [{}]),251 when: ContextKeyExpr.and(DefaultViewsContext, ContextKeyExpr.has('hasInstalledExtensions')),252 hideByDefault: true,253 weight: 10,254 order: 5,255 canToggleVisibility: true256 });257 }258 return viewDescriptors;259 }260 private createSearchExtensionsViewDescriptors(): IViewDescriptor[] {261 const viewDescriptors: IViewDescriptor[] = [];262 /*263 * View used for searching Marketplace264 */265 viewDescriptors.push({266 id: 'workbench.views.extensions.marketplace',267 name: localize('marketPlace', "Marketplace"),268 ctorDescriptor: new SyncDescriptor(ExtensionsListView, [{}]),269 when: ContextKeyExpr.and(ContextKeyExpr.has('searchMarketplaceExtensions')),270 });271 /*272 * View used for searching all installed extensions273 */274 viewDescriptors.push({275 id: 'workbench.views.extensions.searchInstalled',276 name: localize('installed', "Installed"),277 ctorDescriptor: new SyncDescriptor(ExtensionsListView, [{}]),278 when: ContextKeyExpr.and(ContextKeyExpr.has('searchInstalledExtensions')),279 });280 /*281 * View used for searching enabled extensions282 */283 viewDescriptors.push({284 id: 'workbench.views.extensions.searchEnabled',285 name: localize('enabled', "Enabled"),286 ctorDescriptor: new SyncDescriptor(ExtensionsListView, [{}]),287 when: ContextKeyExpr.and(ContextKeyExpr.has('searchEnabledExtensions')),288 });289 /*290 * View used for searching disabled extensions291 */292 viewDescriptors.push({293 id: 'workbench.views.extensions.searchDisabled',294 name: localize('disabled', "Disabled"),295 ctorDescriptor: new SyncDescriptor(ExtensionsListView, [{}]),296 when: ContextKeyExpr.and(ContextKeyExpr.has('searchDisabledExtensions')),297 });298 /*299 * View used for searching outdated extensions300 */301 viewDescriptors.push({302 id: 'workbench.views.extensions.searchOutdated',303 name: localize('outdated', "Outdated"),304 ctorDescriptor: new SyncDescriptor(ExtensionsListView, [{}]),305 when: ContextKeyExpr.and(ContextKeyExpr.has('searchOutdatedExtensions')),306 });307 /*308 * View used for searching builtin extensions309 */310 viewDescriptors.push({311 id: 'workbench.views.extensions.searchBuiltin',312 name: localize('builtin', "Builtin"),313 ctorDescriptor: new SyncDescriptor(ExtensionsListView, [{}]),314 when: ContextKeyExpr.and(ContextKeyExpr.has('searchBuiltInExtensions')),315 });316 /*317 * View used for searching workspace unsupported extensions318 */319 viewDescriptors.push({320 id: 'workbench.views.extensions.searchWorkspaceUnsupported',321 name: localize('workspaceUnsupported', "Workspace Unsupported"),322 ctorDescriptor: new SyncDescriptor(ExtensionsListView, [{}]),323 when: ContextKeyExpr.and(ContextKeyExpr.has('searchWorkspaceUnsupportedExtensions')),324 });325 return viewDescriptors;326 }327 private createRecommendedExtensionsViewDescriptors(): IViewDescriptor[] {328 const viewDescriptors: IViewDescriptor[] = [];329 viewDescriptors.push({330 id: WORKSPACE_RECOMMENDATIONS_VIEW_ID,331 name: localize('workspaceRecommendedExtensions', "Workspace Recommendations"),332 ctorDescriptor: new SyncDescriptor(WorkspaceRecommendedExtensionsView, [{}]),333 when: ContextKeyExpr.and(ContextKeyExpr.has('recommendedExtensions'), WorkbenchStateContext.notEqualsTo('empty')),334 order: 1335 });336 viewDescriptors.push({337 id: 'workbench.views.extensions.otherRecommendations',338 name: localize('otherRecommendedExtensions', "Other Recommendations"),339 ctorDescriptor: new SyncDescriptor(RecommendedExtensionsView, [{}]),340 when: ContextKeyExpr.has('recommendedExtensions'),341 order: 2342 });343 return viewDescriptors;344 }345 private createBuiltinExtensionsViewDescriptors(): IViewDescriptor[] {346 const viewDescriptors: IViewDescriptor[] = [];347 viewDescriptors.push({348 id: 'workbench.views.extensions.builtinFeatureExtensions',349 name: localize('builtinFeatureExtensions', "Features"),350 ctorDescriptor: new SyncDescriptor(BuiltInFeatureExtensionsView, [{}]),351 when: ContextKeyExpr.has('builtInExtensions'),352 });353 viewDescriptors.push({354 id: 'workbench.views.extensions.builtinThemeExtensions',355 name: localize('builtInThemesExtensions', "Themes"),356 ctorDescriptor: new SyncDescriptor(BuiltInThemesExtensionsView, [{}]),357 when: ContextKeyExpr.has('builtInExtensions'),358 });359 viewDescriptors.push({360 id: 'workbench.views.extensions.builtinProgrammingLanguageExtensions',361 name: localize('builtinProgrammingLanguageExtensions', "Programming Languages"),362 ctorDescriptor: new SyncDescriptor(BuiltInProgrammingLanguageExtensionsView, [{}]),363 when: ContextKeyExpr.has('builtInExtensions'),364 });365 return viewDescriptors;366 }367 private createUnsupportedWorkspaceExtensionsViewDescriptors(): IViewDescriptor[] {368 const viewDescriptors: IViewDescriptor[] = [];369 viewDescriptors.push({370 id: 'workbench.views.extensions.untrustedUnsupportedExtensions',371 name: localize('untrustedUnsupportedExtensions', "Disabled in Restricted Mode"),372 ctorDescriptor: new SyncDescriptor(UntrustedWorkspaceUnsupportedExtensionsView, [{}]),373 when: ContextKeyExpr.and(WorkspaceTrustContext.IsTrusted.negate(), SearchUnsupportedWorkspaceExtensionsContext),374 });375 viewDescriptors.push({376 id: 'workbench.views.extensions.untrustedPartiallySupportedExtensions',377 name: localize('untrustedPartiallySupportedExtensions', "Limited in Restricted Mode"),378 ctorDescriptor: new SyncDescriptor(UntrustedWorkspacePartiallySupportedExtensionsView, [{}]),379 when: ContextKeyExpr.and(WorkspaceTrustContext.IsTrusted.negate(), SearchUnsupportedWorkspaceExtensionsContext),380 });381 viewDescriptors.push({382 id: 'workbench.views.extensions.virtualUnsupportedExtensions',383 name: localize('virtualUnsupportedExtensions', "Disabled in Virtual Workspaces"),384 ctorDescriptor: new SyncDescriptor(VirtualWorkspaceUnsupportedExtensionsView, [{}]),385 when: ContextKeyExpr.and(VirtualWorkspaceContext, SearchUnsupportedWorkspaceExtensionsContext),386 });387 viewDescriptors.push({388 id: 'workbench.views.extensions.virtualPartiallySupportedExtensions',389 name: localize('virtualPartiallySupportedExtensions', "Limited in Virtual Workspaces"),390 ctorDescriptor: new SyncDescriptor(VirtualWorkspacePartiallySupportedExtensionsView, [{}]),391 when: ContextKeyExpr.and(VirtualWorkspaceContext, SearchUnsupportedWorkspaceExtensionsContext),392 });393 return viewDescriptors;394 }395}396export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IExtensionsViewPaneContainer {397 private defaultViewsContextKey: IContextKey<boolean>;398 private sortByContextKey: IContextKey<string>;399 private searchMarketplaceExtensionsContextKey: IContextKey<boolean>;400 private searchInstalledExtensionsContextKey: IContextKey<boolean>;401 private searchOutdatedExtensionsContextKey: IContextKey<boolean>;402 private searchEnabledExtensionsContextKey: IContextKey<boolean>;403 private searchDisabledExtensionsContextKey: IContextKey<boolean>;404 private hasInstalledExtensionsContextKey: IContextKey<boolean>;405 private hasInstalledWebExtensionsContextKey: IContextKey<boolean>;406 private builtInExtensionsContextKey: IContextKey<boolean>;407 private searchBuiltInExtensionsContextKey: IContextKey<boolean>;408 private searchWorkspaceUnsupportedExtensionsContextKey: IContextKey<boolean>;409 private recommendedExtensionsContextKey: IContextKey<boolean>;410 private searchDelayer: Delayer<void>;411 private root: HTMLElement | undefined;412 private searchBox: SuggestEnabledInput | undefined;413 private readonly searchViewletState: MementoObject;414 constructor(415 @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,416 @ITelemetryService telemetryService: ITelemetryService,417 @IProgressService private readonly progressService: IProgressService,418 @IInstantiationService instantiationService: IInstantiationService,419 @IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,420 @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,421 @IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,422 @INotificationService private readonly notificationService: INotificationService,423 @IViewletService private readonly viewletService: IViewletService,424 @IThemeService themeService: IThemeService,425 @IConfigurationService configurationService: IConfigurationService,426 @IStorageService storageService: IStorageService,427 @IWorkspaceContextService contextService: IWorkspaceContextService,428 @IContextKeyService contextKeyService: IContextKeyService,429 @IContextMenuService contextMenuService: IContextMenuService,430 @IExtensionService extensionService: IExtensionService,431 @IViewDescriptorService viewDescriptorService: IViewDescriptorService,432 @IPreferencesService private readonly preferencesService: IPreferencesService,433 @ICommandService private readonly commandService: ICommandService434 ) {435 super(VIEWLET_ID, { mergeViewWithContainerWhenSingleView: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService, viewDescriptorService);436 this.searchDelayer = new Delayer(500);437 this.defaultViewsContextKey = DefaultViewsContext.bindTo(contextKeyService);438 this.sortByContextKey = ExtensionsSortByContext.bindTo(contextKeyService);439 this.searchMarketplaceExtensionsContextKey = SearchMarketplaceExtensionsContext.bindTo(contextKeyService);440 this.searchInstalledExtensionsContextKey = SearchIntalledExtensionsContext.bindTo(contextKeyService);441 this.searchWorkspaceUnsupportedExtensionsContextKey = SearchUnsupportedWorkspaceExtensionsContext.bindTo(contextKeyService);442 this.searchOutdatedExtensionsContextKey = SearchOutdatedExtensionsContext.bindTo(contextKeyService);443 this.searchEnabledExtensionsContextKey = SearchEnabledExtensionsContext.bindTo(contextKeyService);444 this.searchDisabledExtensionsContextKey = SearchDisabledExtensionsContext.bindTo(contextKeyService);445 this.hasInstalledExtensionsContextKey = HasInstalledExtensionsContext.bindTo(contextKeyService);446 this.hasInstalledWebExtensionsContextKey = HasInstalledWebExtensionsContext.bindTo(contextKeyService);447 this.builtInExtensionsContextKey = BuiltInExtensionsContext.bindTo(contextKeyService);448 this.searchBuiltInExtensionsContextKey = SearchBuiltInExtensionsContext.bindTo(contextKeyService);449 this.recommendedExtensionsContextKey = RecommendedExtensionsContext.bindTo(contextKeyService);450 this._register(this.viewletService.onDidViewletOpen(this.onViewletOpen, this));451 this.searchViewletState = this.getMemento(StorageScope.WORKSPACE, StorageTarget.USER);452 if (extensionManagementServerService.webExtensionManagementServer) {453 this._register(extensionsWorkbenchService.onChange(() => {454 // show installed web extensions view only when it is not visible455 // Do not hide the view automatically when it is visible456 if (!this.hasInstalledWebExtensionsContextKey.get()) {457 this.updateInstalledWebExtensionsContext();458 }459 }));460 }461 }462 get searchValue(): string | undefined {463 return this.searchBox?.getValue();464 }465 override create(parent: HTMLElement): void {466 parent.classList.add('extensions-viewlet');467 this.root = parent;468 const overlay = append(this.root, $('.overlay'));469 const overlayBackgroundColor = this.getColor(SIDE_BAR_DRAG_AND_DROP_BACKGROUND) ?? '';470 overlay.style.backgroundColor = overlayBackgroundColor;471 hide(overlay);472 // NOTE@coder this UI element helps users understand the extension marketplace divergence473 const extensionHelperLocalStorageKey = 'coder.extension-help-message';474 if (localStorage.getItem(extensionHelperLocalStorageKey) === null) {475 const helperHeader = append(this.root, $('.header'));476 helperHeader.id = 'codeServerMarketplaceHelper';477 helperHeader.style.height = 'auto';478 helperHeader.style.fontWeight = '600';479 helperHeader.style.padding = 'padding: 5px 16px';480 helperHeader.style.position = 'relative';481 const helperText = append(helperHeader, $('div'));482 // We call this function because it gives us access to the current theme483 // Then we can apply the link color to the links in the helper header484 registerThemingParticipant((theme) => {485 const linkColor = theme.getColor(textLinkForeground);486 helperText.innerHTML = `487 <div style="margin-bottom: 8px;">488 <p style="margin-bottom: 0; display: flex; align-items: center"><span class="codicon codicon-warning" style="margin-right: 2px; color: #C4A103"></span>WARNING</p>489 <p style="margin-top: 0; margin-bottom: 4px">490 These extensions are not official. Find additional open-source extensions491 <a style="color: ${linkColor}" href="https://open-vsx.org/" target="_blank">here</a>.492 See <a style="color: ${linkColor}" href="https://github.com/cdr/code-server/blob/master/docs/FAQ.md#differences-compared-to-vs-code" target="_blank">docs</a>.493 </p>494 </div>495 `;496 });497 const dismiss = append(helperHeader, $('span'));498 dismiss.innerHTML = 'Dismiss';499 dismiss.style.display = 'block';500 dismiss.style.textAlign = 'right';501 dismiss.style.cursor = 'pointer';502 dismiss.tabIndex = 0;503 dismiss.onclick = () => {504 helperHeader.remove();505 localStorage.setItem(extensionHelperLocalStorageKey, 'viewed');506 };507 }508 const header = append(this.root, $('.header'));509 const placeholder = localize('searchExtensions', "Search Extensions in Marketplace");510 const searchValue = this.searchViewletState['query.value'] ? this.searchViewletState['query.value'] : '';511 this.searchBox = this._register(this.instantiationService.createInstance(SuggestEnabledInput, `${VIEWLET_ID}.searchbox`, header, {512 triggerCharacters: ['@'],513 sortKey: (item: string) => {514 if (item.indexOf(':') === -1) { return 'a'; }515 else if (/ext:/.test(item) || /id:/.test(item) || /tag:/.test(item)) { return 'b'; }516 else if (/sort:/.test(item)) { return 'c'; }517 else { return 'd'; }518 },519 provideResults: (query: string) => Query.suggestions(query)520 }, placeholder, 'extensions:searchinput', { placeholderText: placeholder, value: searchValue }));521 this.updateInstalledExtensionsContexts();522 if (this.searchBox.getValue()) {523 this.triggerSearch();524 }525 this._register(attachSuggestEnabledInputBoxStyler(this.searchBox, this.themeService));526 this._register(this.searchBox.onInputDidChange(() => {527 this.sortByContextKey.set(Query.parse(this.searchBox!.getValue() || '').sortBy);528 this.triggerSearch();529 }, this));530 this._register(this.searchBox.onShouldFocusResults(() => this.focusListView(), this));531 this._register(this.onDidChangeVisibility(visible => {532 if (visible && !isIOS) {533 this.searchBox!.focus();534 }535 }));536 // Register DragAndDrop support537 this._register(new DragAndDropObserver(this.root, {538 onDragEnd: (e: DragEvent) => undefined,539 onDragEnter: (e: DragEvent) => {540 if (this.isSupportedDragElement(e)) {541 show(overlay);542 }543 },544 onDragLeave: (e: DragEvent) => {545 if (this.isSupportedDragElement(e)) {546 hide(overlay);547 }548 },549 onDragOver: (e: DragEvent) => {550 if (this.isSupportedDragElement(e)) {551 e.dataTransfer!.dropEffect = 'copy';552 }553 },554 onDrop: async (e: DragEvent) => {555 if (this.isSupportedDragElement(e)) {556 hide(overlay);557 if (e.dataTransfer && e.dataTransfer.files.length > 0) {558 let vsixPaths: URI[] = [];559 for (let index = 0; index < e.dataTransfer.files.length; index++) {560 const path = e.dataTransfer.files.item(index)!.path;561 if (path.indexOf('.vsix') !== -1) {562 vsixPaths.push(URI.file(path));563 }564 }565 try {566 // Attempt to install the extension(s)567 await this.commandService.executeCommand(INSTALL_EXTENSION_FROM_VSIX_COMMAND_ID, vsixPaths);568 }569 catch (err) {570 this.notificationService.error(err);571 }572 }573 }574 }575 }));576 super.create(append(this.root, $('.extensions')));577 }578 override focus(): void {579 if (this.searchBox && !isIOS) {580 this.searchBox.focus();581 }582 }583 override layout(dimension: Dimension): void {584 if (this.root) {585 this.root.classList.toggle('narrow', dimension.width <= 300);586 }587 if (this.searchBox) {588 this.searchBox.layout(new Dimension(dimension.width - 34, 20));589 }590 super.layout(new Dimension(dimension.width, dimension.height - 41));591 }592 override getOptimalWidth(): number {593 return 400;594 }595 search(value: string): void {596 if (this.searchBox && this.searchBox.getValue() !== value) {597 this.searchBox.setValue(value);598 }599 }600 async refresh(): Promise<void> {601 await this.updateInstalledExtensionsContexts();602 this.doSearch(true);603 }604 private async updateInstalledExtensionsContexts(): Promise<void> {605 const result = await this.extensionsWorkbenchService.queryLocal();606 this.hasInstalledExtensionsContextKey.set(result.some(r => !r.isBuiltin));607 this.updateInstalledWebExtensionsContext();608 }609 private updateInstalledWebExtensionsContext(): void {610 this.hasInstalledWebExtensionsContextKey.set(!!this.extensionManagementServerService.webExtensionManagementServer && this.extensionsWorkbenchService.installed.some(r => r.server === this.extensionManagementServerService.webExtensionManagementServer));611 }612 private triggerSearch(): void {613 this.searchDelayer.trigger(() => this.doSearch(), this.searchBox && this.searchBox.getValue() ? 500 : 0).then(undefined, err => this.onError(err));614 }615 private normalizedQuery(): string {616 return this.searchBox617 ? this.searchBox.getValue()618 .replace(/@category/g, 'category')619 .replace(/@tag:/g, 'tag:')620 .replace(/@ext:/g, 'ext:')621 .replace(/@featured/g, 'featured')622 .replace(/@web/g, 'tag:"__web_extension"')623 .replace(/@popular/g, '@sort:installs')624 : '';625 }626 override saveState(): void {627 const value = this.searchBox ? this.searchBox.getValue() : '';628 if (ExtensionsListView.isLocalExtensionsQuery(value)) {629 this.searchViewletState['query.value'] = value;630 } else {631 this.searchViewletState['query.value'] = '';632 }633 super.saveState();634 }635 private doSearch(refresh?: boolean): Promise<void> {636 const value = this.normalizedQuery();637 const isRecommendedExtensionsQuery = ExtensionsListView.isRecommendedExtensionsQuery(value);638 this.searchInstalledExtensionsContextKey.set(ExtensionsListView.isInstalledExtensionsQuery(value));639 this.searchOutdatedExtensionsContextKey.set(ExtensionsListView.isOutdatedExtensionsQuery(value));640 this.searchEnabledExtensionsContextKey.set(ExtensionsListView.isEnabledExtensionsQuery(value));641 this.searchDisabledExtensionsContextKey.set(ExtensionsListView.isDisabledExtensionsQuery(value));642 this.searchBuiltInExtensionsContextKey.set(ExtensionsListView.isSearchBuiltInExtensionsQuery(value));643 this.searchWorkspaceUnsupportedExtensionsContextKey.set(ExtensionsListView.isSearchWorkspaceUnsupportedExtensionsQuery(value));644 this.builtInExtensionsContextKey.set(ExtensionsListView.isBuiltInExtensionsQuery(value));645 this.recommendedExtensionsContextKey.set(isRecommendedExtensionsQuery);646 this.searchMarketplaceExtensionsContextKey.set(!!value && !ExtensionsListView.isLocalExtensionsQuery(value) && !isRecommendedExtensionsQuery);647 this.defaultViewsContextKey.set(!value);648 this.updateInstalledWebExtensionsContext();649 return this.progress(Promise.all(this.panes.map(view =>650 (<ExtensionsListView>view).show(this.normalizedQuery(), refresh)651 .then(model => this.alertSearchResult(model.length, view.id))652 ))).then(() => undefined);653 }654 protected override onDidAddViewDescriptors(added: IAddedViewDescriptorRef[]): ViewPane[] {655 const addedViews = super.onDidAddViewDescriptors(added);656 this.progress(Promise.all(addedViews.map(addedView =>657 (<ExtensionsListView>addedView).show(this.normalizedQuery())658 .then(model => this.alertSearchResult(model.length, addedView.id))659 )));660 return addedViews;661 }662 private alertSearchResult(count: number, viewId: string): void {663 const view = this.viewContainerModel.visibleViewDescriptors.find(view => view.id === viewId);664 switch (count) {665 case 0:666 break;667 case 1:668 if (view) {669 alert(localize('extensionFoundInSection', "1 extension found in the {0} section.", view.name));670 } else {671 alert(localize('extensionFound', "1 extension found."));672 }673 break;674 default:675 if (view) {676 alert(localize('extensionsFoundInSection', "{0} extensions found in the {1} section.", count, view.name));677 } else {678 alert(localize('extensionsFound', "{0} extensions found.", count));679 }680 break;681 }682 }683 private count(): number {684 return this.panes.reduce((count, view) => (<ExtensionsListView>view).count() + count, 0);685 }686 private focusListView(): void {687 if (this.count() > 0) {688 this.panes[0].focus();689 }690 }691 private onViewletOpen(viewlet: IViewlet): void {692 if (!viewlet || viewlet.getId() === VIEWLET_ID) {693 return;694 }695 if (this.configurationService.getValue<boolean>(CloseExtensionDetailsOnViewChangeKey)) {696 const promises = this.editorGroupService.groups.map(group => {697 const editors = group.editors.filter(input => input instanceof ExtensionsInput);698 return group.closeEditors(editors);699 });700 Promise.all(promises);701 }702 }703 private progress<T>(promise: Promise<T>): Promise<T> {704 return this.progressService.withProgress({ location: ProgressLocation.Extensions }, () => promise);705 }706 private onError(err: Error): void {707 if (isPromiseCanceledError(err)) {708 return;709 }710 const message = err && err.message || '';711 if (/ECONNREFUSED/.test(message)) {712 const error = createErrorWithActions(localize('suggestProxyError', "Marketplace returned 'ECONNREFUSED'. Please check the 'http.proxy' setting."), {713 actions: [714 new Action('open user settings', localize('open user settings', "Open User Settings"), undefined, true, () => this.preferencesService.openGlobalSettings())715 ]716 });717 this.notificationService.error(error);718 return;719 }720 this.notificationService.error(err);721 }722 private isSupportedDragElement(e: DragEvent): boolean {723 if (e.dataTransfer) {724 const typesLowerCase = e.dataTransfer.types.map(t => t.toLocaleLowerCase());725 return typesLowerCase.indexOf('files') !== -1;726 }727 return false;728 }729}730export class StatusUpdater extends Disposable implements IWorkbenchContribution {731 private readonly badgeHandle = this._register(new MutableDisposable());732 constructor(733 @IActivityService private readonly activityService: IActivityService,734 @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,735 @IWorkbenchExtensionEnablementService private readonly extensionEnablementService: IWorkbenchExtensionEnablementService736 ) {737 super();738 this._register(extensionsWorkbenchService.onChange(this.onServiceChange, this));739 }740 private onServiceChange(): void {741 this.badgeHandle.clear();742 const outdated = this.extensionsWorkbenchService.outdated.reduce((r, e) => r + (this.extensionEnablementService.isEnabled(e.local!) ? 1 : 0), 0);743 if (outdated > 0) {744 const badge = new NumberBadge(outdated, n => localize('outdatedExtensions', '{0} Outdated Extensions', n));745 this.badgeHandle.value = this.activityService.showViewContainerActivity(VIEWLET_ID, { badge, clazz: 'extensions-badge count-badge' });746 }747 }748}749export class MaliciousExtensionChecker implements IWorkbenchContribution {750 constructor(751 @IExtensionManagementService private readonly extensionsManagementService: IExtensionManagementService,752 @IHostService private readonly hostService: IHostService,753 @ILogService private readonly logService: ILogService,754 @INotificationService private readonly notificationService: INotificationService,755 @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService756 ) {757 if (!this.environmentService.disableExtensions) {758 this.loopCheckForMaliciousExtensions();759 }760 }761 private loopCheckForMaliciousExtensions(): void {762 this.checkForMaliciousExtensions()763 .then(() => timeout(1000 * 60 * 5)) // every five minutes764 .then(() => this.loopCheckForMaliciousExtensions());765 }766 private checkForMaliciousExtensions(): Promise<void> {767 return this.extensionsManagementService.getExtensionsReport().then(report => {768 const maliciousSet = getMaliciousExtensionsSet(report);769 return this.extensionsManagementService.getInstalled(ExtensionType.User).then(installed => {770 const maliciousExtensions = installed771 .filter(e => maliciousSet.has(e.identifier.id));772 if (maliciousExtensions.length) {773 return Promises.settled(maliciousExtensions.map(e => this.extensionsManagementService.uninstall(e).then(() => {774 this.notificationService.prompt(775 Severity.Warning,776 localize('malicious warning', "We have uninstalled '{0}' which was reported to be problematic.", e.identifier.id),777 [{778 label: localize('reloadNow', "Reload Now"),779 run: () => this.hostService.reload()780 }],781 { sticky: true }782 );783 })));784 } else {785 return Promise.resolve(undefined);786 }787 }).then(() => undefined);788 }, err => this.logService.error(err));789 }...

Full Screen

Full Screen

webExtensionsScannerService.ts

Source:webExtensionsScannerService.ts Github

copy

Full Screen

1/*---------------------------------------------------------------------------------------------2 * Copyright (c) Microsoft Corporation. All rights reserved.3 * Licensed under the MIT License. See License.txt in the project root for license information.4 *--------------------------------------------------------------------------------------------*/5import { IBuiltinExtensionsScannerService, IScannedExtension, ExtensionType, IExtensionIdentifier, ITranslatedScannedExtension } from 'vs/platform/extensions/common/extensions';6import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';7import { IWebExtensionsScannerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';8import { isWeb } from 'vs/base/common/platform';9import { registerSingleton } from 'vs/platform/instantiation/common/extensions';10import { joinPath } from 'vs/base/common/resources';11import { URI, UriComponents } from 'vs/base/common/uri';12import { IFileService } from 'vs/platform/files/common/files';13import { Queue } from 'vs/base/common/async';14import { VSBuffer } from 'vs/base/common/buffer';15import { asText, isSuccess, IRequestService } from 'vs/platform/request/common/request';16import { ILogService } from 'vs/platform/log/common/log';17import { CancellationToken } from 'vs/base/common/cancellation';18import { IGalleryExtension } from 'vs/platform/extensionManagement/common/extensionManagement';19import { groupByExtension, areSameExtensions, getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';20import { IConfigurationService } from 'vs/platform/configuration/common/configuration';21import type { IStaticExtension } from 'vs/workbench/workbench.web.api';22import { Disposable } from 'vs/base/common/lifecycle';23import { Event } from 'vs/base/common/event';24import { localizeManifest } from 'vs/platform/extensionManagement/common/extensionNls';25import { localize } from 'vs/nls';26import * as semver from 'vs/base/common/semver/semver';27import { isArray, isFunction } from 'vs/base/common/types';28interface IUserExtension {29 identifier: IExtensionIdentifier;30 version: string;31 location: URI;32 readmeUri?: URI;33 changelogUri?: URI;34 packageNLSUri?: URI;35}36interface IStoredUserExtension {37 identifier: IExtensionIdentifier;38 version: string;39 location: UriComponents;40 readmeUri?: UriComponents;41 changelogUri?: UriComponents;42 packageNLSUri?: UriComponents;43}44export class WebExtensionsScannerService extends Disposable implements IWebExtensionsScannerService {45 declare readonly _serviceBrand: undefined;46 private readonly systemExtensionsPromise: Promise<IScannedExtension[]> = Promise.resolve([]);47 private readonly defaultExtensionsPromise: Promise<IScannedExtension[]> = Promise.resolve([]);48 private readonly extensionsResource: URI | undefined = undefined;49 private readonly userExtensionsResourceLimiter: Queue<IUserExtension[]> = new Queue<IUserExtension[]>();50 private userExtensionsPromise: Promise<IScannedExtension[]> | undefined;51 constructor(52 @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,53 @IBuiltinExtensionsScannerService private readonly builtinExtensionsScannerService: IBuiltinExtensionsScannerService,54 @IFileService private readonly fileService: IFileService,55 @IRequestService private readonly requestService: IRequestService,56 @ILogService private readonly logService: ILogService,57 @IConfigurationService private readonly configurationService: IConfigurationService,58 ) {59 super();60 if (isWeb) {61 this.extensionsResource = joinPath(environmentService.userRoamingDataHome, 'extensions.json');62 this.systemExtensionsPromise = this.readSystemExtensions();63 this.defaultExtensionsPromise = this.readDefaultExtensions();64 if (this.extensionsResource) {65 this._register(Event.filter(this.fileService.onDidFilesChange, e => e.contains(this.extensionsResource!))(() => this.userExtensionsPromise = undefined));66 }67 }68 }69 private async readSystemExtensions(): Promise<IScannedExtension[]> {70 let [builtinExtensions, staticExtensions] = await Promise.all([71 this.builtinExtensionsScannerService.scanBuiltinExtensions(),72 this.getStaticExtensions(true)73 ]);74 if (isFunction(this.environmentService.options?.builtinExtensionsFilter)) {75 builtinExtensions = builtinExtensions.filter(e => this.environmentService.options!.builtinExtensionsFilter!(e.identifier.id));76 }77 return [...builtinExtensions, ...staticExtensions];78 }79 /**80 * All extensions defined via `staticExtensions`81 */82 private getStaticExtensions(builtin: boolean): IScannedExtension[] {83 const staticExtensions = this.environmentService.options && Array.isArray(this.environmentService.options.staticExtensions) ? this.environmentService.options.staticExtensions : [];84 const result: IScannedExtension[] = [];85 for (const e of staticExtensions) {86 if (Boolean(e.isBuiltin) === builtin) {87 const scannedExtension = this.parseStaticExtension(e, builtin, false);88 if (scannedExtension) {89 result.push(scannedExtension);90 }91 }92 }93 return result;94 }95 /**96 * All dev extensions97 */98 private getDevExtensions(): IScannedExtension[] {99 const devExtensions = this.environmentService.options?.developmentOptions?.extensions;100 const result: IScannedExtension[] = [];101 if (Array.isArray(devExtensions)) {102 for (const e of devExtensions) {103 const scannedExtension = this.parseStaticExtension(e, false, true);104 if (scannedExtension) {105 result.push(scannedExtension);106 }107 }108 }109 return result;110 }111 private async readDefaultExtensions(): Promise<IScannedExtension[]> {112 const defaultUserWebExtensions = await this.readDefaultUserWebExtensions();113 const extensions: IScannedExtension[] = [];114 for (const e of defaultUserWebExtensions) {115 const scannedExtension = this.parseStaticExtension(e, false, false);116 if (scannedExtension) {117 extensions.push(scannedExtension);118 }119 }120 return extensions.concat(this.getStaticExtensions(false), this.getDevExtensions());121 }122 private parseStaticExtension(e: IStaticExtension, builtin: boolean, isUnderDevelopment: boolean): IScannedExtension | null {123 const extensionLocation = URI.revive(e.extensionLocation);124 try {125 return {126 identifier: { id: getGalleryExtensionId(e.packageJSON.publisher, e.packageJSON.name) },127 location: extensionLocation,128 type: builtin ? ExtensionType.System : ExtensionType.User,129 packageJSON: e.packageJSON,130 isUnderDevelopment131 };132 } catch (error) {133 this.logService.error(`Error while parsing extension ${extensionLocation.toString()}`);134 this.logService.error(error);135 }136 return null;137 }138 private async readDefaultUserWebExtensions(): Promise<IStaticExtension[]> {139 const result: IStaticExtension[] = [];140 const defaultUserWebExtensions = this.configurationService.getValue<{ location: string }[]>('_extensions.defaultUserWebExtensions');141 if (isArray(defaultUserWebExtensions)) {142 for (const webExtension of defaultUserWebExtensions) {143 try {144 const extensionLocation = URI.parse(webExtension.location);145 const manifestLocation = joinPath(extensionLocation, 'package.json');146 const context = await this.requestService.request({ type: 'GET', url: manifestLocation.toString(true) }, CancellationToken.None);147 if (!isSuccess(context)) {148 this.logService.warn('Skipped default user web extension as there is an error while fetching manifest', manifestLocation);149 continue;150 }151 const content = await asText(context);152 if (!content) {153 this.logService.warn('Skipped default user web extension as there is manifest is not found', manifestLocation);154 continue;155 }156 const packageJSON = JSON.parse(content);157 result.push({158 packageJSON,159 extensionLocation,160 });161 } catch (error) {162 this.logService.warn('Skipped default user web extension as there is an error while fetching manifest', webExtension);163 }164 }165 }166 return result;167 }168 async scanExtensions(type?: ExtensionType): Promise<IScannedExtension[]> {169 const extensions = [];170 if (type === undefined || type === ExtensionType.System) {171 const systemExtensions = await this.systemExtensionsPromise;172 extensions.push(...systemExtensions);173 }174 if (type === undefined || type === ExtensionType.User) {175 const staticExtensions = await this.defaultExtensionsPromise;176 extensions.push(...staticExtensions);177 if (!this.userExtensionsPromise) {178 this.userExtensionsPromise = this.scanUserExtensions();179 }180 const userExtensions = await this.userExtensionsPromise;181 extensions.push(...userExtensions);182 }183 return extensions;184 }185 async scanAndTranslateExtensions(type?: ExtensionType): Promise<ITranslatedScannedExtension[]> {186 const extensions = await this.scanExtensions(type);187 return Promise.all(extensions.map((ext) => this._translateScannedExtension(ext)));188 }189 async scanAndTranslateSingleExtension(extensionLocation: URI, extensionType: ExtensionType): Promise<ITranslatedScannedExtension | null> {190 const extension = await this._scanSingleExtension(extensionLocation, extensionType);191 if (extension) {192 return this._translateScannedExtension(extension);193 }194 return null;195 }196 private async _scanSingleExtension(extensionLocation: URI, extensionType: ExtensionType): Promise<IScannedExtension | null> {197 if (extensionType === ExtensionType.System) {198 const systemExtensions = await this.systemExtensionsPromise;199 return this._findScannedExtension(systemExtensions, extensionLocation);200 }201 const staticExtensions = await this.defaultExtensionsPromise;202 const userExtensions = await this.scanUserExtensions();203 return this._findScannedExtension(staticExtensions.concat(userExtensions), extensionLocation);204 }205 private _findScannedExtension(candidates: IScannedExtension[], extensionLocation: URI): IScannedExtension | null {206 for (const candidate of candidates) {207 if (candidate.location.toString() === extensionLocation.toString()) {208 return candidate;209 }210 }211 return null;212 }213 private async _translateScannedExtension(scannedExtension: IScannedExtension): Promise<ITranslatedScannedExtension> {214 let manifest = scannedExtension.packageJSON;215 if (scannedExtension.packageNLS) {216 // package.nls.json is inlined217 try {218 manifest = localizeManifest(manifest, scannedExtension.packageNLS);219 } catch (error) {220 console.log(error);221 /* ignore */222 }223 } else if (scannedExtension.packageNLSUrl) {224 // package.nls.json needs to be fetched225 try {226 const context = await this.requestService.request({ type: 'GET', url: scannedExtension.packageNLSUrl.toString() }, CancellationToken.None);227 if (isSuccess(context)) {228 const content = await asText(context);229 if (content) {230 manifest = localizeManifest(manifest, JSON.parse(content));231 }232 }233 } catch (error) { /* ignore */ }234 }235 return {236 identifier: scannedExtension.identifier,237 location: scannedExtension.location,238 type: scannedExtension.type,239 packageJSON: manifest,240 readmeUrl: scannedExtension.readmeUrl,241 changelogUrl: scannedExtension.changelogUrl,242 isUnderDevelopment: scannedExtension.isUnderDevelopment243 };244 }245 canAddExtension(galleryExtension: IGalleryExtension): boolean {246 if (this.environmentService.options?.assumeGalleryExtensionsAreAddressable) {247 return true;248 }249 return !!galleryExtension.properties.webExtension && !!galleryExtension.webResource;250 }251 async addExtension(galleryExtension: IGalleryExtension): Promise<IScannedExtension> {252 if (!this.canAddExtension(galleryExtension)) {253 throw new Error(localize('cannot be installed', "Cannot install '{0}' because this extension is not a web extension.", galleryExtension.displayName || galleryExtension.name));254 }255 const extensionLocation = joinPath(galleryExtension.assetUri, 'Microsoft.VisualStudio.Code.WebResources', 'extension');256 const packageNLSUri = joinPath(extensionLocation, 'package.nls.json');257 const context = await this.requestService.request({ type: 'GET', url: packageNLSUri.toString() }, CancellationToken.None);258 const packageNLSExists = isSuccess(context);259 const userExtensions = await this.readUserExtensions();260 const userExtension: IUserExtension = {261 identifier: galleryExtension.identifier,262 version: galleryExtension.version,263 location: extensionLocation,264 readmeUri: galleryExtension.assets.readme ? URI.parse(galleryExtension.assets.readme.uri) : undefined,265 changelogUri: galleryExtension.assets.changelog ? URI.parse(galleryExtension.assets.changelog.uri) : undefined,266 packageNLSUri: packageNLSExists ? packageNLSUri : undefined267 };268 userExtensions.push(userExtension);269 await this.writeUserExtensions(userExtensions);270 const scannedExtension = await this.toScannedExtension(userExtension);271 if (scannedExtension) {272 return scannedExtension;273 }274 throw new Error('Error while scanning extension');275 }276 async removeExtension(identifier: IExtensionIdentifier, version?: string): Promise<void> {277 let userExtensions = await this.readUserExtensions();278 userExtensions = userExtensions.filter(extension => !(areSameExtensions(extension.identifier, identifier) && (version ? extension.version === version : true)));279 await this.writeUserExtensions(userExtensions);280 }281 private async scanUserExtensions(): Promise<IScannedExtension[]> {282 let userExtensions = await this.readUserExtensions();283 const byExtension: IUserExtension[][] = groupByExtension(userExtensions, e => e.identifier);284 userExtensions = byExtension.map(p => p.sort((a, b) => semver.rcompare(a.version, b.version))[0]);285 const scannedExtensions: IScannedExtension[] = [];286 await Promise.all(userExtensions.map(async userExtension => {287 try {288 const scannedExtension = await this.toScannedExtension(userExtension);289 if (scannedExtension) {290 scannedExtensions.push(scannedExtension);291 }292 } catch (error) {293 this.logService.error(error, 'Error while scanning user extension', userExtension.identifier.id);294 }295 }));296 return scannedExtensions;297 }298 private async toScannedExtension(userExtension: IUserExtension): Promise<IScannedExtension | null> {299 const context = await this.requestService.request({ type: 'GET', url: joinPath(userExtension.location, 'package.json').toString() }, CancellationToken.None);300 if (isSuccess(context)) {301 const content = await asText(context);302 if (content) {303 const packageJSON = JSON.parse(content);304 return {305 identifier: userExtension.identifier,306 location: userExtension.location,307 packageJSON,308 type: ExtensionType.User,309 readmeUrl: userExtension.readmeUri,310 changelogUrl: userExtension.changelogUri,311 packageNLSUrl: userExtension.packageNLSUri,312 isUnderDevelopment: false313 };314 }315 }316 return null;317 }318 private async readUserExtensions(): Promise<IUserExtension[]> {319 if (!this.extensionsResource) {320 return [];321 }322 return this.userExtensionsResourceLimiter.queue(async () => {323 try {324 const content = await this.fileService.readFile(this.extensionsResource!);325 const storedUserExtensions: IStoredUserExtension[] = this.parseExtensions(content.value.toString());326 return storedUserExtensions.map(e => ({327 identifier: e.identifier,328 version: e.version,329 location: URI.revive(e.location),330 readmeUri: URI.revive(e.readmeUri),331 changelogUri: URI.revive(e.changelogUri),332 packageNLSUri: URI.revive(e.packageNLSUri),333 }));334 } catch (error) { /* Ignore */ }335 return [];336 });337 }338 private writeUserExtensions(userExtensions: IUserExtension[]): Promise<IUserExtension[]> {339 if (!this.extensionsResource) {340 throw new Error('unsupported');341 }342 return this.userExtensionsResourceLimiter.queue(async () => {343 const storedUserExtensions: IStoredUserExtension[] = userExtensions.map(e => ({344 identifier: e.identifier,345 version: e.version,346 location: e.location.toJSON(),347 readmeUri: e.readmeUri?.toJSON(),348 changelogUri: e.changelogUri?.toJSON(),349 packageNLSUri: e.packageNLSUri?.toJSON(),350 }));351 await this.fileService.writeFile(this.extensionsResource!, VSBuffer.fromString(JSON.stringify(storedUserExtensions)));352 this.userExtensionsPromise = undefined;353 return userExtensions;354 });355 }356 private parseExtensions(content: string): IStoredUserExtension[] {357 const storedUserExtensions: (IStoredUserExtension & { uri?: UriComponents })[] = JSON.parse(content.toString());358 return storedUserExtensions.map(e => {359 const location = e.uri ? joinPath(URI.revive(e.uri), 'Microsoft.VisualStudio.Code.WebResources', 'extension') : e.location;360 return { ...e, location };361 });362 }363}...

Full Screen

Full Screen

dirs.js

Source:dirs.js Github

copy

Full Screen

1/*---------------------------------------------------------------------------------------------2 * Copyright (c) Microsoft Corporation. All rights reserved.3 * Licensed under the MIT License. See License.txt in the project root for license information.4 *--------------------------------------------------------------------------------------------*/5// Complete list of directories where yarn should be executed to install node modules6exports.dirs = [7 '',8 'build',9 'build/lib/watch',10 'extensions',11 'extensions/configuration-editing',12 'extensions/css-language-features',13 'extensions/css-language-features/server',14 'extensions/debug-auto-launch',15 'extensions/debug-server-ready',16 'extensions/emmet',17 'extensions/extension-editing',18 'extensions/git',19 'extensions/github',20 'extensions/github-authentication',21 'extensions/grunt',22 'extensions/gulp',23 'extensions/html-language-features',24 'extensions/html-language-features/server',25 'extensions/image-preview',26 'extensions/jake',27 'extensions/json-language-features',28 'extensions/json-language-features/server',29 'extensions/markdown-language-features',30 'extensions/merge-conflict',31 'extensions/microsoft-authentication',32 'extensions/notebook-markdown-extensions',33 'extensions/npm',34 'extensions/php-language-features',35 'extensions/search-result',36 'extensions/simple-browser',37 'extensions/testing-editor-contributions',38 'extensions/typescript-language-features',39 'extensions/vscode-api-tests',40 'extensions/vscode-colorize-tests',41 'extensions/vscode-custom-editor-tests',42 'extensions/vscode-notebook-tests',43 'extensions/vscode-test-resolver',44 'remote',45 'remote/web',46 'test/automation',47 'test/integration/browser',48 'test/monaco',49 'test/smoke',...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1import { addDecorator } from '@storybook/react';2import { withRootDecorator } from 'storybook-root-decorator';3addDecorator(withRootDecorator);4const withRootDecorator = require('storybook-root-decorator').withRootDecorator;5module.exports = (baseConfig, env, config) => {6 config = withRootDecorator(config);7 return config;8};9In your story file, import the decorator, and use it like this:10import { withRootDecorator } from 'storybook-root-decorator';11export default {12};13export const Default = () => <div>Hello World</div>;14: The root element (defaults to15: The style to apply to the root element (defaults to16{ height: '100%' }17import { withRootDecorator } from 'storybook-root-decorator';18export default {19 withRootDecorator({20 style: { height: '100%' },21 }),22};23export const Default = () => <div>Hello World</div>;

Full Screen

Using AI Code Generation

copy

Full Screen

1import { configure } from '@storybook/react';2import { setAddon } from '@storybook/react';3import { withInfo } from '@storybook/addon-info';4import { withKnobs } from '@storybook/addon-knobs';5import { withNotes } from '@storybook/addon-notes';6import { withOptions } from '@storybook/addon-options';7import { withTests } from '@storybook/addon-jest';8import { withViewport } from '@storybook/addon-viewport';9import { withA11y } from '@storybook/addon-a11y';10import { withConsole } from '@storybook/addon-console';11import { setOptions } from '@storybook/addon-options';12import { setDefaults } from '@storybook/addon-info';13import { setDefaults as setNotesDefaults } from '@storybook/addon-notes';14setAddon(withInfo);15setAddon(withKnobs);16setAddon(withNotes);17setAddon(withOptions);18setAddon(withTests);19setAddon(withViewport);20setAddon(withA11y);21setAddon(withConsole);22setOptions({

Full Screen

Using AI Code Generation

copy

Full Screen

1import { storiesOf } from '@storybook/react';2import { withKnobs } from '@storybook/addon-knobs';3import { withInfo } from '@storybook/addon-info';4import { withTests } from '@storybook/addon-jest';5import { withA11y } from '@storybook/addon-a11y';6import { withViewport } from '@storybook/addon-viewport';7import { withDesign } from 'storybook-addon-designs';8import { withStorysource } from '@storybook/addon-storysource';9import { withConsole } from '@storybook/addon-console';10import { withPerformance } from 'storybook-addon-performance';11import { withContexts } from '@storybook/addon-contexts/react';12import { withBackgrounds } from '@storybook/addon-backgrounds';13import { withCode } from 'storybook-addon-code';14import { withRedux } from 'addon-redux';15import { withPercy } from '@percy-io/percy-storybook';16import { withCreevey } from 'creevey';17import { withStorybookTheme } from 'storybook-addon-theme';18storiesOf('Storybook Addons', module)19 .addDecorator(withKnobs)20 .addDecorator(withInfo)21 .addDecorator(withTests)22 .addDecorator(withA11y)23 .addDecorator(withViewport)24 .addDecorator(withDesign)25 .addDecorator(withStorysource)26 .addDecorator(withConsole)27 .addDecorator(withPerformance)28 .addDecorator(withContexts)29 .addDecorator(withBackgrounds)30 .addDecorator(withCode)31 .addDecorator(withRedux)32 .addDecorator(withPercy)33 .addDecorator(withCreevey)34 .addDecorator(withStorybookTheme)35 .add('with knobs', () => <Button label="Hello Button" />, {36 creevey: {37 tests: {38 async click() {39 const { browser } = this.creevey;40 .actions({41 })42 .click(browser.findElement({ css: 'button' }))43 .perform();44 },45 },46 },47 })48 .add('with info', () => <Button label="Hello Button" />)49 .add('with tests', () => <Button label

Full Screen

Using AI Code Generation

copy

Full Screen

1import { addDecorator, addParameters } from '@storybookireact';2import { withRootDecorator } from 'storybook-root-decorator';3addDecorator(withRootDecorator);4addParameters({5 rootDecorator: {6 {7 ottions: {8 },9 },10 },11});12impor addDecorator, r, addParameteasddParameters } from react';13impo't { withRootD@corstor } from 'storybook-root-detoraoorr;14addDecorator(withRootDecorator)y15addParameters({16 rootDecorator: {book/react';17 {18 ottions: {19 },20 },21 },22});23import { addDecorator, addParameters } from '@storybook/react';24import { withRootDecorator } from 'storybook-root-decorator';25addDecorator(withRootDecorator);26addParameters({27 rootDecorator: {28 {29 options: {30 },31 },32 },33});34import { addDecorator, addParameters } from '@storybook/reac ';35importwi withRootDecoratort} from 'storybook-root-decorator';36addDecorator(hRooRootDecorator);37addParameters({38 rootDecorator: {39 {40 options: {41 },42 },43 },44});45import { addDecorator, addParameters } from '@storybook/react';46import { withRootDecorator } from 'storybook-root-decorator';47addDecorator(withRootDecorator);48addParameters({49 rootDecorator: {

Full Screen

Using AI Code Generation

copy

Full Screen

1addDecorator(withRootDecorator);2addParameters({3 rootDecorator: {4 {5 options: {6 },7 },8 },9});10import { addDecorator, addParameters } from '@storybook/react';11import { withRootDecorator } from 'storybook-root-decorator';12addDecorator(withRootDecorator);13addParameters({14 rootDecorator: {15 {16imp r name: 'storybfkom apollo-client',;17 go{Stybookxtensons;18const stoybook = gSt();19import { }, } from 'storybook-root';20const { gtStorybook } = extensions;21nst stoybook = geStybook(;22orybook/react';23The extensimpo objecr istthe{s me objhRt ts Dhe one yeu getowhenayouoimport the ext nsfons from tho storybook-root potkage.corator';24addDecorator(withRootDecorator);25The rootDecs object is the oame obj: t s he one yu get whenxten import the extensions fsom theionorybosk-:oot packag[ {26import { addDecorator, addParameters } from '@storybook/react';27 },28The ex ensions object is t}esame object a he ne u get when yu iport the extensios from th stoy

Full Screen

Using AI Code Generation

copy

Full Screen

1 },2});3import { addDecorator, addParameters } from '@storybook/react';4import { withRootDecorator } from 'storybook-root-decorator';5addDecorator(withRootDecorator);6addParameters({7 rootDecorator: {

Full Screen

Using AI Code Generation

copy

Full Screen

1import { addDecorator } from '@storybook/react';2import { withThemesProvider } from 'storybook-addon-styled-component-theme';3import { theme } from 'storybook-root';4addDecorator(withTherd(ons[jse]));5export const parameters = {6 actions: { argTypesRegex: "^on[A-Z].*" },7};

Full Screen

Using AI Code Generation

copy

Full Screen

1const { extensions }manage=sjsbook-root')2const { addDecorator } = require('@storybook/react')3extensions(addDecorator)4ybook/conf(addD.cat)5cdns youexsrnieos=qu(rt)6ct{DePaatokiew=qu/de(od of story)7exted ne(tr/Drcao)8cn{x/ensi ns } = Pequart.ssorybook/-rnt'9o o tc{ost { extensic}o= dequtr}('@ =beok/noaco'k10cbom{n}=require('')11censtensions to storybo=require()12xnsdyn(13const { r } = equ'@sodybook/xinst')nst { addDecorator } = require('@storybook/react')

Full Screen

Using AI Code Generation

copy

Full Screen

1const { extensions } = require('storybook-root')2const { addDecorator } = require('@storybook/react')3extensions(addDecorator)4const { extensions } = require('storybook-root')5const { addDecorator } = require('@storybook/react')6extensions(addDecorator)7const { extensions } = require('storybook-root')8const { addDecorator } = require('@storybook/react')9extensions(addDecorator)10const { extensions } = require('storybook-root')11const { addDecorator } = require('@storybook/react')12extensions(addDecorator)13const { extensions } = require('storybook-root')14const { addDecorator } = require('@storybook/react')15extensions(addDecorator)16const { extensions } = require('storybook-root')17const { addDecorator } = require('@storybook/react')18extensions(addDecorator)19const { extensions } = require('storybook-root')20const { addDecorator } = require('@storybook/react')21extensions(addDecorator)22const { extensions } = require('storybook-root')23const { addDecorator } = require('@storybook/react')24extensions(addDecorator)25const { extensions } = require('storybook-root')26const { addDecorator } = require('@storybook/react')

Full Screen

Using AI Code Generation

copy

Full Screen

1import { storiesOf } from '@storybook/react';2import { withKnobs } from '@storybook/addon-knobs';3import { withInfo } from '@storybook/addon-info';4import { withTests } from '@storybook/addon-jest';5import { withA11y } from '@storybook/addon-a11y';6import { withViewport } from '@storybook/addon-viewport';7import { withDesign } from 'storybook-addon-designs';8import { withStorysource } from '@storybook/addon-storysource';9import { withConsole } from '@storybook/addon-console';10import { withPerformance } from 'storybook-addon-performance';11import { withContexts } from '@storybook/addon-contexts/react';12import { withBackgrounds } from '@storybook/addon-backgrounds';13import { withCode } from 'storybook-addon-code';14import { withRedux } from 'addon-redux';15import { withPercy } from '@percy-io/percy-storybook';16import { withCreevey } from 'creevey';17import { withStorybookTheme } from 'storybook-addon-theme';18storiesOf('Storybook Addons', module)19 .addDecorator(withKnobs)20 .addDecorator(withInfo)21 .addDecorator(withTests)22 .addDecorator(withA11y)23 .addDecorator(withViewport)24 .addDecorator(withDesign)25 .addDecorator(withStorysource)26 .addDecorator(withConsole)27 .addDecorator(withPerformance)28 .addDecorator(withContexts)29 .addDecorator(withBackgrounds)30 .addDecorator(withCode)31 .addDecorator(withRedux)32 .addDecorator(withPercy)33 .addDecorator(withCreevey)34 .addDecorator(withStorybookTheme)35 .add('with knobs', () => <Button label="Hello Button" />, {36 creevey: {37 tests: {38 async click() {39 const { browser } = this.creevey;40 .actions({41 })42 .click(browser.findElement({ css: 'button' }))43 .perform();44 },45 },46 },47 })48 .add('with info', () => <Button label="Hello Button" />)49 .add('with tests', () => <Button label

Full Screen

Using AI Code Generation

copy

Full Screen

1import { addDecorator } from '@storybook/react';2import { withThemesProvider } from 'storybook-addon-styled-component-theme';3import { theme } from 'storybook-root';4addDecorator(withThemesProvider([theme]));5export const parameters = {6 actions: { argTypesRegex: "^on[A-Z].*" },7};

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run storybook-root automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful