Skip to content

Instantly share code, notes, and snippets.

@vicb
Last active August 29, 2015 14:02
Show Gist options
  • Save vicb/18242765c0acc3fa8eaa to your computer and use it in GitHub Desktop.
Save vicb/18242765c0acc3fa8eaa to your computer and use it in GitHub Desktop.
Dart - JS
import "dart:js" as js;
import "dart:mirrors" as mirrors;
class JsProxy {
js.JsObject $js;
/// Creates the underlying JavaScript object from the [ctorFqn] and a list of [args]
JsProxy.proxy([String ctorFqn, List args = const []])
: this.proxyJsObj(
ctorFqn == null ?
js.context['Object'] :
ctorFqn.split('.').fold(js.context, (p, n) => p[n]),
args);
/// Creates the underlying Javascript object from a [jsObject] and a list of [args]
JsProxy.proxyJsObj([js.JsObject jsObject, List args = const[]]) {
if (jsObject == null) jsObject = js.context['Object'];
var jsArgs = new js.JsObject.jsify(args.map(_toJs));
$js = new js.JsObject(jsObject, jsArgs);
}
JsProxy._(this.$js);
/// Initializes the instance from an existing [jsObject]
factory JsProxy.fromJsObject(js.JsObject jsObject) =>
jsObject == null ? null : new JsProxy._(jsObject);
/// Recursively converts [JsProxy] to their underlying [JsObject]
dynamic _toJs(dart) {
if (dart is Iterable) {
return (dart as Iterable).map(_toJs);
}
if (dart is Map) {
(dart as Map).keys.forEach((k) => dart[k] = _toJs(dart[k]));
return dart;
}
if (dart is JsProxy) {
return (dart as JsProxy).$js;
}
return dart;
}
// Helper for generated getters, setters and methods
void $set(String key, value) {
$js[key] = _toJs(value);
}
dynamic $get(String key) {
// todo fromJsObject() if returns a JsProxy
return $js[key];
}
dynamic $call(String method, [List args = const[]]) {
// todo fromJsObject() if returns a JsProxy
var jsArgs = new js.JsObject.jsify(args.map(_toJs));
return $js.callMethod(method, jsArgs);
}
noSuchMethod(Invocation invocation) {
var pArgs = invocation.positionalArguments;
var field = mirrors.MirrorSystem.getName(invocation.memberName);
if (invocation.isGetter) {
return $js[field];
}
if (invocation.isSetter) {
field = field.substring(0, field.length - 1);
return $js[field] = _toJs(pArgs[0]);
}
if (invocation.isMethod) {
var returnType;
mirrors.reflect(this).type.metadata.forEach((m) {
if (m.type.isSubtypeOf(mirrors.reflectType(ProxyMethod)) &&
m.reflectee.name == field) {
print('match $field');
}
});
print('--match $field');
if (returnType is JsProxy) print('ret JsProxy');
var ret = $call(field, pArgs);
print('match $field');
}
throw new UnimplementedError(field);
}
}
class ProxyMethod {
final Type returnType;
final String name;
final List<Type> arguments;
const ProxyMethod(this.returnType, this.name, this.arguments);
}
class OlMap extends JsProxy {
OlMap(Map options): super.proxy('ol.Map', [options]);
View2d getView() => jsMethod(View2d, 'getView', []);
void setView(View view) => jsMethod(null, 'setView', [view]);
jsMethod(List args) {
}
}
class Tile extends JsProxy {
Tile(Map options): super.proxy('ol.layer.Tile', [options]);
}
class MapQuest extends JsProxy {
MapQuest(Map options): super.proxy('ol.source.MapQuest', [options]);
}
class View2d extends JsProxy {
factory View2d.fromJsObject(jsObject) = JsProxy.fromJsObject;
View2d(Map options): super.proxy('ol.View2D', [options]);
}
void main() {
var center = [0, 0];
var center2 = [4164462.1505763642, 985738.7965919955];
var mq = new MapQuest({'layer': 'sat'});
var tile = new Tile({'source': mq});
var view = new View2d({'center': center, 'zoom': 4});
var map = new OlMap({
'target': 'map',
'layers': [tile],
'view': view
});
print('map view: ${map.getView()}');
var view2 = new View2d.fromJsObject(map.$call('getView'));
view2.$call('setCenter', [center2]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment