mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 08:51:21 +00:00
Remove proxying support from dart:html
I'm moving this functionality to a user-level library. Review URL: https://chromiumcodereview.appspot.com//10914129 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@11997 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
2561dd7544
commit
37b7e470e4
194
client/dart.js
194
client/dart.js
|
@ -46,12 +46,13 @@ function ReceivePortSync() {
|
|||
}
|
||||
|
||||
(function() {
|
||||
// Serialize:
|
||||
// Serialize the following types as follows:
|
||||
// - primitives / null: unchanged
|
||||
// - lists: [ 'list', id, list of recursively serialized elements ]
|
||||
// - maps: [ 'map', id, map of keys and recursively serialized values ]
|
||||
// - functions: [ 'funcref', function-proxy-id, function-proxy-send-port ]
|
||||
// - objects: [ 'objref', object-proxy-id, object-proxy-send-port ]
|
||||
// - lists: [ 'list', internal id, list of recursively serialized elements ]
|
||||
// - maps: [ 'map', internal id, map of keys and recursively serialized values ]
|
||||
// - send ports: [ 'sendport', type, isolate id, port id ]
|
||||
//
|
||||
// Note, internal id's are for cycle detection.
|
||||
function serialize(message) {
|
||||
var visited = [];
|
||||
function checkedSerialization(obj, serializer) {
|
||||
|
@ -85,27 +86,6 @@ function ReceivePortSync() {
|
|||
return [ 'sendport', 'nativejs', message.receivePort.id ];
|
||||
} else if (message instanceof DartSendPortSync) {
|
||||
return [ 'sendport', 'dart', message.isolateId, message.portId ];
|
||||
} else if (message instanceof Function) {
|
||||
// In case we are reserializing a previously serialized
|
||||
// function, use a cached value.
|
||||
if (message._dart_serialized) return message._dart_serialized;
|
||||
message._dart_serialized = [ 'funcref',
|
||||
functionRefTable.makeRef(message),
|
||||
doSerialize(functionRefTable.sendPort) ];
|
||||
return message._dart_serialized;
|
||||
} else if (message instanceof HTMLElement) {
|
||||
var id = elementId(message);
|
||||
// Verify that the element is connected to the document.
|
||||
// Otherwise, we will not be able to find it on the other side.
|
||||
getElement(id);
|
||||
return [ 'element', id ];
|
||||
} else if (message instanceof DartProxy) {
|
||||
return [ 'objref', message._id, doSerialize(message._port) ];
|
||||
} else if (message.__proto__ != {}.__proto__) {
|
||||
// TODO(vsm): Is the above portable and what we want?
|
||||
// Proxy non-map Objects.
|
||||
return [ 'objref', jsRefTable.makeRef(message),
|
||||
doSerialize(jsRefTable.sendPort) ];
|
||||
} else {
|
||||
return checkedSerialization(message, function(id) {
|
||||
var keys = Object.getOwnPropertyNames(message);
|
||||
|
@ -135,9 +115,6 @@ function ReceivePortSync() {
|
|||
case 'map': return deserializeMap(message);
|
||||
case 'sendport': return deserializeSendPort(message);
|
||||
case 'list': return deserializeList(message);
|
||||
case 'funcref': return deserializeFunction(message);
|
||||
case 'objref': return deserializeProxy(message);
|
||||
case 'element': return deserializeElement(message);
|
||||
default: throw 'unimplemented';
|
||||
}
|
||||
}
|
||||
|
@ -180,33 +157,6 @@ function ReceivePortSync() {
|
|||
return result;
|
||||
}
|
||||
|
||||
function deserializeFunction(message) {
|
||||
var ref = message[1];
|
||||
var sendPort = deserializeSendPort(message[2]);
|
||||
// Number of arguments is not used as of now
|
||||
// we cannot find it out for Dart function in pure Dart.
|
||||
var result = _makeFunctionFromRef(ref, sendPort);
|
||||
// Cache the serialized form in case we resend this.
|
||||
result._dart_serialized = message;
|
||||
return result;
|
||||
}
|
||||
|
||||
function deserializeProxy(message) {
|
||||
var id = message[1];
|
||||
var port = deserializeSendPort(message[2]);
|
||||
if (port instanceof LocalSendPortSync) {
|
||||
return jsRefTable.map[id];
|
||||
} else if (port instanceof DartSendPortSync) {
|
||||
return new DartProxy(port, id);
|
||||
}
|
||||
throw 'Illegal proxy object: ' + message;
|
||||
}
|
||||
|
||||
function deserializeElement(message) {
|
||||
var id = message[1];
|
||||
return getElement(id);
|
||||
}
|
||||
|
||||
window.registerPort = function(name, port) {
|
||||
var stringified = JSON.stringify(serialize(port));
|
||||
window.localStorage['dart-port:' + name] = stringified;
|
||||
|
@ -290,136 +240,4 @@ function ReceivePortSync() {
|
|||
window.removeEventListener(source, listener, false);
|
||||
return deserialize(result);
|
||||
}
|
||||
|
||||
// Proxy support
|
||||
|
||||
function RefTable(name) {
|
||||
// TODO(vsm): Fix leaks, particularly in dart2js case.
|
||||
this.name = name;
|
||||
this.map = {};
|
||||
this.id = 0;
|
||||
this.initialized = false;
|
||||
this.port = new ReceivePortSync();
|
||||
this.sendPort = this.port.toSendPort();
|
||||
}
|
||||
|
||||
RefTable.prototype.nextId = function () { return this.id++; }
|
||||
|
||||
RefTable.prototype.makeRef = function (obj) {
|
||||
this.initializeOnce();
|
||||
// TODO(vsm): Cache refs for each obj.
|
||||
var ref = this.name + '-' + this.nextId();
|
||||
this.map[ref] = obj;
|
||||
return ref;
|
||||
}
|
||||
|
||||
RefTable.prototype.initializeOnce = function () {
|
||||
if (!this.initialized) {
|
||||
this.initialize();
|
||||
}
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
// Overridable initialization on first use hook.
|
||||
RefTable.prototype.initialize = function () {}
|
||||
|
||||
RefTable.prototype.get = function (ref) {
|
||||
return this.map[ref];
|
||||
}
|
||||
|
||||
function FunctionRefTable() {}
|
||||
|
||||
FunctionRefTable.prototype = new RefTable('func-ref');
|
||||
|
||||
FunctionRefTable.prototype.initialize = function () {
|
||||
var map = this.map;
|
||||
this.port.receive(function (message) {
|
||||
var id = message[0];
|
||||
var args = message[1];
|
||||
var f = map[id];
|
||||
// TODO(vsm): Should we capture this automatically?
|
||||
return f.apply(null, args);
|
||||
});
|
||||
}
|
||||
|
||||
var functionRefTable = new FunctionRefTable();
|
||||
|
||||
function JSRefTable() {}
|
||||
|
||||
JSRefTable.prototype = new RefTable('js-ref');
|
||||
|
||||
JSRefTable.prototype.initialize = function () {
|
||||
var map = this.map;
|
||||
this.port.receive(function (message) {
|
||||
// TODO(vsm): Support a mechanism to register a handler here.
|
||||
var receiver = map[message[0]];
|
||||
var method = message[1];
|
||||
var args = message[2];
|
||||
if (method.indexOf("get:") == 0) {
|
||||
// Getter.
|
||||
var field = method.substring(4);
|
||||
if (field in receiver && args.length == 0) {
|
||||
return [ 'return', receiver[field] ];
|
||||
}
|
||||
} else if (method.indexOf("set:") == 0) {
|
||||
// Setter.
|
||||
var field = method.substring(4);
|
||||
if (field in receiver && args.length == 1) {
|
||||
return [ 'return', receiver[field] = args[0] ];
|
||||
}
|
||||
} else {
|
||||
var f = receiver[method];
|
||||
if (f) {
|
||||
try {
|
||||
var result = f.apply(receiver, args);
|
||||
return [ 'return', result ];
|
||||
} catch (e) {
|
||||
return [ 'exception', e ];
|
||||
}
|
||||
}
|
||||
}
|
||||
return [ 'none' ];
|
||||
});
|
||||
}
|
||||
|
||||
var jsRefTable = new JSRefTable();
|
||||
|
||||
function DartProxy(port, id) {
|
||||
this._port = port;
|
||||
this._id = id;
|
||||
}
|
||||
|
||||
// Leaking implementation.
|
||||
// TODO(vsm): provide proper, backend-specific implementation.
|
||||
function _makeFunctionFromRef(ref, sendPort) {
|
||||
// If the sendPort is local, just return the underlying function.
|
||||
// Otherwise, create a new function that forwards to the remote
|
||||
// port.
|
||||
if (sendPort instanceof LocalSendPortSync) {
|
||||
return functionRefTable.map[ref];
|
||||
}
|
||||
return function() {
|
||||
return sendPort.callSync([ref, Array.prototype.slice.call(arguments)]);
|
||||
};
|
||||
}
|
||||
|
||||
var localNextElementId = 0;
|
||||
var _DART_ID = 'data-dart_id';
|
||||
|
||||
function elementId(e) {
|
||||
if (e.hasAttribute(_DART_ID)) return e.getAttribute(_DART_ID);
|
||||
var id = (localNextElementId++).toString();
|
||||
e.setAttribute(_DART_ID, id);
|
||||
return id;
|
||||
}
|
||||
|
||||
function getElement(id) {
|
||||
var list = document.querySelectorAll('[' + _DART_ID + '="' + id + '"]');
|
||||
|
||||
if (list.length > 1) throw 'Non unique ID: ' + id;
|
||||
if (list.length == 0) {
|
||||
throw 'Element must be attached to the document: ' + id;
|
||||
}
|
||||
return list[0];
|
||||
}
|
||||
})();
|
||||
|
|
|
@ -37910,43 +37910,6 @@ _serialize(var message) {
|
|||
return new _JsSerializer().traverse(message);
|
||||
}
|
||||
|
||||
class JsProxy {
|
||||
SendPortSync _port;
|
||||
final _id;
|
||||
|
||||
JsProxy._internal(this._port, this._id);
|
||||
|
||||
noSuchMethod(method, args) {
|
||||
var result = _port.callSync([_id, method, args]);
|
||||
switch (result[0]) {
|
||||
case 'return': return result[1];
|
||||
case 'exception': throw result[1];
|
||||
case 'none': throw new NoSuchMethodException(this, method, args);
|
||||
default: throw 'Invalid return value';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int _localNextElementId = 0;
|
||||
|
||||
const _DART_ID = 'data-dart_id';
|
||||
|
||||
_elementId(Element e) {
|
||||
if (e.attributes.containsKey(_DART_ID)) return e.attributes[_DART_ID];
|
||||
var id = '$_isolateId-${_localNextElementId++}';
|
||||
e.attributes[_DART_ID] = id;
|
||||
return id;
|
||||
}
|
||||
|
||||
Element _getElement(var id) {
|
||||
var list = queryAll('[$_DART_ID="$id"]');
|
||||
if (list.length > 1) throw 'Non unique ID: $id';
|
||||
if (list.length == 0) {
|
||||
throw 'Only elements attached to document can be serialized: $id';
|
||||
}
|
||||
return list[0];
|
||||
}
|
||||
|
||||
class _JsSerializer extends _Serializer {
|
||||
|
||||
visitSendPortSync(SendPortSync x) {
|
||||
|
@ -37969,147 +37932,12 @@ class _JsSerializer extends _Serializer {
|
|||
return [ 'sendport', 'dart',
|
||||
x._receivePort._isolateId, x._receivePort._portId ];
|
||||
}
|
||||
|
||||
visitObject(Object x) {
|
||||
if (x is Function) return visitFunction(x);
|
||||
if (x is JsProxy) return visitJsProxy(x);
|
||||
if (x is Element) return visitElement(x);
|
||||
|
||||
// TODO: Handle DOM elements and proxy other objects.
|
||||
var proxyId = _dartProxyRegistry._add(x);
|
||||
return [ 'objref', proxyId,
|
||||
visitSendPortSync(_dartProxyRegistry._sendPort) ];
|
||||
}
|
||||
|
||||
visitFunction(Function func) {
|
||||
// Look for a cached serialization first. The cached version
|
||||
// should point to the original port.
|
||||
var serialized = _deserializedFunctionTable.find(func);
|
||||
if (serialized != null) return serialized;
|
||||
// Create a new serialization forwarding to this port.
|
||||
return [ 'funcref',
|
||||
_functionRegistry._add(func),
|
||||
visitSendPortSync(_functionRegistry._sendPort), null ];
|
||||
}
|
||||
|
||||
visitJsProxy(JsProxy proxy) {
|
||||
return [ 'objref', proxy._id, visitSendPortSync(proxy._port) ];
|
||||
}
|
||||
|
||||
visitElement(Element element) {
|
||||
var id = _elementId(element);
|
||||
// Verify that the element is connected to the document.
|
||||
// Otherwise, we will not be able to find it on the other side.
|
||||
_getElement(id);
|
||||
return [ 'element', id ];
|
||||
}
|
||||
}
|
||||
|
||||
// Leaking implementation. Later will be backend specific and hopefully
|
||||
// not leaking (at least in most of the cases.)
|
||||
// TODO: provide better, backend specific implementation.
|
||||
class _Registry<T> {
|
||||
final String _name;
|
||||
int _nextId;
|
||||
final Map<String, T> _registry;
|
||||
final ReceivePortSync _port;
|
||||
|
||||
_Registry(this._name) :
|
||||
_nextId = 0,
|
||||
_registry = <T>{},
|
||||
_port = new ReceivePortSync();
|
||||
|
||||
String _add(T x) {
|
||||
// TODO(vsm): Cache x and reuse id.
|
||||
final id = '$_name-${_nextId++}';
|
||||
_registry[id] = x;
|
||||
return id;
|
||||
}
|
||||
|
||||
T _get(String id) {
|
||||
return _registry[id];
|
||||
}
|
||||
|
||||
get _sendPort => _port.toSendPort();
|
||||
}
|
||||
|
||||
class _FunctionRegistry extends _Registry<Function> {
|
||||
_FunctionRegistry() : super('func-ref') {
|
||||
_port.receive((msg) {
|
||||
final id = msg[0];
|
||||
final args = msg[1];
|
||||
final f = _registry[id];
|
||||
switch (args.length) {
|
||||
case 0: return f();
|
||||
case 1: return f(args[0]);
|
||||
case 2: return f(args[0], args[1]);
|
||||
case 3: return f(args[0], args[1], args[2]);
|
||||
case 4: return f(args[0], args[1], args[2], args[3]);
|
||||
default: throw 'Unsupported number of arguments.';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_FunctionRegistry __functionRegistry;
|
||||
get _functionRegistry {
|
||||
if (__functionRegistry === null) __functionRegistry = new _FunctionRegistry();
|
||||
return __functionRegistry;
|
||||
}
|
||||
/// End of function serialization implementation.
|
||||
|
||||
/// Object proxy implementation.
|
||||
|
||||
class _DartProxyRegistry extends _Registry<Object> {
|
||||
_DartProxyRegistry() : super('dart-ref') {
|
||||
_port.receive((msg) {
|
||||
// TODO(vsm): Support a mechanism to register a handler here.
|
||||
throw 'Invocation unsupported on Dart proxies';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_DartProxyRegistry __dartProxyRegistry;
|
||||
get _dartProxyRegistry {
|
||||
if (__dartProxyRegistry === null) {
|
||||
__dartProxyRegistry = new _DartProxyRegistry();
|
||||
}
|
||||
return __dartProxyRegistry;
|
||||
}
|
||||
|
||||
/// End of object proxy implementation.
|
||||
|
||||
_deserialize(var message) {
|
||||
return new _JsDeserializer().deserialize(message);
|
||||
}
|
||||
|
||||
// TODO(vsm): Replace this with a hash map once functions are
|
||||
// hashable.
|
||||
class _DeserializedFunctionTable {
|
||||
List data;
|
||||
_DeserializedFunctionTable() {
|
||||
data = [];
|
||||
}
|
||||
|
||||
find(Function f) {
|
||||
for (var item in data) {
|
||||
if (f == item[0]) return item[1];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
add(Function f, x) {
|
||||
data.add([f, x]);
|
||||
}
|
||||
}
|
||||
|
||||
_DeserializedFunctionTable __deserializedFunctionTable = null;
|
||||
get _deserializedFunctionTable {
|
||||
if (__deserializedFunctionTable == null) {
|
||||
__deserializedFunctionTable = new _DeserializedFunctionTable();
|
||||
}
|
||||
return __deserializedFunctionTable;
|
||||
}
|
||||
|
||||
class _JsDeserializer extends _Deserializer {
|
||||
|
||||
|
@ -38129,53 +37957,6 @@ class _JsDeserializer extends _Deserializer {
|
|||
throw 'Illegal SendPortSync type: $tag';
|
||||
}
|
||||
}
|
||||
|
||||
deserializeObject(List x) {
|
||||
String tag = x[0];
|
||||
switch (tag) {
|
||||
case 'funcref': return deserializeFunction(x);
|
||||
case 'objref': return deserializeProxy(x);
|
||||
case 'element': return deserializeElement(x);
|
||||
default: throw 'Illegal object type: $x';
|
||||
}
|
||||
}
|
||||
|
||||
deserializeFunction(List x) {
|
||||
var id = x[1];
|
||||
// If the sendPort is local, just return the underlying function.
|
||||
// Otherwise, create a new function that forwards to the remote
|
||||
// port.
|
||||
SendPortSync port = deserializeSendPort(x[2]);
|
||||
if (port is _LocalSendPortSync) {
|
||||
return _functionRegistry._get(id);
|
||||
}
|
||||
// TODO: Support varargs when there is support in the language.
|
||||
var f = ([arg0 = _UNSPECIFIED, arg1 = _UNSPECIFIED,
|
||||
arg2 = _UNSPECIFIED, arg3 = _UNSPECIFIED]) {
|
||||
var args = [arg0, arg1, arg2, arg3];
|
||||
var last = args.indexOf(_UNSPECIFIED);
|
||||
if (last >= 0) args = args.getRange(0, last);
|
||||
var message = [id, args];
|
||||
return port.callSync(message);
|
||||
};
|
||||
_deserializedFunctionTable.add(f, x);
|
||||
return f;
|
||||
}
|
||||
|
||||
deserializeProxy(x) {
|
||||
var id = x[1];
|
||||
var port = deserializeSendPort(x[2]);
|
||||
if (port is _JsSendPortSync) return new JsProxy._internal(port, id);
|
||||
if (port is _LocalSendPortSync) return _dartProxyRegistry._get(id);
|
||||
// TODO(vsm): Support this case.
|
||||
if (port is _RemoteSendPortSync) throw 'Remote Dart proxies unsupported';
|
||||
throw 'Illegal proxy: $port';
|
||||
}
|
||||
|
||||
deserializeElement(x) {
|
||||
var id = x[1];
|
||||
return _getElement(id);
|
||||
}
|
||||
}
|
||||
|
||||
// The receiver is JS.
|
||||
|
|
|
@ -40943,43 +40943,6 @@ _serialize(var message) {
|
|||
return new _JsSerializer().traverse(message);
|
||||
}
|
||||
|
||||
class JsProxy {
|
||||
SendPortSync _port;
|
||||
final _id;
|
||||
|
||||
JsProxy._internal(this._port, this._id);
|
||||
|
||||
noSuchMethod(method, args) {
|
||||
var result = _port.callSync([_id, method, args]);
|
||||
switch (result[0]) {
|
||||
case 'return': return result[1];
|
||||
case 'exception': throw result[1];
|
||||
case 'none': throw new NoSuchMethodException(this, method, args);
|
||||
default: throw 'Invalid return value';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int _localNextElementId = 0;
|
||||
|
||||
const _DART_ID = 'data-dart_id';
|
||||
|
||||
_elementId(Element e) {
|
||||
if (e.attributes.containsKey(_DART_ID)) return e.attributes[_DART_ID];
|
||||
var id = '$_isolateId-${_localNextElementId++}';
|
||||
e.attributes[_DART_ID] = id;
|
||||
return id;
|
||||
}
|
||||
|
||||
Element _getElement(var id) {
|
||||
var list = queryAll('[$_DART_ID="$id"]');
|
||||
if (list.length > 1) throw 'Non unique ID: $id';
|
||||
if (list.length == 0) {
|
||||
throw 'Only elements attached to document can be serialized: $id';
|
||||
}
|
||||
return list[0];
|
||||
}
|
||||
|
||||
class _JsSerializer extends _Serializer {
|
||||
|
||||
visitSendPortSync(SendPortSync x) {
|
||||
|
@ -41002,147 +40965,12 @@ class _JsSerializer extends _Serializer {
|
|||
return [ 'sendport', 'dart',
|
||||
x._receivePort._isolateId, x._receivePort._portId ];
|
||||
}
|
||||
|
||||
visitObject(Object x) {
|
||||
if (x is Function) return visitFunction(x);
|
||||
if (x is JsProxy) return visitJsProxy(x);
|
||||
if (x is Element) return visitElement(x);
|
||||
|
||||
// TODO: Handle DOM elements and proxy other objects.
|
||||
var proxyId = _dartProxyRegistry._add(x);
|
||||
return [ 'objref', proxyId,
|
||||
visitSendPortSync(_dartProxyRegistry._sendPort) ];
|
||||
}
|
||||
|
||||
visitFunction(Function func) {
|
||||
// Look for a cached serialization first. The cached version
|
||||
// should point to the original port.
|
||||
var serialized = _deserializedFunctionTable.find(func);
|
||||
if (serialized != null) return serialized;
|
||||
// Create a new serialization forwarding to this port.
|
||||
return [ 'funcref',
|
||||
_functionRegistry._add(func),
|
||||
visitSendPortSync(_functionRegistry._sendPort), null ];
|
||||
}
|
||||
|
||||
visitJsProxy(JsProxy proxy) {
|
||||
return [ 'objref', proxy._id, visitSendPortSync(proxy._port) ];
|
||||
}
|
||||
|
||||
visitElement(Element element) {
|
||||
var id = _elementId(element);
|
||||
// Verify that the element is connected to the document.
|
||||
// Otherwise, we will not be able to find it on the other side.
|
||||
_getElement(id);
|
||||
return [ 'element', id ];
|
||||
}
|
||||
}
|
||||
|
||||
// Leaking implementation. Later will be backend specific and hopefully
|
||||
// not leaking (at least in most of the cases.)
|
||||
// TODO: provide better, backend specific implementation.
|
||||
class _Registry<T> {
|
||||
final String _name;
|
||||
int _nextId;
|
||||
final Map<String, T> _registry;
|
||||
final ReceivePortSync _port;
|
||||
|
||||
_Registry(this._name) :
|
||||
_nextId = 0,
|
||||
_registry = <T>{},
|
||||
_port = new ReceivePortSync();
|
||||
|
||||
String _add(T x) {
|
||||
// TODO(vsm): Cache x and reuse id.
|
||||
final id = '$_name-${_nextId++}';
|
||||
_registry[id] = x;
|
||||
return id;
|
||||
}
|
||||
|
||||
T _get(String id) {
|
||||
return _registry[id];
|
||||
}
|
||||
|
||||
get _sendPort => _port.toSendPort();
|
||||
}
|
||||
|
||||
class _FunctionRegistry extends _Registry<Function> {
|
||||
_FunctionRegistry() : super('func-ref') {
|
||||
_port.receive((msg) {
|
||||
final id = msg[0];
|
||||
final args = msg[1];
|
||||
final f = _registry[id];
|
||||
switch (args.length) {
|
||||
case 0: return f();
|
||||
case 1: return f(args[0]);
|
||||
case 2: return f(args[0], args[1]);
|
||||
case 3: return f(args[0], args[1], args[2]);
|
||||
case 4: return f(args[0], args[1], args[2], args[3]);
|
||||
default: throw 'Unsupported number of arguments.';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_FunctionRegistry __functionRegistry;
|
||||
get _functionRegistry {
|
||||
if (__functionRegistry === null) __functionRegistry = new _FunctionRegistry();
|
||||
return __functionRegistry;
|
||||
}
|
||||
/// End of function serialization implementation.
|
||||
|
||||
/// Object proxy implementation.
|
||||
|
||||
class _DartProxyRegistry extends _Registry<Object> {
|
||||
_DartProxyRegistry() : super('dart-ref') {
|
||||
_port.receive((msg) {
|
||||
// TODO(vsm): Support a mechanism to register a handler here.
|
||||
throw 'Invocation unsupported on Dart proxies';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_DartProxyRegistry __dartProxyRegistry;
|
||||
get _dartProxyRegistry {
|
||||
if (__dartProxyRegistry === null) {
|
||||
__dartProxyRegistry = new _DartProxyRegistry();
|
||||
}
|
||||
return __dartProxyRegistry;
|
||||
}
|
||||
|
||||
/// End of object proxy implementation.
|
||||
|
||||
_deserialize(var message) {
|
||||
return new _JsDeserializer().deserialize(message);
|
||||
}
|
||||
|
||||
// TODO(vsm): Replace this with a hash map once functions are
|
||||
// hashable.
|
||||
class _DeserializedFunctionTable {
|
||||
List data;
|
||||
_DeserializedFunctionTable() {
|
||||
data = [];
|
||||
}
|
||||
|
||||
find(Function f) {
|
||||
for (var item in data) {
|
||||
if (f == item[0]) return item[1];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
add(Function f, x) {
|
||||
data.add([f, x]);
|
||||
}
|
||||
}
|
||||
|
||||
_DeserializedFunctionTable __deserializedFunctionTable = null;
|
||||
get _deserializedFunctionTable {
|
||||
if (__deserializedFunctionTable == null) {
|
||||
__deserializedFunctionTable = new _DeserializedFunctionTable();
|
||||
}
|
||||
return __deserializedFunctionTable;
|
||||
}
|
||||
|
||||
class _JsDeserializer extends _Deserializer {
|
||||
|
||||
|
@ -41162,53 +40990,6 @@ class _JsDeserializer extends _Deserializer {
|
|||
throw 'Illegal SendPortSync type: $tag';
|
||||
}
|
||||
}
|
||||
|
||||
deserializeObject(List x) {
|
||||
String tag = x[0];
|
||||
switch (tag) {
|
||||
case 'funcref': return deserializeFunction(x);
|
||||
case 'objref': return deserializeProxy(x);
|
||||
case 'element': return deserializeElement(x);
|
||||
default: throw 'Illegal object type: $x';
|
||||
}
|
||||
}
|
||||
|
||||
deserializeFunction(List x) {
|
||||
var id = x[1];
|
||||
// If the sendPort is local, just return the underlying function.
|
||||
// Otherwise, create a new function that forwards to the remote
|
||||
// port.
|
||||
SendPortSync port = deserializeSendPort(x[2]);
|
||||
if (port is _LocalSendPortSync) {
|
||||
return _functionRegistry._get(id);
|
||||
}
|
||||
// TODO: Support varargs when there is support in the language.
|
||||
var f = ([arg0 = _UNSPECIFIED, arg1 = _UNSPECIFIED,
|
||||
arg2 = _UNSPECIFIED, arg3 = _UNSPECIFIED]) {
|
||||
var args = [arg0, arg1, arg2, arg3];
|
||||
var last = args.indexOf(_UNSPECIFIED);
|
||||
if (last >= 0) args = args.getRange(0, last);
|
||||
var message = [id, args];
|
||||
return port.callSync(message);
|
||||
};
|
||||
_deserializedFunctionTable.add(f, x);
|
||||
return f;
|
||||
}
|
||||
|
||||
deserializeProxy(x) {
|
||||
var id = x[1];
|
||||
var port = deserializeSendPort(x[2]);
|
||||
if (port is _JsSendPortSync) return new JsProxy._internal(port, id);
|
||||
if (port is _LocalSendPortSync) return _dartProxyRegistry._get(id);
|
||||
// TODO(vsm): Support this case.
|
||||
if (port is _RemoteSendPortSync) throw 'Remote Dart proxies unsupported';
|
||||
throw 'Illegal proxy: $port';
|
||||
}
|
||||
|
||||
deserializeElement(x) {
|
||||
var id = x[1];
|
||||
return _getElement(id);
|
||||
}
|
||||
}
|
||||
|
||||
// The receiver is JS.
|
||||
|
|
|
@ -6,43 +6,6 @@ _serialize(var message) {
|
|||
return new _JsSerializer().traverse(message);
|
||||
}
|
||||
|
||||
class JsProxy {
|
||||
SendPortSync _port;
|
||||
final _id;
|
||||
|
||||
JsProxy._internal(this._port, this._id);
|
||||
|
||||
noSuchMethod(method, args) {
|
||||
var result = _port.callSync([_id, method, args]);
|
||||
switch (result[0]) {
|
||||
case 'return': return result[1];
|
||||
case 'exception': throw result[1];
|
||||
case 'none': throw new NoSuchMethodException(this, method, args);
|
||||
default: throw 'Invalid return value';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int _localNextElementId = 0;
|
||||
|
||||
const _DART_ID = 'data-dart_id';
|
||||
|
||||
_elementId(Element e) {
|
||||
if (e.attributes.containsKey(_DART_ID)) return e.attributes[_DART_ID];
|
||||
var id = '$_isolateId-${_localNextElementId++}';
|
||||
e.attributes[_DART_ID] = id;
|
||||
return id;
|
||||
}
|
||||
|
||||
Element _getElement(var id) {
|
||||
var list = queryAll('[$_DART_ID="$id"]');
|
||||
if (list.length > 1) throw 'Non unique ID: $id';
|
||||
if (list.length == 0) {
|
||||
throw 'Only elements attached to document can be serialized: $id';
|
||||
}
|
||||
return list[0];
|
||||
}
|
||||
|
||||
class _JsSerializer extends _Serializer {
|
||||
|
||||
visitSendPortSync(SendPortSync x) {
|
||||
|
@ -65,147 +28,12 @@ class _JsSerializer extends _Serializer {
|
|||
return [ 'sendport', 'dart',
|
||||
x._receivePort._isolateId, x._receivePort._portId ];
|
||||
}
|
||||
|
||||
visitObject(Object x) {
|
||||
if (x is Function) return visitFunction(x);
|
||||
if (x is JsProxy) return visitJsProxy(x);
|
||||
if (x is Element) return visitElement(x);
|
||||
|
||||
// TODO: Handle DOM elements and proxy other objects.
|
||||
var proxyId = _dartProxyRegistry._add(x);
|
||||
return [ 'objref', proxyId,
|
||||
visitSendPortSync(_dartProxyRegistry._sendPort) ];
|
||||
}
|
||||
|
||||
visitFunction(Function func) {
|
||||
// Look for a cached serialization first. The cached version
|
||||
// should point to the original port.
|
||||
var serialized = _deserializedFunctionTable.find(func);
|
||||
if (serialized != null) return serialized;
|
||||
// Create a new serialization forwarding to this port.
|
||||
return [ 'funcref',
|
||||
_functionRegistry._add(func),
|
||||
visitSendPortSync(_functionRegistry._sendPort), null ];
|
||||
}
|
||||
|
||||
visitJsProxy(JsProxy proxy) {
|
||||
return [ 'objref', proxy._id, visitSendPortSync(proxy._port) ];
|
||||
}
|
||||
|
||||
visitElement(Element element) {
|
||||
var id = _elementId(element);
|
||||
// Verify that the element is connected to the document.
|
||||
// Otherwise, we will not be able to find it on the other side.
|
||||
_getElement(id);
|
||||
return [ 'element', id ];
|
||||
}
|
||||
}
|
||||
|
||||
// Leaking implementation. Later will be backend specific and hopefully
|
||||
// not leaking (at least in most of the cases.)
|
||||
// TODO: provide better, backend specific implementation.
|
||||
class _Registry<T> {
|
||||
final String _name;
|
||||
int _nextId;
|
||||
final Map<String, T> _registry;
|
||||
final ReceivePortSync _port;
|
||||
|
||||
_Registry(this._name) :
|
||||
_nextId = 0,
|
||||
_registry = <T>{},
|
||||
_port = new ReceivePortSync();
|
||||
|
||||
String _add(T x) {
|
||||
// TODO(vsm): Cache x and reuse id.
|
||||
final id = '$_name-${_nextId++}';
|
||||
_registry[id] = x;
|
||||
return id;
|
||||
}
|
||||
|
||||
T _get(String id) {
|
||||
return _registry[id];
|
||||
}
|
||||
|
||||
get _sendPort => _port.toSendPort();
|
||||
}
|
||||
|
||||
class _FunctionRegistry extends _Registry<Function> {
|
||||
_FunctionRegistry() : super('func-ref') {
|
||||
_port.receive((msg) {
|
||||
final id = msg[0];
|
||||
final args = msg[1];
|
||||
final f = _registry[id];
|
||||
switch (args.length) {
|
||||
case 0: return f();
|
||||
case 1: return f(args[0]);
|
||||
case 2: return f(args[0], args[1]);
|
||||
case 3: return f(args[0], args[1], args[2]);
|
||||
case 4: return f(args[0], args[1], args[2], args[3]);
|
||||
default: throw 'Unsupported number of arguments.';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_FunctionRegistry __functionRegistry;
|
||||
get _functionRegistry {
|
||||
if (__functionRegistry === null) __functionRegistry = new _FunctionRegistry();
|
||||
return __functionRegistry;
|
||||
}
|
||||
/// End of function serialization implementation.
|
||||
|
||||
/// Object proxy implementation.
|
||||
|
||||
class _DartProxyRegistry extends _Registry<Object> {
|
||||
_DartProxyRegistry() : super('dart-ref') {
|
||||
_port.receive((msg) {
|
||||
// TODO(vsm): Support a mechanism to register a handler here.
|
||||
throw 'Invocation unsupported on Dart proxies';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_DartProxyRegistry __dartProxyRegistry;
|
||||
get _dartProxyRegistry {
|
||||
if (__dartProxyRegistry === null) {
|
||||
__dartProxyRegistry = new _DartProxyRegistry();
|
||||
}
|
||||
return __dartProxyRegistry;
|
||||
}
|
||||
|
||||
/// End of object proxy implementation.
|
||||
|
||||
_deserialize(var message) {
|
||||
return new _JsDeserializer().deserialize(message);
|
||||
}
|
||||
|
||||
// TODO(vsm): Replace this with a hash map once functions are
|
||||
// hashable.
|
||||
class _DeserializedFunctionTable {
|
||||
List data;
|
||||
_DeserializedFunctionTable() {
|
||||
data = [];
|
||||
}
|
||||
|
||||
find(Function f) {
|
||||
for (var item in data) {
|
||||
if (f == item[0]) return item[1];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
add(Function f, x) {
|
||||
data.add([f, x]);
|
||||
}
|
||||
}
|
||||
|
||||
_DeserializedFunctionTable __deserializedFunctionTable = null;
|
||||
get _deserializedFunctionTable {
|
||||
if (__deserializedFunctionTable == null) {
|
||||
__deserializedFunctionTable = new _DeserializedFunctionTable();
|
||||
}
|
||||
return __deserializedFunctionTable;
|
||||
}
|
||||
|
||||
class _JsDeserializer extends _Deserializer {
|
||||
|
||||
|
@ -225,53 +53,6 @@ class _JsDeserializer extends _Deserializer {
|
|||
throw 'Illegal SendPortSync type: $tag';
|
||||
}
|
||||
}
|
||||
|
||||
deserializeObject(List x) {
|
||||
String tag = x[0];
|
||||
switch (tag) {
|
||||
case 'funcref': return deserializeFunction(x);
|
||||
case 'objref': return deserializeProxy(x);
|
||||
case 'element': return deserializeElement(x);
|
||||
default: throw 'Illegal object type: $x';
|
||||
}
|
||||
}
|
||||
|
||||
deserializeFunction(List x) {
|
||||
var id = x[1];
|
||||
// If the sendPort is local, just return the underlying function.
|
||||
// Otherwise, create a new function that forwards to the remote
|
||||
// port.
|
||||
SendPortSync port = deserializeSendPort(x[2]);
|
||||
if (port is _LocalSendPortSync) {
|
||||
return _functionRegistry._get(id);
|
||||
}
|
||||
// TODO: Support varargs when there is support in the language.
|
||||
var f = ([arg0 = _UNSPECIFIED, arg1 = _UNSPECIFIED,
|
||||
arg2 = _UNSPECIFIED, arg3 = _UNSPECIFIED]) {
|
||||
var args = [arg0, arg1, arg2, arg3];
|
||||
var last = args.indexOf(_UNSPECIFIED);
|
||||
if (last >= 0) args = args.getRange(0, last);
|
||||
var message = [id, args];
|
||||
return port.callSync(message);
|
||||
};
|
||||
_deserializedFunctionTable.add(f, x);
|
||||
return f;
|
||||
}
|
||||
|
||||
deserializeProxy(x) {
|
||||
var id = x[1];
|
||||
var port = deserializeSendPort(x[2]);
|
||||
if (port is _JsSendPortSync) return new JsProxy._internal(port, id);
|
||||
if (port is _LocalSendPortSync) return _dartProxyRegistry._get(id);
|
||||
// TODO(vsm): Support this case.
|
||||
if (port is _RemoteSendPortSync) throw 'Remote Dart proxies unsupported';
|
||||
throw 'Illegal proxy: $port';
|
||||
}
|
||||
|
||||
deserializeElement(x) {
|
||||
var id = x[1];
|
||||
return _getElement(id);
|
||||
}
|
||||
}
|
||||
|
||||
// The receiver is JS.
|
||||
|
|
|
@ -83,10 +83,6 @@ js_interop_1_test: Fail
|
|||
js_interop_2_test: Fail
|
||||
js_interop_3_test: Fail
|
||||
js_interop_4_test: Fail
|
||||
js_interop_func_passing_test: Fail
|
||||
js_interop_obj_passing_test: Fail
|
||||
js_interop_obj_invoke_test: Fail
|
||||
js_interop_element_test: Fail
|
||||
measurement_test: Fail
|
||||
messageevent_test: Fail
|
||||
mutationobserver_test: Fail
|
||||
|
@ -129,10 +125,6 @@ indexeddb_4_test: Fail # Need window.mozIndexedDB instead of window.webkitIn
|
|||
inner_frame_test: Skip
|
||||
js_interop_3_test: Fail
|
||||
js_interop_4_test: Fail
|
||||
js_interop_func_passing_test: Fail
|
||||
js_interop_obj_passing_test: Fail
|
||||
js_interop_obj_invoke_test: Fail
|
||||
js_interop_element_test: Fail
|
||||
# Interfaces not implemented: SVGTests, SVGLangSpace, SVGExternalResourcesRequired, SVGStylable
|
||||
svg_3_test: Fail
|
||||
svgelement_test: Fail
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file
|
||||
|
||||
#library('JsInteropElementTest');
|
||||
#import('../../pkg/unittest/unittest.dart');
|
||||
#import('../../pkg/unittest/html_config.dart');
|
||||
#import('dart:html');
|
||||
#import('dart:isolate');
|
||||
|
||||
injectSource(code) {
|
||||
final script = new ScriptElement();
|
||||
script.type = 'text/javascript';
|
||||
script.innerHTML = code;
|
||||
document.body.nodes.add(script);
|
||||
}
|
||||
|
||||
var jsElementTest = """
|
||||
var canvas = document.createElement('canvas');
|
||||
document.body.appendChild(canvas);
|
||||
|
||||
var port = window.lookupPort('test1');
|
||||
port.callSync(canvas);
|
||||
""";
|
||||
|
||||
var dartElementTest = """
|
||||
var port = new ReceivePortSync();
|
||||
port.receive(function (data) {
|
||||
return (data instanceof HTMLDivElement);
|
||||
});
|
||||
window.registerPort('test2', port.toSendPort());
|
||||
""";
|
||||
|
||||
main() {
|
||||
useHtmlConfiguration();
|
||||
|
||||
test('js-element', () {
|
||||
int invoked = 0;
|
||||
|
||||
var port = new ReceivePortSync();
|
||||
port.receive((data) {
|
||||
expect(data is CanvasElement);
|
||||
++invoked;
|
||||
});
|
||||
window.registerPort('test1', port.toSendPort());
|
||||
|
||||
injectSource(jsElementTest);
|
||||
expect(invoked, equals(1));
|
||||
});
|
||||
|
||||
test('dart-element', () {
|
||||
injectSource(dartElementTest);
|
||||
|
||||
var port = window.lookupPort('test2');
|
||||
var div = new DivElement();
|
||||
var canvas = new CanvasElement(100,100);
|
||||
document.body.nodes.addAll([div, canvas]);
|
||||
expect(port.callSync(div));
|
||||
expect(!port.callSync(canvas));
|
||||
});
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file
|
||||
|
||||
#library('JsInteropFuncPassingTest');
|
||||
#import('../../pkg/unittest/unittest.dart');
|
||||
#import('../../pkg/unittest/html_config.dart');
|
||||
#import('dart:html');
|
||||
#import('dart:isolate');
|
||||
|
||||
injectSource(code) {
|
||||
final script = new ScriptElement();
|
||||
script.type = 'text/javascript';
|
||||
script.innerHTML = code;
|
||||
document.body.nodes.add(script);
|
||||
}
|
||||
|
||||
var dartToJsTest = """
|
||||
var port = new ReceivePortSync();
|
||||
port.receive(function (f) {
|
||||
return f('fromJS');
|
||||
});
|
||||
window.registerPort('test1', port.toSendPort());
|
||||
""";
|
||||
|
||||
var jsToDartTest = """
|
||||
var port1 = window.lookupPort('test2a');
|
||||
var result = port1.callSync(function (x) {
|
||||
return x*2;
|
||||
});
|
||||
|
||||
var port2 = window.lookupPort('test2b');
|
||||
port2.callSync(result);
|
||||
""";
|
||||
|
||||
var dartToJsToDartTest = """
|
||||
var port = new ReceivePortSync();
|
||||
port.receive(function (f) {
|
||||
return f;
|
||||
});
|
||||
window.registerPort('test3', port.toSendPort());
|
||||
""";
|
||||
|
||||
main() {
|
||||
useHtmlConfiguration();
|
||||
|
||||
test('dart-to-js-function', () {
|
||||
injectSource(dartToJsTest);
|
||||
|
||||
SendPortSync port = window.lookupPort('test1');
|
||||
var result = port.callSync((msg) {
|
||||
Expect.equals('fromJS', msg);
|
||||
return 'received';
|
||||
});
|
||||
Expect.equals('received', result);
|
||||
});
|
||||
|
||||
test('js-to-dart-function', () {
|
||||
var port1 = new ReceivePortSync();
|
||||
int invoked1 = 0;
|
||||
port1.receive((f) {
|
||||
++invoked1;
|
||||
var data = f(21);
|
||||
expect(data, equals(42));
|
||||
return 'fromDart';
|
||||
});
|
||||
window.registerPort('test2a', port1.toSendPort());
|
||||
|
||||
var port2 = new ReceivePortSync();
|
||||
int invoked2 = 0;
|
||||
port2.receive((x) {
|
||||
++invoked2;
|
||||
expect(x, equals('fromDart'));
|
||||
});
|
||||
window.registerPort('test2b', port2.toSendPort());
|
||||
|
||||
injectSource(jsToDartTest);
|
||||
|
||||
expect(1, equals(invoked1));
|
||||
expect(1, equals(invoked2));
|
||||
});
|
||||
|
||||
test('dart-to-js-to-dart-function', () {
|
||||
injectSource(dartToJsToDartTest);
|
||||
|
||||
validate(x) {
|
||||
expect(x, equals('fromCaller'));
|
||||
return 'fromCallee';
|
||||
}
|
||||
|
||||
SendPortSync port = window.lookupPort('test3');
|
||||
var f = port.callSync(validate);
|
||||
var result = f('fromCaller');
|
||||
Expect.equals('fromCallee', result);
|
||||
|
||||
});
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file
|
||||
|
||||
#library('JsInteropObjInvokeTest');
|
||||
#import('../../pkg/unittest/unittest.dart');
|
||||
#import('../../pkg/unittest/html_config.dart');
|
||||
#import('dart:html');
|
||||
#import('dart:isolate');
|
||||
|
||||
injectSource(code) {
|
||||
final script = new ScriptElement();
|
||||
script.type = 'text/javascript';
|
||||
script.innerHTML = code;
|
||||
document.body.nodes.add(script);
|
||||
}
|
||||
|
||||
var jsProxyTest = """
|
||||
function TestType(x) {
|
||||
this.x = x;
|
||||
}
|
||||
TestType.prototype.razzle = function () {
|
||||
return this.x * 2;
|
||||
}
|
||||
var data = new TestType(21);
|
||||
|
||||
var port = window.lookupPort('test1');
|
||||
port.callSync(data);
|
||||
""";
|
||||
|
||||
main() {
|
||||
useHtmlConfiguration();
|
||||
|
||||
test('js-proxy', () {
|
||||
int invoked = 0;
|
||||
|
||||
var port = new ReceivePortSync();
|
||||
port.receive((data) {
|
||||
expect(data.x, equals(21));
|
||||
expect(data.razzle(), equals(42));
|
||||
data.x = 100;
|
||||
expect(data.razzle(), equals(200));
|
||||
|
||||
++invoked;
|
||||
});
|
||||
window.registerPort('test1', port.toSendPort());
|
||||
|
||||
injectSource(jsProxyTest);
|
||||
expect(invoked, equals(1));
|
||||
});
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file
|
||||
|
||||
#library('JsInteropObjPassingTest');
|
||||
#import('../../pkg/unittest/unittest.dart');
|
||||
#import('../../pkg/unittest/html_config.dart');
|
||||
#import('dart:html');
|
||||
#import('dart:isolate');
|
||||
|
||||
injectSource(code) {
|
||||
final script = new ScriptElement();
|
||||
script.type = 'text/javascript';
|
||||
script.innerHTML = code;
|
||||
document.body.nodes.add(script);
|
||||
}
|
||||
|
||||
var jsProxyTest = """
|
||||
function TestType(x) {
|
||||
this.x = x;
|
||||
}
|
||||
TestType.prototype.razzle = function () {
|
||||
return this.x * 2;
|
||||
}
|
||||
var data = new TestType(21);
|
||||
|
||||
var port1 = new ReceivePortSync();
|
||||
port1.receive(function (x) {
|
||||
return x.razzle();
|
||||
});
|
||||
window.registerPort('test1a', port1.toSendPort());
|
||||
|
||||
var port2 = window.lookupPort('test1b');
|
||||
port2.callSync(data);
|
||||
""";
|
||||
|
||||
var dartProxyTest = """
|
||||
var port2 = new ReceivePortSync();
|
||||
port2.receive(function (x) {
|
||||
var port1 = window.lookupPort('test2a');
|
||||
port1.callSync(x);
|
||||
});
|
||||
window.registerPort('test2b', port2.toSendPort());
|
||||
""";
|
||||
|
||||
main() {
|
||||
useHtmlConfiguration();
|
||||
|
||||
test('js-proxy', () {
|
||||
int invoked = 0;
|
||||
|
||||
var port2 = new ReceivePortSync();
|
||||
port2.receive((x) {
|
||||
var port1 = window.lookupPort('test1a');
|
||||
var result = port1.callSync(x);
|
||||
expect(result, equals(42));
|
||||
++invoked;
|
||||
});
|
||||
window.registerPort('test1b', port2.toSendPort());
|
||||
|
||||
injectSource(jsProxyTest);
|
||||
expect(invoked, equals(1));
|
||||
});
|
||||
|
||||
test('dart-proxy', () {
|
||||
injectSource(dartProxyTest);
|
||||
|
||||
var buffer = new StringBuffer();
|
||||
buffer.add('hello');
|
||||
|
||||
var port1 = new ReceivePortSync();
|
||||
port1.receive((x) => x.add(' from dart'));
|
||||
window.registerPort('test2a', port1.toSendPort());
|
||||
|
||||
var port2 = window.lookupPort('test2b');
|
||||
port2.callSync(buffer);
|
||||
|
||||
expect(buffer.toString(), equals('hello from dart'));
|
||||
});
|
||||
}
|
Loading…
Reference in a new issue