fix(WebWorker): Fix Todo Server demo and add test to ensure the demo can bootstrap.
Closes #3970
This commit is contained in:
@ -1,66 +1,8 @@
|
||||
library angular2.src.web_workers.event_serializer;
|
||||
|
||||
import 'package:angular2/src/core/facade/collection.dart';
|
||||
// TODO(jteplitz602): Remove Mirrors from serialization #3348
|
||||
@MirrorsUsed(
|
||||
symbols: "altKey, bubbles, button, cancelable, client, ctrlKey, " +
|
||||
"defaultPrevented, detail, eventPhase, layer, metaKey, offset, page, region, screen, " +
|
||||
"shiftKey, timeStamp, type, magnitude, x, y, charCode, keyCode, keyLocation, location, repeat")
|
||||
import 'dart:mirrors';
|
||||
import 'dart:core';
|
||||
import 'dart:html';
|
||||
|
||||
// These Maps can't be const due to a dartj2 bug (see http://github.com/dart-lang/sdk/issues/21825)
|
||||
// Once that bug is fixed these should be const
|
||||
final Map MOUSE_EVENT_PROPERTIES = {
|
||||
#altKey: bool,
|
||||
#bubbles: bool,
|
||||
#button: int,
|
||||
#cancelable: bool,
|
||||
#client: Point,
|
||||
#ctrlKey: bool,
|
||||
#defaultPrevented: bool,
|
||||
#detail: int,
|
||||
#eventPhase: int,
|
||||
#layer: Point,
|
||||
#metaKey: bool,
|
||||
#offset: Point,
|
||||
#page: Point,
|
||||
#region: String,
|
||||
#screen: Point,
|
||||
#shiftKey: bool,
|
||||
#timeStamp: int,
|
||||
#type: String
|
||||
};
|
||||
|
||||
final Map KEYBOARD_EVENT_PROPERTIES = {
|
||||
#altKey: bool,
|
||||
#bubbles: bool,
|
||||
#cancelable: bool,
|
||||
#charCode: int,
|
||||
#ctrlKey: bool,
|
||||
#defaultPrevented: bool,
|
||||
#detail: int,
|
||||
#eventPhase: int,
|
||||
#keyCode: int,
|
||||
#keyLocation: int,
|
||||
#layer: Point,
|
||||
#location: int,
|
||||
#repeat: bool,
|
||||
#shiftKey: bool,
|
||||
#timeStamp: int,
|
||||
#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([
|
||||
@ -75,23 +17,74 @@ final Set<String> NODES_WITH_VALUE = new Set<String>.from([
|
||||
]);
|
||||
|
||||
Map<String, dynamic> serializeGenericEvent(dynamic e) {
|
||||
return serializeEvent(e, EVENT_PROPERTIES);
|
||||
var serialized = new Map<String, dynamic>();
|
||||
serialized['bubbles'] = e.bubbles;
|
||||
serialized['cancelable'] = e.cancelable;
|
||||
serialized['defaultPrevented'] = e.defaultPrevented;
|
||||
serialized['eventPhase'] = e.eventPhase;
|
||||
serialized['timeStamp'] = e.timeStamp;
|
||||
serialized['type'] = e.type;
|
||||
return serialized;
|
||||
}
|
||||
|
||||
// TODO(jteplitz602): Allow users to specify the properties they need rather than always
|
||||
// adding value #3374
|
||||
Map<String, dynamic> serializeEventWithTarget(dynamic e) {
|
||||
var serializedEvent = serializeEvent(e, EVENT_PROPERTIES);
|
||||
var serializedEvent = serializeGenericEvent(e);
|
||||
return addTarget(e, serializedEvent);
|
||||
}
|
||||
|
||||
Map<String, dynamic> serializeMouseEvent(dynamic e) {
|
||||
return serializeEvent(e, MOUSE_EVENT_PROPERTIES);
|
||||
var serialized = new Map<String, dynamic>();
|
||||
serialized['altKey'] = e.altKey;
|
||||
serialized['bubbles'] = e.bubbles;
|
||||
serialized['button'] = e.button;
|
||||
serialized['cancelable'] = e.cancelable;
|
||||
serialized['client'] = serializePoint(e.client);
|
||||
serialized['ctrlKey'] = e.ctrlKey;
|
||||
serialized['defaultPrevented'] = e.defaultPrevented;
|
||||
serialized['detail'] = e.detail;
|
||||
serialized['eventPhase'] = e.eventPhase;
|
||||
serialized['layer'] = serializePoint(e.layer);
|
||||
serialized['metaKey'] = e.metaKey;
|
||||
serialized['offset'] = serializePoint(e.offset);
|
||||
serialized['page'] = serializePoint(e.page);
|
||||
serialized['region'] = e.region;
|
||||
serialized['screen'] = serializePoint(e.screen);
|
||||
serialized['shiftKey'] = e.shiftKey;
|
||||
serialized['timeStamp'] = e.timeStamp;
|
||||
serialized['type'] = e.type;
|
||||
return serialized;
|
||||
}
|
||||
|
||||
Map<String, dynamic> serializePoint(Point point) {
|
||||
var serialized = new Map<String, dynamic>();
|
||||
serialized['magnitude'] = point.magnitude;
|
||||
serialized['x'] = point.x;
|
||||
serialized['y'] = point.y;
|
||||
return serialized;
|
||||
}
|
||||
|
||||
Map<String, dynamic> serializeKeyboardEvent(dynamic e) {
|
||||
var serializedEvent = serializeEvent(e, KEYBOARD_EVENT_PROPERTIES);
|
||||
return addTarget(e, serializedEvent);
|
||||
var serialized = new Map<String, dynamic>();
|
||||
serialized['altKey'] = e.altKey;
|
||||
serialized['bubbles'] = e.bubbles;
|
||||
serialized['cancelable'] = e.cancelable;
|
||||
serialized['charCode'] = e.charCode;
|
||||
serialized['ctrlKey'] = e.ctrlKey;
|
||||
serialized['defaultPrevented'] = e.defaultPrevented;
|
||||
serialized['detail'] = e.detail;
|
||||
serialized['eventPhase'] = e.eventPhase;
|
||||
serialized['keyCode'] = e.keyCode;
|
||||
serialized['keyLocation'] = e.keyLocation;
|
||||
serialized['layer'] = serializePoint(e.layer);
|
||||
serialized['location'] = e.location;
|
||||
serialized['repeat'] = e.repeat;
|
||||
serialized['shiftKey'] = e.shiftKey;
|
||||
serialized['timeStamp'] = e.timeStamp;
|
||||
serialized['type'] = e.type;
|
||||
//return addTarget(e, serialized);
|
||||
return serialized;
|
||||
}
|
||||
|
||||
// TODO(jteplitz602): #3374. See above.
|
||||
@ -105,24 +98,3 @@ Map<String, dynamic> addTarget(
|
||||
}
|
||||
return serializedEvent;
|
||||
}
|
||||
|
||||
Map<String, dynamic> serializeEvent(dynamic e, Map<Symbol, Type> PROPERTIES) {
|
||||
var serialized = StringMapWrapper.create();
|
||||
var mirror = reflect(e);
|
||||
PROPERTIES.forEach((property, type) {
|
||||
var value = mirror.getField(property).reflectee;
|
||||
var propertyName = MirrorSystem.getName(property);
|
||||
if (type == int || type == bool || type == String) {
|
||||
serialized[propertyName] = value;
|
||||
} else if (type == Point) {
|
||||
var point = reflect(value);
|
||||
serialized[propertyName] = {
|
||||
'magnitude': point.getField(#magnitude).reflectee,
|
||||
'x': point.getField(#x).reflectee,
|
||||
'y': point.getField(#y).reflectee
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
return serialized;
|
||||
}
|
||||
|
@ -90,7 +90,6 @@ function _injectorBindings(appComponentType, bus: MessageBus, initData: StringMa
|
||||
bind(APP_COMPONENT_REF_PROMISE)
|
||||
.toFactory(
|
||||
(dynamicComponentLoader, injector) => {
|
||||
|
||||
// TODO(rado): investigate whether to support bindings on root component.
|
||||
return dynamicComponentLoader.loadAsRoot(appComponentType, null, injector)
|
||||
.then((componentRef) => { return componentRef; });
|
||||
@ -150,32 +149,39 @@ export function bootstrapWebWorkerCommon(
|
||||
// index.html and main.js are possible.
|
||||
//
|
||||
|
||||
|
||||
var subscription: any;
|
||||
var emitter = bus.from(SETUP_CHANNEL);
|
||||
subscription = ObservableWrapper.subscribe(emitter, (message: StringMap<string, any>) => {
|
||||
var appInjector =
|
||||
_createAppInjector(appComponentType, componentInjectableBindings, zone, bus, message);
|
||||
var compRefToken = PromiseWrapper.wrap(() => {
|
||||
try {
|
||||
return appInjector.get(APP_COMPONENT_REF_PROMISE);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
var exceptionHandler;
|
||||
try {
|
||||
var appInjector =
|
||||
_createAppInjector(appComponentType, componentInjectableBindings, zone, bus, message);
|
||||
exceptionHandler = appInjector.get(ExceptionHandler);
|
||||
zone.overrideOnErrorHandler((e, s) => exceptionHandler.call(e, s));
|
||||
var compRefToken: Promise<any> = appInjector.get(APP_COMPONENT_REF_PROMISE);
|
||||
var tick = (componentRef) => {
|
||||
var appChangeDetector = internalView(componentRef.hostView).changeDetector;
|
||||
// retrieve life cycle: may have already been created if injected in root component
|
||||
var lc = appInjector.get(LifeCycle);
|
||||
lc.registerWith(zone, appChangeDetector);
|
||||
lc.tick(); // the first tick that will bootstrap the app
|
||||
|
||||
bootstrapProcess.resolve(new ApplicationRef(componentRef, appComponentType, appInjector));
|
||||
};
|
||||
|
||||
var tickResult = PromiseWrapper.then(compRefToken, tick);
|
||||
|
||||
PromiseWrapper.then(tickResult,
|
||||
(_) => {}); // required for Dart to trigger the default error handler
|
||||
PromiseWrapper.then(tickResult, null,
|
||||
(err, stackTrace) => { bootstrapProcess.reject(err, stackTrace); });
|
||||
ObservableWrapper.dispose(subscription);
|
||||
} catch (e) {
|
||||
if (isPresent(exceptionHandler)) {
|
||||
exceptionHandler.call(e, e.stack);
|
||||
}
|
||||
});
|
||||
var tick = (componentRef) => {
|
||||
var appChangeDetector = internalView(componentRef.hostView).changeDetector;
|
||||
// retrieve life cycle: may have already been created if injected in root component
|
||||
var lc = appInjector.get(LifeCycle);
|
||||
lc.registerWith(zone, appChangeDetector);
|
||||
lc.tick(); // the first tick that will bootstrap the app
|
||||
|
||||
bootstrapProcess.resolve(new ApplicationRef(componentRef, appComponentType, appInjector));
|
||||
};
|
||||
PromiseWrapper.then(compRefToken, tick,
|
||||
(err, stackTrace) => { bootstrapProcess.reject(err, stackTrace); });
|
||||
|
||||
ObservableWrapper.dispose(subscription);
|
||||
bootstrapProcess.reject(e, e.stack);
|
||||
}
|
||||
});
|
||||
|
||||
ObservableWrapper.callNext(bus.to(SETUP_CHANNEL), "ready");
|
||||
|
Reference in New Issue
Block a user