Skip to content

Commit

Permalink
Add resolveExternalUri embedder contribution point
Browse files Browse the repository at this point in the history
  • Loading branch information
mjbvz committed Sep 17, 2019
1 parent 86baf83 commit 5fc4fe2
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 7 deletions.
14 changes: 12 additions & 2 deletions src/vs/editor/browser/services/openerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ import { equalsIgnoreCase } from 'vs/base/common/strings';
import { URI } from 'vs/base/common/uri';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
import { IOpener, IOpenerService, IValidator } from 'vs/platform/opener/common/opener';
import { IOpener, IOpenerService, IValidator, IExternalUriResolver } from 'vs/platform/opener/common/opener';

export class OpenerService extends Disposable implements IOpenerService {

_serviceBrand: undefined;

private readonly _openers = new LinkedList<IOpener>();
private readonly _validators = new LinkedList<IValidator>();
private readonly _resolvers = new LinkedList<IExternalUriResolver>();

constructor(
@ICodeEditorService private readonly _editorService: ICodeEditorService,
Expand All @@ -39,6 +40,11 @@ export class OpenerService extends Disposable implements IOpenerService {
return { dispose: remove };
}

registerExternalUriResolver(resolver: IExternalUriResolver): IDisposable {
const remove = this._resolvers.push(resolver);
return { dispose: remove };
}

async open(resource: URI, options?: { openToSide?: boolean, openExternal?: boolean }): Promise<boolean> {
// no scheme ?!?
if (!resource.scheme) {
Expand Down Expand Up @@ -118,7 +124,11 @@ export class OpenerService extends Disposable implements IOpenerService {
}
}

private _doOpenExternal(resource: URI): Promise<boolean> {
private async _doOpenExternal(resource: URI): Promise<boolean> {
for (const resolver of this._resolvers.toArray()) {
resource = await resolver.resolveExternalUri(resource);
}

dom.windowOpenNoOpener(encodeURI(resource.toString(true)));

return Promise.resolve(true);
Expand Down
18 changes: 14 additions & 4 deletions src/vs/platform/opener/common/opener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { URI } from 'vs/base/common/uri';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';

export const IOpenerService = createDecorator<IOpenerService>('openerService');

Expand All @@ -18,6 +18,10 @@ export interface IValidator {
shouldOpen(resource: URI): Promise<boolean>;
}

export interface IExternalUriResolver {
resolveExternalUri(resource: URI): Promise<URI>;
}

export interface IOpenerService {

_serviceBrand: undefined;
Expand All @@ -29,10 +33,15 @@ export interface IOpenerService {

/**
* Register a participant that can validate if the URI resource be opened.
* validators are run before openers.
* Validators are run before openers.
*/
registerValidator(validator: IValidator): IDisposable;

/**
* Register a participant that can resolve an external URI resource to be opened.
*/
registerExternalUriResolver(resolver: IExternalUriResolver): IDisposable;

/**
* Opens a resource, like a webaddress, a document uri, or executes command.
*
Expand All @@ -45,7 +54,8 @@ export interface IOpenerService {

export const NullOpenerService: IOpenerService = Object.freeze({
_serviceBrand: undefined,
registerOpener() { return { dispose() { } }; },
registerValidator() { return { dispose() { } }; },
registerOpener() { return Disposable.None; },
registerValidator() { return Disposable.None; },
registerExternalUriResolver() { return Disposable.None; },
open() { return Promise.resolve(false); },
});
26 changes: 26 additions & 0 deletions src/vs/workbench/contrib/url/common/externalUriResolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*---------------------------------------------------------------------------------------------
* 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 { IOpenerService } from 'vs/platform/opener/common/opener';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';

export class ExternalUriResolverContribution extends Disposable implements IWorkbenchContribution {
constructor(
@IOpenerService _openerService: IOpenerService,
@IWorkbenchEnvironmentService _workbenchEnvironmentService: IWorkbenchEnvironmentService,
) {
super();

if (_workbenchEnvironmentService.options && _workbenchEnvironmentService.options.resolveExternalUri) {
this._register(_openerService.registerExternalUriResolver({
resolveExternalUri: async (resource) => {
return _workbenchEnvironmentService.options!.resolveExternalUri!(resource);
}
}));
}
}
}
7 changes: 6 additions & 1 deletion src/vs/workbench/contrib/url/common/url.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import { Registry } from 'vs/platform/registry/common/platform';
import { IURLService } from 'vs/platform/url/common/url';
import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions';
import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
import { ExternalUriResolverContribution } from 'vs/workbench/contrib/url/common/externalUriResolver';
import { configureTrustedDomainSettingsCommand } from 'vs/workbench/contrib/url/common/trustedDomains';
import { OpenerValidatorContributions } from 'vs/workbench/contrib/url/common/trustedDomainsValidator';
import { TrustedDomainsFileSystemProvider } from 'vs/workbench/contrib/url/common/trustedDomainsFileSystemProvider';
import { OpenerValidatorContributions } from 'vs/workbench/contrib/url/common/trustedDomainsValidator';

export class OpenUrlAction extends Action {
static readonly ID = 'workbench.action.url.openUrl';
Expand Down Expand Up @@ -65,3 +66,7 @@ Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).regi
TrustedDomainsFileSystemProvider,
LifecyclePhase.Ready
);
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(
ExternalUriResolverContribution,
LifecyclePhase.Ready
);
5 changes: 5 additions & 0 deletions src/vs/workbench/workbench.web.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ interface IWorkbenchConstructionOptions {
* Experimental: Support for update reporting.
*/
updateProvider?: IUpdateProvider;

/**
* Experimental: Resolves an external uri before it is opened.
*/
readonly resolveExternalUri?: (uri: URI) => Promise<URI>;
}

/**
Expand Down

0 comments on commit 5fc4fe2

Please sign in to comment.