feat(WebWorkers): Add WebWorker Todo Example. Add support for more DOM events.
Fixed breakage caused by previous DI commit in WebWorker Todo example
This commit is contained in:
@ -28,7 +28,8 @@ import {
|
||||
RenderFragmentRef,
|
||||
RenderElementRef,
|
||||
ViewType,
|
||||
ViewEncapsulation
|
||||
ViewEncapsulation,
|
||||
PropertyBindingType
|
||||
} from "angular2/src/render/api";
|
||||
import {WorkerElementRef} from 'angular2/src/web-workers/shared/api';
|
||||
import {AST, ASTWithSource} from 'angular2/src/change_detection/change_detection';
|
||||
@ -57,6 +58,13 @@ export class Serializer {
|
||||
viewEncapsulationMap[1] = ViewEncapsulation.NATIVE;
|
||||
viewEncapsulationMap[2] = ViewEncapsulation.NONE;
|
||||
this._enumRegistry.set(ViewEncapsulation, viewEncapsulationMap);
|
||||
|
||||
var propertyBindingTypeMap = new Map<int, 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 {
|
||||
@ -93,6 +101,8 @@ export class Serializer {
|
||||
return this._renderViewStore.serializeRenderFragmentRef(obj);
|
||||
} else if (type == WorkerElementRef) {
|
||||
return this._serializeWorkerElementRef(obj);
|
||||
} else if (type == ElementPropertyBinding) {
|
||||
return this._serializeElementPropertyBinding(obj);
|
||||
} else if (type == EventBinding) {
|
||||
return this._serializeEventBinding(obj);
|
||||
} else {
|
||||
@ -137,6 +147,8 @@ export class Serializer {
|
||||
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());
|
||||
}
|
||||
@ -165,7 +177,7 @@ export class Serializer {
|
||||
if (isPresent(type)) {
|
||||
var map: Map<string, any> = new Map();
|
||||
StringMapWrapper.forEach(obj,
|
||||
(key, val) => { map.set(key, this.deserialize(val, type, data)); });
|
||||
(val, key) => { map.set(key, this.deserialize(val, type, data)); });
|
||||
return map;
|
||||
} else {
|
||||
return MapWrapper.createFromStringMap(obj);
|
||||
@ -174,13 +186,29 @@ export class Serializer {
|
||||
|
||||
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, "binding"));
|
||||
this.deserialize(map['source'], ASTWithSource, "action"));
|
||||
}
|
||||
|
||||
private _serializeWorkerElementRef(elementRef: RenderElementRef): StringMap<string, any> {
|
||||
@ -223,15 +251,12 @@ export class Serializer {
|
||||
// TODO: make ASTs serializable
|
||||
var ast: AST;
|
||||
switch (data) {
|
||||
case "interpolation":
|
||||
ast = this._parser.parseInterpolation(obj['input'], obj['location']);
|
||||
case "action":
|
||||
ast = this._parser.parseAction(obj['input'], obj['location']);
|
||||
break;
|
||||
case "binding":
|
||||
ast = this._parser.parseBinding(obj['input'], obj['location']);
|
||||
break;
|
||||
case "simpleBinding":
|
||||
ast = this._parser.parseSimpleBinding(obj['input'], obj['location']);
|
||||
break;
|
||||
case "interpolation":
|
||||
ast = this._parser.parseInterpolation(obj['input'], obj['location']);
|
||||
break;
|
||||
|
@ -52,12 +52,45 @@ final Map KEYBOARD_EVENT_PROPERTIES = {
|
||||
#type: String
|
||||
};
|
||||
|
||||
final Map EVENT_PROPERTIES = {
|
||||
#bubbles: bool,
|
||||
#cancelable: bool,
|
||||
#defaultPrevented: bool,
|
||||
#eventPhase: int,
|
||||
#timeStamp: int,
|
||||
#type: String
|
||||
};
|
||||
|
||||
// List of all elements with HTML value attribute.
|
||||
// Taken from: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
|
||||
final Set<String> NODES_WITH_VALUE =
|
||||
new Set<String>.from(["input", "select", "option", "button", "li", "meter", "progress", "param"]);
|
||||
|
||||
Map<String, dynamic> serializeGenericEvent(dynamic e) {
|
||||
return serializeEvent(e, EVENT_PROPERTIES);
|
||||
}
|
||||
|
||||
// TODO(jteplitz602): Allow users to specify the properties they need rather than always
|
||||
// adding value #3374
|
||||
Map<String, dynamic> serializeEventWithValue(dynamic e) {
|
||||
var serializedEvent = serializeEvent(e, EVENT_PROPERTIES);
|
||||
return addValue(e, serializedEvent);
|
||||
}
|
||||
Map<String, dynamic> serializeMouseEvent(dynamic e) {
|
||||
return serializeEvent(e, MOUSE_EVENT_PROPERTIES);
|
||||
}
|
||||
|
||||
Map<String, dynamic> serializeKeyboardEvent(dynamic e) {
|
||||
return serializeEvent(e, KEYBOARD_EVENT_PROPERTIES);
|
||||
var serializedEvent = serializeEvent(e, KEYBOARD_EVENT_PROPERTIES);
|
||||
return addValue(e, serializedEvent);
|
||||
}
|
||||
|
||||
// TODO(jteplitz602): #3374. See above.
|
||||
Map<String, dynamic> addValue(dynamic e, Map<String, dynamic> serializedEvent) {
|
||||
if (NODES_WITH_VALUE.contains(e.target.tagName.toLowerCase())){
|
||||
serializedEvent['target'] = {'value': e.target.value};
|
||||
}
|
||||
return serializedEvent;
|
||||
}
|
||||
|
||||
Map<String, dynamic> serializeEvent(dynamic e, Map<Symbol, Type> PROPERTIES) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {StringMap} from 'angular2/src/facade/collection';
|
||||
import {StringMap, Set} from 'angular2/src/facade/collection';
|
||||
|
||||
const MOUSE_EVENT_PROPERTIES = [
|
||||
"altKey",
|
||||
@ -31,12 +31,37 @@ const KEYBOARD_EVENT_PROPERTIES = [
|
||||
'which'
|
||||
];
|
||||
|
||||
const EVENT_PROPERTIES = ['type', 'bubbles', 'cancelable'];
|
||||
|
||||
const NODES_WITH_VALUE =
|
||||
new Set(["input", "select", "option", "button", "li", "meter", "progress", "param"]);
|
||||
|
||||
export function serializeGenericEvent(e: Event): StringMap<string, any> {
|
||||
return serializeEvent(e, EVENT_PROPERTIES);
|
||||
}
|
||||
|
||||
// TODO(jteplitz602): Allow users to specify the properties they need rather than always
|
||||
// adding value #3374
|
||||
export function serializeEventWithValue(e: Event): StringMap<string, any> {
|
||||
var serializedEvent = serializeEvent(e, EVENT_PROPERTIES);
|
||||
return addValue(e, serializedEvent);
|
||||
}
|
||||
|
||||
export function serializeMouseEvent(e: MouseEvent): StringMap<string, any> {
|
||||
return serializeEvent(e, MOUSE_EVENT_PROPERTIES);
|
||||
}
|
||||
|
||||
export function serializeKeyboardEvent(e: KeyboardEvent): StringMap<string, any> {
|
||||
return serializeEvent(e, KEYBOARD_EVENT_PROPERTIES);
|
||||
var serializedEvent = serializeEvent(e, KEYBOARD_EVENT_PROPERTIES);
|
||||
return addValue(e, serializedEvent);
|
||||
}
|
||||
|
||||
// TODO(jteplitz602): #3374. See above.
|
||||
function addValue(e: Event, serializedEvent: StringMap<string, any>): StringMap<string, any> {
|
||||
if (NODES_WITH_VALUE.has((<HTMLElement>e.target).tagName.toLowerCase())) {
|
||||
serializedEvent['target'] = {'value': (<HTMLInputElement>e.target).value};
|
||||
}
|
||||
return serializedEvent;
|
||||
}
|
||||
|
||||
function serializeEvent(e: any, properties: List<string>): StringMap<string, any> {
|
||||
|
@ -35,7 +35,9 @@ import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter';
|
||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||
import {
|
||||
serializeMouseEvent,
|
||||
serializeKeyboardEvent
|
||||
serializeKeyboardEvent,
|
||||
serializeGenericEvent,
|
||||
serializeEventWithValue
|
||||
} from 'angular2/src/web-workers/ui/event_serializer';
|
||||
|
||||
/**
|
||||
@ -236,7 +238,8 @@ class EventDispatcher implements RenderEventDispatcher {
|
||||
dispatchRenderEvent(elementIndex: number, eventName: string, locals: Map<string, any>) {
|
||||
var e = locals.get('$event');
|
||||
var serializedEvent;
|
||||
switch (eventName) {
|
||||
// TODO (jteplitz602): support custom events #3350
|
||||
switch (e.type) {
|
||||
case "click":
|
||||
case "mouseup":
|
||||
case "mousedown":
|
||||
@ -255,6 +258,60 @@ class EventDispatcher implements RenderEventDispatcher {
|
||||
case "keyup":
|
||||
serializedEvent = serializeKeyboardEvent(e);
|
||||
break;
|
||||
case "input":
|
||||
case "change":
|
||||
case "blur":
|
||||
serializedEvent = serializeEventWithValue(e);
|
||||
break;
|
||||
case "abort":
|
||||
case "afterprint":
|
||||
case "beforeprint":
|
||||
case "cached":
|
||||
case "canplay":
|
||||
case "canplaythrough":
|
||||
case "chargingchange":
|
||||
case "chargingtimechange":
|
||||
case "close":
|
||||
case "dischargingtimechange":
|
||||
case "DOMContentLoaded":
|
||||
case "downloading":
|
||||
case "durationchange":
|
||||
case "emptied":
|
||||
case "ended":
|
||||
case "error":
|
||||
case "fullscreenchange":
|
||||
case "fullscreenerror":
|
||||
case "invalid":
|
||||
case "languagechange":
|
||||
case "levelfchange":
|
||||
case "loadeddata":
|
||||
case "loadedmetadata":
|
||||
case "obsolete":
|
||||
case "offline":
|
||||
case "online":
|
||||
case "open":
|
||||
case "orientatoinchange":
|
||||
case "pause":
|
||||
case "pointerlockchange":
|
||||
case "pointerlockerror":
|
||||
case "play":
|
||||
case "playing":
|
||||
case "ratechange":
|
||||
case "readystatechange":
|
||||
case "reset":
|
||||
case "seeked":
|
||||
case "seeking":
|
||||
case "stalled":
|
||||
case "submit":
|
||||
case "success":
|
||||
case "suspend":
|
||||
case "timeupdate":
|
||||
case "updateready":
|
||||
case "visibilitychange":
|
||||
case "volumechange":
|
||||
case "waiting":
|
||||
serializedEvent = serializeGenericEvent(e);
|
||||
break;
|
||||
default:
|
||||
throw new BaseException(eventName + " not supported on WebWorkers");
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import {Injectable} from "angular2/di";
|
||||
import {Type} from "angular2/src/facade/lang";
|
||||
import {RenderViewRef, RenderEventDispatcher} from 'angular2/src/render/api';
|
||||
import {NgZone} from 'angular2/src/core/zone/ng_zone';
|
||||
import {deserializeGenericEvent} from './event_deserializer';
|
||||
|
||||
@Injectable()
|
||||
export class MessageBroker {
|
||||
@ -96,6 +97,7 @@ export class MessageBroker {
|
||||
private _dispatchEvent(eventData: RenderEventData): void {
|
||||
var dispatcher = this._eventDispatchRegistry.get(eventData.viewRef);
|
||||
this._zone.run(() => {
|
||||
eventData.locals['$event'] = deserializeGenericEvent(eventData.locals['$event']);
|
||||
dispatcher.dispatchRenderEvent(eventData.elementIndex, eventData.eventName, eventData.locals);
|
||||
});
|
||||
}
|
||||
|
@ -0,0 +1,69 @@
|
||||
library angular2.src.web_workers.worker.event_deserializer;
|
||||
|
||||
class GenericEvent {
|
||||
Map<String, dynamic> properties;
|
||||
EventTarget _target = null;
|
||||
|
||||
GenericEvent(this.properties);
|
||||
|
||||
bool get bubbles => properties['bubbles'];
|
||||
bool get cancelable => properties['cancelable'];
|
||||
bool get defaultPrevented => properties['defaultPrevented'];
|
||||
int get eventPhase => properties['eventPhase'];
|
||||
int get timeStamp => properties['timeStamp'];
|
||||
String get type => properties['type'];
|
||||
bool get altKey => properties['altKey'];
|
||||
|
||||
int get charCode => properties['charCode'];
|
||||
bool get ctrlKey => properties['ctrlKey'];
|
||||
int get detail => properties['detail'];
|
||||
int get keyCode => properties['keyCode'];
|
||||
int get keyLocation => properties['keyLocation'];
|
||||
Point get layer => _getPoint('layer');
|
||||
int get location => properties['location'];
|
||||
bool get repeat => properties['repeat'];
|
||||
bool get shiftKey => properties['shiftKey'];
|
||||
|
||||
int get button => properties['button'];
|
||||
Point get client => _getPoint('client');
|
||||
bool get metaKey => properties['metaKey'];
|
||||
Point get offset => _getPoint('offset');
|
||||
Point get page => _getPoint('page');
|
||||
Point get screen => _getPoint('screen');
|
||||
|
||||
EventTarget get target{
|
||||
if (_target != null){
|
||||
return _target;
|
||||
} else if (properties.containsKey("target")){
|
||||
_target = new EventTarget(properties['target']);
|
||||
return _target;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
dynamic _getPoint(name) {
|
||||
Map<String, dynamic> point = properties[name];
|
||||
return new Point(point['x'], point['y'], point['magnitude']);
|
||||
}
|
||||
}
|
||||
|
||||
class EventTarget {
|
||||
dynamic value;
|
||||
|
||||
EventTarget(Map<String, dynamic> properties) {
|
||||
value = properties['value'];
|
||||
}
|
||||
}
|
||||
|
||||
class Point {
|
||||
int x;
|
||||
int y;
|
||||
double magnitude;
|
||||
|
||||
Point(this.x, this.y, this.magnitude);
|
||||
}
|
||||
|
||||
GenericEvent deserializeGenericEvent(Map<String, dynamic> serializedEvent) {
|
||||
return new GenericEvent(serializedEvent);
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
import {StringMap} from "angular2/src/facade/collection";
|
||||
|
||||
// no deserialization is necessary in TS.
|
||||
// This is only here to match dart interface
|
||||
export function deserializeGenericEvent(serializedEvent: StringMap<string, any>):
|
||||
StringMap<string, any> {
|
||||
return serializedEvent;
|
||||
}
|
@ -171,7 +171,7 @@ export class WorkerRenderer implements Renderer {
|
||||
*/
|
||||
dehydrateView(viewRef: RenderViewRef) {
|
||||
var fnArgs = [new FnArg(viewRef, RenderViewRef)];
|
||||
var args = new UiArguments("renderer", "deyhdrateView", fnArgs);
|
||||
var args = new UiArguments("renderer", "dehydrateView", fnArgs);
|
||||
this._messageBroker.runOnUiThread(args, null);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user