2015-07-10 16:09:18 -07:00
|
|
|
import {
|
|
|
|
|
Type,
|
|
|
|
|
isArray,
|
|
|
|
|
isPresent,
|
|
|
|
|
serializeEnum,
|
2015-09-10 15:25:36 -07:00
|
|
|
deserializeEnum
|
2015-08-20 14:28:25 -07:00
|
|
|
} from "angular2/src/core/facade/lang";
|
2015-09-10 15:25:36 -07:00
|
|
|
import {BaseException, WrappedException} from 'angular2/src/core/facade/exceptions';
|
|
|
|
|
|
2015-10-02 16:47:54 -07:00
|
|
|
import {ListWrapper, Map, StringMapWrapper, MapWrapper} from "angular2/src/core/facade/collection";
|
2015-07-10 16:09:18 -07:00
|
|
|
import {
|
2015-07-10 16:09:18 -07:00
|
|
|
RenderProtoViewRef,
|
|
|
|
|
RenderViewRef,
|
|
|
|
|
RenderFragmentRef,
|
|
|
|
|
RenderElementRef,
|
2015-07-10 16:09:18 -07:00
|
|
|
ViewType,
|
2015-07-28 16:38:55 -07:00
|
|
|
ViewEncapsulation,
|
2015-10-01 10:07:49 -07:00
|
|
|
RenderTemplateCmd,
|
|
|
|
|
RenderCommandVisitor,
|
|
|
|
|
RenderTextCmd,
|
|
|
|
|
RenderNgContentCmd,
|
|
|
|
|
RenderBeginElementCmd,
|
|
|
|
|
RenderBeginComponentCmd,
|
|
|
|
|
RenderEmbeddedTemplateCmd
|
2015-08-20 14:28:25 -07:00
|
|
|
} from "angular2/src/core/render/api";
|
2015-10-01 10:07:49 -07:00
|
|
|
import {
|
|
|
|
|
WebWorkerElementRef,
|
|
|
|
|
WebWorkerTemplateCmd,
|
|
|
|
|
WebWorkerTextCmd,
|
|
|
|
|
WebWorkerNgContentCmd,
|
|
|
|
|
WebWorkerBeginElementCmd,
|
|
|
|
|
WebWorkerEndElementCmd,
|
|
|
|
|
WebWorkerBeginComponentCmd,
|
|
|
|
|
WebWorkerEndComponentCmd,
|
|
|
|
|
WebWorkerEmbeddedTemplateCmd
|
|
|
|
|
} from 'angular2/src/web_workers/shared/api';
|
2015-09-03 22:01:36 -07:00
|
|
|
import {Injectable} from "angular2/src/core/di";
|
2015-08-21 12:21:29 -07:00
|
|
|
import {RenderProtoViewRefStore} from 'angular2/src/web_workers/shared/render_proto_view_ref_store';
|
2015-07-10 16:09:18 -07:00
|
|
|
import {
|
|
|
|
|
RenderViewWithFragmentsStore
|
2015-08-21 12:21:29 -07:00
|
|
|
} from 'angular2/src/web_workers/shared/render_view_with_fragments_store';
|
2015-07-10 16:09:18 -07:00
|
|
|
|
2015-08-21 16:55:50 -07:00
|
|
|
// 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.
|
|
|
|
|
export const PRIMITIVE: Type = String;
|
|
|
|
|
|
2015-07-10 16:09:18 -07:00
|
|
|
@Injectable()
|
2015-07-10 16:09:18 -07:00
|
|
|
export class Serializer {
|
2015-08-20 16:25:34 -07:00
|
|
|
private _enumRegistry: Map<any, Map<number, any>>;
|
2015-10-01 20:47:49 -07:00
|
|
|
constructor(private _protoViewStore: RenderProtoViewRefStore,
|
2015-07-10 16:09:18 -07:00
|
|
|
private _renderViewStore: RenderViewWithFragmentsStore) {
|
2015-08-20 16:25:34 -07:00
|
|
|
this._enumRegistry = new Map<any, Map<number, any>>();
|
2015-07-10 16:09:18 -07:00
|
|
|
|
2015-08-20 16:25:34 -07:00
|
|
|
var viewTypeMap = new Map<number, any>();
|
2015-07-10 16:09:18 -07:00
|
|
|
viewTypeMap[0] = ViewType.HOST;
|
|
|
|
|
viewTypeMap[1] = ViewType.COMPONENT;
|
|
|
|
|
viewTypeMap[2] = ViewType.EMBEDDED;
|
|
|
|
|
this._enumRegistry.set(ViewType, viewTypeMap);
|
2015-07-10 16:09:18 -07:00
|
|
|
|
2015-08-20 16:25:34 -07:00
|
|
|
var viewEncapsulationMap = new Map<number, any>();
|
2015-08-28 21:03:19 -07:00
|
|
|
viewEncapsulationMap[0] = ViewEncapsulation.Emulated;
|
|
|
|
|
viewEncapsulationMap[1] = ViewEncapsulation.Native;
|
|
|
|
|
viewEncapsulationMap[2] = ViewEncapsulation.None;
|
2015-07-10 16:09:18 -07:00
|
|
|
this._enumRegistry.set(ViewEncapsulation, viewEncapsulationMap);
|
2015-07-10 16:09:18 -07:00
|
|
|
}
|
2015-07-10 16:09:18 -07:00
|
|
|
|
2015-07-10 16:09:18 -07:00
|
|
|
serialize(obj: any, type: Type): Object {
|
2015-07-10 16:09:18 -07:00
|
|
|
if (!isPresent(obj)) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
if (isArray(obj)) {
|
|
|
|
|
var serializedObj = [];
|
2015-07-10 16:09:18 -07:00
|
|
|
ListWrapper.forEach(obj, (val) => { serializedObj.push(this.serialize(val, type)); });
|
2015-07-10 16:09:18 -07:00
|
|
|
return serializedObj;
|
|
|
|
|
}
|
2015-08-21 16:55:50 -07:00
|
|
|
if (type == PRIMITIVE) {
|
2015-07-10 16:09:18 -07:00
|
|
|
return obj;
|
|
|
|
|
}
|
2015-10-01 20:47:49 -07:00
|
|
|
if (type == RenderProtoViewRef) {
|
2015-07-10 16:09:18 -07:00
|
|
|
return this._protoViewStore.serialize(obj);
|
|
|
|
|
} else if (type == RenderViewRef) {
|
|
|
|
|
return this._renderViewStore.serializeRenderViewRef(obj);
|
|
|
|
|
} else if (type == RenderFragmentRef) {
|
|
|
|
|
return this._renderViewStore.serializeRenderFragmentRef(obj);
|
2015-08-07 13:17:54 -07:00
|
|
|
} else if (type == WebWorkerElementRef) {
|
2015-07-10 16:09:18 -07:00
|
|
|
return this._serializeWorkerElementRef(obj);
|
2015-10-01 10:07:49 -07:00
|
|
|
} else if (type == WebWorkerTemplateCmd) {
|
|
|
|
|
return serializeTemplateCmd(obj);
|
2015-07-10 16:09:18 -07:00
|
|
|
} else {
|
2015-07-10 16:09:18 -07:00
|
|
|
throw new BaseException("No serializer for " + type.toString());
|
2015-07-10 16:09:18 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-10 16:09:18 -07:00
|
|
|
deserialize(map: any, type: Type, data?: any): any {
|
2015-07-10 16:09:18 -07:00
|
|
|
if (!isPresent(map)) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
if (isArray(map)) {
|
2015-08-28 11:29:19 -07:00
|
|
|
var obj: any[] = [];
|
2015-07-10 16:09:18 -07:00
|
|
|
ListWrapper.forEach(map, (val) => { obj.push(this.deserialize(val, type, data)); });
|
2015-07-10 16:09:18 -07:00
|
|
|
return obj;
|
|
|
|
|
}
|
2015-08-21 16:55:50 -07:00
|
|
|
if (type == PRIMITIVE) {
|
2015-07-10 16:09:18 -07:00
|
|
|
return map;
|
|
|
|
|
}
|
2015-07-10 16:09:18 -07:00
|
|
|
|
2015-10-01 20:47:49 -07:00
|
|
|
if (type == RenderProtoViewRef) {
|
2015-07-10 16:09:18 -07:00
|
|
|
return this._protoViewStore.deserialize(map);
|
|
|
|
|
} else if (type == RenderViewRef) {
|
|
|
|
|
return this._renderViewStore.deserializeRenderViewRef(map);
|
|
|
|
|
} else if (type == RenderFragmentRef) {
|
|
|
|
|
return this._renderViewStore.deserializeRenderFragmentRef(map);
|
2015-08-07 13:17:54 -07:00
|
|
|
} else if (type == WebWorkerElementRef) {
|
2015-07-10 16:09:18 -07:00
|
|
|
return this._deserializeWorkerElementRef(map);
|
2015-10-01 10:07:49 -07:00
|
|
|
} else if (type == WebWorkerTemplateCmd) {
|
|
|
|
|
return deserializeTemplateCmd(map);
|
2015-07-10 16:09:18 -07:00
|
|
|
} else {
|
2015-07-10 16:09:18 -07:00
|
|
|
throw new BaseException("No deserializer for " + type.toString());
|
2015-07-10 16:09:18 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-10 16:09:18 -07:00
|
|
|
mapToObject(map: Map<string, any>, type?: Type): Object {
|
2015-07-10 16:09:18 -07:00
|
|
|
var object = {};
|
|
|
|
|
var serialize = isPresent(type);
|
|
|
|
|
|
|
|
|
|
MapWrapper.forEach(map, (value, key) => {
|
|
|
|
|
if (serialize) {
|
2015-07-10 16:09:18 -07:00
|
|
|
object[key] = this.serialize(value, type);
|
2015-07-10 16:09:18 -07:00
|
|
|
} else {
|
|
|
|
|
object[key] = value;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return object;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
2015-07-10 16:09:18 -07:00
|
|
|
* Transforms a Javascript object (StringMap) into a Map<string, V>
|
2015-07-10 16:09:18 -07:00
|
|
|
* If the values need to be deserialized pass in their type
|
|
|
|
|
* and they will be deserialized before being placed in the map
|
|
|
|
|
*/
|
2015-10-02 16:47:54 -07:00
|
|
|
objectToMap(obj: {[key: string]: any}, type?: Type, data?: any): Map<string, any> {
|
2015-07-10 16:09:18 -07:00
|
|
|
if (isPresent(type)) {
|
2015-09-29 11:11:06 -07:00
|
|
|
var map = new Map<string, any>();
|
2015-07-10 16:09:18 -07:00
|
|
|
StringMapWrapper.forEach(obj,
|
2015-07-28 16:38:55 -07:00
|
|
|
(val, key) => { map.set(key, this.deserialize(val, type, data)); });
|
2015-07-10 16:09:18 -07:00
|
|
|
return map;
|
|
|
|
|
} else {
|
|
|
|
|
return MapWrapper.createFromStringMap(obj);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-10 16:09:18 -07:00
|
|
|
allocateRenderViews(fragmentCount: number) { this._renderViewStore.allocate(fragmentCount); }
|
|
|
|
|
|
2015-10-02 16:47:54 -07:00
|
|
|
private _serializeWorkerElementRef(elementRef: RenderElementRef): {[key: string]: any} {
|
2015-07-10 16:09:18 -07:00
|
|
|
return {
|
|
|
|
|
'renderView': this.serialize(elementRef.renderView, RenderViewRef),
|
2015-10-01 20:47:49 -07:00
|
|
|
'boundElementIndex': elementRef.boundElementIndex
|
2015-07-10 16:09:18 -07:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-02 16:47:54 -07:00
|
|
|
private _deserializeWorkerElementRef(map: {[key: string]: any}): RenderElementRef {
|
2015-08-07 13:17:54 -07:00
|
|
|
return new WebWorkerElementRef(this.deserialize(map['renderView'], RenderViewRef),
|
2015-10-01 20:47:49 -07:00
|
|
|
map['boundElementIndex']);
|
2015-07-10 16:09:18 -07:00
|
|
|
}
|
|
|
|
|
}
|
2015-10-01 10:07:49 -07:00
|
|
|
|
|
|
|
|
function serializeTemplateCmd(cmd: RenderTemplateCmd): Object {
|
|
|
|
|
return cmd.visit(RENDER_TEMPLATE_CMD_SERIALIZER, null);
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-02 16:47:54 -07:00
|
|
|
function deserializeTemplateCmd(data: {[key: string]: any}): RenderTemplateCmd {
|
2015-10-01 10:07:49 -07:00
|
|
|
return RENDER_TEMPLATE_CMD_DESERIALIZERS[data['deserializerIndex']](data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class RenderTemplateCmdSerializer implements RenderCommandVisitor {
|
|
|
|
|
visitText(cmd: RenderTextCmd, context: any): any {
|
|
|
|
|
return {
|
|
|
|
|
'deserializerIndex': 0,
|
|
|
|
|
'isBound': cmd.isBound,
|
|
|
|
|
'ngContentIndex': cmd.ngContentIndex,
|
|
|
|
|
'value': cmd.value
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
visitNgContent(cmd: RenderNgContentCmd, context: any): any {
|
|
|
|
|
return {'deserializerIndex': 1, 'ngContentIndex': cmd.ngContentIndex};
|
|
|
|
|
}
|
|
|
|
|
visitBeginElement(cmd: RenderBeginElementCmd, context: any): any {
|
|
|
|
|
return {
|
|
|
|
|
'deserializerIndex': 2,
|
|
|
|
|
'isBound': cmd.isBound,
|
|
|
|
|
'ngContentIndex': cmd.ngContentIndex,
|
|
|
|
|
'name': cmd.name,
|
|
|
|
|
'attrNameAndValues': cmd.attrNameAndValues,
|
|
|
|
|
'eventTargetAndNames': cmd.eventTargetAndNames
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
visitEndElement(context: any): any { return {'deserializerIndex': 3}; }
|
|
|
|
|
visitBeginComponent(cmd: RenderBeginComponentCmd, context: any): any {
|
|
|
|
|
return {
|
|
|
|
|
'deserializerIndex': 4,
|
|
|
|
|
'isBound': cmd.isBound,
|
|
|
|
|
'ngContentIndex': cmd.ngContentIndex,
|
|
|
|
|
'name': cmd.name,
|
|
|
|
|
'attrNameAndValues': cmd.attrNameAndValues,
|
|
|
|
|
'eventTargetAndNames': cmd.eventTargetAndNames,
|
|
|
|
|
'nativeShadow': cmd.nativeShadow,
|
|
|
|
|
'templateId': cmd.templateId
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
visitEndComponent(context: any): any { return {'deserializerIndex': 5}; }
|
|
|
|
|
visitEmbeddedTemplate(cmd: RenderEmbeddedTemplateCmd, context: any): any {
|
|
|
|
|
var children = cmd.children.map(child => child.visit(this, null));
|
|
|
|
|
return {
|
|
|
|
|
'deserializerIndex': 6,
|
|
|
|
|
'isBound': cmd.isBound,
|
|
|
|
|
'ngContentIndex': cmd.ngContentIndex,
|
|
|
|
|
'name': cmd.name,
|
|
|
|
|
'attrNameAndValues': cmd.attrNameAndValues,
|
|
|
|
|
'eventTargetAndNames': cmd.eventTargetAndNames,
|
|
|
|
|
'isMerged': cmd.isMerged,
|
|
|
|
|
'children': children
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var RENDER_TEMPLATE_CMD_SERIALIZER = new RenderTemplateCmdSerializer();
|
|
|
|
|
|
|
|
|
|
var RENDER_TEMPLATE_CMD_DESERIALIZERS = [
|
2015-10-02 16:47:54 -07:00
|
|
|
(data: {[key: string]: any}) =>
|
2015-10-01 10:07:49 -07:00
|
|
|
new WebWorkerTextCmd(data['isBound'], data['ngContentIndex'], data['value']),
|
2015-10-02 16:47:54 -07:00
|
|
|
(data: {[key: string]: any}) => new WebWorkerNgContentCmd(data['ngContentIndex']),
|
|
|
|
|
(data: {[key: string]: any}) =>
|
2015-10-01 10:07:49 -07:00
|
|
|
new WebWorkerBeginElementCmd(data['isBound'], data['ngContentIndex'], data['name'],
|
|
|
|
|
data['attrNameAndValues'], data['eventTargetAndNames']),
|
2015-10-02 16:47:54 -07:00
|
|
|
(data: {[key: string]: any}) => new WebWorkerEndElementCmd(),
|
|
|
|
|
(data: {[key: string]: any}) => new WebWorkerBeginComponentCmd(
|
2015-10-01 10:07:49 -07:00
|
|
|
data['isBound'], data['ngContentIndex'], data['name'], data['attrNameAndValues'],
|
|
|
|
|
data['eventTargetAndNames'], data['nativeShadow'], data['templateId']),
|
2015-10-02 16:47:54 -07:00
|
|
|
(data: {[key: string]: any}) => new WebWorkerEndComponentCmd(),
|
|
|
|
|
(data: {[key: string]: any}) => new WebWorkerEmbeddedTemplateCmd(
|
2015-10-01 10:07:49 -07:00
|
|
|
data['isBound'], data['ngContentIndex'], data['name'], data['attrNameAndValues'],
|
|
|
|
|
data['eventTargetAndNames'], data['isMerged'],
|
|
|
|
|
(<any[]>data['children']).map(childData => deserializeTemplateCmd(childData))),
|
|
|
|
|
];
|