@@ -0,0 +1,9 @@
|
||||
import {CONST_EXPR} from "angular2/src/facade/lang";
|
||||
import {OpaqueToken} from "angular2/di";
|
||||
import {RenderElementRef, RenderViewRef} from "angular2/src/render/api";
|
||||
|
||||
export const ON_WEB_WORKER = CONST_EXPR(new OpaqueToken('WebWorker.onWebWorker'));
|
||||
|
||||
export class WebWorkerElementRef implements RenderElementRef {
|
||||
constructor(public renderView: RenderViewRef, public renderBoundElementIndex: number) {}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
library angular2.src.web_workers.shared.isolate_message_bus;
|
||||
|
||||
import 'dart:isolate';
|
||||
import 'dart:async';
|
||||
import 'dart:core';
|
||||
import 'package:angular2/src/web_workers/shared/message_bus.dart'
|
||||
show MessageBus, MessageBusSink, MessageBusSource;
|
||||
import 'package:angular2/src/facade/async.dart';
|
||||
|
||||
class IsolateMessageBus implements MessageBus {
|
||||
final IsolateMessageBusSink sink;
|
||||
final IsolateMessageBusSource source;
|
||||
|
||||
IsolateMessageBus(IsolateMessageBusSink sink, IsolateMessageBusSource source)
|
||||
: sink = sink,
|
||||
source = source;
|
||||
|
||||
EventEmitter from(String channel) {
|
||||
return source.from(channel);
|
||||
}
|
||||
|
||||
EventEmitter to(String channel) {
|
||||
return sink.to(channel);
|
||||
}
|
||||
}
|
||||
|
||||
class IsolateMessageBusSink implements MessageBusSink {
|
||||
final SendPort _port;
|
||||
final Map<String, EventEmitter> _channels = new Map<String, EventEmitter>();
|
||||
|
||||
IsolateMessageBusSink(SendPort port) : _port = port;
|
||||
|
||||
EventEmitter to(String channel) {
|
||||
if (_channels.containsKey(channel)) {
|
||||
return _channels[channel];
|
||||
} else {
|
||||
var emitter = new EventEmitter();
|
||||
emitter.listen((message) {
|
||||
_port.send({'channel': channel, 'message': message});
|
||||
});
|
||||
_channels[channel] = emitter;
|
||||
return emitter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class IsolateMessageBusSource extends MessageBusSource {
|
||||
final Stream rawDataStream;
|
||||
final Map<String, EventEmitter> _channels = new Map<String, EventEmitter>();
|
||||
|
||||
IsolateMessageBusSource(ReceivePort port)
|
||||
: rawDataStream = port.asBroadcastStream() {
|
||||
rawDataStream.listen((message) {
|
||||
if (message is SendPort){
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.containsKey("channel")) {
|
||||
var channel = message['channel'];
|
||||
if (_channels.containsKey(channel)) {
|
||||
_channels[channel].add(message['message']);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
EventEmitter from(String channel) {
|
||||
if (_channels.containsKey(channel)) {
|
||||
return _channels[channel];
|
||||
} else {
|
||||
var emitter = new EventEmitter();
|
||||
_channels[channel] = emitter;
|
||||
return emitter;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import {EventEmitter} from 'angular2/src/facade/async';
|
||||
import {BaseException} from 'angular2/src/facade/lang';
|
||||
|
||||
function _abstract() {
|
||||
throw new BaseException("This method is abstract");
|
||||
}
|
||||
|
||||
/**
|
||||
* Message Bus is a low level API used to communicate between the UI and the background.
|
||||
* Communication is based on a channel abstraction. Messages published in a
|
||||
* given channel to one MessageBusSink are received on the same channel
|
||||
* by the corresponding MessageBusSource.
|
||||
*/
|
||||
export /* abstract (with TS 1.6) */ class MessageBus implements MessageBusSource, MessageBusSink {
|
||||
/**
|
||||
* Returns an {@link EventEmitter} that emits every time a messsage
|
||||
* is received on the given channel.
|
||||
*/
|
||||
from(channel: string): EventEmitter { throw _abstract(); }
|
||||
|
||||
|
||||
/**
|
||||
* Returns an {@link EventEmitter} for the given channel
|
||||
* To publish methods to that channel just call next (or add in dart) on the returned emitter
|
||||
*/
|
||||
to(channel: string): EventEmitter { throw _abstract(); }
|
||||
}
|
||||
|
||||
export interface MessageBusSource {
|
||||
/**
|
||||
* Returns an {@link EventEmitter} that emits every time a messsage
|
||||
* is received on the given channel.
|
||||
*/
|
||||
from(channel: string): EventEmitter;
|
||||
}
|
||||
|
||||
export interface MessageBusSink {
|
||||
/**
|
||||
* Returns an {@link EventEmitter} for the given channel
|
||||
* To publish methods to that channel just call next (or add in dart) on the returned emitter
|
||||
*/
|
||||
to(channel: string): EventEmitter;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* All channels used by angular's WebWorker components are listed here.
|
||||
* You should not use these channels in your application code.
|
||||
*/
|
||||
export const SETUP_CHANNEL = "ng-WebWorkerSetup";
|
||||
export const RENDER_COMPILER_CHANNEL = "ng-RenderCompiler";
|
||||
export const RENDERER_CHANNEL = "ng-Renderer";
|
||||
export const XHR_CHANNEL = "ng-XHR";
|
||||
export const EVENT_CHANNEL = "ng-events";
|
||||
@@ -0,0 +1,3 @@
|
||||
// PostMessageBus can't be implemented in dart since dart doesn't use postMessage
|
||||
// This file is only here to prevent ts2dart from trying to transpile the PostMessageBus
|
||||
library angular2.src.web_workers.shared.post_message_bus;
|
||||
@@ -0,0 +1,75 @@
|
||||
import {
|
||||
MessageBus,
|
||||
MessageBusSource,
|
||||
MessageBusSink
|
||||
} from "angular2/src/web_workers/shared/message_bus";
|
||||
import {EventEmitter} from 'angular2/src/facade/async';
|
||||
import {StringMap, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
import {Injectable} from "angular2/di";
|
||||
|
||||
/**
|
||||
* A TypeScript implementation of {@link MessageBus} for communicating via JavaScript's
|
||||
* postMessage API.
|
||||
*/
|
||||
@Injectable()
|
||||
export class PostMessageBus implements MessageBus {
|
||||
constructor(private _sink: PostMessageBusSink, private _source: PostMessageBusSource) {}
|
||||
|
||||
from(channel: string): EventEmitter { return this._source.from(channel); }
|
||||
|
||||
to(channel: string): EventEmitter { return this._sink.to(channel); }
|
||||
}
|
||||
|
||||
export class PostMessageBusSink implements MessageBusSink {
|
||||
private _channels: StringMap<string, EventEmitter> = StringMapWrapper.create();
|
||||
|
||||
constructor(private _postMessageTarget: PostMessageTarget) {}
|
||||
|
||||
public to(channel: string): EventEmitter {
|
||||
if (StringMapWrapper.contains(this._channels, channel)) {
|
||||
return this._channels[channel];
|
||||
} else {
|
||||
var emitter = new EventEmitter();
|
||||
emitter.observer({
|
||||
next: (message: Object) => {
|
||||
this._postMessageTarget.postMessage({channel: channel, message: message});
|
||||
}
|
||||
});
|
||||
return emitter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class PostMessageBusSource implements MessageBusSource {
|
||||
private _channels: StringMap<string, EventEmitter> = StringMapWrapper.create();
|
||||
|
||||
constructor(eventTarget?: EventTarget) {
|
||||
if (eventTarget) {
|
||||
eventTarget.addEventListener("message", (ev: MessageEvent) => this._handleMessage(ev));
|
||||
} else {
|
||||
// if no eventTarget is given we assume we're in a WebWorker and listen on the global scope
|
||||
addEventListener("message", (ev: MessageEvent) => this._handleMessage(ev));
|
||||
}
|
||||
}
|
||||
|
||||
private _handleMessage(ev: MessageEvent) {
|
||||
var data = ev.data;
|
||||
var channel = data.channel;
|
||||
if (StringMapWrapper.contains(this._channels, channel)) {
|
||||
this._channels[channel].next(data.message);
|
||||
}
|
||||
}
|
||||
|
||||
public from(channel: string): EventEmitter {
|
||||
if (StringMapWrapper.contains(this._channels, channel)) {
|
||||
return this._channels[channel];
|
||||
} else {
|
||||
var emitter = new EventEmitter();
|
||||
this._channels[channel] = emitter;
|
||||
return emitter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(jteplitz602) Replace this with the definition in lib.webworker.d.ts(#3492)
|
||||
export interface PostMessageTarget { postMessage: (message: any, transfer?:[ArrayBuffer]) => void; }
|
||||
@@ -0,0 +1,56 @@
|
||||
import {Injectable, Inject} from "angular2/di";
|
||||
import {RenderProtoViewRef} from "angular2/src/render/api";
|
||||
import {ON_WEB_WORKER} from "angular2/src/web_workers/shared/api";
|
||||
|
||||
@Injectable()
|
||||
export class RenderProtoViewRefStore {
|
||||
private _lookupByIndex: Map<number, RenderProtoViewRef> = new Map<number, RenderProtoViewRef>();
|
||||
private _lookupByProtoView: Map<RenderProtoViewRef, number> =
|
||||
new Map<RenderProtoViewRef, number>();
|
||||
private _nextIndex: number = 0;
|
||||
private _onWebworker: boolean;
|
||||
|
||||
constructor(@Inject(ON_WEB_WORKER) onWebworker) { this._onWebworker = onWebworker; }
|
||||
|
||||
storeRenderProtoViewRef(ref: RenderProtoViewRef): number {
|
||||
if (this._lookupByProtoView.has(ref)) {
|
||||
return this._lookupByProtoView.get(ref);
|
||||
} else {
|
||||
this._lookupByIndex.set(this._nextIndex, ref);
|
||||
this._lookupByProtoView.set(ref, this._nextIndex);
|
||||
return this._nextIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
retreiveRenderProtoViewRef(index: number): RenderProtoViewRef {
|
||||
return this._lookupByIndex.get(index);
|
||||
}
|
||||
|
||||
deserialize(index: number): RenderProtoViewRef {
|
||||
if (index == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this._onWebworker) {
|
||||
return new WebWorkerRenderProtoViewRef(index);
|
||||
} else {
|
||||
return this.retreiveRenderProtoViewRef(index);
|
||||
}
|
||||
}
|
||||
|
||||
serialize(ref: RenderProtoViewRef): number {
|
||||
if (ref == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this._onWebworker) {
|
||||
return (<WebWorkerRenderProtoViewRef>ref).refNumber;
|
||||
} else {
|
||||
return this.storeRenderProtoViewRef(ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class WebWorkerRenderProtoViewRef extends RenderProtoViewRef {
|
||||
constructor(public refNumber: number) { super(); }
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
import {Injectable, Inject} from "angular2/di";
|
||||
import {RenderViewRef, RenderFragmentRef, RenderViewWithFragments} from "angular2/src/render/api";
|
||||
import {ON_WEB_WORKER} from "angular2/src/web_workers/shared/api";
|
||||
import {List, ListWrapper} from "angular2/src/facade/collection";
|
||||
|
||||
@Injectable()
|
||||
export class RenderViewWithFragmentsStore {
|
||||
private _nextIndex: number = 0;
|
||||
private _onWebWorker: boolean;
|
||||
private _lookupByIndex: Map<number, RenderViewRef | RenderFragmentRef>;
|
||||
private _lookupByView: Map<RenderViewRef | RenderFragmentRef, number>;
|
||||
|
||||
constructor(@Inject(ON_WEB_WORKER) onWebWorker) {
|
||||
this._onWebWorker = onWebWorker;
|
||||
this._lookupByIndex = new Map<number, RenderViewRef | RenderFragmentRef>();
|
||||
this._lookupByView = new Map<RenderViewRef | RenderFragmentRef, number>();
|
||||
}
|
||||
|
||||
allocate(fragmentCount: number): RenderViewWithFragments {
|
||||
var initialIndex = this._nextIndex;
|
||||
|
||||
var viewRef = new WebWorkerRenderViewRef(this._nextIndex++);
|
||||
var fragmentRefs = ListWrapper.createGrowableSize(fragmentCount);
|
||||
|
||||
for (var i = 0; i < fragmentCount; i++) {
|
||||
fragmentRefs[i] = new WebWorkerRenderFragmentRef(this._nextIndex++);
|
||||
}
|
||||
var renderViewWithFragments = new RenderViewWithFragments(viewRef, fragmentRefs);
|
||||
this.store(renderViewWithFragments, initialIndex);
|
||||
return renderViewWithFragments;
|
||||
}
|
||||
|
||||
store(view: RenderViewWithFragments, startIndex: number) {
|
||||
this._lookupByIndex.set(startIndex, view.viewRef);
|
||||
this._lookupByView.set(view.viewRef, startIndex);
|
||||
startIndex++;
|
||||
|
||||
ListWrapper.forEach(view.fragmentRefs, (ref) => {
|
||||
this._lookupByIndex.set(startIndex, ref);
|
||||
this._lookupByView.set(ref, startIndex);
|
||||
startIndex++;
|
||||
});
|
||||
}
|
||||
|
||||
retreive(ref: number): RenderViewRef | RenderFragmentRef {
|
||||
if (ref == null) {
|
||||
return null;
|
||||
}
|
||||
return this._lookupByIndex.get(ref);
|
||||
}
|
||||
|
||||
serializeRenderViewRef(viewRef: RenderViewRef): number {
|
||||
return this._serializeRenderFragmentOrViewRef(viewRef);
|
||||
}
|
||||
|
||||
serializeRenderFragmentRef(fragmentRef: RenderFragmentRef): number {
|
||||
return this._serializeRenderFragmentOrViewRef(fragmentRef);
|
||||
}
|
||||
|
||||
deserializeRenderViewRef(ref: number): RenderViewRef {
|
||||
if (ref == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.retreive(ref);
|
||||
}
|
||||
|
||||
deserializeRenderFragmentRef(ref: number): RenderFragmentRef {
|
||||
if (ref == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.retreive(ref);
|
||||
}
|
||||
|
||||
private _serializeRenderFragmentOrViewRef(ref: RenderViewRef | RenderFragmentRef): number {
|
||||
if (ref == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this._onWebWorker) {
|
||||
return (<WebWorkerRenderFragmentRef | WebWorkerRenderViewRef>ref).serialize();
|
||||
} else {
|
||||
return this._lookupByView.get(ref);
|
||||
}
|
||||
}
|
||||
|
||||
serializeViewWithFragments(view: RenderViewWithFragments): StringMap<string, any> {
|
||||
if (view == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this._onWebWorker) {
|
||||
return {
|
||||
'viewRef': (<WebWorkerRenderViewRef>view.viewRef).serialize(),
|
||||
'fragmentRefs': ListWrapper.map(view.fragmentRefs, (val) => val.serialize())
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
'viewRef': this._lookupByView.get(view.viewRef),
|
||||
'fragmentRefs': ListWrapper.map(view.fragmentRefs, (val) => this._lookupByView.get(val))
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
deserializeViewWithFragments(obj: StringMap<string, any>): RenderViewWithFragments {
|
||||
if (obj == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var viewRef = this.deserializeRenderViewRef(obj['viewRef']);
|
||||
var fragments =
|
||||
ListWrapper.map(obj['fragmentRefs'], (val) => this.deserializeRenderFragmentRef(val));
|
||||
|
||||
return new RenderViewWithFragments(viewRef, fragments);
|
||||
}
|
||||
}
|
||||
|
||||
export class WebWorkerRenderViewRef extends RenderViewRef {
|
||||
constructor(public refNumber: number) { super(); }
|
||||
serialize(): number { return this.refNumber; }
|
||||
|
||||
static deserialize(ref: number): WebWorkerRenderViewRef {
|
||||
return new WebWorkerRenderViewRef(ref);
|
||||
}
|
||||
}
|
||||
|
||||
export class WebWorkerRenderFragmentRef extends RenderFragmentRef {
|
||||
constructor(public refNumber: number) { super(); }
|
||||
|
||||
serialize(): number { return this.refNumber; }
|
||||
|
||||
static deserialize(ref: number): WebWorkerRenderFragmentRef {
|
||||
return new WebWorkerRenderFragmentRef(ref);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,406 @@
|
||||
import {
|
||||
Type,
|
||||
isArray,
|
||||
isPresent,
|
||||
serializeEnum,
|
||||
deserializeEnum,
|
||||
BaseException
|
||||
} from "angular2/src/facade/lang";
|
||||
import {
|
||||
List,
|
||||
ListWrapper,
|
||||
Map,
|
||||
StringMap,
|
||||
StringMapWrapper,
|
||||
MapWrapper
|
||||
} from "angular2/src/facade/collection";
|
||||
import {
|
||||
ProtoViewDto,
|
||||
RenderDirectiveMetadata,
|
||||
RenderElementBinder,
|
||||
DirectiveBinder,
|
||||
ElementPropertyBinding,
|
||||
EventBinding,
|
||||
ViewDefinition,
|
||||
RenderProtoViewRef,
|
||||
RenderProtoViewMergeMapping,
|
||||
RenderViewRef,
|
||||
RenderFragmentRef,
|
||||
RenderElementRef,
|
||||
ViewType,
|
||||
ViewEncapsulation,
|
||||
PropertyBindingType
|
||||
} from "angular2/src/render/api";
|
||||
import {WebWorkerElementRef} from 'angular2/src/web_workers/shared/api';
|
||||
import {AST, ASTWithSource} from 'angular2/src/change_detection/change_detection';
|
||||
import {Parser} from "angular2/src/change_detection/parser/parser";
|
||||
import {Injectable} from "angular2/di";
|
||||
import {RenderProtoViewRefStore} from 'angular2/src/web_workers/shared/render_proto_view_ref_store';
|
||||
import {
|
||||
RenderViewWithFragmentsStore
|
||||
} from 'angular2/src/web_workers/shared/render_view_with_fragments_store';
|
||||
|
||||
@Injectable()
|
||||
export class Serializer {
|
||||
private _enumRegistry: Map<any, Map<number, any>>;
|
||||
constructor(private _parser: Parser, private _protoViewStore: RenderProtoViewRefStore,
|
||||
private _renderViewStore: RenderViewWithFragmentsStore) {
|
||||
this._enumRegistry = new Map<any, Map<number, any>>();
|
||||
|
||||
var viewTypeMap = new Map<number, any>();
|
||||
viewTypeMap[0] = ViewType.HOST;
|
||||
viewTypeMap[1] = ViewType.COMPONENT;
|
||||
viewTypeMap[2] = ViewType.EMBEDDED;
|
||||
this._enumRegistry.set(ViewType, viewTypeMap);
|
||||
|
||||
var viewEncapsulationMap = new Map<number, any>();
|
||||
viewEncapsulationMap[0] = ViewEncapsulation.EMULATED;
|
||||
viewEncapsulationMap[1] = ViewEncapsulation.NATIVE;
|
||||
viewEncapsulationMap[2] = ViewEncapsulation.NONE;
|
||||
this._enumRegistry.set(ViewEncapsulation, viewEncapsulationMap);
|
||||
|
||||
var propertyBindingTypeMap = new Map<number, any>();
|
||||
propertyBindingTypeMap[0] = PropertyBindingType.PROPERTY;
|
||||
propertyBindingTypeMap[1] = PropertyBindingType.ATTRIBUTE;
|
||||
propertyBindingTypeMap[2] = PropertyBindingType.CLASS;
|
||||
propertyBindingTypeMap[3] = PropertyBindingType.STYLE;
|
||||
this._enumRegistry.set(PropertyBindingType, propertyBindingTypeMap);
|
||||
}
|
||||
|
||||
serialize(obj: any, type: Type): Object {
|
||||
if (!isPresent(obj)) {
|
||||
return null;
|
||||
}
|
||||
if (isArray(obj)) {
|
||||
var serializedObj = [];
|
||||
ListWrapper.forEach(obj, (val) => { serializedObj.push(this.serialize(val, type)); });
|
||||
return serializedObj;
|
||||
}
|
||||
if (type == String) {
|
||||
return obj;
|
||||
}
|
||||
if (type == ViewDefinition) {
|
||||
return this._serializeViewDefinition(obj);
|
||||
} else if (type == DirectiveBinder) {
|
||||
return this._serializeDirectiveBinder(obj);
|
||||
} else if (type == ProtoViewDto) {
|
||||
return this._serializeProtoViewDto(obj);
|
||||
} else if (type == RenderElementBinder) {
|
||||
return this._serializeElementBinder(obj);
|
||||
} else if (type == RenderDirectiveMetadata) {
|
||||
return this._serializeDirectiveMetadata(obj);
|
||||
} else if (type == ASTWithSource) {
|
||||
return this._serializeASTWithSource(obj);
|
||||
} else if (type == RenderProtoViewRef) {
|
||||
return this._protoViewStore.serialize(obj);
|
||||
} else if (type == RenderProtoViewMergeMapping) {
|
||||
return this._serializeRenderProtoViewMergeMapping(obj);
|
||||
} else if (type == RenderViewRef) {
|
||||
return this._renderViewStore.serializeRenderViewRef(obj);
|
||||
} else if (type == RenderFragmentRef) {
|
||||
return this._renderViewStore.serializeRenderFragmentRef(obj);
|
||||
} else if (type == WebWorkerElementRef) {
|
||||
return this._serializeWorkerElementRef(obj);
|
||||
} else if (type == ElementPropertyBinding) {
|
||||
return this._serializeElementPropertyBinding(obj);
|
||||
} else if (type == EventBinding) {
|
||||
return this._serializeEventBinding(obj);
|
||||
} else {
|
||||
throw new BaseException("No serializer for " + type.toString());
|
||||
}
|
||||
}
|
||||
|
||||
deserialize(map: any, type: Type, data?: any): any {
|
||||
if (!isPresent(map)) {
|
||||
return null;
|
||||
}
|
||||
if (isArray(map)) {
|
||||
var obj: List<any> = new List<any>();
|
||||
ListWrapper.forEach(map, (val) => { obj.push(this.deserialize(val, type, data)); });
|
||||
return obj;
|
||||
}
|
||||
if (type == String) {
|
||||
return map;
|
||||
}
|
||||
|
||||
if (type == ViewDefinition) {
|
||||
return this._deserializeViewDefinition(map);
|
||||
} else if (type == DirectiveBinder) {
|
||||
return this._deserializeDirectiveBinder(map);
|
||||
} else if (type == ProtoViewDto) {
|
||||
return this._deserializeProtoViewDto(map);
|
||||
} else if (type == RenderDirectiveMetadata) {
|
||||
return this._deserializeDirectiveMetadata(map);
|
||||
} else if (type == RenderElementBinder) {
|
||||
return this._deserializeElementBinder(map);
|
||||
} else if (type == ASTWithSource) {
|
||||
return this._deserializeASTWithSource(map, data);
|
||||
} else if (type == RenderProtoViewRef) {
|
||||
return this._protoViewStore.deserialize(map);
|
||||
} else if (type == RenderProtoViewMergeMapping) {
|
||||
return this._deserializeRenderProtoViewMergeMapping(map);
|
||||
} else if (type == RenderViewRef) {
|
||||
return this._renderViewStore.deserializeRenderViewRef(map);
|
||||
} else if (type == RenderFragmentRef) {
|
||||
return this._renderViewStore.deserializeRenderFragmentRef(map);
|
||||
} else if (type == WebWorkerElementRef) {
|
||||
return this._deserializeWorkerElementRef(map);
|
||||
} else if (type == EventBinding) {
|
||||
return this._deserializeEventBinding(map);
|
||||
} else if (type == ElementPropertyBinding) {
|
||||
return this._deserializeElementPropertyBinding(map);
|
||||
} else {
|
||||
throw new BaseException("No deserializer for " + type.toString());
|
||||
}
|
||||
}
|
||||
|
||||
mapToObject(map: Map<string, any>, type?: Type): Object {
|
||||
var object = {};
|
||||
var serialize = isPresent(type);
|
||||
|
||||
MapWrapper.forEach(map, (value, key) => {
|
||||
if (serialize) {
|
||||
object[key] = this.serialize(value, type);
|
||||
} else {
|
||||
object[key] = value;
|
||||
}
|
||||
});
|
||||
return object;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transforms a Javascript object (StringMap) into a Map<string, V>
|
||||
* If the values need to be deserialized pass in their type
|
||||
* and they will be deserialized before being placed in the map
|
||||
*/
|
||||
objectToMap(obj: StringMap<string, any>, type?: Type, data?: any): Map<string, any> {
|
||||
if (isPresent(type)) {
|
||||
var map: Map<string, any> = new Map();
|
||||
StringMapWrapper.forEach(obj,
|
||||
(val, key) => { map.set(key, this.deserialize(val, type, data)); });
|
||||
return map;
|
||||
} else {
|
||||
return MapWrapper.createFromStringMap(obj);
|
||||
}
|
||||
}
|
||||
|
||||
allocateRenderViews(fragmentCount: number) { this._renderViewStore.allocate(fragmentCount); }
|
||||
|
||||
private _serializeElementPropertyBinding(binding:
|
||||
ElementPropertyBinding): StringMap<string, any> {
|
||||
return {
|
||||
'type': serializeEnum(binding.type),
|
||||
'astWithSource': this.serialize(binding.astWithSource, ASTWithSource),
|
||||
'property': binding.property,
|
||||
'unit': binding.unit
|
||||
};
|
||||
}
|
||||
|
||||
private _deserializeElementPropertyBinding(map: StringMap<string, any>): ElementPropertyBinding {
|
||||
var type = deserializeEnum(map['type'], this._enumRegistry.get(PropertyBindingType));
|
||||
var ast = this.deserialize(map['astWithSource'], ASTWithSource, "binding");
|
||||
return new ElementPropertyBinding(type, ast, map['property'], map['unit']);
|
||||
}
|
||||
|
||||
private _serializeEventBinding(binding: EventBinding): StringMap<string, any> {
|
||||
return {'fullName': binding.fullName, 'source': this.serialize(binding.source, ASTWithSource)};
|
||||
}
|
||||
|
||||
private _deserializeEventBinding(map: StringMap<string, any>): EventBinding {
|
||||
return new EventBinding(map['fullName'],
|
||||
this.deserialize(map['source'], ASTWithSource, "action"));
|
||||
}
|
||||
|
||||
private _serializeWorkerElementRef(elementRef: RenderElementRef): StringMap<string, any> {
|
||||
return {
|
||||
'renderView': this.serialize(elementRef.renderView, RenderViewRef),
|
||||
'renderBoundElementIndex': elementRef.renderBoundElementIndex
|
||||
};
|
||||
}
|
||||
|
||||
private _deserializeWorkerElementRef(map: StringMap<string, any>): RenderElementRef {
|
||||
return new WebWorkerElementRef(this.deserialize(map['renderView'], RenderViewRef),
|
||||
map['renderBoundElementIndex']);
|
||||
}
|
||||
|
||||
private _serializeRenderProtoViewMergeMapping(mapping: RenderProtoViewMergeMapping): Object {
|
||||
return {
|
||||
'mergedProtoViewRef': this._protoViewStore.serialize(mapping.mergedProtoViewRef),
|
||||
'fragmentCount': mapping.fragmentCount,
|
||||
'mappedElementIndices': mapping.mappedElementIndices,
|
||||
'mappedElementCount': mapping.mappedElementCount,
|
||||
'mappedTextIndices': mapping.mappedTextIndices,
|
||||
'hostElementIndicesByViewIndex': mapping.hostElementIndicesByViewIndex,
|
||||
'nestedViewCountByViewIndex': mapping.nestedViewCountByViewIndex
|
||||
};
|
||||
}
|
||||
|
||||
private _deserializeRenderProtoViewMergeMapping(obj: StringMap<string, any>):
|
||||
RenderProtoViewMergeMapping {
|
||||
return new RenderProtoViewMergeMapping(
|
||||
this._protoViewStore.deserialize(obj['mergedProtoViewRef']), obj['fragmentCount'],
|
||||
obj['mappedElementIndices'], obj['mappedElementCount'], obj['mappedTextIndices'],
|
||||
obj['hostElementIndicesByViewIndex'], obj['nestedViewCountByViewIndex']);
|
||||
}
|
||||
|
||||
private _serializeASTWithSource(tree: ASTWithSource): Object {
|
||||
return {'input': tree.source, 'location': tree.location};
|
||||
}
|
||||
|
||||
private _deserializeASTWithSource(obj: StringMap<string, any>, data: string): AST {
|
||||
// TODO: make ASTs serializable
|
||||
var ast: AST;
|
||||
switch (data) {
|
||||
case "action":
|
||||
ast = this._parser.parseAction(obj['input'], obj['location']);
|
||||
break;
|
||||
case "binding":
|
||||
ast = this._parser.parseBinding(obj['input'], obj['location']);
|
||||
break;
|
||||
case "interpolation":
|
||||
ast = this._parser.parseInterpolation(obj['input'], obj['location']);
|
||||
break;
|
||||
default:
|
||||
throw "No AST deserializer for " + data;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
private _serializeViewDefinition(view: ViewDefinition): Object {
|
||||
return {
|
||||
'componentId': view.componentId,
|
||||
'templateAbsUrl': view.templateAbsUrl,
|
||||
'template': view.template,
|
||||
'directives': this.serialize(view.directives, RenderDirectiveMetadata),
|
||||
'styleAbsUrls': view.styleAbsUrls,
|
||||
'styles': view.styles,
|
||||
'encapsulation': serializeEnum(view.encapsulation)
|
||||
};
|
||||
}
|
||||
|
||||
private _deserializeViewDefinition(obj: StringMap<string, any>): ViewDefinition {
|
||||
return new ViewDefinition({
|
||||
componentId: obj['componentId'],
|
||||
templateAbsUrl: obj['templateAbsUrl'], template: obj['template'],
|
||||
directives: this.deserialize(obj['directives'], RenderDirectiveMetadata),
|
||||
styleAbsUrls: obj['styleAbsUrls'],
|
||||
styles: obj['styles'],
|
||||
encapsulation:
|
||||
deserializeEnum(obj['encapsulation'], this._enumRegistry.get(ViewEncapsulation))
|
||||
});
|
||||
}
|
||||
|
||||
private _serializeDirectiveBinder(binder: DirectiveBinder): Object {
|
||||
return {
|
||||
'directiveIndex': binder.directiveIndex,
|
||||
'propertyBindings': this.mapToObject(binder.propertyBindings, ASTWithSource),
|
||||
'eventBindings': this.serialize(binder.eventBindings, EventBinding),
|
||||
'hostPropertyBindings': this.serialize(binder.hostPropertyBindings, ElementPropertyBinding)
|
||||
};
|
||||
}
|
||||
|
||||
private _deserializeDirectiveBinder(obj: StringMap<string, any>): DirectiveBinder {
|
||||
return new DirectiveBinder({
|
||||
directiveIndex: obj['directiveIndex'],
|
||||
propertyBindings: this.objectToMap(obj['propertyBindings'], ASTWithSource, "binding"),
|
||||
eventBindings: this.deserialize(obj['eventBindings'], EventBinding),
|
||||
hostPropertyBindings: this.deserialize(obj['hostPropertyBindings'], ElementPropertyBinding)
|
||||
});
|
||||
}
|
||||
|
||||
private _serializeElementBinder(binder: RenderElementBinder): Object {
|
||||
return {
|
||||
'index': binder.index,
|
||||
'parentIndex': binder.parentIndex,
|
||||
'distanceToParent': binder.distanceToParent,
|
||||
'directives': this.serialize(binder.directives, DirectiveBinder),
|
||||
'nestedProtoView': this.serialize(binder.nestedProtoView, ProtoViewDto),
|
||||
'propertyBindings': this.serialize(binder.propertyBindings, ElementPropertyBinding),
|
||||
'variableBindings': this.mapToObject(binder.variableBindings),
|
||||
'eventBindings': this.serialize(binder.eventBindings, EventBinding),
|
||||
'readAttributes': this.mapToObject(binder.readAttributes)
|
||||
};
|
||||
}
|
||||
|
||||
private _deserializeElementBinder(obj: StringMap<string, any>): RenderElementBinder {
|
||||
return new RenderElementBinder({
|
||||
index: obj['index'],
|
||||
parentIndex: obj['parentIndex'],
|
||||
distanceToParent: obj['distanceToParent'],
|
||||
directives: this.deserialize(obj['directives'], DirectiveBinder),
|
||||
nestedProtoView: this.deserialize(obj['nestedProtoView'], ProtoViewDto),
|
||||
propertyBindings: this.deserialize(obj['propertyBindings'], ElementPropertyBinding),
|
||||
variableBindings: this.objectToMap(obj['variableBindings']),
|
||||
eventBindings: this.deserialize(obj['eventBindings'], EventBinding),
|
||||
readAttributes: this.objectToMap(obj['readAttributes'])
|
||||
});
|
||||
}
|
||||
|
||||
private _serializeProtoViewDto(view: ProtoViewDto): Object {
|
||||
return {
|
||||
'render': this._protoViewStore.serialize(view.render),
|
||||
'elementBinders': this.serialize(view.elementBinders, RenderElementBinder),
|
||||
'variableBindings': this.mapToObject(view.variableBindings),
|
||||
'type': serializeEnum(view.type),
|
||||
'textBindings': this.serialize(view.textBindings, ASTWithSource),
|
||||
'transitiveNgContentCount': view.transitiveNgContentCount
|
||||
};
|
||||
}
|
||||
|
||||
private _deserializeProtoViewDto(obj: StringMap<string, any>): ProtoViewDto {
|
||||
return new ProtoViewDto({
|
||||
render: this._protoViewStore.deserialize(obj["render"]),
|
||||
elementBinders: this.deserialize(obj['elementBinders'], RenderElementBinder),
|
||||
variableBindings: this.objectToMap(obj['variableBindings']),
|
||||
textBindings: this.deserialize(obj['textBindings'], ASTWithSource, "interpolation"),
|
||||
type: deserializeEnum(obj['type'], this._enumRegistry.get(ViewType)),
|
||||
transitiveNgContentCount: obj['transitiveNgContentCount']
|
||||
});
|
||||
}
|
||||
|
||||
private _serializeDirectiveMetadata(meta: RenderDirectiveMetadata): Object {
|
||||
var obj = {
|
||||
'id': meta.id,
|
||||
'selector': meta.selector,
|
||||
'compileChildren': meta.compileChildren,
|
||||
'events': meta.events,
|
||||
'properties': meta.properties,
|
||||
'readAttributes': meta.readAttributes,
|
||||
'type': meta.type,
|
||||
'callOnDestroy': meta.callOnDestroy,
|
||||
'callOnChange': meta.callOnChange,
|
||||
'callOnCheck': meta.callOnCheck,
|
||||
'callOnInit': meta.callOnInit,
|
||||
'callOnAllChangesDone': meta.callOnAllChangesDone,
|
||||
'changeDetection': meta.changeDetection,
|
||||
'exportAs': meta.exportAs,
|
||||
'hostProperties': this.mapToObject(meta.hostProperties),
|
||||
'hostListeners': this.mapToObject(meta.hostListeners),
|
||||
'hostActions': this.mapToObject(meta.hostActions),
|
||||
'hostAttributes': this.mapToObject(meta.hostAttributes)
|
||||
};
|
||||
return obj;
|
||||
}
|
||||
private _deserializeDirectiveMetadata(obj: StringMap<string, any>): RenderDirectiveMetadata {
|
||||
return new RenderDirectiveMetadata({
|
||||
id: obj['id'],
|
||||
selector: obj['selector'],
|
||||
compileChildren: obj['compileChildren'],
|
||||
hostProperties: this.objectToMap(obj['hostProperties']),
|
||||
hostListeners: this.objectToMap(obj['hostListeners']),
|
||||
hostActions: this.objectToMap(obj['hostActions']),
|
||||
hostAttributes: this.objectToMap(obj['hostAttributes']),
|
||||
properties: obj['properties'],
|
||||
readAttributes: obj['readAttributes'],
|
||||
type: obj['type'],
|
||||
exportAs: obj['exportAs'],
|
||||
callOnDestroy: obj['callOnDestroy'],
|
||||
callOnChange: obj['callOnChange'],
|
||||
callOnCheck: obj['callOnCheck'],
|
||||
callOnInit: obj['callOnInit'],
|
||||
callOnAllChangesDone: obj['callOnAllChangesDone'],
|
||||
changeDetection: obj['changeDetection'],
|
||||
events: obj['events']
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user