refactor(browser): merge static & dynamic platforms
This commit is contained in:
@ -1,223 +0,0 @@
|
||||
library angular2.src.web_workers.debug_tools.multi_client_server_message_bus;
|
||||
|
||||
import 'dart:io';
|
||||
import 'dart:convert' show JSON;
|
||||
import 'dart:async';
|
||||
import 'package:angular2/src/web_workers/shared/messaging_api.dart';
|
||||
import 'package:angular2/src/web_workers/shared/generic_message_bus.dart';
|
||||
|
||||
// TODO(jteplitz602): Remove hard coded result type and
|
||||
// clear messageHistory once app is done with it #3859
|
||||
class MultiClientServerMessageBus extends GenericMessageBus {
|
||||
bool hasPrimary = false;
|
||||
|
||||
@override
|
||||
MultiClientServerMessageBusSink get sink => super.sink;
|
||||
@override
|
||||
MultiClientServerMessageBusSource get source => super.source;
|
||||
|
||||
MultiClientServerMessageBus(MultiClientServerMessageBusSink sink,
|
||||
MultiClientServerMessageBusSource source)
|
||||
: super(sink, source);
|
||||
|
||||
MultiClientServerMessageBus.fromHttpServer(HttpServer server)
|
||||
: super(new MultiClientServerMessageBusSink(),
|
||||
new MultiClientServerMessageBusSource()) {
|
||||
source.onResult.listen(_resultReceived);
|
||||
server.listen((HttpRequest request) {
|
||||
if (request.uri.path == "/ws") {
|
||||
WebSocketTransformer.upgrade(request).then((WebSocket socket) {
|
||||
var wrapper = new WebSocketWrapper(
|
||||
sink.messageHistory, sink.resultMarkers, socket);
|
||||
if (!hasPrimary) {
|
||||
wrapper.setPrimary(true);
|
||||
hasPrimary = true;
|
||||
}
|
||||
sink.addConnection(wrapper);
|
||||
source.addConnection(wrapper);
|
||||
|
||||
wrapper.stream.listen(null, onDone: _handleDisconnect(wrapper));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _resultReceived(_) {
|
||||
sink.resultReceived();
|
||||
}
|
||||
|
||||
Function _handleDisconnect(WebSocketWrapper wrapper) {
|
||||
return () {
|
||||
sink.removeConnection(wrapper);
|
||||
if (wrapper.isPrimary) {
|
||||
hasPrimary = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class WebSocketWrapper {
|
||||
WebSocket _socket;
|
||||
Stream stream;
|
||||
int _numResultsReceived = 0;
|
||||
bool _isPrimary = false;
|
||||
bool caughtUp = false;
|
||||
List<String> _messageHistory;
|
||||
List<int> _resultMarkers;
|
||||
StreamController<String> _sendStream;
|
||||
|
||||
WebSocketWrapper(this._messageHistory, this._resultMarkers, this._socket) {
|
||||
stream = _socket.asBroadcastStream();
|
||||
stream.listen((encodedMessage) {
|
||||
var messages = JSON.decode(encodedMessage);
|
||||
messages.forEach((data) {
|
||||
var message = data['message'];
|
||||
if (message is Map && message.containsKey("type")) {
|
||||
if (message['type'] == 'result') {
|
||||
resultReceived();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
_sendStream = new StreamController<String>();
|
||||
_socket.addStream(_sendStream.stream);
|
||||
}
|
||||
|
||||
void send(String data) {
|
||||
_sendStream.add(data);
|
||||
}
|
||||
|
||||
bool get isPrimary => _isPrimary;
|
||||
|
||||
void resultReceived() {
|
||||
if (!isPrimary && !caughtUp) {
|
||||
_numResultsReceived++;
|
||||
sendToMarker(_numResultsReceived);
|
||||
}
|
||||
}
|
||||
|
||||
void setPrimary(bool primary) {
|
||||
_isPrimary = primary;
|
||||
if (primary) {
|
||||
caughtUp = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Sends up to the given result marker
|
||||
void sendToMarker(int markerIndex) {
|
||||
int numMessages;
|
||||
int curr;
|
||||
if (markerIndex >= _resultMarkers.length) {
|
||||
// we're past the final result marker so send all messages in history
|
||||
curr = (_resultMarkers.length > 0)
|
||||
? _resultMarkers[_resultMarkers.length - 1]
|
||||
: 0;
|
||||
numMessages = _messageHistory.length - curr;
|
||||
caughtUp = true;
|
||||
} else {
|
||||
curr = (markerIndex == 0) ? 0 : _resultMarkers[markerIndex - 1];
|
||||
var end = _resultMarkers[markerIndex];
|
||||
numMessages = end - curr;
|
||||
}
|
||||
while (numMessages > 0) {
|
||||
send(_messageHistory[curr]);
|
||||
curr++;
|
||||
numMessages--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MultiClientServerMessageBusSink extends GenericMessageBusSink {
|
||||
final List<String> messageHistory = new List<String>();
|
||||
final Set<WebSocketWrapper> openConnections = new Set<WebSocketWrapper>();
|
||||
final List<int> resultMarkers = new List<int>();
|
||||
|
||||
void resultReceived() {
|
||||
resultMarkers.add(messageHistory.length);
|
||||
}
|
||||
|
||||
void addConnection(WebSocketWrapper webSocket) {
|
||||
openConnections.add(webSocket);
|
||||
// send messages up to the first result marker to this socket
|
||||
webSocket.sendToMarker(0);
|
||||
}
|
||||
|
||||
void removeConnection(WebSocketWrapper webSocket) {
|
||||
openConnections.remove(webSocket);
|
||||
}
|
||||
|
||||
@override
|
||||
void sendMessages(List<dynamic> messages) {
|
||||
String encodedMessages = JSON.encode(messages);
|
||||
openConnections.forEach((WebSocketWrapper webSocket) {
|
||||
if (webSocket.caughtUp) {
|
||||
webSocket.send(encodedMessages);
|
||||
}
|
||||
});
|
||||
messageHistory.add(encodedMessages);
|
||||
}
|
||||
}
|
||||
|
||||
class MultiClientServerMessageBusSource extends GenericMessageBusSource {
|
||||
Function onResultReceived;
|
||||
final StreamController mainController;
|
||||
final StreamController resultController = new StreamController();
|
||||
|
||||
MultiClientServerMessageBusSource._(controller)
|
||||
: mainController = controller,
|
||||
super(controller.stream);
|
||||
|
||||
factory MultiClientServerMessageBusSource() {
|
||||
return new MultiClientServerMessageBusSource._(
|
||||
new StreamController.broadcast());
|
||||
}
|
||||
|
||||
Stream get onResult => resultController.stream;
|
||||
|
||||
void addConnection(WebSocketWrapper webSocket) {
|
||||
if (webSocket.isPrimary) {
|
||||
webSocket.stream.listen((encodedMessages) {
|
||||
var decodedMessages = _decodeMessages(encodedMessages);
|
||||
decodedMessages.forEach((decodedMessage) {
|
||||
var message = decodedMessage['message'];
|
||||
if (message is Map && message.containsKey("type")) {
|
||||
if (message['type'] == 'result') {
|
||||
// tell the bus that a result was received on the primary
|
||||
resultController.add(message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mainController.add(decodedMessages);
|
||||
});
|
||||
} else {
|
||||
webSocket.stream.listen((encodedMessages) {
|
||||
// handle events from non-primary connection.
|
||||
var decodedMessages = _decodeMessages(encodedMessages);
|
||||
var eventMessages = new List<Map<String, dynamic>>();
|
||||
decodedMessages.forEach((decodedMessage) {
|
||||
var channel = decodedMessage['channel'];
|
||||
if (channel == EVENT_CHANNEL) {
|
||||
eventMessages.add(decodedMessage);
|
||||
}
|
||||
});
|
||||
if (eventMessages.length > 0) {
|
||||
mainController.add(eventMessages);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
List<dynamic> _decodeMessages(dynamic messages) {
|
||||
return JSON.decode(messages);
|
||||
}
|
||||
|
||||
// This is a noop for the MultiClientBus because it has to decode the JSON messages before
|
||||
// the generic bus receives them in order to check for results and forward events
|
||||
// from the non-primary connection.
|
||||
@override
|
||||
List<dynamic> decodeMessages(dynamic messages) {
|
||||
return messages;
|
||||
}
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
library angular2.src.web_workers.debug_tools.single_client_server_message_bus;
|
||||
|
||||
import 'dart:io';
|
||||
import 'dart:convert' show JSON;
|
||||
import 'package:angular2/src/web_workers/shared/generic_message_bus.dart';
|
||||
|
||||
class SingleClientServerMessageBus extends GenericMessageBus {
|
||||
bool connected = false;
|
||||
|
||||
@override
|
||||
SingleClientServerMessageBusSink get sink => super.sink;
|
||||
@override
|
||||
SingleClientServerMessageBusSource get source => super.source;
|
||||
|
||||
SingleClientServerMessageBus(SingleClientServerMessageBusSink sink,
|
||||
SingleClientServerMessageBusSource source)
|
||||
: super(sink, source);
|
||||
|
||||
SingleClientServerMessageBus.fromHttpServer(HttpServer server)
|
||||
: super(new SingleClientServerMessageBusSink(),
|
||||
new SingleClientServerMessageBusSource()) {
|
||||
server.listen((HttpRequest request) {
|
||||
if (request.uri.path == "/ws") {
|
||||
if (!connected) {
|
||||
WebSocketTransformer.upgrade(request).then((WebSocket socket) {
|
||||
sink.setConnection(socket);
|
||||
|
||||
var stream = socket.asBroadcastStream();
|
||||
source.attachTo(stream);
|
||||
stream.listen(null, onDone: _handleDisconnect);
|
||||
}).catchError((error) {
|
||||
throw error;
|
||||
connected = false;
|
||||
});
|
||||
connected = true;
|
||||
} else {
|
||||
// refuse additional clients
|
||||
request.response.statusCode = HttpStatus.SERVICE_UNAVAILABLE;
|
||||
request.response.write("Maximum number of clients connected.");
|
||||
request.response.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _handleDisconnect() {
|
||||
sink.removeConnection();
|
||||
connected = false;
|
||||
}
|
||||
}
|
||||
|
||||
class SingleClientServerMessageBusSink extends GenericMessageBusSink {
|
||||
final List<String> _messageBuffer = new List<String>();
|
||||
WebSocket _socket = null;
|
||||
|
||||
void setConnection(WebSocket webSocket) {
|
||||
_socket = webSocket;
|
||||
_sendBufferedMessages();
|
||||
}
|
||||
|
||||
void removeConnection() {
|
||||
_socket = null;
|
||||
}
|
||||
|
||||
@override
|
||||
void sendMessages(List<dynamic> message) {
|
||||
String encodedMessages = JSON.encode(message);
|
||||
if (_socket != null) {
|
||||
_socket.add(encodedMessages);
|
||||
} else {
|
||||
_messageBuffer.add(encodedMessages);
|
||||
}
|
||||
}
|
||||
|
||||
void _sendBufferedMessages() {
|
||||
_messageBuffer.forEach((message) => _socket.add(message));
|
||||
_messageBuffer.clear();
|
||||
}
|
||||
}
|
||||
|
||||
class SingleClientServerMessageBusSource extends GenericMessageBusSource {
|
||||
SingleClientServerMessageBusSource() : super(null);
|
||||
|
||||
@override
|
||||
List<dynamic> decodeMessages(dynamic messages) {
|
||||
return JSON.decode(messages);
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
library angular2.src.web_workers.worker.web_socket_message_bus;
|
||||
|
||||
import 'dart:html';
|
||||
import 'dart:convert' show JSON;
|
||||
import 'package:angular2/src/web_workers/shared/generic_message_bus.dart';
|
||||
|
||||
class WebSocketMessageBus extends GenericMessageBus {
|
||||
WebSocketMessageBus(
|
||||
WebSocketMessageBusSink sink, WebSocketMessageBusSource source)
|
||||
: super(sink, source);
|
||||
|
||||
WebSocketMessageBus.fromWebSocket(WebSocket webSocket)
|
||||
: super(new WebSocketMessageBusSink(webSocket),
|
||||
new WebSocketMessageBusSource(webSocket));
|
||||
}
|
||||
|
||||
class WebSocketMessageBusSink extends GenericMessageBusSink {
|
||||
final WebSocket _webSocket;
|
||||
|
||||
WebSocketMessageBusSink(this._webSocket);
|
||||
|
||||
void sendMessages(List<dynamic> messages) {
|
||||
_webSocket.send(JSON.encode(messages));
|
||||
}
|
||||
}
|
||||
|
||||
class WebSocketMessageBusSource extends GenericMessageBusSource {
|
||||
WebSocketMessageBusSource(WebSocket webSocket) : super(webSocket.onMessage);
|
||||
|
||||
List<dynamic> decodeMessages(MessageEvent event) {
|
||||
var messages = event.data;
|
||||
return JSON.decode(messages);
|
||||
}
|
||||
}
|
@ -1,156 +0,0 @@
|
||||
library angular2.src.web_workers.shared.generic_message_bus;
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:angular2/src/facade/async.dart' show EventEmitter;
|
||||
import 'package:angular2/src/web_workers/shared/message_bus.dart'
|
||||
show MessageBus, MessageBusSink, MessageBusSource;
|
||||
import 'package:angular2/src/core/zone/ng_zone.dart';
|
||||
import 'package:angular2/src/facade/lang.dart';
|
||||
import 'package:angular2/src/facade/exceptions.dart';
|
||||
|
||||
class GenericMessageBus implements MessageBus {
|
||||
final MessageBusSink _sink;
|
||||
final MessageBusSource _source;
|
||||
|
||||
MessageBusSink get sink => _sink;
|
||||
MessageBusSource get source => _source;
|
||||
|
||||
GenericMessageBus(MessageBusSink sink, MessageBusSource source)
|
||||
: _sink = sink,
|
||||
_source = source;
|
||||
|
||||
void attachToZone(NgZone zone) {
|
||||
_sink.attachToZone(zone);
|
||||
_source.attachToZone(zone);
|
||||
}
|
||||
|
||||
void initChannel(String channel, [bool runInZone = true]) {
|
||||
_sink.initChannel(channel, runInZone);
|
||||
_source.initChannel(channel, runInZone);
|
||||
}
|
||||
|
||||
EventEmitter from(String channel) {
|
||||
return _source.from(channel);
|
||||
}
|
||||
|
||||
EventEmitter to(String channel) {
|
||||
return _sink.to(channel);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class GenericMessageBusSink implements MessageBusSink {
|
||||
NgZone _zone;
|
||||
final _channels = new Map<String, _Channel>();
|
||||
final _messageBuffer = new List<dynamic>();
|
||||
|
||||
void attachToZone(NgZone zone) {
|
||||
_zone = zone;
|
||||
_zone.runOutsideAngular(() {
|
||||
_zone.onStable.listen((_) {
|
||||
if (_messageBuffer.length > 0) {
|
||||
sendMessages(_messageBuffer);
|
||||
_messageBuffer.clear();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void initChannel(String channelName, [bool runInZone = true]) {
|
||||
if (_channels.containsKey(channelName)) {
|
||||
throw new BaseException("${channelName} has already been initialized.");
|
||||
}
|
||||
|
||||
var emitter = new EventEmitter();
|
||||
var channel = new _Channel(emitter, runInZone);
|
||||
|
||||
emitter.listen((data) {
|
||||
var message = {'channel': channelName, 'message': data};
|
||||
if (runInZone) {
|
||||
_messageBuffer.add(message);
|
||||
} else {
|
||||
sendMessages([message]);
|
||||
}
|
||||
});
|
||||
|
||||
_channels[channelName] = channel;
|
||||
}
|
||||
|
||||
EventEmitter to(String channelName) {
|
||||
if (_channels.containsKey(channelName)) {
|
||||
return _channels[channelName].emitter;
|
||||
} else {
|
||||
throw new BaseException(
|
||||
"${channelName} is not set up. Did you forget to call initChannel?");
|
||||
}
|
||||
}
|
||||
|
||||
void sendMessages(List<dynamic> messages);
|
||||
}
|
||||
|
||||
abstract class GenericMessageBusSource implements MessageBusSource {
|
||||
Stream _stream;
|
||||
final _channels = new Map<String, _Channel>();
|
||||
NgZone _zone;
|
||||
|
||||
Stream get stream => _stream;
|
||||
|
||||
GenericMessageBusSource(Stream stream) {
|
||||
attachTo(stream);
|
||||
}
|
||||
|
||||
void attachTo(Stream stream) {
|
||||
_stream = stream;
|
||||
if (stream != null) {
|
||||
stream.listen((messages) {
|
||||
List<dynamic> decodedMessages = decodeMessages(messages);
|
||||
if (decodedMessages != null) {
|
||||
decodedMessages.forEach((message) => _handleMessage(message));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void attachToZone(NgZone zone) {
|
||||
_zone = zone;
|
||||
}
|
||||
|
||||
void initChannel(String channelName, [bool runInZone = true]) {
|
||||
if (_channels.containsKey(channelName)) {
|
||||
throw new BaseException("${channelName} has already been initialized.");
|
||||
}
|
||||
|
||||
var emitter = new EventEmitter();
|
||||
var channelInfo = new _Channel(emitter, runInZone);
|
||||
_channels[channelName] = channelInfo;
|
||||
}
|
||||
|
||||
EventEmitter from(String channelName) {
|
||||
if (_channels.containsKey(channelName)) {
|
||||
return _channels[channelName].emitter;
|
||||
} else {
|
||||
throw new BaseException(
|
||||
"${channelName} is not set up. Did you forget to call initChannel?");
|
||||
}
|
||||
}
|
||||
|
||||
void _handleMessage(dynamic data) {
|
||||
var channelName = data['channel'];
|
||||
if (_channels.containsKey(channelName)) {
|
||||
var channelInfo = _channels[channelName];
|
||||
if (channelInfo.runInZone) {
|
||||
_zone.run(() => channelInfo.emitter.add(data['message']));
|
||||
} else {
|
||||
channelInfo.emitter.add(data['message']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<dynamic> decodeMessages(dynamic message);
|
||||
}
|
||||
|
||||
class _Channel {
|
||||
EventEmitter emitter;
|
||||
bool runInZone;
|
||||
|
||||
_Channel(this.emitter, this.runInZone);
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
library angular2.src.web_workers.shared.isolate_message_bus;
|
||||
|
||||
import 'dart:isolate';
|
||||
import 'package:angular2/src/web_workers/shared/generic_message_bus.dart';
|
||||
|
||||
class IsolateMessageBus extends GenericMessageBus {
|
||||
IsolateMessageBus(IsolateMessageBusSink sink, IsolateMessageBusSource source)
|
||||
: super(sink, source);
|
||||
}
|
||||
|
||||
class IsolateMessageBusSink extends GenericMessageBusSink {
|
||||
final SendPort _port;
|
||||
|
||||
IsolateMessageBusSink(SendPort port) : _port = port;
|
||||
|
||||
@override
|
||||
void sendMessages(List<dynamic> messages) {
|
||||
_port.send(messages);
|
||||
}
|
||||
}
|
||||
|
||||
class IsolateMessageBusSource extends GenericMessageBusSource {
|
||||
IsolateMessageBusSource(ReceivePort port) : super(port.asBroadcastStream());
|
||||
|
||||
@override
|
||||
List<dynamic> decodeMessages(dynamic messages) {
|
||||
if (messages is SendPort) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return messages;
|
||||
}
|
||||
}
|
@ -5,3 +5,4 @@
|
||||
export const RENDERER_CHANNEL = "ng-Renderer";
|
||||
export const EVENT_CHANNEL = "ng-Events";
|
||||
export const ROUTER_CHANNEL = "ng-Router";
|
||||
export const XHR_CHANNEL = "ng-XHR";
|
||||
|
@ -1,3 +0,0 @@
|
||||
// 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;
|
@ -1,108 +0,0 @@
|
||||
library angular2.src.web_workers.event_serializer;
|
||||
|
||||
import 'dart:core';
|
||||
import 'dart:html';
|
||||
|
||||
// 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",
|
||||
"textarea"
|
||||
]);
|
||||
|
||||
Map<String, dynamic> serializeGenericEvent(dynamic e) {
|
||||
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 = serializeGenericEvent(e);
|
||||
return addTarget(e, serializedEvent);
|
||||
}
|
||||
|
||||
Map<String, dynamic> serializeMouseEvent(dynamic e) {
|
||||
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 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['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;
|
||||
}
|
||||
|
||||
Map<String, dynamic> serializeTransitionEvent(dynamic e) {
|
||||
var serialized = serializeGenericEvent(e);
|
||||
serialized['propertyName'] = e.propertyName;
|
||||
serialized['elapsedTime'] = e.elapsedTime;
|
||||
serialized['pseudoElement'] = e.pseudoElement;
|
||||
return addTarget(e, serialized);
|
||||
}
|
||||
|
||||
// TODO(jteplitz602): #3374. See above.
|
||||
Map<String, dynamic> addTarget(
|
||||
dynamic e, Map<String, dynamic> serializedEvent) {
|
||||
if (NODES_WITH_VALUE.contains(e.target.tagName.toLowerCase())) {
|
||||
serializedEvent['target'] = {'value': e.target.value};
|
||||
if (e.target is InputElement) {
|
||||
serializedEvent['target']['files'] = e.target.files;
|
||||
}
|
||||
}
|
||||
return serializedEvent;
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {PRIMITIVE} from '../shared/serializer';
|
||||
import {ServiceMessageBrokerFactory} from '../shared/service_message_broker';
|
||||
import {XHR_CHANNEL} from '../shared/messaging_api';
|
||||
import {XHR} from '@angular/compiler';
|
||||
import {FunctionWrapper} from '../../facade/lang';
|
||||
|
||||
/**
|
||||
* XHR requests triggered on the worker side are executed on the UI side.
|
||||
*
|
||||
* This is only strictly required for Dart where the isolates do not have access to XHRs.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
@Injectable()
|
||||
export class MessageBasedXHRImpl {
|
||||
constructor(private _brokerFactory: ServiceMessageBrokerFactory, private _xhr: XHR) {}
|
||||
|
||||
start(): void {
|
||||
var broker = this._brokerFactory.createMessageBroker(XHR_CHANNEL);
|
||||
broker.registerMethod("get", [PRIMITIVE], FunctionWrapper.bind(this._xhr.get, this._xhr),
|
||||
PRIMITIVE);
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
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');
|
||||
|
||||
String get propertyName => properties['propertyName'];
|
||||
num get elapsedTime => properties['elapsedTime'];
|
||||
String get pseudoElement => properties['pseudoElement'];
|
||||
|
||||
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);
|
||||
}
|
@ -1,390 +0,0 @@
|
||||
library angular2.dom.webWorkerAdapter;
|
||||
|
||||
import 'abstract_html_adapter.dart';
|
||||
import 'package:angular2/platform/common_dom.dart';
|
||||
|
||||
/**
|
||||
* This adapter is required to log error messages.
|
||||
*
|
||||
* Note: other methods all throw as the DOM is not accessible directly
|
||||
* in web worker context.
|
||||
*/
|
||||
class WebWorkerDomAdapter implements DomAdapter {
|
||||
static void makeCurrent() {
|
||||
setRootDomAdapter(new WebWorkerDomAdapter());
|
||||
}
|
||||
|
||||
logError(error) {
|
||||
print('${error}');
|
||||
}
|
||||
|
||||
log(error) {
|
||||
print('${error}');
|
||||
}
|
||||
|
||||
logGroup(error) {
|
||||
print('${error}');
|
||||
}
|
||||
|
||||
logGroupEnd() {}
|
||||
|
||||
hasProperty(element, String name) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
void setProperty(Element element, String name, Object value) =>
|
||||
throw 'not implemented';
|
||||
|
||||
getProperty(Element element, String name) => throw 'not implemented';
|
||||
|
||||
invoke(Element element, String methodName, List args) =>
|
||||
throw 'not implemented';
|
||||
|
||||
get attrToPropMap => throw 'not implemented';
|
||||
|
||||
set attrToPropMap(value) {
|
||||
throw 'readonly';
|
||||
}
|
||||
|
||||
getGlobalEventTarget(String target) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
getTitle() {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
setTitle(String newTitle) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
String getEventKey(event) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
void replaceChild(el, newNode, oldNode) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
dynamic getBoundingClientRect(el) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
Type getXHR() => throw 'not implemented';
|
||||
|
||||
Element parse(String templateHtml) => throw 'not implemented';
|
||||
query(selector) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
querySelector(el, String selector) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
List querySelectorAll(el, String selector) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
on(el, evt, listener) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
Function onAndCancel(el, evt, listener) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
dispatchEvent(el, evt) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
createMouseEvent(eventType) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
createEvent(eventType) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
preventDefault(evt) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
isPrevented(evt) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
getInnerHTML(el) => throw 'not implemented';
|
||||
|
||||
getOuterHTML(el) => throw 'not implemented';
|
||||
|
||||
String nodeName(node) => throw 'not implemented';
|
||||
|
||||
String nodeValue(node) => throw 'not implemented';
|
||||
|
||||
String type(node) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
content(node) => throw 'not implemented';
|
||||
|
||||
firstChild(el) => throw 'not implemented';
|
||||
|
||||
nextSibling(el) => throw 'not implemented';
|
||||
|
||||
parentElement(el) => throw 'not implemented';
|
||||
|
||||
List childNodes(el) => throw 'not implemented';
|
||||
List childNodesAsList(el) => throw 'not implemented';
|
||||
clearNodes(el) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
appendChild(el, node) => throw 'not implemented';
|
||||
removeChild(el, node) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
remove(el) => throw 'not implemented';
|
||||
insertBefore(el, node) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
insertAllBefore(el, nodes) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
insertAfter(el, node) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
setInnerHTML(el, value) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
getText(el) => throw 'not implemented';
|
||||
|
||||
setText(el, String value) => throw 'not implemented';
|
||||
|
||||
getValue(el) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
setValue(el, String value) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
getChecked(el) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
setChecked(el, bool value) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
createComment(String text) => throw 'not implemented';
|
||||
createTemplate(String html) => throw 'not implemented';
|
||||
createElement(tagName, [doc]) => throw 'not implemented';
|
||||
|
||||
createElementNS(ns, tagName, [doc]) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
createTextNode(String text, [doc]) => throw 'not implemented';
|
||||
|
||||
createScriptTag(String attrName, String attrValue, [doc]) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
createStyleElement(String css, [doc]) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
createShadowRoot(el) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
getShadowRoot(el) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
getHost(el) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
clone(node) => throw 'not implemented';
|
||||
getElementsByClassName(element, String name) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
getElementsByTagName(element, String name) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
List classList(element) => throw 'not implemented';
|
||||
|
||||
addClass(element, String className) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
removeClass(element, String className) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
hasClass(element, String className) => throw 'not implemented';
|
||||
|
||||
setStyle(element, String styleName, String styleValue) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
bool hasStyle(Element element, String styleName, [String styleValue]) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
removeStyle(element, String styleName) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
getStyle(element, String styleName) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
String tagName(element) => throw 'not implemented';
|
||||
|
||||
attributeMap(element) => throw 'not implemented';
|
||||
|
||||
hasAttribute(element, String attribute) => throw 'not implemented';
|
||||
|
||||
hasAttributeNS(element, String ns, String attribute) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
getAttribute(element, String attribute) => throw 'not implemented';
|
||||
|
||||
getAttributeNS(element, String ns, String attribute) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
setAttribute(element, String name, String value) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
setAttributeNS(element, String ns, String name, String value) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
removeAttribute(element, String attribute) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
removeAttributeNS(element, String ns, String attribute) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
templateAwareRoot(el) => throw 'not implemented';
|
||||
|
||||
createHtmlDocument() {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
defaultDoc() {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
bool elementMatches(n, String selector) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
bool isTemplateElement(Element el) => throw 'not implemented';
|
||||
|
||||
bool isTextNode(node) => throw 'not implemented';
|
||||
bool isCommentNode(node) => throw 'not implemented';
|
||||
|
||||
bool isElementNode(node) => throw 'not implemented';
|
||||
|
||||
bool hasShadowRoot(node) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
bool isShadowRoot(node) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
importIntoDoc(node) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
adoptNode(node) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
String getHref(element) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
void resolveAndSetHref(element, baseUrl, href) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
List getDistributedNodes(Node) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
bool supportsDOMEvents() => throw 'not implemented';
|
||||
|
||||
bool supportsNativeShadowDOM() => throw 'not implemented';
|
||||
|
||||
getHistory() => throw 'not implemented';
|
||||
|
||||
getLocation() {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
getBaseHref() {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
resetBaseElement() {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
String getUserAgent() => throw 'not implemented';
|
||||
|
||||
void setData(Element element, String name, String value) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
getComputedStyle(element) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
String getData(Element element, String name) => throw 'not implemented';
|
||||
|
||||
// TODO(tbosch): move this into a separate environment class once we have it
|
||||
setGlobalVar(String name, value) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
requestAnimationFrame(callback) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
cancelAnimationFrame(id) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
performanceNow() {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
getAnimationPrefix() {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
getTransitionEnd() {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
supportsAnimation() {
|
||||
throw 'not implemented';
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {XHR} from '@angular/compiler';
|
||||
import {
|
||||
FnArg,
|
||||
UiArguments,
|
||||
ClientMessageBroker,
|
||||
ClientMessageBrokerFactory
|
||||
} from '../shared/client_message_broker';
|
||||
import {XHR_CHANNEL} from '../shared/messaging_api';
|
||||
|
||||
/**
|
||||
* Implementation of compiler/xhr that relays XHR requests to the UI side where they are sent
|
||||
* and the result is proxied back to the worker.
|
||||
*
|
||||
* This is only strictly required for Dart where isolates do not have access to the XHRs.
|
||||
*/
|
||||
@Injectable()
|
||||
export class WebWorkerXHRImpl extends XHR {
|
||||
private _messageBroker: ClientMessageBroker;
|
||||
|
||||
constructor(messageBrokerFactory: ClientMessageBrokerFactory) {
|
||||
super();
|
||||
this._messageBroker = messageBrokerFactory.createMessageBroker(XHR_CHANNEL);
|
||||
}
|
||||
|
||||
get(url: string): Promise<string> {
|
||||
var fnArgs: FnArg[] = [new FnArg(url, null)];
|
||||
var args: UiArguments = new UiArguments("get", fnArgs);
|
||||
return this._messageBroker.runOnService(args, String);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user