diff --git a/modules/@angular/platform-webworker/src/platform-webworker.ts b/modules/@angular/platform-webworker/src/platform-webworker.ts index 14ce817e9d..fa193e8db7 100644 --- a/modules/@angular/platform-webworker/src/platform-webworker.ts +++ b/modules/@angular/platform-webworker/src/platform-webworker.ts @@ -13,16 +13,13 @@ import {WORKER_SCRIPT, platformWorkerUi} from './worker_render'; export {VERSION} from './version'; export {ClientMessageBroker, ClientMessageBrokerFactory, FnArg, UiArguments} from './web_workers/shared/client_message_broker'; export {MessageBus, MessageBusSink, MessageBusSource} from './web_workers/shared/message_bus'; -export {SerializerTypes} from './web_workers/shared/serialized_types'; -export {PRIMITIVE} from './web_workers/shared/serializer'; +export {PRIMITIVE, SerializerTypes} from './web_workers/shared/serializer'; export {ReceivedMessage, ServiceMessageBroker, ServiceMessageBrokerFactory} from './web_workers/shared/service_message_broker'; export {WORKER_UI_LOCATION_PROVIDERS} from './web_workers/ui/location_providers'; export {WORKER_APP_LOCATION_PROVIDERS} from './web_workers/worker/location_providers'; export {WorkerAppModule, platformWorkerApp} from './worker_app'; export {platformWorkerUi} from './worker_render'; - - /** * Bootstraps the worker ui. * diff --git a/modules/@angular/platform-webworker/src/web_workers/shared/client_message_broker.ts b/modules/@angular/platform-webworker/src/web_workers/shared/client_message_broker.ts index 57eeed0da3..197f5a02b7 100644 --- a/modules/@angular/platform-webworker/src/web_workers/shared/client_message_broker.ts +++ b/modules/@angular/platform-webworker/src/web_workers/shared/client_message_broker.ts @@ -12,8 +12,7 @@ import {EventEmitter} from '../../facade/async'; import {stringify} from '../../facade/lang'; import {MessageBus} from './message_bus'; -import {SerializerTypes} from './serialized_types'; -import {Serializer} from './serializer'; +import {Serializer, SerializerTypes} from './serializer'; /** @@ -48,7 +47,7 @@ export class ClientMessageBrokerFactory_ extends ClientMessageBrokerFactory { * @experimental WebWorker support in Angular is experimental. */ export abstract class ClientMessageBroker { - abstract runOnService(args: UiArguments, returnType: Type): Promise; + abstract runOnService(args: UiArguments, returnType: Type|SerializerTypes): Promise; } interface PromiseCompleter { @@ -68,7 +67,7 @@ export class ClientMessageBroker_ extends ClientMessageBroker { this._serializer = _serializer; const source = messageBus.from(channel); - source.subscribe({next: (message: {[key: string]: any}) => this._handleMessage(message)}); + source.subscribe({next: (message: MessageData) => this._handleMessage(message)}); } private _generateMessageId(name: string): string { @@ -82,7 +81,7 @@ export class ClientMessageBroker_ extends ClientMessageBroker { return id; } - runOnService(args: UiArguments, returnType: Type): Promise { + runOnService(args: UiArguments, returnType: Type|SerializerTypes): Promise { const fnArgs: any[] = []; if (args.args) { args.args.forEach(argument => { @@ -127,15 +126,14 @@ export class ClientMessageBroker_ extends ClientMessageBroker { return promise; } - private _handleMessage(message: {[key: string]: any}): void { - const data = new MessageData(message); - if (data.type === 'result' || data.type === 'error') { - const id = data.id; + private _handleMessage(message: MessageData): void { + if (message.type === 'result' || message.type === 'error') { + const id = message.id; if (this._pending.has(id)) { - if (data.type === 'result') { - this._pending.get(id).resolve(data.value); + if (message.type === 'result') { + this._pending.get(id).resolve(message.value); } else { - this._pending.get(id).reject(data.value); + this._pending.get(id).reject(message.value); } this._pending.delete(id); } @@ -143,31 +141,18 @@ export class ClientMessageBroker_ extends ClientMessageBroker { } } -class MessageData { - type: string; - value: any; - id: string; - - constructor(data: {[key: string]: any}) { - this.type = data['type']; - this.id = this._getValueIfPresent(data, 'id'); - this.value = this._getValueIfPresent(data, 'value'); - } - - /** - * Returns the value if present, otherwise returns null - * @internal - */ - _getValueIfPresent(data: {[key: string]: any}, key: string) { - return data.hasOwnProperty(key) ? data[key] : null; - } +interface MessageData { + type: 'result'|'error'; + value?: any; + id?: string; } /** * @experimental WebWorker support in Angular is experimental. */ export class FnArg { - constructor(public value: any, public type: Type|SerializerTypes = null) {} + constructor( + public value: any, public type: Type|SerializerTypes = SerializerTypes.PRIMITIVE) {} } /** diff --git a/modules/@angular/platform-webworker/src/web_workers/shared/serialized_types.ts b/modules/@angular/platform-webworker/src/web_workers/shared/serialized_types.ts deleted file mode 100644 index 21222e9267..0000000000 --- a/modules/@angular/platform-webworker/src/web_workers/shared/serialized_types.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @license - * Copyright Google Inc. All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - -// This file contains interface versions of browser types that can be serialized to Plain Old -// JavaScript Objects -export class LocationType { - constructor( - public href: string, public protocol: string, public host: string, public hostname: string, - public port: string, public pathname: string, public search: string, public hash: string, - public origin: string) {} -} - -/** - * @experimental WebWorker support in Angular is currently experimental. - */ -export const enum SerializerTypes { - // RendererTypeV2 - RENDERER_TYPE_V2, -} diff --git a/modules/@angular/platform-webworker/src/web_workers/shared/serializer.ts b/modules/@angular/platform-webworker/src/web_workers/shared/serializer.ts index b99af6c911..53297de382 100644 --- a/modules/@angular/platform-webworker/src/web_workers/shared/serializer.ts +++ b/modules/@angular/platform-webworker/src/web_workers/shared/serializer.ts @@ -6,36 +6,52 @@ * found in the LICENSE file at https://angular.io/license */ -import {Injectable, RenderComponentType, RendererTypeV2, Type, ViewEncapsulation} from '@angular/core'; +import {Injectable, RenderComponentType, RendererTypeV2, Type} from '@angular/core'; import {stringify} from '../../facade/lang'; import {RenderStore} from './render_store'; -import {LocationType, SerializerTypes} from './serialized_types'; -// PRIMITIVE is any type that does not need to be serialized (string, number, boolean) -// We set it to String so that it is considered a Type. +/** + * Any type that does not need to be serialized (string, number, boolean) + * + * @experimental WebWorker support in Angular is currently experimental. + * @deprecated in v4. Use SerializerTypes.PRIMITIVE instead + */ +export const PRIMITIVE: Type = String; + +export class LocationType { + constructor( + public href: string, public protocol: string, public host: string, public hostname: string, + public port: string, public pathname: string, public search: string, public hash: string, + public origin: string) {} +} + /** * @experimental WebWorker support in Angular is currently experimental. */ -export const PRIMITIVE: Type = String; +export const enum SerializerTypes { + // RendererTypeV2 + RENDERER_TYPE_V2, + // Primitive types + PRIMITIVE, + // An object stored in a RenderStore + RENDER_STORE_OBJECT, +} @Injectable() export class Serializer { constructor(private _renderStore: RenderStore) {} - serialize(obj: any, type: any): Object { - if (obj == null) { - return null; + serialize(obj: any, type: Type|SerializerTypes = SerializerTypes.PRIMITIVE): Object { + if (obj == null || type === PRIMITIVE || type === SerializerTypes.PRIMITIVE) { + return obj; } if (Array.isArray(obj)) { return obj.map(v => this.serialize(v, type)); } - if (type == PRIMITIVE) { - return obj; - } - if (type == RenderStoreObject) { + if (type === SerializerTypes.RENDER_STORE_OBJECT) { return this._renderStore.serialize(obj); } if (type === RenderComponentType) { @@ -44,26 +60,21 @@ export class Serializer { if (type === SerializerTypes.RENDERER_TYPE_V2) { return this._serializeRendererTypeV2(obj); } - if (type === ViewEncapsulation) { - return obj; - } if (type === LocationType) { return this._serializeLocation(obj); } throw new Error(`No serializer for type ${stringify(type)}`); } - deserialize(map: any, type: any, data?: any): any { - if (map == null) { - return null; + deserialize(map: any, type: Type|SerializerTypes = SerializerTypes.PRIMITIVE, data?: any): + any { + if (map == null || type === PRIMITIVE || type === SerializerTypes.PRIMITIVE) { + return map; } if (Array.isArray(map)) { return map.map(val => this.deserialize(val, type, data)); } - if (type === PRIMITIVE) { - return map; - } - if (type === RenderStoreObject) { + if (type === SerializerTypes.RENDER_STORE_OBJECT) { return this._renderStore.deserialize(map); } if (type === RenderComponentType) { @@ -72,9 +83,6 @@ export class Serializer { if (type === SerializerTypes.RENDERER_TYPE_V2) { return this._deserializeRendererTypeV2(map); } - if (type === ViewEncapsulation) { - return map as ViewEncapsulation; - } if (type === LocationType) { return this._deserializeLocation(map); } @@ -106,24 +114,23 @@ export class Serializer { 'id': type.id, 'templateUrl': type.templateUrl, 'slotCount': type.slotCount, - 'encapsulation': this.serialize(type.encapsulation, ViewEncapsulation), - 'styles': this.serialize(type.styles, PRIMITIVE), + 'encapsulation': this.serialize(type.encapsulation), + 'styles': this.serialize(type.styles), }; } private _deserializeRenderComponentType(props: {[key: string]: any}): RenderComponentType { return new RenderComponentType( props['id'], props['templateUrl'], props['slotCount'], - this.deserialize(props['encapsulation'], ViewEncapsulation), - this.deserialize(props['styles'], PRIMITIVE), {}); + this.deserialize(props['encapsulation']), this.deserialize(props['styles']), {}); } private _serializeRendererTypeV2(type: RendererTypeV2): {[key: string]: any} { return { 'id': type.id, - 'encapsulation': this.serialize(type.encapsulation, ViewEncapsulation), - 'styles': this.serialize(type.styles, PRIMITIVE), - 'data': this.serialize(type.data, PRIMITIVE), + 'encapsulation': this.serialize(type.encapsulation), + 'styles': this.serialize(type.styles), + 'data': this.serialize(type.data), }; } @@ -131,12 +138,10 @@ export class Serializer { return { id: props['id'], encapsulation: props['encapsulation'], - styles: this.deserialize(props['styles'], PRIMITIVE), - data: this.deserialize(props['data'], PRIMITIVE) + styles: this.deserialize(props['styles']), + data: this.deserialize(props['data']) }; } } export const ANIMATION_WORKER_PLAYER_PREFIX = 'AnimationPlayer.'; - -export class RenderStoreObject {} diff --git a/modules/@angular/platform-webworker/src/web_workers/shared/service_message_broker.ts b/modules/@angular/platform-webworker/src/web_workers/shared/service_message_broker.ts index 4cbd6cadb9..936f6a0413 100644 --- a/modules/@angular/platform-webworker/src/web_workers/shared/service_message_broker.ts +++ b/modules/@angular/platform-webworker/src/web_workers/shared/service_message_broker.ts @@ -9,9 +9,8 @@ import {Injectable, Type} from '@angular/core'; import {EventEmitter} from '../../facade/async'; -import {isPresent} from '../../facade/lang'; import {MessageBus} from '../shared/message_bus'; -import {Serializer} from '../shared/serializer'; +import {Serializer, SerializerTypes} from '../shared/serializer'; /** * @experimental WebWorker support in Angular is currently experimental. @@ -49,12 +48,13 @@ export class ServiceMessageBrokerFactory_ extends ServiceMessageBrokerFactory { */ export abstract class ServiceMessageBroker { abstract registerMethod( - methodName: string, signature: Type[], method: Function, returnType?: Type): void; + methodName: string, signature: Array|SerializerTypes>, method: Function, + returnType?: Type|SerializerTypes): void; } export class ServiceMessageBroker_ extends ServiceMessageBroker { private _sink: EventEmitter; - private _methods: Map = new Map(); + private _methods = new Map(); constructor(messageBus: MessageBus, private _serializer: Serializer, public channel: string) { super(); @@ -64,11 +64,11 @@ export class ServiceMessageBroker_ extends ServiceMessageBroker { } registerMethod( - methodName: string, signature: Type[], method: (..._: any[]) => Promise| void, - returnType?: Type): void { + methodName: string, signature: Array|SerializerTypes>, + method: (..._: any[]) => Promise| void, returnType?: Type|SerializerTypes): void { this._methods.set(methodName, (message: ReceivedMessage) => { const serializedArgs = message.args; - const numArgs = signature === null ? 0 : signature.length; + const numArgs = signature ? signature.length : 0; const deserializedArgs = new Array(numArgs); for (let i = 0; i < numArgs; i++) { const serializedArg = serializedArgs[i]; @@ -82,14 +82,14 @@ export class ServiceMessageBroker_ extends ServiceMessageBroker { }); } - private _handleMessage(map: {[key: string]: any}): void { - const message = new ReceivedMessage(map); + private _handleMessage(message: ReceivedMessage): void { if (this._methods.has(message.method)) { this._methods.get(message.method)(message); } } - private _wrapWebWorkerPromise(id: string, promise: Promise, type: Type): void { + private _wrapWebWorkerPromise(id: string, promise: Promise, type: Type|SerializerTypes): + void { promise.then((result: any) => { this._sink.emit({ 'type': 'result', @@ -103,16 +103,9 @@ export class ServiceMessageBroker_ extends ServiceMessageBroker { /** * @experimental WebWorker support in Angular is currently experimental. */ -export class ReceivedMessage { +export interface ReceivedMessage { method: string; args: any[]; id: string; type: string; - - constructor(data: {[key: string]: any}) { - this.method = data['method']; - this.args = data['args']; - this.id = data['id']; - this.type = data['type']; - } } diff --git a/modules/@angular/platform-webworker/src/web_workers/ui/event_dispatcher.ts b/modules/@angular/platform-webworker/src/web_workers/ui/event_dispatcher.ts index f1fdbe7781..af79b98f99 100644 --- a/modules/@angular/platform-webworker/src/web_workers/ui/event_dispatcher.ts +++ b/modules/@angular/platform-webworker/src/web_workers/ui/event_dispatcher.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ import {EventEmitter} from '../../facade/async'; -import {RenderStoreObject, Serializer} from '../shared/serializer'; +import {Serializer, SerializerTypes} from '../shared/serializer'; import {serializeEventWithTarget, serializeGenericEvent, serializeKeyboardEvent, serializeMouseEvent, serializeTransitionEvent} from './event_serializer'; @@ -15,8 +15,8 @@ export class EventDispatcher { dispatchAnimationEvent(player: any, phaseName: string, element: any): boolean { this._sink.emit({ - 'element': this._serializer.serialize(element, RenderStoreObject), - 'animationPlayer': this._serializer.serialize(player, RenderStoreObject), + 'element': this._serializer.serialize(element, SerializerTypes.RENDER_STORE_OBJECT), + 'animationPlayer': this._serializer.serialize(player, SerializerTypes.RENDER_STORE_OBJECT), 'phaseName': phaseName, }); return true; @@ -107,7 +107,7 @@ export class EventDispatcher { } this._sink.emit({ - 'element': this._serializer.serialize(element, RenderStoreObject), + 'element': this._serializer.serialize(element, SerializerTypes.RENDER_STORE_OBJECT), 'eventName': eventName, 'eventTarget': eventTarget, 'event': serializedEvent, diff --git a/modules/@angular/platform-webworker/src/web_workers/ui/platform_location.ts b/modules/@angular/platform-webworker/src/web_workers/ui/platform_location.ts index 0fc96a3a8b..eeedbc03f8 100644 --- a/modules/@angular/platform-webworker/src/web_workers/ui/platform_location.ts +++ b/modules/@angular/platform-webworker/src/web_workers/ui/platform_location.ts @@ -13,8 +13,7 @@ import {EventEmitter} from '../../facade/async'; import {BrowserPlatformLocation} from '../../private_import_platform-browser'; import {MessageBus} from '../shared/message_bus'; import {ROUTER_CHANNEL} from '../shared/messaging_api'; -import {LocationType} from '../shared/serialized_types'; -import {PRIMITIVE, Serializer} from '../shared/serializer'; +import {LocationType, Serializer, SerializerTypes} from '../shared/serializer'; import {ServiceMessageBroker, ServiceMessageBrokerFactory} from '../shared/service_message_broker'; @Injectable() @@ -34,13 +33,14 @@ export class MessageBasedPlatformLocation { } start(): void { + const P = SerializerTypes.PRIMITIVE; + this._broker.registerMethod('getLocation', null, this._getLocation.bind(this), LocationType); - this._broker.registerMethod('setPathname', [PRIMITIVE], this._setPathname.bind(this)); + this._broker.registerMethod('setPathname', [P], this._setPathname.bind(this)); this._broker.registerMethod( - 'pushState', [PRIMITIVE, PRIMITIVE, PRIMITIVE], - this._platformLocation.pushState.bind(this._platformLocation)); + 'pushState', [P, P, P], this._platformLocation.pushState.bind(this._platformLocation)); this._broker.registerMethod( - 'replaceState', [PRIMITIVE, PRIMITIVE, PRIMITIVE], + 'replaceState', [P, P, P], this._platformLocation.replaceState.bind(this._platformLocation)); this._broker.registerMethod( 'forward', null, this._platformLocation.forward.bind(this._platformLocation)); @@ -52,11 +52,11 @@ export class MessageBasedPlatformLocation { return Promise.resolve(this._platformLocation.location); } - private _sendUrlChangeEvent(e: Event): void { - const loc = this._serializer.serialize(this._platformLocation.location, LocationType); - const serializedEvent = {'type': e.type}; - this._channelSink.emit({'event': serializedEvent, 'location': loc}); + this._channelSink.emit({ + 'event': {'type': e.type}, + 'location': this._serializer.serialize(this._platformLocation.location, LocationType), + }); } private _setPathname(pathname: string): void { this._platformLocation.pathname = pathname; } diff --git a/modules/@angular/platform-webworker/src/web_workers/ui/renderer.ts b/modules/@angular/platform-webworker/src/web_workers/ui/renderer.ts index a203c067b9..2e52ea3aba 100644 --- a/modules/@angular/platform-webworker/src/web_workers/ui/renderer.ts +++ b/modules/@angular/platform-webworker/src/web_workers/ui/renderer.ts @@ -11,8 +11,7 @@ import {AnimationPlayer, Injectable, RenderComponentType, Renderer, RendererFact import {MessageBus} from '../shared/message_bus'; import {EVENT_CHANNEL, EVENT_V2_CHANNEL, RENDERER_CHANNEL, RENDERER_V2_CHANNEL} from '../shared/messaging_api'; import {RenderStore} from '../shared/render_store'; -import {SerializerTypes} from '../shared/serialized_types'; -import {ANIMATION_WORKER_PLAYER_PREFIX, PRIMITIVE, RenderStoreObject, Serializer} from '../shared/serializer'; +import {ANIMATION_WORKER_PLAYER_PREFIX, Serializer, SerializerTypes} from '../shared/serializer'; import {ServiceMessageBroker, ServiceMessageBrokerFactory} from '../shared/service_message_broker'; import {EventDispatcher} from '../ui/event_dispatcher'; @@ -31,7 +30,11 @@ export class MessageBasedRenderer { this._bus.initChannel(EVENT_CHANNEL); this._eventDispatcher = new EventDispatcher(this._bus.to(EVENT_CHANNEL), this._serializer); - const [RCT, RSO, P] = [RenderComponentType, RenderStoreObject, PRIMITIVE]; + const [RCT, RSO, P] = [ + RenderComponentType, + SerializerTypes.RENDER_STORE_OBJECT, + SerializerTypes.PRIMITIVE, + ]; const methods: any[][] = [ ['renderComponent', this._renderComponent, RCT, P], @@ -65,52 +68,51 @@ export class MessageBasedRenderer { } private _bindAnimationPlayerMethods(broker: ServiceMessageBroker) { + const [P, RSO] = [SerializerTypes.PRIMITIVE, SerializerTypes.RENDER_STORE_OBJECT]; + broker.registerMethod( - ANIMATION_WORKER_PLAYER_PREFIX + 'play', [RenderStoreObject, RenderStoreObject], + ANIMATION_WORKER_PLAYER_PREFIX + 'play', [RSO, RSO], (player: AnimationPlayer, element: any) => player.play()); broker.registerMethod( - ANIMATION_WORKER_PLAYER_PREFIX + 'pause', [RenderStoreObject, RenderStoreObject], + ANIMATION_WORKER_PLAYER_PREFIX + 'pause', [RSO, RSO], (player: AnimationPlayer, element: any) => player.pause()); broker.registerMethod( - ANIMATION_WORKER_PLAYER_PREFIX + 'init', [RenderStoreObject, RenderStoreObject], + ANIMATION_WORKER_PLAYER_PREFIX + 'init', [RSO, RSO], (player: AnimationPlayer, element: any) => player.init()); broker.registerMethod( - ANIMATION_WORKER_PLAYER_PREFIX + 'restart', [RenderStoreObject, RenderStoreObject], + ANIMATION_WORKER_PLAYER_PREFIX + 'restart', [RSO, RSO], (player: AnimationPlayer, element: any) => player.restart()); broker.registerMethod( - ANIMATION_WORKER_PLAYER_PREFIX + 'destroy', [RenderStoreObject, RenderStoreObject], + ANIMATION_WORKER_PLAYER_PREFIX + 'destroy', [RSO, RSO], (player: AnimationPlayer, element: any) => { player.destroy(); this._renderStore.remove(player); }); broker.registerMethod( - ANIMATION_WORKER_PLAYER_PREFIX + 'finish', [RenderStoreObject, RenderStoreObject], + ANIMATION_WORKER_PLAYER_PREFIX + 'finish', [RSO, RSO], (player: AnimationPlayer, element: any) => player.finish()); broker.registerMethod( - ANIMATION_WORKER_PLAYER_PREFIX + 'getPosition', [RenderStoreObject, RenderStoreObject], + ANIMATION_WORKER_PLAYER_PREFIX + 'getPosition', [RSO, RSO], (player: AnimationPlayer, element: any) => player.getPosition()); broker.registerMethod( - ANIMATION_WORKER_PLAYER_PREFIX + 'onStart', - [RenderStoreObject, RenderStoreObject, PRIMITIVE], + ANIMATION_WORKER_PLAYER_PREFIX + 'onStart', [RSO, RSO, P], (player: AnimationPlayer, element: any) => this._listenOnAnimationPlayer(player, element, 'onStart')); broker.registerMethod( - ANIMATION_WORKER_PLAYER_PREFIX + 'onDone', - [RenderStoreObject, RenderStoreObject, PRIMITIVE], + ANIMATION_WORKER_PLAYER_PREFIX + 'onDone', [RSO, RSO, P], (player: AnimationPlayer, element: any) => this._listenOnAnimationPlayer(player, element, 'onDone')); broker.registerMethod( - ANIMATION_WORKER_PLAYER_PREFIX + 'setPosition', - [RenderStoreObject, RenderStoreObject, PRIMITIVE], + ANIMATION_WORKER_PLAYER_PREFIX + 'setPosition', [RSO, RSO, P], (player: AnimationPlayer, element: any, position: number) => player.setPosition(position)); } @@ -254,7 +256,11 @@ export class MessageBasedRendererV2 { this._bus.initChannel(EVENT_V2_CHANNEL); this._eventDispatcher = new EventDispatcher(this._bus.to(EVENT_V2_CHANNEL), this._serializer); - const [RSO, P, CRT] = [RenderStoreObject, PRIMITIVE, SerializerTypes.RENDERER_TYPE_V2]; + const [RSO, P, CRT] = [ + SerializerTypes.RENDER_STORE_OBJECT, + SerializerTypes.PRIMITIVE, + SerializerTypes.RENDERER_TYPE_V2, + ]; const methods: any[][] = [ ['createRenderer', this.createRenderer, RSO, CRT, P], diff --git a/modules/@angular/platform-webworker/src/web_workers/worker/platform_location.ts b/modules/@angular/platform-webworker/src/web_workers/worker/platform_location.ts index 98607d122f..8af4804277 100644 --- a/modules/@angular/platform-webworker/src/web_workers/worker/platform_location.ts +++ b/modules/@angular/platform-webworker/src/web_workers/worker/platform_location.ts @@ -13,8 +13,7 @@ import {EventEmitter} from '../../facade/async'; import {ClientMessageBroker, ClientMessageBrokerFactory, FnArg, UiArguments} from '../shared/client_message_broker'; import {MessageBus} from '../shared/message_bus'; import {ROUTER_CHANNEL} from '../shared/messaging_api'; -import {LocationType} from '../shared/serialized_types'; -import {PRIMITIVE, Serializer} from '../shared/serializer'; +import {LocationType, Serializer, SerializerTypes} from '../shared/serializer'; @Injectable() export class WebWorkerPlatformLocation extends PlatformLocation { @@ -28,8 +27,8 @@ export class WebWorkerPlatformLocation extends PlatformLocation { brokerFactory: ClientMessageBrokerFactory, bus: MessageBus, private _serializer: Serializer) { super(); this._broker = brokerFactory.createMessageBroker(ROUTER_CHANNEL); - this._channelSource = bus.from(ROUTER_CHANNEL); + this._channelSource.subscribe({ next: (msg: {[key: string]: any}) => { let listeners: Array = null; @@ -86,21 +85,27 @@ export class WebWorkerPlatformLocation extends PlatformLocation { this._location.pathname = newPath; - const fnArgs = [new FnArg(newPath, PRIMITIVE)]; + const fnArgs = [new FnArg(newPath, SerializerTypes.PRIMITIVE)]; const args = new UiArguments('setPathname', fnArgs); this._broker.runOnService(args, null); } pushState(state: any, title: string, url: string): void { - const fnArgs = - [new FnArg(state, PRIMITIVE), new FnArg(title, PRIMITIVE), new FnArg(url, PRIMITIVE)]; + const fnArgs = [ + new FnArg(state, SerializerTypes.PRIMITIVE), + new FnArg(title, SerializerTypes.PRIMITIVE), + new FnArg(url, SerializerTypes.PRIMITIVE), + ]; const args = new UiArguments('pushState', fnArgs); this._broker.runOnService(args, null); } replaceState(state: any, title: string, url: string): void { - const fnArgs = - [new FnArg(state, PRIMITIVE), new FnArg(title, PRIMITIVE), new FnArg(url, PRIMITIVE)]; + const fnArgs = [ + new FnArg(state, SerializerTypes.PRIMITIVE), + new FnArg(title, SerializerTypes.PRIMITIVE), + new FnArg(url, SerializerTypes.PRIMITIVE), + ]; const args = new UiArguments('replaceState', fnArgs); this._broker.runOnService(args, null); } diff --git a/modules/@angular/platform-webworker/src/web_workers/worker/renderer.ts b/modules/@angular/platform-webworker/src/web_workers/worker/renderer.ts index 3d6f826e19..98c709def8 100644 --- a/modules/@angular/platform-webworker/src/web_workers/worker/renderer.ts +++ b/modules/@angular/platform-webworker/src/web_workers/worker/renderer.ts @@ -8,19 +8,50 @@ import {Injectable, RenderComponentType, Renderer, RendererFactoryV2, RendererTypeV2, RendererV2, RootRenderer, ViewEncapsulation} from '@angular/core'; -import {ListWrapper} from '../../facade/collection'; import {AnimationKeyframe, AnimationPlayer, AnimationStyles, RenderDebugInfo} from '../../private_import_core'; import {ClientMessageBroker, ClientMessageBrokerFactory, FnArg, UiArguments} from '../shared/client_message_broker'; import {MessageBus} from '../shared/message_bus'; import {EVENT_CHANNEL, EVENT_V2_CHANNEL, RENDERER_CHANNEL, RENDERER_V2_CHANNEL} from '../shared/messaging_api'; import {RenderStore} from '../shared/render_store'; -import {SerializerTypes} from '../shared/serialized_types'; -import {ANIMATION_WORKER_PLAYER_PREFIX, RenderStoreObject, Serializer} from '../shared/serializer'; +import {ANIMATION_WORKER_PLAYER_PREFIX, Serializer, SerializerTypes} from '../shared/serializer'; + +export class NamedEventEmitter { + private _listeners: Map; + + listen(eventName: string, callback: Function) { this._getListeners(eventName).push(callback); } + + unlisten(eventName: string, listener: Function) { + const listeners = this._getListeners(eventName); + const index = listeners.indexOf(listener); + if (index > -1) { + listeners.splice(index, 1); + } + } + + dispatchEvent(eventName: string, event: any) { + const listeners = this._getListeners(eventName); + for (let i = 0; i < listeners.length; i++) { + listeners[i](event); + } + } + + private _getListeners(eventName: string): Function[] { + if (!this._listeners) { + this._listeners = new Map(); + } + let listeners = this._listeners.get(eventName); + if (!listeners) { + listeners = []; + this._listeners.set(eventName, listeners); + } + return listeners; + } +} + +const globalEvents = new NamedEventEmitter(); @Injectable() export class WebWorkerRootRenderer implements RootRenderer { - globalEvents = new NamedEventEmitter(); - private _messageBroker: ClientMessageBroker; private _componentRenderers = new Map(); @@ -34,20 +65,21 @@ export class WebWorkerRootRenderer implements RootRenderer { } private _dispatchEvent(message: {[key: string]: any}): void { - const element = - this._serializer.deserialize(message['element'], RenderStoreObject); + const element: WebWorkerRenderNode = + this._serializer.deserialize(message['element'], SerializerTypes.RENDER_STORE_OBJECT); const playerData = message['animationPlayer']; if (playerData) { const phaseName = message['phaseName']; - const player = this._serializer.deserialize(playerData, RenderStoreObject); + const player: AnimationPlayer = + this._serializer.deserialize(playerData, SerializerTypes.RENDER_STORE_OBJECT); element.animationPlayerEvents.dispatchEvent(player, phaseName); } else { const eventName = message['eventName']; const target = message['eventTarget']; const event = message['event']; if (target) { - this.globalEvents.dispatchEvent(eventNameWithTarget(target, eventName), event); + globalEvents.dispatchEvent(eventNameWithTarget(target, eventName), event); } else { element.events.dispatchEvent(eventName, event); } @@ -63,7 +95,7 @@ export class WebWorkerRootRenderer implements RootRenderer { this.renderStore.store(result, id); this.runOnService('renderComponent', [ new FnArg(componentType, RenderComponentType), - new FnArg(result, RenderStoreObject), + new FnArg(result, SerializerTypes.RENDER_STORE_OBJECT), ]); } return result; @@ -90,27 +122,30 @@ export class WebWorkerRootRenderer implements RootRenderer { } } -export class WebWorkerRenderer implements Renderer, RenderStoreObject { +export class WebWorkerRenderer implements Renderer { constructor( private _rootRenderer: WebWorkerRootRenderer, private _componentType: RenderComponentType) {} private _runOnService(fnName: string, fnArgs: FnArg[]) { - const fnArgsWithRenderer = [new FnArg(this, RenderStoreObject)].concat(fnArgs); + const fnArgsWithRenderer = [new FnArg(this, SerializerTypes.RENDER_STORE_OBJECT), ...fnArgs]; this._rootRenderer.runOnService(fnName, fnArgsWithRenderer); } selectRootElement(selectorOrNode: string, debugInfo?: RenderDebugInfo): any { const node = this._rootRenderer.allocateNode(); - this._runOnService( - 'selectRootElement', [new FnArg(selectorOrNode, null), new FnArg(node, RenderStoreObject)]); + this._runOnService('selectRootElement', [ + new FnArg(selectorOrNode), + new FnArg(node, SerializerTypes.RENDER_STORE_OBJECT), + ]); return node; } createElement(parentElement: any, name: string, debugInfo?: RenderDebugInfo): any { const node = this._rootRenderer.allocateNode(); this._runOnService('createElement', [ - new FnArg(parentElement, RenderStoreObject), new FnArg(name, null), - new FnArg(node, RenderStoreObject) + new FnArg(parentElement, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(name), + new FnArg(node, SerializerTypes.RENDER_STORE_OBJECT), ]); return node; } @@ -119,121 +154,139 @@ export class WebWorkerRenderer implements Renderer, RenderStoreObject { const viewRoot = this._componentType.encapsulation === ViewEncapsulation.Native ? this._rootRenderer.allocateNode() : hostElement; - this._runOnService( - 'createViewRoot', - [new FnArg(hostElement, RenderStoreObject), new FnArg(viewRoot, RenderStoreObject)]); + this._runOnService('createViewRoot', [ + new FnArg(hostElement, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(viewRoot, SerializerTypes.RENDER_STORE_OBJECT), + ]); return viewRoot; } createTemplateAnchor(parentElement: any, debugInfo?: RenderDebugInfo): any { const node = this._rootRenderer.allocateNode(); - this._runOnService( - 'createTemplateAnchor', - [new FnArg(parentElement, RenderStoreObject), new FnArg(node, RenderStoreObject)]); + this._runOnService('createTemplateAnchor', [ + new FnArg(parentElement, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(node, SerializerTypes.RENDER_STORE_OBJECT), + ]); return node; } createText(parentElement: any, value: string, debugInfo?: RenderDebugInfo): any { const node = this._rootRenderer.allocateNode(); this._runOnService('createText', [ - new FnArg(parentElement, RenderStoreObject), new FnArg(value, null), - new FnArg(node, RenderStoreObject) + new FnArg(parentElement, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(value), + new FnArg(node, SerializerTypes.RENDER_STORE_OBJECT), ]); return node; } projectNodes(parentElement: any, nodes: any[]) { - this._runOnService( - 'projectNodes', - [new FnArg(parentElement, RenderStoreObject), new FnArg(nodes, RenderStoreObject)]); + this._runOnService('projectNodes', [ + new FnArg(parentElement, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(nodes, SerializerTypes.RENDER_STORE_OBJECT), + ]); } attachViewAfter(node: any, viewRootNodes: any[]) { - this._runOnService( - 'attachViewAfter', - [new FnArg(node, RenderStoreObject), new FnArg(viewRootNodes, RenderStoreObject)]); + this._runOnService('attachViewAfter', [ + new FnArg(node, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(viewRootNodes, SerializerTypes.RENDER_STORE_OBJECT), + ]); } detachView(viewRootNodes: any[]) { - this._runOnService('detachView', [new FnArg(viewRootNodes, RenderStoreObject)]); + this._runOnService( + 'detachView', [new FnArg(viewRootNodes, SerializerTypes.RENDER_STORE_OBJECT)]); } destroyView(hostElement: any, viewAllNodes: any[]) { - this._runOnService( - 'destroyView', - [new FnArg(hostElement, RenderStoreObject), new FnArg(viewAllNodes, RenderStoreObject)]); + this._runOnService('destroyView', [ + new FnArg(hostElement, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(viewAllNodes, SerializerTypes.RENDER_STORE_OBJECT), + ]); this._rootRenderer.destroyNodes(viewAllNodes); } setElementProperty(renderElement: any, propertyName: string, propertyValue: any) { this._runOnService('setElementProperty', [ - new FnArg(renderElement, RenderStoreObject), new FnArg(propertyName, null), - new FnArg(propertyValue, null) + new FnArg(renderElement, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(propertyName), + new FnArg(propertyValue), ]); } setElementAttribute(renderElement: any, attributeName: string, attributeValue: string) { this._runOnService('setElementAttribute', [ - new FnArg(renderElement, RenderStoreObject), new FnArg(attributeName, null), - new FnArg(attributeValue, null) + new FnArg(renderElement, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(attributeName), + new FnArg(attributeValue), ]); } setBindingDebugInfo(renderElement: any, propertyName: string, propertyValue: string) { this._runOnService('setBindingDebugInfo', [ - new FnArg(renderElement, RenderStoreObject), new FnArg(propertyName, null), - new FnArg(propertyValue, null) + new FnArg(renderElement, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(propertyName), + new FnArg(propertyValue), ]); } setElementClass(renderElement: any, className: string, isAdd: boolean) { this._runOnService('setElementClass', [ - new FnArg(renderElement, RenderStoreObject), new FnArg(className, null), - new FnArg(isAdd, null) + new FnArg(renderElement, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(className), + new FnArg(isAdd), ]); } setElementStyle(renderElement: any, styleName: string, styleValue: string) { this._runOnService('setElementStyle', [ - new FnArg(renderElement, RenderStoreObject), new FnArg(styleName, null), - new FnArg(styleValue, null) + new FnArg(renderElement, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(styleName), + new FnArg(styleValue), ]); } invokeElementMethod(renderElement: any, methodName: string, args?: any[]) { this._runOnService('invokeElementMethod', [ - new FnArg(renderElement, RenderStoreObject), new FnArg(methodName, null), - new FnArg(args, null) + new FnArg(renderElement, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(methodName), + new FnArg(args), ]); } setText(renderNode: any, text: string) { - this._runOnService( - 'setText', [new FnArg(renderNode, RenderStoreObject), new FnArg(text, null)]); + this._runOnService('setText', [ + new FnArg(renderNode, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(text), + ]); } listen(renderElement: WebWorkerRenderNode, name: string, callback: Function): Function { renderElement.events.listen(name, callback); const unlistenCallbackId = this._rootRenderer.allocateId(); this._runOnService('listen', [ - new FnArg(renderElement, RenderStoreObject), new FnArg(name, null), - new FnArg(unlistenCallbackId, null) + new FnArg(renderElement, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(name), + new FnArg(unlistenCallbackId), ]); return () => { renderElement.events.unlisten(name, callback); - this._runOnService('listenDone', [new FnArg(unlistenCallbackId, null)]); + this._runOnService('listenDone', [new FnArg(unlistenCallbackId)]); }; } listenGlobal(target: string, name: string, callback: Function): Function { - this._rootRenderer.globalEvents.listen(eventNameWithTarget(target, name), callback); + globalEvents.listen(eventNameWithTarget(target, name), callback); const unlistenCallbackId = this._rootRenderer.allocateId(); - this._runOnService( - 'listenGlobal', - [new FnArg(target, null), new FnArg(name, null), new FnArg(unlistenCallbackId, null)]); + this._runOnService('listenGlobal', [ + new FnArg(target), + new FnArg(name, null), + new FnArg(unlistenCallbackId), + ]); return () => { - this._rootRenderer.globalEvents.unlisten(eventNameWithTarget(target, name), callback); - this._runOnService('listenDone', [new FnArg(unlistenCallbackId, null)]); + globalEvents.unlisten(eventNameWithTarget(target, name), callback); + this._runOnService('listenDone', [new FnArg(unlistenCallbackId)]); }; } @@ -246,9 +299,14 @@ export class WebWorkerRenderer implements Renderer, RenderStoreObject { previousPlayers.map(player => this._rootRenderer.renderStore.serialize(player)); this._runOnService('animate', [ - new FnArg(renderElement, RenderStoreObject), new FnArg(startingStyles, null), - new FnArg(keyframes, null), new FnArg(duration, null), new FnArg(delay, null), - new FnArg(easing, null), new FnArg(previousPlayerIds, null), new FnArg(playerId, null) + new FnArg(renderElement, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(startingStyles), + new FnArg(keyframes), + new FnArg(duration), + new FnArg(delay), + new FnArg(easing), + new FnArg(previousPlayerIds), + new FnArg(playerId), ]); const player = new _AnimationWorkerRendererPlayer(this._rootRenderer, renderElement); @@ -262,37 +320,6 @@ function eventNameWithTarget(target: string, eventName: string): string { return `${target}:${eventName}`; } -export class NamedEventEmitter { - private _listeners: Map; - - listen(eventName: string, callback: Function) { this._getListeners(eventName).push(callback); } - - unlisten(eventName: string, callback: Function) { - ListWrapper.remove(this._getListeners(eventName), callback); - } - - dispatchEvent(eventName: string, event: any) { - const listeners = this._getListeners(eventName); - for (let i = 0; i < listeners.length; i++) { - listeners[i](event); - } - } - - private _getListeners(eventName: string): Function[] { - if (!this._listeners) { - this._listeners = new Map(); - } - let listeners = this._listeners.get(eventName); - if (!listeners) { - listeners = []; - this._listeners.set(eventName, listeners); - } - return listeners; - } -} - -const globalEvents = new NamedEventEmitter(); - @Injectable() export class WebWorkerRendererFactoryV2 implements RendererFactoryV2 { private _messageBroker: ClientMessageBroker; @@ -312,9 +339,9 @@ export class WebWorkerRendererFactoryV2 implements RendererFactoryV2 { const id = this.renderStore.allocateId(); this.renderStore.store(renderer, id); this.callUI('createRenderer', [ - new FnArg(element, RenderStoreObject), + new FnArg(element, SerializerTypes.RENDER_STORE_OBJECT), new FnArg(type, SerializerTypes.RENDERER_TYPE_V2), - new FnArg(renderer, RenderStoreObject), + new FnArg(renderer, SerializerTypes.RENDER_STORE_OBJECT), ]); return renderer; @@ -336,7 +363,7 @@ export class WebWorkerRendererFactoryV2 implements RendererFactoryV2 { private _dispatchEvent(message: {[key: string]: any}): void { const element: WebWorkerRenderNode = - this._serializer.deserialize(message['element'], RenderStoreObject); + this._serializer.deserialize(message['element'], SerializerTypes.RENDER_STORE_OBJECT); const eventName = message['eventName']; const target = message['eventTarget']; @@ -355,7 +382,7 @@ export class WebWorkerRendererV2 implements RendererV2 { constructor(private _rendererFactory: WebWorkerRendererFactoryV2) {} destroyNode: (node: any) => void | null = null; - private asFnArg = new FnArg(this, RenderStoreObject); + private asFnArg = new FnArg(this, SerializerTypes.RENDER_STORE_OBJECT); // TODO(vicb): destroy the allocated nodes destroy(): void { this.callUIWithRenderer('destroy'); } @@ -365,7 +392,7 @@ export class WebWorkerRendererV2 implements RendererV2 { this.callUIWithRenderer('createElement', [ new FnArg(name), new FnArg(namespace), - new FnArg(node, RenderStoreObject), + new FnArg(node, SerializerTypes.RENDER_STORE_OBJECT), ]); return node; } @@ -374,7 +401,7 @@ export class WebWorkerRendererV2 implements RendererV2 { const node = this._rendererFactory.allocateNode(); this.callUIWithRenderer('createComment', [ new FnArg(value), - new FnArg(node, RenderStoreObject), + new FnArg(node, SerializerTypes.RENDER_STORE_OBJECT), ]); return node; } @@ -383,15 +410,15 @@ export class WebWorkerRendererV2 implements RendererV2 { const node = this._rendererFactory.allocateNode(); this.callUIWithRenderer('createText', [ new FnArg(value), - new FnArg(node, RenderStoreObject), + new FnArg(node, SerializerTypes.RENDER_STORE_OBJECT), ]); return node; } appendChild(parent: any, newChild: any): void { this.callUIWithRenderer('appendChild', [ - new FnArg(parent, RenderStoreObject), - new FnArg(newChild, RenderStoreObject), + new FnArg(parent, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(newChild, SerializerTypes.RENDER_STORE_OBJECT), ]); } @@ -401,16 +428,16 @@ export class WebWorkerRendererV2 implements RendererV2 { } this.callUIWithRenderer('insertBefore', [ - new FnArg(parent, RenderStoreObject), - new FnArg(newChild, RenderStoreObject), - new FnArg(refChild, RenderStoreObject), + new FnArg(parent, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(newChild, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(refChild, SerializerTypes.RENDER_STORE_OBJECT), ]); } removeChild(parent: any, oldChild: any): void { this.callUIWithRenderer('removeChild', [ - new FnArg(parent, RenderStoreObject), - new FnArg(oldChild, RenderStoreObject), + new FnArg(parent, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(oldChild, SerializerTypes.RENDER_STORE_OBJECT), ]); } @@ -418,7 +445,7 @@ export class WebWorkerRendererV2 implements RendererV2 { const node = this._rendererFactory.allocateNode(); this.callUIWithRenderer('selectRootElement', [ new FnArg(selectorOrNode), - new FnArg(node, RenderStoreObject), + new FnArg(node, SerializerTypes.RENDER_STORE_OBJECT), ]); return node; } @@ -426,8 +453,8 @@ export class WebWorkerRendererV2 implements RendererV2 { parentNode(node: any): any { const res = this._rendererFactory.allocateNode(); this.callUIWithRenderer('parentNode', [ - new FnArg(node, RenderStoreObject), - new FnArg(res, RenderStoreObject), + new FnArg(node, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(res, SerializerTypes.RENDER_STORE_OBJECT), ]); return res; } @@ -435,15 +462,15 @@ export class WebWorkerRendererV2 implements RendererV2 { nextSibling(node: any): any { const res = this._rendererFactory.allocateNode(); this.callUIWithRenderer('nextSibling', [ - new FnArg(node, RenderStoreObject), - new FnArg(res, RenderStoreObject), + new FnArg(node, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(res, SerializerTypes.RENDER_STORE_OBJECT), ]); return res; } setAttribute(el: any, name: string, value: string, namespace?: string): void { this.callUIWithRenderer('setAttribute', [ - new FnArg(el, RenderStoreObject), + new FnArg(el, SerializerTypes.RENDER_STORE_OBJECT), new FnArg(name), new FnArg(value), new FnArg(namespace), @@ -452,7 +479,7 @@ export class WebWorkerRendererV2 implements RendererV2 { removeAttribute(el: any, name: string, namespace?: string): void { this.callUIWithRenderer('removeAttribute', [ - new FnArg(el, RenderStoreObject), + new FnArg(el, SerializerTypes.RENDER_STORE_OBJECT), new FnArg(name), new FnArg(namespace), ]); @@ -460,14 +487,14 @@ export class WebWorkerRendererV2 implements RendererV2 { addClass(el: any, name: string): void { this.callUIWithRenderer('addClass', [ - new FnArg(el, RenderStoreObject), + new FnArg(el, SerializerTypes.RENDER_STORE_OBJECT), new FnArg(name), ]); } removeClass(el: any, name: string): void { this.callUIWithRenderer('removeClass', [ - new FnArg(el, RenderStoreObject), + new FnArg(el, SerializerTypes.RENDER_STORE_OBJECT), new FnArg(name), ]); } @@ -475,7 +502,7 @@ export class WebWorkerRendererV2 implements RendererV2 { setStyle(el: any, style: string, value: any, hasVendorPrefix: boolean, hasImportant: boolean): void { this.callUIWithRenderer('setStyle', [ - new FnArg(el, RenderStoreObject), + new FnArg(el, SerializerTypes.RENDER_STORE_OBJECT), new FnArg(style), new FnArg(value), new FnArg(hasVendorPrefix), @@ -485,7 +512,7 @@ export class WebWorkerRendererV2 implements RendererV2 { removeStyle(el: any, style: string, hasVendorPrefix: boolean): void { this.callUIWithRenderer('removeStyle', [ - new FnArg(el, RenderStoreObject), + new FnArg(el, SerializerTypes.RENDER_STORE_OBJECT), new FnArg(style), new FnArg(hasVendorPrefix), ]); @@ -493,7 +520,7 @@ export class WebWorkerRendererV2 implements RendererV2 { setProperty(el: any, name: string, value: any): void { this.callUIWithRenderer('setProperty', [ - new FnArg(el, RenderStoreObject), + new FnArg(el, SerializerTypes.RENDER_STORE_OBJECT), new FnArg(name), new FnArg(value), ]); @@ -501,7 +528,7 @@ export class WebWorkerRendererV2 implements RendererV2 { setValue(node: any, value: string): void { this.callUIWithRenderer('setValue', [ - new FnArg(node, RenderStoreObject), + new FnArg(node, SerializerTypes.RENDER_STORE_OBJECT), new FnArg(value), ]); } @@ -522,7 +549,7 @@ export class WebWorkerRendererV2 implements RendererV2 { } this.callUIWithRenderer('listen', [ - new FnArg(targetEl, RenderStoreObject), + new FnArg(targetEl, SerializerTypes.RENDER_STORE_OBJECT), new FnArg(targetName), new FnArg(eventName), new FnArg(unlistenId), @@ -581,7 +608,7 @@ export class WebWorkerRenderNode { animationPlayerEvents = new AnimationPlayerEmitter(); } -class _AnimationWorkerRendererPlayer implements RenderStoreObject { +class _AnimationWorkerRendererPlayer { public parentPlayer: AnimationPlayer = null; private _destroyed: boolean = false; @@ -592,8 +619,9 @@ class _AnimationWorkerRendererPlayer implements RenderStoreObject { private _runOnService(fnName: string, fnArgs: FnArg[]) { if (!this._destroyed) { const fnArgsWithRenderer = [ - new FnArg(this, RenderStoreObject), new FnArg(this._renderElement, RenderStoreObject) - ].concat(fnArgs); + new FnArg(this, SerializerTypes.RENDER_STORE_OBJECT), + new FnArg(this._renderElement, SerializerTypes.RENDER_STORE_OBJECT), ...fnArgs + ]; this._rootRenderer.runOnService(ANIMATION_WORKER_PLAYER_PREFIX + fnName, fnArgsWithRenderer); } } @@ -639,7 +667,7 @@ class _AnimationWorkerRendererPlayer implements RenderStoreObject { reset(): void { this._runOnService('reset', []); } - setPosition(p: number): void { this._runOnService('setPosition', [new FnArg(p, null)]); } + setPosition(p: number): void { this._runOnService('setPosition', [new FnArg(p)]); } getPosition(): number { return 0; } } diff --git a/modules/@angular/platform-webworker/test/web_workers/shared/service_message_broker_spec.ts b/modules/@angular/platform-webworker/test/web_workers/shared/service_message_broker_spec.ts index 560157279b..9dc32cdab9 100644 --- a/modules/@angular/platform-webworker/test/web_workers/shared/service_message_broker_spec.ts +++ b/modules/@angular/platform-webworker/test/web_workers/shared/service_message_broker_spec.ts @@ -9,10 +9,9 @@ import {beforeEach, beforeEachProviders, describe, expect, inject, it} from '@angular/core/testing/testing_internal'; import {ON_WEB_WORKER} from '@angular/platform-webworker/src/web_workers/shared/api'; import {RenderStore} from '@angular/platform-webworker/src/web_workers/shared/render_store'; -import {PRIMITIVE, Serializer} from '@angular/platform-webworker/src/web_workers/shared/serializer'; +import {Serializer, SerializerTypes} from '@angular/platform-webworker/src/web_workers/shared/serializer'; import {ServiceMessageBroker_} from '@angular/platform-webworker/src/web_workers/shared/service_message_broker'; - import {createPairedMessageBuses} from './web_worker_test_util'; export function main() { @@ -36,17 +35,20 @@ export function main() { it('should call registered method with correct arguments', inject([Serializer], (serializer: Serializer) => { const broker = new ServiceMessageBroker_(messageBuses.ui, serializer, CHANNEL); - broker.registerMethod(TEST_METHOD, [PRIMITIVE, PRIMITIVE], (arg1, arg2) => { - expect(arg1).toEqual(PASSED_ARG_1); - expect(arg2).toEqual(PASSED_ARG_2); + broker.registerMethod( + TEST_METHOD, [SerializerTypes.PRIMITIVE, SerializerTypes.PRIMITIVE], (arg1, arg2) => { + expect(arg1).toEqual(PASSED_ARG_1); + expect(arg2).toEqual(PASSED_ARG_2); + }); + messageBuses.worker.to(CHANNEL).emit({ + 'method': TEST_METHOD, + 'args': [PASSED_ARG_1, PASSED_ARG_2], }); - messageBuses.worker.to(CHANNEL).emit( - {'method': TEST_METHOD, 'args': [PASSED_ARG_1, PASSED_ARG_2]}); })); it('should return promises to the worker', inject([Serializer], (serializer: Serializer) => { const broker = new ServiceMessageBroker_(messageBuses.ui, serializer, CHANNEL); - broker.registerMethod(TEST_METHOD, [PRIMITIVE], (arg1) => { + broker.registerMethod(TEST_METHOD, [SerializerTypes.PRIMITIVE], (arg1) => { expect(arg1).toEqual(PASSED_ARG_1); return new Promise((res, rej) => { try { diff --git a/modules/@angular/platform-webworker/test/web_workers/worker/platform_location_spec.ts b/modules/@angular/platform-webworker/test/web_workers/worker/platform_location_spec.ts index 5d9a30a419..e5db04f43d 100644 --- a/modules/@angular/platform-webworker/test/web_workers/worker/platform_location_spec.ts +++ b/modules/@angular/platform-webworker/test/web_workers/worker/platform_location_spec.ts @@ -9,7 +9,7 @@ import {Type} from '@angular/core'; import {UiArguments} from '@angular/platform-webworker/src/web_workers/shared/client_message_broker'; import {MessageBus} from '@angular/platform-webworker/src/web_workers/shared/message_bus'; -import {LocationType} from '@angular/platform-webworker/src/web_workers/shared/serialized_types'; +import {LocationType, SerializerTypes} from '@angular/platform-webworker/src/web_workers/shared/serializer'; import {WebWorkerPlatformLocation} from '@angular/platform-webworker/src/web_workers/worker/platform_location'; import {MockMessageBrokerFactory, createPairedMessageBuses, expectBrokerCall} from '../shared/web_worker_test_util'; @@ -21,17 +21,19 @@ export function main() { let uiBus: MessageBus = null; let workerBus: MessageBus = null; let broker: any = null; + const TEST_LOCATION = new LocationType( 'http://www.example.com', 'http', 'example.com', 'example.com', '80', '/', '', '', 'http://www.example.com'); function createWebWorkerPlatformLocation(loc: LocationType): WebWorkerPlatformLocation { - broker.spy('runOnService').and.callFake((args: UiArguments, returnType: Type) => { - if (args.method === 'getLocation') { - return Promise.resolve(loc); - } - }); + broker.spy('runOnService') + .and.callFake((args: UiArguments, returnType: Type| SerializerTypes) => { + if (args.method === 'getLocation') { + return Promise.resolve(loc); + } + }); const factory = new MockMessageBrokerFactory(broker); return new WebWorkerPlatformLocation(factory, workerBus, null); } diff --git a/modules/playground/src/web_workers/message_broker/index.ts b/modules/playground/src/web_workers/message_broker/index.ts index 84520ade96..4d14bd5d62 100644 --- a/modules/playground/src/web_workers/message_broker/index.ts +++ b/modules/playground/src/web_workers/message_broker/index.ts @@ -7,7 +7,7 @@ */ import {PlatformRef} from '@angular/core'; -import {ClientMessageBrokerFactory, FnArg, PRIMITIVE, UiArguments, bootstrapWorkerUi} from '@angular/platform-webworker'; +import {ClientMessageBrokerFactory, FnArg, SerializerTypes, UiArguments, bootstrapWorkerUi} from '@angular/platform-webworker'; const ECHO_CHANNEL = 'ECHO'; @@ -23,14 +23,10 @@ function afterBootstrap(ref: PlatformRef) { const val = (document.getElementById('echo_input')).value; // TODO(jteplitz602): Replace default constructors with real constructors // once they're in the .d.ts file (#3926) - const args = new UiArguments('echo'); - args.method = 'echo'; - const fnArg = new FnArg(val, PRIMITIVE); - fnArg.value = val; - fnArg.type = PRIMITIVE; - args.args = [fnArg]; + const fnArg = new FnArg(val); + const args = new UiArguments('echo', [fnArg]); - broker.runOnService(args, PRIMITIVE).then((echo_result: string) => { + broker.runOnService(args, SerializerTypes.PRIMITIVE).then((echo_result: string) => { document.getElementById('echo_result').innerHTML = `${echo_result}`; }); diff --git a/modules/playground/src/web_workers/message_broker/index_common.ts b/modules/playground/src/web_workers/message_broker/index_common.ts index c52a03265e..181b581166 100644 --- a/modules/playground/src/web_workers/message_broker/index_common.ts +++ b/modules/playground/src/web_workers/message_broker/index_common.ts @@ -7,7 +7,7 @@ */ import {Component} from '@angular/core'; -import {PRIMITIVE, ServiceMessageBrokerFactory} from '@angular/platform-webworker'; +import {SerializerTypes, ServiceMessageBrokerFactory} from '@angular/platform-webworker'; const ECHO_CHANNEL = 'ECHO'; @@ -15,16 +15,9 @@ const ECHO_CHANNEL = 'ECHO'; export class App { constructor(private _serviceBrokerFactory: ServiceMessageBrokerFactory) { const broker = _serviceBrokerFactory.createMessageBroker(ECHO_CHANNEL, false); - broker.registerMethod('echo', [PRIMITIVE], this._echo, PRIMITIVE); + broker.registerMethod( + 'echo', [SerializerTypes.PRIMITIVE], this._echo, SerializerTypes.PRIMITIVE); } - private _echo(val: string) { - return new Promise((res, rej) => { - try { - res(val); - } catch (e) { - rej(e); - } - }); - } + private _echo(val: string) { return new Promise((res) => res(val)); } } diff --git a/tools/public_api_guard/platform-webworker/index.d.ts b/tools/public_api_guard/platform-webworker/index.d.ts index e07a48c843..226bd40472 100644 --- a/tools/public_api_guard/platform-webworker/index.d.ts +++ b/tools/public_api_guard/platform-webworker/index.d.ts @@ -3,7 +3,7 @@ export declare function bootstrapWorkerUi(workerScriptUri: string, customProvide /** @experimental */ export declare abstract class ClientMessageBroker { - abstract runOnService(args: UiArguments, returnType: Type): Promise; + abstract runOnService(args: UiArguments, returnType: Type | SerializerTypes): Promise; } /** @experimental */ @@ -50,24 +50,23 @@ export declare const platformWorkerUi: (extraProviders?: Provider[]) => Platform export declare const PRIMITIVE: Type; /** @experimental */ -export declare class ReceivedMessage { +export interface ReceivedMessage { args: any[]; id: string; method: string; type: string; - constructor(data: { - [key: string]: any; - }); } /** @experimental */ export declare const enum SerializerTypes { RENDERER_TYPE_V2 = 0, + PRIMITIVE = 1, + RENDER_STORE_OBJECT = 2, } /** @experimental */ export declare abstract class ServiceMessageBroker { - abstract registerMethod(methodName: string, signature: Type[], method: Function, returnType?: Type): void; + abstract registerMethod(methodName: string, signature: Array | SerializerTypes>, method: Function, returnType?: Type | SerializerTypes): void; } /** @experimental */