From 0cbf1c75862df5594144f00a9e23d8ba7c12bfa8 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 9 Aug 2016 16:14:24 +0200 Subject: [PATCH] use URI for UrlService --- src/vs/base/parts/ipc/common/ipc.ts | 12 ++++++++---- src/vs/platform/url/common/url.ts | 3 ++- src/vs/platform/url/common/urlIpc.ts | 12 ++++++++---- src/vs/platform/url/electron-main/urlService.ts | 16 ++++++++++++---- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/vs/base/parts/ipc/common/ipc.ts b/src/vs/base/parts/ipc/common/ipc.ts index 72ba4b14cde..e6df9b04e0b 100644 --- a/src/vs/base/parts/ipc/common/ipc.ts +++ b/src/vs/base/parts/ipc/common/ipc.ts @@ -310,21 +310,25 @@ export function getNextTickChannel(channel: T): T { return { call } as T; } -export function eventToCall(event: Event): TPromise { +export type Serializer = (obj: T) => R; +export type Deserializer = (raw: R) => T; + +export function eventToCall(event: Event, serializer: Serializer = t => t): TPromise { let disposable: IDisposable; return new Promise( - (c, e, p) => disposable = event(p), + (c, e, p) => disposable = event(t => p(serializer(t))), () => disposable.dispose() ); } -export function eventFromCall(channel: IChannel, name: string, arg: any = null): Event { +export function eventFromCall(channel: IChannel, name: string, arg: any = null, deserializer: Deserializer = t => t): Event { let promise: Promise; const emitter = new Emitter({ onFirstListenerAdd: () => { - promise = channel.call(name, arg).then(null, err => null, e => emitter.fire(e)); + promise = channel.call(name, arg) + .then(null, err => null, e => emitter.fire(deserializer(e))); }, onLastListenerRemove: () => { promise.cancel(); diff --git a/src/vs/platform/url/common/url.ts b/src/vs/platform/url/common/url.ts index 7caa5dbda95..6e762cbceaf 100644 --- a/src/vs/platform/url/common/url.ts +++ b/src/vs/platform/url/common/url.ts @@ -6,6 +6,7 @@ 'use strict'; import Event from 'vs/base/common/event'; +import URI from 'vs/base/common/uri'; import {createDecorator} from 'vs/platform/instantiation/common/instantiation'; export const ID = 'urlService'; @@ -13,5 +14,5 @@ export const IURLService = createDecorator(ID); export interface IURLService { _serviceBrand: any; - onOpenURL: Event; + onOpenURL: Event; } diff --git a/src/vs/platform/url/common/urlIpc.ts b/src/vs/platform/url/common/urlIpc.ts index bb4f041bd8a..da64e492167 100644 --- a/src/vs/platform/url/common/urlIpc.ts +++ b/src/vs/platform/url/common/urlIpc.ts @@ -6,10 +6,14 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IChannel, eventToCall, eventFromCall } from 'vs/base/parts/ipc/common/ipc'; +import { IChannel, eventToCall, eventFromCall, Serializer, Deserializer } from 'vs/base/parts/ipc/common/ipc'; import { IURLService } from './url'; import Event, { filterEvent } from 'vs/base/common/event'; import { IWindowsService } from 'vs/code/electron-main/windows'; +import URI from 'vs/base/common/uri'; + +const URISerializer: Serializer = uri => uri.toJSON(); +const URIDeserializer: Deserializer = raw => URI.revive(raw); export interface IURLChannel extends IChannel { call(command: 'event:onOpenURL'): TPromise; @@ -25,7 +29,7 @@ export class URLChannel implements IURLChannel { call(command: string, arg: any): TPromise { switch (command) { - case 'event:onOpenURL': return eventToCall(filterEvent(this.service.onOpenURL, () => this.isWindowFocused(arg))); + case 'event:onOpenURL': return eventToCall(filterEvent(this.service.onOpenURL, () => this.isWindowFocused(arg)), URISerializer); } } @@ -49,6 +53,6 @@ export class URLChannelClient implements IURLService { constructor(private channel: IChannel, private windowID: number) { } - private _onOpenURL = eventFromCall(this.channel, 'event:onOpenURL', this.windowID); - get onOpenURL(): Event { return this._onOpenURL; } + private _onOpenURL = eventFromCall(this.channel, 'event:onOpenURL', this.windowID, URIDeserializer); + get onOpenURL(): Event { return this._onOpenURL; } } \ No newline at end of file diff --git a/src/vs/platform/url/electron-main/urlService.ts b/src/vs/platform/url/electron-main/urlService.ts index 710c7bc4e1d..d896dc2d511 100644 --- a/src/vs/platform/url/electron-main/urlService.ts +++ b/src/vs/platform/url/electron-main/urlService.ts @@ -5,26 +5,34 @@ 'use strict'; -import Event, {mapEvent} from 'vs/base/common/event'; +import Event, {mapEvent,filterEvent} from 'vs/base/common/event'; import {fromEventEmitter} from 'vs/base/node/event'; import {IURLService} from 'vs/platform/url/common/url'; import product from 'vs/platform/product'; import {app} from 'electron'; +import URI from 'vs/base/common/uri'; export class URLService implements IURLService { _serviceBrand: any; - onOpenURL: Event; + onOpenURL: Event; constructor() { const rawOnOpenUrl = fromEventEmitter(app, 'open-url', (event: Electron.Event, url: string) => ({ event, url })); - this.onOpenURL = mapEvent(rawOnOpenUrl, ({ event, url }) => { + const uriEvent = mapEvent(rawOnOpenUrl, ({ event, url }) => { event.preventDefault(); - return url; + + try { + return URI.parse(url); + } catch(e) { + return null; + } }); + this.onOpenURL = filterEvent(uriEvent, uri => !!uri); + app.setAsDefaultProtocolClient(product.urlProtocol); } } \ No newline at end of file -- GitLab