Last active
August 29, 2015 14:02
-
-
Save vicb/18242765c0acc3fa8eaa to your computer and use it in GitHub Desktop.
Dart - JS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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