@@ -16,7 +16,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
1616import { IStorageService , StorageScope , StorageTarget } from 'vs/platform/storage/common/storage' ;
1717import { IURLHandler , IURLService , IOpenURLOptions } from 'vs/platform/url/common/url' ;
1818import { IHostService } from 'vs/workbench/services/host/browser/host' ;
19- import { IExtensionService , toExtensionDescription } from 'vs/workbench/services/extensions/common/extensions' ;
19+ import { ActivationKind , IExtensionService , toExtensionDescription } from 'vs/workbench/services/extensions/common/extensions' ;
2020import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions' ;
2121import { InstantiationType , registerSingleton } from 'vs/platform/instantiation/common/extensions' ;
2222import { Registry } from 'vs/platform/registry/common/platform' ;
@@ -70,9 +70,13 @@ class UserTrustedExtensionIdStorage {
7070
7171export const IExtensionUrlHandler = createDecorator < IExtensionUrlHandler > ( 'extensionUrlHandler' ) ;
7272
73+ export interface IExtensionContributedURLHandler extends IURLHandler {
74+ extensionDisplayName : string ;
75+ }
76+
7377export interface IExtensionUrlHandler {
7478 readonly _serviceBrand : undefined ;
75- registerExtensionHandler ( extensionId : ExtensionIdentifier , handler : IURLHandler ) : void ;
79+ registerExtensionHandler ( extensionId : ExtensionIdentifier , handler : IExtensionContributedURLHandler ) : void ;
7680 unregisterExtensionHandler ( extensionId : ExtensionIdentifier ) : void ;
7781}
7882
@@ -99,7 +103,7 @@ class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler {
99103
100104 readonly _serviceBrand : undefined ;
101105
102- private extensionHandlers = new Map < string , IURLHandler > ( ) ;
106+ private extensionHandlers = new Map < string , IExtensionContributedURLHandler > ( ) ;
103107 private uriBuffer = new Map < string , { timestamp : number ; uri : URI } [ ] > ( ) ;
104108 private userTrustedExtensionsStorage : UserTrustedExtensionIdStorage ;
105109 private disposable : IDisposable ;
@@ -145,12 +149,20 @@ class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler {
145149 const extensionId = uri . authority ;
146150 this . telemetryService . publicLog2 < ExtensionUrlHandlerEvent , ExtensionUrlHandlerClassification > ( 'uri_invoked/start' , { extensionId } ) ;
147151
148- const wasHandlerAvailable = this . extensionHandlers . has ( ExtensionIdentifier . toKey ( extensionId ) ) ;
149- const extension = await this . extensionService . getExtension ( extensionId ) ;
152+ const initialHandler = this . extensionHandlers . get ( ExtensionIdentifier . toKey ( extensionId ) ) ;
153+ let extensionDisplayName : string ;
150154
151- if ( ! extension ) {
152- await this . handleUnhandledURL ( uri , { id : extensionId } , options ) ;
153- return true ;
155+ if ( ! initialHandler ) {
156+ // The extension is not yet activated, so let's check if it is installed and enabled
157+ const extension = await this . extensionService . getExtension ( extensionId ) ;
158+ if ( ! extension ) {
159+ await this . handleUnhandledURL ( uri , { id : extensionId } , options ) ;
160+ return true ;
161+ } else {
162+ extensionDisplayName = extension . displayName || extension . name ;
163+ }
164+ } else {
165+ extensionDisplayName = initialHandler . extensionDisplayName ;
154166 }
155167
156168 const trusted = options ?. trusted
@@ -169,7 +181,7 @@ class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler {
169181 checkbox : {
170182 label : localize ( 'rememberConfirmUrl' , "Don't ask again for this extension." ) ,
171183 } ,
172- detail : `${ extension . displayName || extension . name } (${ extensionId } ) wants to open a URI:\n\n${ uriString } ` ,
184+ detail : `${ extensionDisplayName } (${ extensionId } ) wants to open a URI:\n\n${ uriString } ` ,
173185 primaryButton : localize ( { key : 'open' , comment : [ '&& denotes a mnemonic' ] } , "&&Open" )
174186 } ) ;
175187
@@ -186,7 +198,7 @@ class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler {
186198 const handler = this . extensionHandlers . get ( ExtensionIdentifier . toKey ( extensionId ) ) ;
187199
188200 if ( handler ) {
189- if ( ! wasHandlerAvailable ) {
201+ if ( ! initialHandler ) {
190202 // forward it directly
191203 return await this . handleURLByExtension ( extensionId , handler , uri , options ) ;
192204 }
@@ -206,12 +218,13 @@ class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler {
206218
207219 uris . push ( { timestamp, uri } ) ;
208220
209- // activate the extension
210- await this . extensionService . activateByEvent ( `onUri:${ ExtensionIdentifier . toKey ( extensionId ) } ` ) ;
221+ // activate the extension using ActivationKind.Immediate because URI handling might be part
222+ // of resolving authorities (via authentication extensions)
223+ await this . extensionService . activateByEvent ( `onUri:${ ExtensionIdentifier . toKey ( extensionId ) } ` , ActivationKind . Immediate ) ;
211224 return true ;
212225 }
213226
214- registerExtensionHandler ( extensionId : ExtensionIdentifier , handler : IURLHandler ) : void {
227+ registerExtensionHandler ( extensionId : ExtensionIdentifier , handler : IExtensionContributedURLHandler ) : void {
215228 this . extensionHandlers . set ( ExtensionIdentifier . toKey ( extensionId ) , handler ) ;
216229
217230 const uris = this . uriBuffer . get ( ExtensionIdentifier . toKey ( extensionId ) ) || [ ] ;
0 commit comments