diff --git a/extensions/simple-browser/README.md b/extensions/simple-browser/README.md index 5cc65e7b19a..42a681dfc2e 100644 --- a/extensions/simple-browser/README.md +++ b/extensions/simple-browser/README.md @@ -1,3 +1,8 @@ # Simple Browser files **Notice:** This extension is bundled with Visual Studio Code. It can be disabled but not uninstalled. + + +a $a + b = c$ b + +a $\pm\sqrt{a^2 + b^2}$ b diff --git a/extensions/simple-browser/package.json b/extensions/simple-browser/package.json index 9982f6c7d12..d93645f13c0 100644 --- a/extensions/simple-browser/package.json +++ b/extensions/simple-browser/package.json @@ -39,12 +39,6 @@ "default": true, "title": "Focus Lock Indicator Enabled", "description": "%configuration.focusLockIndicator.enabled.description%" - }, - "simpleBrowser.opener.enabled": { - "type": "boolean", - "default": false, - "title": "Opener Enabled", - "description": "%configuration.opener.enabled.description%" } } } diff --git a/extensions/simple-browser/package.nls.json b/extensions/simple-browser/package.nls.json index 6c34681a480..05136be16fe 100644 --- a/extensions/simple-browser/package.nls.json +++ b/extensions/simple-browser/package.nls.json @@ -2,6 +2,5 @@ "displayName": "Simple Browser", "description": "A very basic built-in webview for displaying web content.", "configuration.focusLockIndicator.enabled.description": "Enable/disable ", - "configuration.opener.enabled.description": "(Experimental) Enables using the built-in simple browser when opening http and https urls.", - "configuration.opener.enabledHosts.description": "Lists of hosts to open in the simple browser. For example: `localhost`." + "configuration.opener.enabled.description": "(Experimental) Enables using the built-in simple browser when opening http and https urls." } diff --git a/extensions/simple-browser/src/extension.ts b/extensions/simple-browser/src/extension.ts index 7274a7343b7..9e645667153 100644 --- a/extensions/simple-browser/src/extension.ts +++ b/extensions/simple-browser/src/extension.ts @@ -45,27 +45,26 @@ export function activate(context: vscode.ExtensionContext) { manager.show(url.toString(), showOptions); })); - context.subscriptions.push(vscode.window.registerExternalUriOpener(['http', 'https'], { + context.subscriptions.push(vscode.window.registerExternalUriOpener(openerId, ['http', 'https'], { canOpenExternalUri(uri: vscode.Uri) { const configuration = vscode.workspace.getConfiguration('simpleBrowser'); if (!configuration.get('opener.enabled', false)) { - return vscode.ExternalUriOpenerEnablement.Disabled; + return vscode.ExternalUriOpenerPriority.None; } const originalUri = new URL(uri.toString()); if (enabledHosts.has(originalUri.hostname)) { return isWeb() - ? vscode.ExternalUriOpenerEnablement.Preferred - : vscode.ExternalUriOpenerEnablement.Enabled; + ? vscode.ExternalUriOpenerPriority.Preferred + : vscode.ExternalUriOpenerPriority.Option; } - return vscode.ExternalUriOpenerEnablement.Disabled; + return vscode.ExternalUriOpenerPriority.None; }, openExternalUri(resolveUri: vscode.Uri) { return manager.show(resolveUri.toString()); } }, { - id: openerId, label: localize('openTitle', "Open in simple browser"), })); } diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts index 35b306d602f..b0ddffe0e42 100644 --- a/src/vs/editor/common/modes.ts +++ b/src/vs/editor/common/modes.ts @@ -1881,8 +1881,9 @@ export const TokenizationRegistry = new TokenizationRegistryImpl(); /** * @internal */ -export enum ExternalUriOpenerEnablement { - Disabled, - Enabled, - Preferred +export enum ExternalUriOpenerPriority { + None = 0, + Option = 1, + Default = 2, + Preferred = 3, } diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 0b792160eab..59df165ca02 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -2294,21 +2294,39 @@ declare module 'vscode' { //#region Opener service (https://github.com/microsoft/vscode/issues/109277) - export enum ExternalUriOpenerEnablement { + export enum ExternalUriOpenerPriority { /** - * The opener cannot handle the uri. + * The opener is disabled and will not be shown to users. + * + * Note that the opener can still be used if the user + * specifically configures it in their settings. */ - Disabled = 0, + None = 0, /** - * The opener can handle the uri. + * The opener can open the uri but will not be shown by default when a + * user clicks on the uri. + * + * If only optional openers are enabled, then VS Code's default opener + * will be automatically used. */ - Enabled = 1, + Option = 1, /** - * The opener can handle the uri and should be automatically selected if possible. + * The opener can open the uri. + * + * When the user clicks on a uri, they will be prompted to select the opener + * they wish to use for it. */ - Preferred = 2 + Default = 2, + + /** + * The opener can open the uri and should be automatically selected if possible. + * + * Preferred openers will be automatically selected if no other preferred openers + * are available. + */ + Preferred = 3, } /** @@ -2330,7 +2348,7 @@ declare module 'vscode' { * * @return If the opener can open the external uri. */ - canOpenExternalUri(uri: Uri, token: CancellationToken): ProviderResult; + canOpenExternalUri(uri: Uri, token: CancellationToken): ExternalUriOpenerPriority | Thenable; /** * Open the given uri. @@ -2368,12 +2386,6 @@ declare module 'vscode' { * Additional metadata about the registered opener. */ interface ExternalUriOpenerMetadata { - /** - * Unique id of the opener, such as `myExtension.browserPreview` - * - * This is used in settings and commands to identifier the opener. - */ - readonly id: string; /** * Text displayed to the user that explains what the opener does. @@ -2389,13 +2401,16 @@ declare module 'vscode' { * * When a uri is about to be opened, an `onUriOpen:SCHEME` activation event is fired. * + * @param id Unique id of the opener, such as `myExtension.browserPreview`. This is used in settings + * and commands to identify the opener. * @param schemes List of uri schemes the opener is triggered for. Currently only `http` * and `https` are supported. * @param opener Opener to register. + * @param metadata Additional information about the opener. * * @returns Disposable that unregisters the opener. */ - export function registerExternalUriOpener(schemes: readonly string[], opener: ExternalUriOpener, metadata: ExternalUriOpenerMetadata): Disposable; + export function registerExternalUriOpener(id: string, schemes: readonly string[], opener: ExternalUriOpener, metadata: ExternalUriOpenerMetadata): Disposable; } //#endregion diff --git a/src/vs/workbench/api/browser/mainThreadUriOpeners.ts b/src/vs/workbench/api/browser/mainThreadUriOpeners.ts index 99e26769eb0..c4c5c42bbb0 100644 --- a/src/vs/workbench/api/browser/mainThreadUriOpeners.ts +++ b/src/vs/workbench/api/browser/mainThreadUriOpeners.ts @@ -10,8 +10,9 @@ import { URI } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { INotificationService } from 'vs/platform/notification/common/notification'; +import { IStorageService } from 'vs/platform/storage/common/storage'; import { ExtHostContext, ExtHostUriOpenersShape, IExtHostContext, MainContext, MainThreadUriOpenersShape } from 'vs/workbench/api/common/extHost.protocol'; -import { externalUriOpenerIdSchemaAddition } from 'vs/workbench/contrib/externalUriOpener/common/configuration'; +import { ContributedExternalUriOpenersStore } from 'vs/workbench/contrib/externalUriOpener/common/contributedOpeners'; import { IExternalOpenerProvider, IExternalUriOpener, IExternalUriOpenerService } from 'vs/workbench/contrib/externalUriOpener/common/externalUriOpenerService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { extHostNamedCustomer } from '../common/extHostCustomers'; @@ -27,9 +28,11 @@ export class MainThreadUriOpeners extends Disposable implements MainThreadUriOpe private readonly proxy: ExtHostUriOpenersShape; private readonly _registeredOpeners = new Map(); + private readonly _contributedExternalUriOpenersStore: ContributedExternalUriOpenersStore; constructor( context: IExtHostContext, + @IStorageService storageService: IStorageService, @IExternalUriOpenerService externalUriOpenerService: IExternalUriOpenerService, @IExtensionService private readonly extensionService: IExtensionService, @INotificationService private readonly notificationService: INotificationService, @@ -38,6 +41,8 @@ export class MainThreadUriOpeners extends Disposable implements MainThreadUriOpe this.proxy = context.getProxy(ExtHostContext.ExtHostUriOpeners); this._register(externalUriOpenerService.registerExternalOpenerProvider(this)); + + this._contributedExternalUriOpenersStore = this._register(new ContributedExternalUriOpenersStore(storageService, extensionService)); } public async *getOpeners(targetUri: URI): AsyncIterable { @@ -92,11 +97,12 @@ export class MainThreadUriOpeners extends Disposable implements MainThreadUriOpe extensionId, }); - externalUriOpenerIdSchemaAddition.enum?.push(id); + this._contributedExternalUriOpenersStore.add(id, extensionId.value); } async $unregisterUriOpener(id: string): Promise { this._registeredOpeners.delete(id); + this._contributedExternalUriOpenersStore.delete(id); } dispose(): void { diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 232d2734fd9..8f271b937f9 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -672,9 +672,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I checkProposedApiEnabled(extension); return extHostNotebook.showNotebookDocument(document, options); }, - registerExternalUriOpener(schemes: readonly string[], opener: vscode.ExternalUriOpener, metadata: vscode.ExternalUriOpenerMetadata) { + registerExternalUriOpener(id: string, schemes: readonly string[], opener: vscode.ExternalUriOpener, metadata: vscode.ExternalUriOpenerMetadata) { checkProposedApiEnabled(extension); - return extHostUriOpeners.registerUriOpener(extension.identifier, schemes, opener, metadata); + return extHostUriOpeners.registerUriOpener(extension.identifier, id, schemes, opener, metadata); }, }; @@ -1133,7 +1133,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I EventEmitter: Emitter, ExtensionKind: extHostTypes.ExtensionKind, ExtensionMode: extHostTypes.ExtensionMode, - ExternalUriOpenerEnablement: extHostTypes.ExternalUriOpenerEnablement, + ExternalUriOpenerPriority: extHostTypes.ExternalUriOpenerPriority, FileChangeType: extHostTypes.FileChangeType, FileDecoration: extHostTypes.FileDecoration, FileSystemError: extHostTypes.FileSystemError, diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 4f24459ce50..34618fde866 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -808,7 +808,7 @@ export interface MainThreadUriOpenersShape extends IDisposable { } export interface ExtHostUriOpenersShape { - $canOpenUri(id: string, uri: UriComponents, token: CancellationToken): Promise; + $canOpenUri(id: string, uri: UriComponents, token: CancellationToken): Promise; $openUri(id: string, context: { resolvedUri: UriComponents, sourceUri: UriComponents }, token: CancellationToken): Promise; } diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index fbd6592c661..9513d3047ff 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -2978,8 +2978,9 @@ export type RequiredTestItem = { //#endregion -export enum ExternalUriOpenerEnablement { - Disabled = 0, - Enabled = 1, - Preferred = 2 +export enum ExternalUriOpenerPriority { + None = 0, + Option = 1, + Default = 2, + Preferred = 3, } diff --git a/src/vs/workbench/api/common/extHostUriOpener.ts b/src/vs/workbench/api/common/extHostUriOpener.ts index eaaaca2088d..30612009743 100644 --- a/src/vs/workbench/api/common/extHostUriOpener.ts +++ b/src/vs/workbench/api/common/extHostUriOpener.ts @@ -32,11 +32,11 @@ export class ExtHostUriOpeners implements ExtHostUriOpenersShape { registerUriOpener( extensionId: ExtensionIdentifier, + id: string, schemes: readonly string[], opener: vscode.ExternalUriOpener, metadata: vscode.ExternalUriOpenerMetadata, ): vscode.Disposable { - const id = metadata.id; if (this._openers.has(id)) { throw new Error(`Opener with id already registered: '${id}'`); } @@ -55,15 +55,14 @@ export class ExtHostUriOpeners implements ExtHostUriOpenersShape { }); } - async $canOpenUri(id: string, uriComponents: UriComponents, token: CancellationToken): Promise { + async $canOpenUri(id: string, uriComponents: UriComponents, token: CancellationToken): Promise { const entry = this._openers.get(id); if (!entry) { throw new Error(`Unknown opener with id: ${id}`); } const uri = URI.revive(uriComponents); - const result = await entry.opener.canOpenExternalUri(uri, token); - return result ? result : modes.ExternalUriOpenerEnablement.Disabled; + return entry.opener.canOpenExternalUri(uri, token); } async $openUri(id: string, context: { resolvedUri: UriComponents, sourceUri: UriComponents }, token: CancellationToken): Promise { diff --git a/src/vs/workbench/contrib/externalUriOpener/common/configuration.ts b/src/vs/workbench/contrib/externalUriOpener/common/configuration.ts index fcd27ca5263..bed2f5e7d76 100644 --- a/src/vs/workbench/contrib/externalUriOpener/common/configuration.ts +++ b/src/vs/workbench/contrib/externalUriOpener/common/configuration.ts @@ -3,10 +3,11 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IConfigurationNode } from 'vs/platform/configuration/common/configurationRegistry'; +import { IConfigurationNode, IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry'; import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration'; import * as nls from 'vs/nls'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; +import { Registry } from 'vs/platform/registry/common/platform'; export const externalUriOpenersSettingId = 'workbench.externalUriOpeners'; @@ -15,7 +16,7 @@ export interface ExternalUriOpenerConfiguration { readonly id: string; } -export const externalUriOpenerIdSchemaAddition: IJSONSchema = { +const externalUriOpenerIdSchemaAddition: IJSONSchema = { type: 'string', enum: [] }; @@ -66,3 +67,11 @@ export const externalUriOpenersConfigurationNode: IConfigurationNode = { } } }; + +export function updateContributedOpeners(enumValues: string[], enumDescriptions: string[]): void { + externalUriOpenerIdSchemaAddition.enum = enumValues; + externalUriOpenerIdSchemaAddition.enumDescriptions = enumDescriptions; + + Registry.as(Extensions.Configuration) + .notifyConfigurationSchemaUpdated(externalUriOpenersConfigurationNode); +} diff --git a/src/vs/workbench/contrib/externalUriOpener/common/contributedOpeners.ts b/src/vs/workbench/contrib/externalUriOpener/common/contributedOpeners.ts new file mode 100644 index 00000000000..4c6a5f0bbf4 --- /dev/null +++ b/src/vs/workbench/contrib/externalUriOpener/common/contributedOpeners.ts @@ -0,0 +1,88 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Disposable } from 'vs/base/common/lifecycle'; +import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; +import { Memento } from 'vs/workbench/common/memento'; +import { updateContributedOpeners } from 'vs/workbench/contrib/externalUriOpener/common/configuration'; +import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; + +export const defaultExternalUriOpenerId = 'default'; + +interface RegisteredExternalOpener { + readonly extensionId: string; +} + +interface OpenersMemento { + [id: string]: RegisteredExternalOpener; +} + +/** + */ +export class ContributedExternalUriOpenersStore extends Disposable { + + private static readonly STORAGE_ID = 'externalUriOpeners'; + + private readonly _openers = new Map(); + private readonly _memento: Memento; + private _mementoObject: OpenersMemento; + + constructor( + @IStorageService storageService: IStorageService, + @IExtensionService private readonly _extensionService: IExtensionService + ) { + super(); + + this._memento = new Memento(ContributedExternalUriOpenersStore.STORAGE_ID, storageService); + this._mementoObject = this._memento.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE); + for (const id of Object.keys(this._mementoObject || {})) { + this.add(id, this._mementoObject[id].extensionId); + } + + this.invalidateOpenersForUninstalledExtension(); + + this._register(this._extensionService.onDidChangeExtensions(() => this.invalidateOpenersForUninstalledExtension())); + } + + public add(id: string, extensionId: string): void { + this._openers.set(id, { extensionId }); + + this._mementoObject[id] = { extensionId }; + this._memento.saveMemento(); + + this.updateSchema(); + } + + public delete(id: string): void { + this._openers.delete(id); + + delete this._mementoObject[id]; + this._memento.saveMemento(); + + this.updateSchema(); + } + + private async invalidateOpenersForUninstalledExtension() { + const registeredExtensions = await this._extensionService.getExtensions(); + for (const [id, entry] of this._openers) { + const isExtensionRegistered = registeredExtensions.some(r => r.identifier.value === entry.extensionId); + if (!isExtensionRegistered) { + this.delete(id); + } + } + } + + private updateSchema() { + const ids: string[] = []; + const descriptions: string[] = []; + + for (const [id, entry] of this._openers) { + ids.push(id); + descriptions.push(entry.extensionId); + } + + updateContributedOpeners(ids, descriptions); + } +} diff --git a/src/vs/workbench/contrib/externalUriOpener/common/externalUriOpenerService.ts b/src/vs/workbench/contrib/externalUriOpener/common/externalUriOpenerService.ts index 75fa9995d8d..a0fddc2063c 100644 --- a/src/vs/workbench/contrib/externalUriOpener/common/externalUriOpenerService.ts +++ b/src/vs/workbench/contrib/externalUriOpener/common/externalUriOpenerService.ts @@ -15,6 +15,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IExternalOpener, IOpenerService } from 'vs/platform/opener/common/opener'; import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; +import { IStorageService } from 'vs/platform/storage/common/storage'; import { ExternalUriOpenerConfiguration, externalUriOpenersSettingId } from 'vs/workbench/contrib/externalUriOpener/common/configuration'; import { testUrlMatchesGlob } from 'vs/workbench/contrib/url/common/urlGlob'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; @@ -30,7 +31,7 @@ export interface IExternalUriOpener { readonly id: string; readonly label: string; - canOpen(uri: URI, token: CancellationToken): Promise; + canOpen(uri: URI, token: CancellationToken): Promise; openExternalUri(uri: URI, ctx: { sourceUri: URI }, token: CancellationToken): Promise; } @@ -51,6 +52,7 @@ export class ExternalUriOpenerService extends Disposable implements IExternalUri constructor( @IOpenerService openerService: IOpenerService, + @IStorageService storageService: IStorageService, @IConfigurationService private readonly configurationService: IConfigurationService, @IPreferencesService private readonly preferencesService: IPreferencesService, @IQuickInputService private readonly quickInputService: IQuickInputService, @@ -86,16 +88,16 @@ export class ExternalUriOpenerService extends Disposable implements IExternalUri } // Then check to see if there is a valid opener - const validOpeners: Array<{ opener: IExternalUriOpener, preferred: boolean }> = []; + const validOpeners: Array<{ opener: IExternalUriOpener, priority: modes.ExternalUriOpenerPriority }> = []; await Promise.all(Array.from(allOpeners.values()).map(async opener => { - switch (await opener.canOpen(targetUri, token)) { - case modes.ExternalUriOpenerEnablement.Enabled: - validOpeners.push({ opener, preferred: false }); + const priority = await opener.canOpen(targetUri, token); + switch (priority) { + case modes.ExternalUriOpenerPriority.Option: + case modes.ExternalUriOpenerPriority.Default: + case modes.ExternalUriOpenerPriority.Preferred: + validOpeners.push({ opener, priority }); break; - case modes.ExternalUriOpenerEnablement.Preferred: - validOpeners.push({ opener, preferred: true }); - break; } })); if (validOpeners.length === 0) { @@ -103,13 +105,18 @@ export class ExternalUriOpenerService extends Disposable implements IExternalUri } // See if we have a preferred opener first - const preferred = firstOrDefault(validOpeners.filter(x => x.preferred)); + const preferred = firstOrDefault(validOpeners.filter(x => x.priority === modes.ExternalUriOpenerPriority.Preferred)); if (preferred) { return preferred.opener.openExternalUri(targetUri, ctx, token); } + // See if we only have optional openers, use the default opener + if (validOpeners.every(x => x.priority === modes.ExternalUriOpenerPriority.Option)) { + return false; + } + // Otherwise prompt - return this.showOpenerPrompt(validOpeners, targetUri, ctx, token); + return this.showOpenerPrompt(validOpeners.map(x => x.opener), targetUri, ctx, token); } private getConfiguredOpenerForUri(openers: Map, targetUri: URI): IExternalUriOpener | undefined { @@ -127,17 +134,17 @@ export class ExternalUriOpenerService extends Disposable implements IExternalUri } private async showOpenerPrompt( - openers: ReadonlyArray<{ opener: IExternalUriOpener, preferred: boolean }>, + openers: ReadonlyArray, targetUri: URI, ctx: { sourceUri: URI }, token: CancellationToken ): Promise { type PickItem = IQuickPickItem & { opener?: IExternalUriOpener | 'configureDefault' }; - const items: Array = openers.map((entry): PickItem => { + const items: Array = openers.map((opener): PickItem => { return { - label: entry.opener.label, - opener: entry.opener + label: opener.label, + opener: opener }; }); items.push( diff --git a/src/vs/workbench/contrib/externalUriOpener/test/common/externalUriOpenerService.test.ts b/src/vs/workbench/contrib/externalUriOpener/test/common/externalUriOpenerService.test.ts index ab8fc8d7a8a..557424f74b1 100644 --- a/src/vs/workbench/contrib/externalUriOpener/test/common/externalUriOpenerService.test.ts +++ b/src/vs/workbench/contrib/externalUriOpener/test/common/externalUriOpenerService.test.ts @@ -7,7 +7,7 @@ import * as assert from 'assert'; import { CancellationToken } from 'vs/base/common/cancellation'; import { Disposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; -import { ExternalUriOpenerEnablement } from 'vs/editor/common/modes'; +import { ExternalUriOpenerPriority } from 'vs/editor/common/modes'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; @@ -73,13 +73,13 @@ suite('ExternalUriOpenerService', () => { yield { id: 'disabled-id', label: 'disabled', - canOpen: async () => ExternalUriOpenerEnablement.Disabled, + canOpen: async () => ExternalUriOpenerPriority.None, openExternalUri: async () => true, }; yield { id: 'enabled-id', label: 'enabled', - canOpen: async () => ExternalUriOpenerEnablement.Enabled, + canOpen: async () => ExternalUriOpenerPriority.Default, openExternalUri: async () => { openedWithEnabled = true; return true; @@ -103,7 +103,7 @@ suite('ExternalUriOpenerService', () => { yield { id: 'other-id', label: 'other', - canOpen: async () => ExternalUriOpenerEnablement.Enabled, + canOpen: async () => ExternalUriOpenerPriority.Default, openExternalUri: async () => { return true; } @@ -111,7 +111,7 @@ suite('ExternalUriOpenerService', () => { yield { id: 'preferred-id', label: 'preferred', - canOpen: async () => ExternalUriOpenerEnablement.Preferred, + canOpen: async () => ExternalUriOpenerPriority.Preferred, openExternalUri: async () => { openedWithPreferred = true; return true;