Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions extensions/git/src/protocolHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@

'use strict';

import { ProtocolHandler, Uri, window, Disposable, commands } from 'vscode';
import { UriHandler, Uri, window, Disposable, commands } from 'vscode';
import { dispose } from './util';
import * as querystring from 'querystring';

export class GitProtocolHandler implements ProtocolHandler {
export class GitProtocolHandler implements UriHandler {

private disposables: Disposable[] = [];

constructor() {
this.disposables.push(window.registerProtocolHandler(this));
this.disposables.push(window.registerUriHandler(this));
}

handleUri(uri: Uri): void {
Expand Down
38 changes: 38 additions & 0 deletions src/vs/vscode.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5732,6 +5732,21 @@ declare module 'vscode' {
readonly focused: boolean;
}

/**
* A uri handler is responsible for handling system-wide [uris](#Uri).
*
* @see [window.registerUriHandler](#window.registerUriHandler).
*/
export interface UriHandler {

/**
* Handle the provided system-wide [uri](#Uri).
*
* @see [window.registerUriHandler](#window.registerUriHandler).
*/
handleUri(uri: Uri): ProviderResult<void>;
}

/**
* Namespace for dealing with the current window of the editor. That is visible
* and active editors, as well as, UI elements to show messages, selections, and
Expand Down Expand Up @@ -6203,6 +6218,29 @@ declare module 'vscode' {
*/
export function createTreeView<T>(viewId: string, options: { treeDataProvider: TreeDataProvider<T> }): TreeView<T>;

/**
* Registers a [uri handler](#UriHandler) capable of handling system-wide [uris](#Uri).
* In case there are multiple windows open, the topmost window will handle the uri.
* A uri handler is scoped to the extension it is contributed from; it will only
* be able to handle uris which are directed to the extension itself. A uri must respect
* the following rules:
*
* - The uri-scheme must be the product name;
* - The uri-authority must be the extension id (eg. `my.extension`);
* - The uri-path, -query and -fragment parts are arbitrary.
*
* For example, if the `my.extension` extension registers a uri handler, it will only
* be allowed to handle uris with the prefix `product-name://my.extension`.
*
* An extension can only register a single uri handler in its entire activation lifetime.
*
* * *Note:* There is an activation event `onUri` that fires when a uri directed for
* the current extension is about to be handled.
*
* @param handler The uri handler to register for this extension.
*/
export function registerUriHandler(handler: UriHandler): Disposable;

/**
* Registers a webview panel serializer.
*
Expand Down
16 changes: 0 additions & 16 deletions src/vs/vscode.proposed.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -638,22 +638,6 @@ declare module 'vscode' {

//#endregion

//#region URLs

export interface ProtocolHandler {
handleUri(uri: Uri): void;
}

export namespace window {

/**
* Registers a protocol handler capable of handling system-wide URIs.
*/
export function registerProtocolHandler(handler: ProtocolHandler): Disposable;
}

//#endregion

//#region Joh -> exclusive document filters

export interface DocumentFilter {
Expand Down
4 changes: 2 additions & 2 deletions src/vs/workbench/api/electron-browser/mainThreadUrls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class MainThreadUrls implements MainThreadUrlsShape {
this.proxy = context.getProxy(ExtHostContext.ExtHostUrls);
}

$registerProtocolHandler(handle: number, extensionId: string): TPromise<void> {
$registerUriHandler(handle: number, extensionId: string): TPromise<void> {
const handler = new ExtensionUrlHandler(this.proxy, handle, extensionId);
const disposable = this.urlService.registerHandler(handler);

Expand All @@ -52,7 +52,7 @@ export class MainThreadUrls implements MainThreadUrlsShape {
return TPromise.as(null);
}

$unregisterProtocolHandler(handle: number): TPromise<void> {
$unregisterUriHandler(handle: number): TPromise<void> {
const tuple = this.handlers.get(handle);

if (!tuple) {
Expand Down
6 changes: 3 additions & 3 deletions src/vs/workbench/api/node/extHost.api.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -452,9 +452,9 @@ export function createApiFactory(
registerDecorationProvider: proposedApiFunction(extension, (provider: vscode.DecorationProvider) => {
return extHostDecorations.registerDecorationProvider(provider, extension.id);
}),
registerProtocolHandler: proposedApiFunction(extension, (handler: vscode.ProtocolHandler) => {
return extHostUrls.registerProtocolHandler(extension.id, handler);
}),
registerUriHandler(handler: vscode.UriHandler) {
return extHostUrls.registerUriHandler(extension.id, handler);
},
get quickInputBackButton() {
return proposedApiFunction(extension, (): vscode.QuickInputButton => {
return extHostQuickOpen.backButton;
Expand Down
4 changes: 2 additions & 2 deletions src/vs/workbench/api/node/extHost.protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -453,8 +453,8 @@ export interface ExtHostWebviewsShape {
}

export interface MainThreadUrlsShape extends IDisposable {
$registerProtocolHandler(handle: number, extensionId: string): TPromise<void>;
$unregisterProtocolHandler(handle: number): TPromise<void>;
$registerUriHandler(handle: number, extensionId: string): TPromise<void>;
$unregisterUriHandler(handle: number): TPromise<void>;
}

export interface ExtHostUrlsShape {
Expand Down
14 changes: 9 additions & 5 deletions src/vs/workbench/api/node/extHostUrls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,37 @@ import { MainContext, IMainContext, ExtHostUrlsShape, MainThreadUrlsShape } from
import URI, { UriComponents } from 'vs/base/common/uri';
import { TPromise } from 'vs/base/common/winjs.base';
import { toDisposable } from 'vs/base/common/lifecycle';
import { asWinJsPromise } from 'vs/base/common/async';
import { onUnexpectedError } from 'vs/base/common/errors';

export class ExtHostUrls implements ExtHostUrlsShape {

private static HandlePool = 0;
private readonly _proxy: MainThreadUrlsShape;

private handles = new Set<string>();
private handlers = new Map<number, vscode.ProtocolHandler>();
private handlers = new Map<number, vscode.UriHandler>();

constructor(
mainContext: IMainContext
) {
this._proxy = mainContext.getProxy(MainContext.MainThreadUrls);
}

registerProtocolHandler(extensionId: string, handler: vscode.ProtocolHandler): vscode.Disposable {
registerUriHandler(extensionId: string, handler: vscode.UriHandler): vscode.Disposable {
if (this.handles.has(extensionId)) {
throw new Error(`Protocol handler already registered for extension ${extensionId}`);
}

const handle = ExtHostUrls.HandlePool++;
this.handles.add(extensionId);
this.handlers.set(handle, handler);
this._proxy.$registerProtocolHandler(handle, extensionId);
this._proxy.$registerUriHandler(handle, extensionId);

return toDisposable(() => {
this.handles.delete(extensionId);
this.handlers.delete(handle);
this._proxy.$unregisterProtocolHandler(handle);
this._proxy.$unregisterUriHandler(handle);
});
}

Expand All @@ -47,7 +49,9 @@ export class ExtHostUrls implements ExtHostUrlsShape {
return TPromise.as(null);
}

handler.handleUri(URI.revive(uri));
asWinJsPromise(_ => handler.handleUri(URI.revive(uri)))
.done(null, onUnexpectedError);

return TPromise.as(null);
}
}